CMake-使用/MT而不是/MD进行编译 [英] CMake - compile with /MT instead of /MD

查看:151
本文介绍了CMake-使用/MT而不是/MD进行编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是cmake(2.8.12.1)的新手,并且在Windows上使用它来生成用于使用Visual Studio 2012构建cpp-netlib的项目文件.

默认情况下,它使用/MDd编译器开关进行编译.我想对其进行更改,使其使用/MTd.

我遵循了此处给出的建议 https://stackoverflow.com/a/14172871 ,但它对我不起作用.

具体来说,我在if语句中向CmakeLists.txt添加了下面显示的第二行.

  if(MSVC)设置(CMAKE_CXX_FLAGS"$ {CMAKE_CXX_FLAGS}/bigobj")设置(CMAKE_CXX_FLAGS_DEBUG"$ {CMAKE_CXX_FLAGS_DEBUG}/MTd")万一() 

当我打开Visual Studio sln文件时,可以看到/MDd选项仍然设置.此外,我在CMakeCache.txt中看到以下内容:

 //编译器在调试版本期间使用的标志.CMAKE_CXX_FLAGS_DEBUG:STRING =/D_DEBUG/MDd/Zi/Ob0/Od/RTC1 

我也尝试过像这样从头开始设置标志:

  set(CMAKE_CXX_FLAGS_DEBUG"/MTd") 

但这也不起作用.

如果我通过这样的命令行传递选项:

  -DCMAKE_CXX_FLAGS_DEBUG ="/MTd" 

该选项已在Visual Studio项目中成功设置.

有人可以告诉我我在做什么错吗?

如果有人能启发我关于缓存中的值的来源(我未在命令行上指定或不在CmakeLists.txt中),我也将不胜感激.

根据要求添加CMakeList.txt.如果我做不到这一点,我从来没有发布过如此抱歉的声明.

 #来自cpp-netlib.org的原始文件,带有我的修改cmake_minimum_required(版本2.8)项目(CPP-NETLIB)设置(Boost_USE_STATIC_LIBS ON)设置(Boost_USE_MULTI_THREADED ON)find_package(Boost 1.45.0必需unit_test_framework系统regex date_time线程文件系统program_options chrono)find_package(OpenSSL)find_package(线程)设置(CMAKE_VERBOSE_MAKEFILE true)如果(CMAKE_BUILD_TYPE MATCHES调试)add_definitions(-DBOOST_NETWORK_DEBUG)万一()如果(OPENSSL_FOUND)add_definitions(-DBOOST_NETWORK_ENABLE_HTTPS)include_directories($ {OPENSSL_INCLUDE_DIR})万一()如果($ {CMAKE_CXX_COMPILER_ID} MATCHES GNU)设置(CMAKE_CXX_FLAGS"$ {CMAKE_CXX_FLAGS} -Wall")万一()如果(Boost_FOUND)################# 添加 #################add_definitions(-DBOOST_ALL_NO_LIB)########################################如果(MSVC)add_definitions(-D_SCL_SECURE_NO_WARNINGS)endif(MSVC)如果(WIN32)add_definitions(-D_WIN32_WINNT = 0x0501)endif(WIN32)include_directories($ {Boost_INCLUDE_DIRS})enable_testing()add_subdirectory(libs/network/src)add_subdirectory(库/网络/测试)如果(不是MSVC)add_subdirectory(libs/mime/test)endif(非MSVC)add_subdirectory(库/网络/示例)endif(Boost_FOUND)如果(MSVC)设置(CMAKE_CXX_FLAGS"$ {CMAKE_CXX_FLAGS}/bigobj")################# 添加 #################设置(CMAKE_CXX_FLAGS_DEBUG"$ {CMAKE_CXX_FLAGS_DEBUG}/MTd")########################################万一()enable_testing() 

解决方案

if 块中添加代码应该可以正常工作.但是,由于它不会在您的.sln中产生所需的效果,因此或者未执行 if 块中的代码,或者稍后在CMakeLists.txt中替换这些标志.

关于这些标志的缓存值来自哪里;CMake会应用并缓存对每种默认构建类型有用的默认值.

您是否已将更改添加到 project 电话? project 设置了很多东西,包括编译器标志.如果您在不缓存它们的情况下设置了这些标志(即,如图所示调用 set ),则 project 将覆盖它们.如果设置了标记对其进行缓存(例如,使用 set(... CACHE),或者通过命令行arg -D ,如所示),然后 project 不会覆盖它们.

此外,由于调用 set(CMAKE_CXX_FLAGS"$ {CMAKE_CXX_FLAGS}/bigobj")不会使用 add_subdirectory 命令引入了一个新的范围(尽管在文档中没有提到),它继承了父变量的副本.但是,对父范围中变量的后续更改不会影响子副本,同样,更改子副本也不会影响父副本的值(除非您使用 set(...)).

因此,要解决您的问题,只需将 if(MSVC)块移至所有 add_subdirectory 调用之前.

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 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.

这篇关于CMake-使用/MT而不是/MD进行编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆