Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use fpm to fill the gap between gcc macros and gfortran to enable seamless cpp preprocessing #1084

Open
jalvesz opened this issue Oct 2, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@jalvesz
Copy link

jalvesz commented Oct 2, 2024

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

gcc -dM -E - < /dev/null

Windows

gcc -dM -E - <NUL:

And pass them through the preprocess.cpp mechanism by default.

Additional Information

No response

@jalvesz jalvesz added the enhancement New feature or request label Oct 2, 2024
@jalvesz jalvesz changed the title use fpm to fill the gap from gcc macros to enable seamless cpp preprocessing use fpm to fill the gap between gcc macros and gfortran to enable seamless cpp preprocessing Oct 2, 2024
@ivan-pi
Copy link
Member

ivan-pi commented Oct 18, 2024

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, -D__FreeBSD__

Concerning the behaviour of CMake, some material can be found in the discussion #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?

@jalvesz
Copy link
Author

jalvesz commented Oct 18, 2024

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.

@perazz
Copy link
Contributor

perazz commented Oct 19, 2024

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).

@jalvesz
Copy link
Author

jalvesz commented Oct 20, 2024

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.

@zoziha
Copy link
Contributor

zoziha commented Oct 23, 2024

Most macro definitions in GCC are rarely used by GFortran users. The commonly used ones are __GFORTRAN__ and _WIN32. In at least some scenarios, perhaps fpm can, like CMake, define a macro definition similar to CMAKE_SYSTEM_NAME to compile fpm projects and address the issue of operating system judgment first?

For example, fpm defines -DOS_WINDOWS and -D_WIN32 under Windows, defines -DOS_Linux under Linux, and defines -DOS_MACOS under macOS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants