I'm a newbie to cmake (2.8.12.1) and I'm using it on Windows to generate the project files to build cpp-netlib using Visual Studio 2012.
By default it compiles with the /MDd compiler switch. I want to change it so that it uses /MTd.
I followed the advice given here https://stackoverflow.com/a/14172871 but it isn't working for me.
Specifically, I added the second line shown below in the if statement to CmakeLists.txt.
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif()
When I open the Visual Studio sln file I can see that the /MDd option is still set. Furthermore, I see the following in CMakeCache.txt:
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1
I've also tried setting the flags from scratch like this:
set(CMAKE_CXX_FLAGS_DEBUG "/MTd")
but that doesn't work either.
If I pass the option via the command line like this:
-DCMAKE_CXX_FLAGS_DEBUG="/MTd"
the option is successfully set in the Visual Studio projects.
Can anyone tell me what I'm doing wrong?
I would also appreciate it if someone could enlighten me as to where the values in the cache come from that I don't specify on the command line or aren't in CmakeLists.txt.
Adding CMakeList.txt as requested. I've never posted before so apologies if I've not done this right.
# Original from cpp-netlib.org with my edits
cmake_minimum_required(VERSION 2.8)
project(CPP-NETLIB)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTI_THREADED ON)
find_package( Boost 1.45.0 REQUIRED unit_test_framework system regex date_time thread filesystem program_options chrono )
find_package( OpenSSL )
find_package( Threads )
set(CMAKE_VERBOSE_MAKEFILE true)
if (CMAKE_BUILD_TYPE MATCHES Debug)
add_definitions(-DBOOST_NETWORK_DEBUG)
endif()
if (OPENSSL_FOUND)
add_definitions(-DBOOST_NETWORK_ENABLE_HTTPS)
include_directories(${OPENSSL_INCLUDE_DIR})
endif()
if (${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()
if (Boost_FOUND)
################# added #################
add_definitions(-DBOOST_ALL_NO_LIB)
#########################################
if (MSVC)
add_definitions(-D_SCL_SECURE_NO_WARNINGS)
endif(MSVC)
if (WIN32)
add_definitions(-D_WIN32_WINNT=0x0501)
endif(WIN32)
include_directories(${Boost_INCLUDE_DIRS})
enable_testing()
add_subdirectory(libs/network/src)
add_subdirectory(libs/network/test)
if (NOT MSVC)
add_subdirectory(libs/mime/test)
endif(NOT MSVC)
add_subdirectory(libs/network/example)
endif(Boost_FOUND)
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
################# added #################
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
#########################################
endif()
enable_testing()
Adding the code inside your
if
block should work fine. However, since it doesn't produce the required effect in your .sln, either the code inside theif
block isn't being executed or the flags are being replaced later in the CMakeLists.txt.As to where the cached values for these flags come from; CMake applies and caches what are considered to be useful default values for each default build type.
Have you added your changes to the flags before the
project
call?project
sets up a lot of things, including the compiler flags. If you set these flags without caching them (i.e. callingset
as you have shown),project
will overwrite them. If you set the flags and cache them (e.g. usingset(... CACHE)
, or by adding them via the command line arg-D
as you have shown), thenproject
won't overwrite them.Also, since calling
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
doesn't use theCACHE
option ofset
, then this change to the variableCMAKE_CXX_FLAGS
won't appear in your CMakeCache.txt file.In order to get this into the cache, you'd have to also use the
FORCE
option ofset
, since you'd be telling CMake to replace an already-cached value (CMake itself caches these flag variables by default). I wouldn't recommend this however - I can't see why you'd need to do this, and you'd be best to look for a better way than appending the flag(s) you want, since every time CMake runs the appended flags would be re-appended.If this doesn't allow you to resolve your issue, perhaps you could show a full (small) CMakeLists.txt which exhibits the problem?
UPDATE:
OK - The problem is a scoping issue. The changes to the compiler flags will be applied to all targets (exes/libs) which are defined in that CMakeLists.txt, but only to subdirectory targets which are added after the flags are modified.
The
add_subdirectory
command introduces a new scope (although this isn't mentioned in the docs) which inherits a copy of the parent's variables. However, subsequent changes to the variables in the parent scope don't affect the child copies, and likewise changing the child copies doesn't affect the value of the parent's copies (unless you force it usingset(... PARENT_SCOPE)
).So, to fix your issue, just move the
if(MSVC)
block to before all theadd_subdirectory
calls.