CMake - compile with /MT instead of /MD

ksl

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()
Fraser

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 the if 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. calling set as you have shown), project will overwrite them. If you set the flags and cache them (e.g. using set(... CACHE), or by adding them via the command line arg -D as you have shown), then project won't overwrite them.

Also, since calling set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") doesn't use the CACHE option of set, then this change to the variable CMAKE_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 of set, 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 using set(... PARENT_SCOPE)).

So, to fix your issue, just move the if(MSVC) block to before all the add_subdirectory calls.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

if I change "runtime library" to MD, should I re-compile ALL MT libraries to MD?

From Dev

Add /MT compile flag to project

From Dev

How to tell if a lib was compiled with /mt or /md?

From Dev

Conceptual ambiguity between "/MD /MT " and "dll lib"

From Dev

CMake to compile java code

From Dev

CMake does not compile anything

From Dev

CMake not compile on raspberry

From Dev

How to compile cmake locally

From Dev

MT / MD mismatch when compiling cryptopp despite no library dependencies

From Dev

What difference does /MD, /MT make when compiling object files?

From Dev

Compile with clang instead of gcc

From Dev

CMake compile time generation of source

From Dev

How to compile glfw on OSX with cmake

From Dev

CMAKE COMPILE_DEFINITION not working

From Dev

cmake - error in compile regular expression

From Dev

CMake cross compile target rpath

From Dev

CMAKE - setting compile flags for libraries

From Dev

CMAKE cross compile libraries are not found

From Dev

CMake compile-time defines

From Dev

CMake, UnitBuild specific compile options

From Dev

CMake cross compile target rpath

From Dev

Using Art instead of Dalvik to compile

From Dev

NVCC compile to ptx using CMAKE's cuda_compile_ptx

From Dev

cmake will not compile to C++ 11 standard

From Dev

Building a toolchain with cmake to cross-compile for android

From Dev

CMake not generating compile_commands.json

From Dev

CMake generated Xcode project won't compile

From Java

Difference between using Makefile and CMake to compile the code

From Dev

How to compile jsoncpp with -fPIC through cmake