2

I'm hoping to add some additional info logging if a program gets compiled the debug flag, -g. I'm using gfortran (although I think -g is ubiquitous). Stepping through the program, in this case, would be especially tedious in gdb. In particular, I'm hoping something like:

if (compiledwithg()) then
    print *, extraNiceInfo
endif

I know in C programs people usually would use stuff like #ifdef DEBUG, then print some additional info. As far as I know, there's no similar feature in Fortran. Does anyone know of anything like this?

Gavin Ridley
  • 371
  • 3
  • 15
  • 2
    You can often [get details](https://stackoverflow.com/q/46464763/3157076) of how a program was complied. – francescalus Nov 30 '17 at 07:20
  • 2
    The ifdef DEBUG can be uses in Fortran as well! Just enable the preprocessor. The reason for it is to not even compile those if checks, when not using them. – Vladimir F Героям слава Nov 30 '17 at 07:23
  • @Gavin : What about creating a source file with the function `compiled_with_g()` that returns always true ? If some source files are to be compiled with `-g` and some other aren't, what about creating a rule in the make file that generates this function per source file basis ? But using the preprocessor are proposed by @Vladimir, surely is the best solution – mszmurlo Nov 30 '17 at 08:46
  • A function is not necessary, a global constant is enough. – Vladimir F Героям слава Nov 30 '17 at 09:17

1 Answers1

6

To answer your question as it was asked: yes, it is now possible in modern versions of Fortran to know which options were used for compiling. As linked by francescalus, the COMPILER_OPTIONS() subroutine is the way to go.

  use iso_fortran_env

  logical :: compiled_with_g
  character(:), allocatable :: options

  options = compiler_options()

  compiled_with_g =  index(options, "-g") > 0

  print *, compiled_with_g
end

and

> gfortran-7 compiled_with_g.f90
> ./a.out 
 F
> gfortran-7 -g compiled_with_g.f90
> ./a.out 
 T

Note, it will trigger true on any compiler option that begins with -g or just contains substring -g. I tried using " -g ", but it is problematic when the string begins or ends with this option. You can also just add these two special cases to the if condition.


You can use the #ifdef DEBUG everywhere and compile all sources with -cpp or -fpp (depending on the compiler).


Or you can define a global constant in a module

#ifdef DEBUG
  logical, parameter :: compiled_with_g  = .true.
#else
  logical, parameter :: compiled_with_g  = .false.
#endif

and compile just this module with -cpp or -fpp.

You can do the same with a function compiledwithg() and have the macro only in the function.


Or you can have two versions of this very small module:

module debug_mod
  logical, parameter :: debug = .true.
end module

and

module debug_mod
  logical, parameter :: debug = .false.
end module

and set your build system (like a Makefile) to use the right one. The compiler will then remove the dead code, if the parameter is false, so it is as efficient, as a macro.