Open jalvesz opened 2 weeks ago
You are referring to the issue also documented here, https://cyber.dabamos.de/programming/modernfortran/preprocessor.html,
As CPP, the preprocessor of GNU Fortran, is not indicating the current operating system, we have to pass the macro through argument -D, in this particular case, -DFreeBSD
Concerning the behaviour of CMake, some material can be found in the discussion https://github.com/fortran-lang/fpm/discussions/730. If I understood you correctly, you are saying the CMake somehow merges the preprocessor environment of gcc and gfortran, and then invokes gfortran on the preprocessed file?
Well, I had done some tests in which CMake managed to preprocess for instance the WIN32 definition... I'm testing a single file test anew and I'm not getting the behavior, so I might need to go again through it ...
Now, CMake does have OS definitions which can be used. For instance, one can add the following to a CMakeLists.txt:
# Convert CMAKE_SYSTEM_NAME to uppercase
string(TOUPPER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME_UPPER)
# Pass the uppercase system name as a macro
add_compile_options(-D${SYSTEM_NAME_UPPER})
So any of the system names provided here https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_NAME.html can be used as a definition.
It seems that it would also be necessary to find way to recover gcc definitions with CMake.
One way to identify the OS and save it as a parameter
would be to use the compiler_version
and compiler_options
intrinsic functions. It will certainly need quite some testing and experimenting, but I believe that at least for the major compilers it would be relatively easy to come up with a parameter boolean flag that stores whether the local system is Windows/unix/etc.:
use iso_fortran_env
character(1024), parameter :: opts= compiler_options()
character(1024), parameter :: vers =compiler_version()
logical :: is_windows = index(opts,"C:\")>0 .or. &
index(opts,":\")>0 .or. &
index(vers,'Windows')>0 .or. &
index(vers,'MSYS')>0
print *, opts
print *, vers
print *, 'is_windows = ',is_windows
end
note that this would not work if we're cross-compiling (i.e. a Windows .exe from a unix machine).
For cross compilation I guess it would be necessary to distinguish between the current build OS and the "target" OS. If the target is different from the build OS then one should pass this as an optional parameter. I'm not familiar with this though, I usually build directly for the target OS and use a virtual machine to build for a different one, which in any case implies that the build system sees it as "native".
I was imagining to maybe print the defined macros from the compiler to a temp file which can be retrieved to pass the macros as definitions, at least for gnu as it seems that intel fortran does the job. But for cross compilation this would not be enough indeed.
Description
Hi, I would like to propose that fpm fills in the gap left between gcc and gfortran where all defined macros are not available from gfortran without using CMake.
While there are many discussions about preprocessors, most of the defacto preprocessing is being done using cpp/fpp. Simple tasks such as determining on which OS a program is running (which can be set at compile time) either rely on C preprocessing or having to use
get_environment_variable
at runtime.Possible Solution
One idea would be to make it such that fpm catches the list of macros from gcc by running (if using gfortran) the commands: Linux
Windows
And pass them through the
preprocess.cpp
mechanism by default.Additional Information
No response