-
Notifications
You must be signed in to change notification settings - Fork 45
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
Adjust how TriBITS handles compiler and linker options according to modern CMake best practices #375
Comments
CC: @masterleinad, @keitat, @fnrizzi, @crtrott I know Kokkos made the change to handle compiler flags as a list of arguments due to @jjwilke's work but where did that change in CMake come from and where is that documented? Note that in "Professional CMake: 5th Edition" it says:
so when did it change that CMake wants you to handle compiler and linker flags as a list of arguments instead of a single string? There is no hit of how you are supposed to handle this at: I can't find handling compiler options as lists anywhere. (On the other hand, handling arguments to add_test() as a list has been the case for a long time.) |
Some interfaces take lists of canonical options, others take flags as command-line string fragments. In general, settings with CMake MR 5915 added documentation that The add_compile_options and target_compile_options commands and associated infrastructure use |
So @bradking partly the problem is I think we add stuff via add_compile_options which has quotes in the flags we need to pass to the compiler, and something then went wrong at the export for the Trilinos install. But I understand you that lists are the correct way to go for add_compile_options right? |
Okay, I see that in 'git-master' at: which says:
so this will be in CMake 3.21+ documentation. Thanks for pointing that out.
With modern CMake, everything should be target based, right? So you should only use Okay but how is |
But how does |
Yes. CMake will quote/escape things for you. Same for
Both are used. The
If the user adds ABI-changing flags to
If the project wants to add optional/overridable flags, it should provide its own cache settings that affect how it adds them. |
So we actually discussed this recently. CMAKE_CXX_FLAGS set during Kokkos install are NOT propagated to downstream folks right now (when using Kokkos outside of Trilinos). We considered telling users to set Kokkos_CXX_FLAGS for stuff which should be propagated, and we would attach those to add_compile_options. |
Ah @bradking: what I just wrote there is essentially the recommended way of handling this? |
Yes, though I'd be interested in an example of what flags you might propagate to consumers, e.g. via |
we propagate all kinds of stuff. In particular a lot of architecture specific and backend specific flags. Like all the "compile this for GPU" flags, "use these optimization flags", "enable specific options" stuff. Its all here somewhere: https://github.com/kokkos/kokkos/tree/master/cmake |
@crtrott, @bradking, so it would be considered recommended/good practice for a modern CMake project to allow users to pass compiler options on the CMake command-line as:
? Is that a reasonable convention/standard? NOTE: If you don't define |
@bartlettroscoe that may work, but I think only experience will tell for sure. Note that The FWIW, I generally try to avoid forcing flags on consumers, even through
The last bullet is somewhat mitigated by target-centric APIs because only consuming targets that link to the relevant targets get those requirements. IIUC, Kokkos's purpose is in part to provide these flags. |
Okay, I think I see how this works. The command So the only way to get compiler options to propagate to downstream targets is to use If this is the case, then I guess you have to define
(You would allow this to be specified at the TriBITS package level as well with But to apply such options consistently and call
The word "typically" worries me here. Is it documented (and is it pinned down with automated tests in the CMake test suite) what order all of these are these compiler flags are listed when a given source file is actually compiled? That is actually very important in some cases (as some flags can override others). The set of compiler flags that I see here are:
So what is the order? I could do some experiments to try to find out but it would be better if the documentation just explicitly spelled this out. And then there is the question of how can the user append arbitrary compiler options to override whatever is set in the internal CMakeLists.txt files in case they need to? For TriBITS, I provided
Note that the current Actually, the refactoring in #299 will technically break backward compatibility of Trilinos in that targets exported/imported from Trilinos will have the Kokkos system-specific flags set in their
Note that for deeply templated C++ code is usually very dangerous to mix and match compilers and even different compiler versions. The only safe way to build a stack of C++ software that uses the C++ standard library is to use the exact same C++ compiler for everything from the bare metal on up. (We are lucky if we get a large amount of C++ code to build and work when using even a single C++ compiler :-))
In general, I agree. A good library (even a C++ library) should be usable without any compiler flags (not even |
Yes. I mean its impossible for normal users to figure out which flags are needed on all these different platforms to get correct code. In some of these cases (like for SYCL) we figured these flags out only with direct input from the compiler developers. It is a pretty iffy situation, made worse by the fact that all these new compilers by default identify as clang even though they might not even accept all normal clang flags. |
Yes.
After thinking about that approach more, there may be some problems:
In that case, why offer a general-purpose
CMake has no model for that. The project code has final control. If it wants to offer control to the user, the project code must do that. In particular, the project should offer settings to avoid getting the flags in the first place.
It is true for Ninja and Makefile generators. On generators like Visual Studio, we don't actually control the specific order of the command line. MSBuild does that. We map from the command-line flags to
I opened CMake MR 6187 to formally document and test the order. |
CC: @keitat, @crtrott, @masterleinad
@bradking, that is a good point. With the can of worms that de-duplication and ordering of compiler options opens up as described above, I think it is best that TriBITS and Trilinos (and other TriBITS-base projects) don't even bother provide a general way to set compiler options that get forwarded to downstream customers automatically. Note that to maintain backward compatibility, the TriBITS-generated So going forward, the refactoring of TriBITS and Trilinos will just focus on making sure that any
If, in the future, we find the need to support compiler options that get automatically forwarded to downstream customers, then we will use the
Thanks for that! In conclusion, I don't think there is anything more that needs to be done here in this Issue #375. We will just focus on doing #299 correctly (i.e. propagating everything correctly between targets with exported/imported targets in Thanks for the discussion! |
CC: @keitat
Part of modernizing TriBITS and CMake build systems based on TriBITS is the handling of compiler and linker options. This story is to probe the issues at hand and some of the driving requirements from Kokkos and Trilinos.
A comment that come from #299 (comment) was "change variables to lists instead of strings". In "Professional CMake: 5th Edition", it says:
So what are all of the issues here?
Tasks:
=> CMake projects should use
target_compile_options( ... <PUBLIC|INTERFACE> ...)
sparingly and likely only Kokkos will do this.=> For now, TriBITS will not add any special cache variables for accepting compiler flags that will be propagated to downstream customers and will just stick with
CMAKE_<LANG>_FLAGS
(see below)The text was updated successfully, but these errors were encountered: