Visual Studio 2017 comes with full CMake integration. To learn about this combination, I was starting with this basic sample:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(foo)
add_executable(foo foo.cpp)
and
// foo.cpp
int main() {}
This properly generates build scripts, and compiles and links with no issues. That was easy.
Trying to set compiler options, on the other hand, turned out to be anything but trivial. In my case I was attempting to set the warning level to 4.
The obvious solution
add_compile_options("/W4")
didn't pan out as expected. The command line passed to the compiler now contains both /W4
(as intended) as well as /W3
(picked up from somewhere else), producing the following warning:
cl : Command line warning D9025: overriding '/W3' with '/W4'
To work around this, I would need to replace any incompatible compiler option(s) instead of just adding one. CMake does not provide any immediate support for this, and the standard solution (as this Q&A suggests) seems to be:
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
This, however, has two issues:
- It sets the global
CMAKE_CXX_FLAGS
, applying to all C++ targets. This may not be intended (not an issue for me right now). - It doesn't scale. For every compiler option to add, you would have to read up on incompatible options, and manually strip those first. This will inevitably fail1.
My question is two-fold:
- Where does the CMake integration pick up default settings from, and can this be controlled?
- How do you set compiler options in general? (If this is too broad a topic, I'd be happy for help on setting the warning level only.)
1 Incidentally, the solution I replicated fails to account for the
/Wall
option, that is incompatible with /W4
as well.