CMake设置MSVC工程MT/MTd/MD/MDd


0. 前言

MSVC工程上右键->属性,找到配置属性->C/C++->代码生成->运行库,会发现有好几种选项:MT MTd MD MDd
在这里插入图片描述
这是对于多线程程序生成对象链接内容的控制。

先理解一下这四个有什么不同:

  1. 首先后面带d表示Debug,生成对象(exe、lib都行)是带有调试信息的,生成对象占用空间相比不带d的会更大一些;
  2. MTMD区别:前者是静态链接,将有关依赖库都打包进生成对象了,所以占用空间更大;后者是动态链接,运行时依赖电脑环境,容易出现换个电脑报错dll的现象。

这个出问题常见于依赖某个lib文件时,弹出LNK2038错误:
在这里插入图片描述
一般因为VS工程默认是MD/MDd,即动态链接方式,而一些库在生成时采用的是MT/MTd方式(如GoogleTest),整个项目混合使用二者产生的报错。


1. 如何设置

1.1 CMakeLists代码

先直接上代码,随后讲解要点:

# 设置策略CMP0091为NEW,新策略
if (POLICY CMP0091)
  cmake_policy(SET CMP0091 NEW)
endif (POLICY CMP0091)

# 声明一个工程
project(TestpyTest)

# 添加一个exe
add_executable(test test.cpp)

# 设置MT/MTd
set_property(TARGET test PROPERTY
  MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
	

1.2 要点1:POLICY

首先是设置POLICY CMP0091,通过cmake_policy(SET policy NEW)进行设置;

策略大概可以理解为:cmake通过选择策略的NEWOLD,可以使用不同的语法,来实现同样的功能。详情可看cmake_policy

CMP0091策略是用来控制MSVC运行库标志位flags如何设置的。就拿现在要设置的MT/MD而言,cmake 3.14及以前的版本是通过CMAKE_<LANG>_FLAGS_<CONFIG>变量进行设置的,所以网上会有很多博客说设置MT的办法大概是:

set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")

cmake官方说了,这种字符串的形式不太方便,所以有了新方式,详情可看CMP0091

关于POLICY设置还有一点需要注意:要在project()之前设置,另外,子项目想要使用,也需要在父项目中设置,否则cmake之后用VS打开工程,依然会LNK2038

笔者在使用GoogleTest时(GoogleTest库是MTd),把Test项目作为子项目,仅在父项目或子项目中添加POLICY不行,需要都添加CMP0091

1.3 要点2:set_property

首先记住MSVC_RUNTIME_LIBRARY属性,它的取值可以是:

  • MultiThreaded :对应MT
  • MultiThreadedDLL :对应MD
  • MultiThreadedDebug:对应MTd
  • MultiThreadedDebugDLL:对应MDd

这几个取值通过字符串形式设置给MSVC_RUNTIME_LIBRARY属性,但官方给的字符串是:

"MultiThreaded$<$<CONFIG:Debug>:Debug>"

这用到了cmake的生成表达式(generator expression)功能,使得当ConfigDebug时,自动添加Debug。使用到了嵌套表达式:

  1. $<CONFIG:Debug>使用了变量查询的语句,当处于Debug模式时,该表达式为1
    在这里插入图片描述
  2. 知道上一条之后,<$<$<CONFIG:Debug>: Debug>就变成了$<1或0:Debug>,使用的是条件表达式,当前部分为1是该表达式为Debug,否则为空:
    在这里插入图片描述

生成表达式可以参考官方:cmake-generator-expressions(7)

在不设置MSVC_RUNTIME_LIBRARY属性时,它默认值为MultiThreaded$<$<CONFIG:Debug>:Debug>DLL,是MDMDd

更多细节参见官方教程:MSVC_RUNTIME_LIBRARY

  • 13
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值