0

I have a set of C++ potential compiler flags stored in a variable and over it, I'm running the following test on CMake 3.14.5, to see which ones applies and which doesn't to a certain version of the compiler (I'm using GCC, CLANG and ICC to compile the same project, hence the necessity to apply to each only the relevant flags):

foreach (FLAG IN LISTS CXX_COMPILER_FLAGS_TO_USE)
    # Check if the compiler supports the flag.
    string(REGEX REPLACE "[-=+]" "" FLAG_NO_SIGNS ${FLAG}) # <- The variable recieving the result of the test can't have those signs in its name
    check_cxx_compiler_flag(${FLAG} CXX_COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
    if(CXX_COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
        message(STATUS "Flag ${FLAG} accepted by C++ compiler")
        string(APPEND CMAKE_CXX_FLAGS " ${FLAG}")
    else()
        message(STATUS "Flag ${FLAG} not accepted by C++ compiler")
    endif()
endforeach()

For GCC 8 and the -Wabi flag, I get:

-- Performing Test CXX_COMPILER_SUPPORTS_Wabi
-- Performing Test CXX_COMPILER_SUPPORTS_Wabi - Failed
-- Flag -Wabi not accepted by C++ compiler

Now, if instead of pushing the flags inside CMAKE_CXX_FLAGS, I use add_compile_options(), the result of my test changes!!!:

foreach (FLAG IN LISTS CXX_COMPILER_FLAGS_TO_USE)
    # Check if the compiler supports the flag.
    string(REGEX REPLACE "[-=+]" "" FLAG_NO_SIGNS ${FLAG})
    check_cxx_compiler_flag(${FLAG} CXX_COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
    if(CXX_COMPILER_SUPPORTS_${FLAG_NO_SIGNS})
        message(STATUS "Flag ${FLAG} accepted by C++ compiler")
        add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${FLAG}>)  # <- ONLY THIS LINE CHANGED
    else()
        message(STATUS "Flag ${FLAG} not accepted by C++ compiler")
    endif()
endforeach()

The test for -Wabi now reports:

-- Performing Test CXX_COMPILER_SUPPORTS_Wabi
-- Performing Test CXX_COMPILER_SUPPORTS_Wabi - Success
-- Flag -Wabi accepted by C++ compiler  

Which leads the second case to fail on compile time later:

cc1plus: error: -Wabi won't warn about anything [-Werror=abi]

It's like add_compile_options() would have modified the result of check_cxx_compiler_flag(), which is weird since the latter runs BEFORE the former.

Just out of curiosity, I combined both approaches in the same test (which could sound redundant):

add_compile_options($<$<COMPILE_LANGUAGE:CXX>:${FLAG}>)
string(APPEND CMAKE_CXX_FLAGS " ${FLAG}")

and that works, meaning -Wabi is NOT added to the compilation options for C++ files.

I wouldn't expect that replacing the usage of CMAKE_CXX_FLAGS by add_compile_options() would change the result of a test made PREVIOUSLY and using a third function.

So, the question is: Am I doing something I'm not supposed to? Or did I hit a real bug?

I couldn't find anything similar in the knowledge base, and when I post the issue to the CMake bug tracker, I really didn't understand the response.

Thanks a lot for your help.

  • 1
    It looks like the variable `CMAKE_CXX_FLAGS` is changed between the different `cmake` runs. This is why you got different results of the check. You may add `message("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")` before `check_cxx_compiler_flag` invocation to see a difference. – Tsyvarev Jul 02 '19 at 20:46
  • @Tsyvarev, I think you misunderstood my question. I'm using exactly the same script in two different runs, modifying only one line on it between the runs. It's not the same code with the small change repeated twice in the same script. – Alvaro Palma Aste Jul 02 '19 at 21:04
  • 2
    I understand that. But it is almost impossible that calls after `check_cxx_compiler_flag` affect on its results. So I guess that results of that call are affected by something else, e.g. by different value of `CMAKE_CXX_FLAGS` which you have at the time of that check. – Tsyvarev Jul 02 '19 at 21:43
  • That's what really puzzles. I'm only changing the line I mentioned, which is run _AFTER_ `check_cxx_compiler_flag`, I can't figure out how that line could affect the result of an operation run previously. – Alvaro Palma Aste Jul 03 '19 at 14:56
  • 1
    So, have you tried to print value of `CMAKE_CXX_FLAGS` variable before the `check_cxx_compiler_flag`? Exactly this variable may affect on the check result. – Tsyvarev Jul 03 '19 at 15:35
  • Sorry for the so late response :-). Yes, I printed the variable, as: `message(STATUS "CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")` before `check_cxx_compiler_flag(${FLAG}` and `CMAKE_CXX_FLAGS` simply remains empty all the time. – Alvaro Palma Aste Feb 25 '21 at 21:14

0 Answers0