3

Visual Studio allows to select either the cl compiler or the clang-cl compiler to build projects -- these are called toolsets. These two compilers have different sets of flags, and in particular different flags for disabling warnings. Flags for one compiler produces errors on the other.

This problem can be solved in Visual Studio for both compilers at the same time by defining compiler flags conditionally based on the used toolset. Official documentation for that here.

I use CMake to generate the Visual Studio projects. How can I make CMake add such conditional flags for the generated Visual Studio projects?

2 Answers 2

3

You can use CMAKE_CXX_COMPILER_ID and CMAKE_CXX_SIMULATE_ID with your favourite way of handling compilers (if-else or generator expressions)

Output for -T ClangCL (Visual Studio 2019):

message(STATUS ${CMAKE_CXX_COMPILER_ID}) // Clang
message(STATUS ${CMAKE_CXX_SIMULATE_ID}) // MSVC

Output with no toolkit (Visual Studio 2019):

message(STATUS ${CMAKE_CXX_COMPILER_ID}) // MSVC
message(STATUS ${CMAKE_CXX_SIMULATE_ID}) // <empty>
Sign up to request clarification or add additional context in comments.

2 Comments

CMAKE_CXX_SIMULATE_ID is really useful; I did not know that existed. I used that to branch settings for clang-cl. A strange detail is that if (NOT ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")) works as expected but if (NOT (${CMAKE_CXX_SIMULATE_ID} STREQUAL "MSVC")) does not (it is always true).
@kaba this happens when CMAKE_CXX_SIMULATE_ID not defined (empty). the second condition should yield an error. simply use if (NOT (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")).
3

Essentially a more modern approach to the earlier question here, you can use an if-statement to check the compiler type, and set compile flags based on that:

if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
    # Disable a Clang warning type.
    target_compile_options(MyLib PRIVATE -Wno-unused-variable)
elseif(MSVC)
    # Disable a MSVC warning type.
    target_compile_options(MyLib PRIVATE /wd4101)
endif()

For putting this into a single expression, you can use CMake generator expressions (which are evaluated at the CMake buildsystem generation stage):

target_compile_options(MyLib PRIVATE 
    "$<IF:$<STREQUAL:${CMAKE_CXX_COMPILER_ID},Clang>,-Wno-unused-variable,/wd4101>"
)

For reference, here is a list of all of the clang warnings types.

5 Comments

I have these kind of compiler-specific switches already. The problem in the question is a bit different: the same generated Visual Studio project has to be able to work for both cl and clang-cl when switched in the Visual Studio project settings without regenerating the project by CMake.
@kaba If you are switching the compiler/toolset, the CMake really should be re-run.
I see. I could deal with that if the MSBuild conditions cannot be made to work.
@kaba I also added a generator expression approach which might be closer to what you're try to achieve.
I concur that rerunning CMake is better than relying on special MSBuild features.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.