I'm new to CMake and I've run into a little bit of a snag here, wondering if there is an "elegant" solution to this problem, or maybe there's just an easy solution.
As an example, for setting up compiler flags I'm doing the following:
target_compile_options(${PROJECT_NAME}
PUBLIC
$<$<CXX_COMPILER_ID:GNU>:"-some_gnu_flag">
$<$<CXX_COMPILER_ID:Clang>:"-some_clang_flag">
$<$<CXX_COMPILER_ID:MSVC>:"/some_msvc_flag">
)
This works perfectly as expected, except for when I try a build using clang-cl as a compiler, ie:
cmake .. -G "Visual Studio 15 2017 Win64" -T "LLVM-vs2014"
The CXX ID is reported as Clang (it is clang after all) but I don't want to be using Clang flags, I actually want to be using MSVC flags since clang-cl is designed to be a drop in replacement for MSVCs cl - and hence only accepts MSVC style flags.
So what are some good solutions to this without creating some messy code? I know I could probably do a bunch of if() checks and set some variable, but I was trying to stick to "modern cmake" conventions, hence why I was using generator expressions to begin with.
● The driver provides convenience and compatibility ● clang-cl is a cl.exe compatible driver mode for clang ● It understands the environment, the flags, and the tools ● Integrates with Visual Studio ● /fallback allows bring-up of large projects.
We do recommend that you use the most recent version of Clang to get the best support in the IDE.
Clang is designed as an API from its inception, allowing it to be reused by source analysis tools, refactoring, IDEs (etc) as well as for code generation. GCC is built as a monolithic static compiler, which makes it extremely difficult to use as an API and integrate into other tools.
When Clang compiles C++ code for Windows, it attempts to be compatible with MSVC. There are multiple dimensions to compatibility. First, Clang attempts to be ABI-compatible, meaning that Clang-compiled code should be able to link against MSVC-compiled code successfully.
This is my current "solution". I found the CMAKE_CXX_SIMULATE_ID variable which holds the information I want - although this still feels a bit dirty to me.
# Get compiler info
set(CXX_FLAGS_STYLE_GNU OFF)
set(CXX_FLAGS_STYLE_MSVC OFF)
set(CXX_FLAGS_STYLE_CLANGCL OFF)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CXX_FLAGS_STYLE_GNU ON)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
set(CXX_FLAGS_STYLE_CLANGCL ON)
else ()
set(CXX_FLAGS_STYLE_GNU ON)
endif ()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(CXX_FLAGS_STYLE_MSVC ON)
else ()
message(FATAL_ERROR "Unsupported compiler!")
endif ()
# Compiler flags
target_compile_options(${PROJECT_NAME}
PRIVATE
## GCC/Clang Flags
$<$<BOOL:${CXX_FLAGS_STYLE_GNU}>:"-someflag">
## MSVC flags
$<$<BOOL:${CXX_FLAGS_STYLE_MSVC}>:"/someflag">
## CLANG-CL flags
$<$<BOOL:${CXX_FLAGS_STYLE_CLANGCL}>:"-someflag">
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With