Handling compiler arguments in fpm project - Blog by Jakub Jelinek

Hello everyone,

my name is Jakub and this summer I am working on compiler arguments support for fpm.
If you have any suggestions or ideas for this topic, please join the call mentioned in the post below:
I will try to update you about my progress at least once a week so that I can receive feedback and suggestions from the community.
I am looking forward to contributing to this awesome project and I want to thank you for giving me this opportunity.


Progress status - #1
I have spent most of last week and today reading fpm documentation. I have to say that it is quite neat. I like that the documentation allows the user to see both the subroutines and procedure specification and it code itself.
Today I’ve had a brief chat with Laurence and Brad which helped me to understand the most important parts of the fpm build process.
For the rest of the week, I plan to research the documentation more in-depth and focus on studying how to write tests in Fortran well. At the end of the week, I also want to have a clear idea of what I need to do for this project and what I should start with.


Progress status - #2
As mentioned in the previous post this week was about planning for me. After Tuesday’s meeting with @certik, @lkedward, @everythingfunctional, and @awvwgk I summarised the next week’s plan in these points:

  1. Create a test package with compiler profiles specified in the toml. This will allow me to test out the features introduced in the steps below.
  2. Modify the new_package subroutine in fpm_manifest_package to accept a new table in the toml file called profiles. I have researched the documentation of the fpm modules in depth during the week, but I still need to research more on the toml-f ones (most likely just the get_value methods).
    Then I need to create a new derived type profile_config_t, representing each of the profiles parsed out of the toml table. There is going to be an allocatable list of the in package_config_t. Profiles need to be handled in info and check subroutines too, but only check is required for basic functionality, therefore I will probably include it in check first and in info later.
  3. I have not researched all the functionalities in the build_model subroutine of the fpm.f90 yet, therefore if I have time when done with steps 1 and 2, I will look into it as the next step is going to be including profiles in model.

For anybody interested in this project, please share your suggestions or comments with me or visit one of the weekly mentor chats happening every Thursday at 14.00 UTC at this link.


Progress status - #3
I have started coding on Monday by creating the new source file fpm_manifest_profiles.f90. This includes the profile_config_t type, all subroutines necessary for parsing toml profiles table and a subroutine find_profile which finds the best matching profile based on given arguments.
The parsing of the toml should follow the following rules:

  1. Default behaviour is the creation of a profile with the full specification, e.g.
flags="-g -Wall"
  1. If a user does not specify the name of the profile flag (debug in the last example), add the flags to all profiles that match the other two fields (compiler and OS).
  2. If a user does not specify the name of the compiler, use the default compiler name (currently set to gfortran).
  3. If a user does not specify the operating system, use these flags if no profile matches OS exactly. Example:
flags="-g -Wall"

flags="/g /Wall"

Assuming we are on Unix based system, the first profile is going to be used. On Windows device, the second profile has priority.
The built-in profiles from fpm_compiler are loaded now to the profiles and if a user does not specify a better matching profile, they can be used. If anybody knows, what the id_f95 stands for, please let me know. I also assumed that id_nvhpc should use nvfortran as a compiler.

The user’s profile has to be specified from the command line with the --profile flag. If this flag is not present, build_model checks whether the settings%flag field is not empty and in case it is, debug profile is used. If both settings%flag and settings%profile are present, the flags are appended together.

All my commits are in my Load_compiler_arguments branch. If you have any suggestions or comments on my code, please do not hesitate to tell me.

Next steps:

  1. Error handling
  2. Testing
  3. Implementation of c_flags and link_time_flags
  4. Research on dependencies in build_model and discussion about the flag scope implementation

Hey Jakub, great work!

By the looks of things it is just an alias for the gfortran compiler enumeration which is used commonly on Linux systems (defining code is here: fpm/fpm_compiler.f90 at 6d9004d93460dc15b99051c90d1b58d724b010e6 · fortran-lang/fpm · GitHub).

Historically on Unix systems the Fortran compiler was named f77. Before gfortran became the primary open-source compiler, there were compilers g77 and g95. Before these there was f2c, so f77 might have been a driver which first translated the Fortran sources to C using f2c and then invoked a C compiler. At some point the OS developers probably introduced f95 as an alias for an open-source f95 compiler (meaning it supported free form syntax and other novelties introduced with the F90 and F95 language standards). If anyone is more familiar with Fortran compiler history please correct me.

Maybe @awvwgk can comment more on the compiler enumerations (@kubajj, you can use the Blame button in the GitHub UI to find out who contributed each part of the code and ping them).

1 Like

I might have posted this already somewhere in a GitHub issue.

I took most of the identifiers either from meson’s reference tables (Reference tables) or CMake’s compiler identifiers (CMAKE_<LANG>_COMPILER_ID — CMake 3.20.3 Documentation). There is also an incredible detailed compendium of compiler macros for compiler, platform and architecture identification at Pre-defined Compiler Macros / Wiki / Compilers, which is comping in quite handy ever so often.

The reason to not use the Fortran compiler name is that it is potentially inaccurate, when dealing with e.g. the flang compiler which can either be the classic one, or the rebranded f18 frontend, or AMDs patched AOCC variant. The f95 compiler on most systems is a symlink to gfortran, but there is also Oracle’s Fortran compiler, which still goes under the name f95. An accurate compiler identification still requires us to parse the version output of the compilers or check the defined macros, which we are currently not doing but probably have to do at some point.


Progress status - #4
This week I started by implementing basic error handling for compiler profiles and added two tests (one testing the various valid combinations and one for one invalid case). Then I added the c_flags and link_time_flags fields to the profile_config_t type and tried to make the logic handling the parsing of toml easier to understand.
On Thursday, I have merged all the PRs from master to avoid merge conflicts further in the development.
The rest of the week, I was researching the future implementation of the scope of profiles (global, package-wide, source-file-local) and after discussion with Brad and Laurence during yesterday’s meeting, I think that I have a well-formed idea about how to approach it. During the loop over dependencies in build_model, I store the profiles from the dependency manifest in the newly added profiles field in package_t. The logic handling the flags is moved to the end of build_model to account for future features with scope. Flags will be added as strings to the src_file_t in the get_object_name function, which will be slightly modified to account for the hash of flags being created in a different subroutine passed to the join_path instead of model%output_directory. Brad and Laurence both agreed that we should not store all the builds in one archive but rather more.


Thank you @kubajj for the updates! Good job.

POSIX specifies a fort77 program, but I’ve never seen it used and even my own machine does not have it.

Probably just historical trivia at this point, but figured I’d mention it.

I don’t know if this has been mentioned before, but the Flang developers put together a list of compiler options and how they compare across different compilers.

This hasn’t been updated since November 2020, but it would be great if we can extend it, or use it as the seed for a more comprehensive list that is used in your project, @kubajj.


@gak, very cool, thanks for posting the link. And welcome to the Fortran Discourse!

A document like that is something we should even maintain at fortran-lang.org as a community. This is related to the discussion at: Should fpm be compiler independent as much as possible with regards to flags? · Discussion #443 · fortran-lang/fpm · GitHub where we brainstormed (and mostly agreed) to make fpm eventually support the most commonly used options.


Progress status - #5
This week, I have worked on the package and file scope of flags and moved the hashing of flags from fpm_command_line's check_build_vals to fpm_targets to a new function that operates on a per-file basis.
After yesterday’s discussion with Brad, I have created a draft of a PR. Please have a look at my progress if you’ve got a minute and let me know what I should improve/add/change/…
I have tried to comment on the important parts concerning syntax of the toml both in manifest_reference.md and src/fpm/manifest/profiles.f90. Please let me know if my explanation makes sense.

For the next steps, I am hoping to implement changes suggested from my PR and then look into the list of compiler options suggested by @gak. The plan is to try to find options that are similar to fast math and try to decide what to do with them. Initial ideas were to create a field for forbidden flags that would make listed flags forbidden from inclusion in the whole project and the packages using this package as a dependency. Is this something that would fit the needs of @certik?

If you have additional/better ideas of what to work on, please let me know as it helps me focus on the development itself rather than coming up with what should be done next.


Thanks for the update. Great work. The PR is getting big, thus harder to review. It’s a good idea to keep sending smaller PRs, get them reviewed and merged on a quicker basis. Just something to keep in mind for your future patches.

I would have to see the details of the “forbidden flags”. When is your meeting next week? I’ll try to attend and we can discuss it.

1 Like

It is probably on Thursday at 2 pm UTC if @lkedward is free this time as Brad is not.

That’s 7am my time, which is too early. If you can postpone by 2h, then I can attend.

1 Like

No problem, 4pm UTC works for me. How is that for you @kubajj and @everythingfunctional?

1 Like

I am free at that time.

Ok, let’s do it. @kubajj would you mind sending a calendar invite please?

1 Like

I think I did, let me know if it worked.

Can we use the usual link @lkedward?

Yes @kubajj and @certik we can use the same Zoom link, see here: GSoC project meeting - fpm compiler flags - #10 by lkedward

I’ve changed the time for this occurence to 16:00 UTC 24th June 2021.

A reminder that this meeting is open to everyone who is interested in the project.

1 Like