C++ 如何使用 CMake 在特定构建配置中为特定目标设置特定编译器标志?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10199904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I set specific compiler flags for a specific target in a specific build configuration using CMake?
提问by Billy ONeal
I've got a CMakeLists where I want to build some targets using the dynamic version of the C runtime, and some other targets using the static version.
我有一个 CMakeLists,我想在其中使用 C 运行时的动态版本构建一些目标,并使用静态版本构建其他一些目标。
Because this needs to be set per target, the default method of setting CMAKE_CXX_FLAGS_<Config>
does not work; this overrides for all targets.
因为这个需要按target设置,默认的设置方法是CMAKE_CXX_FLAGS_<Config>
不行的;这将覆盖所有目标。
To that end, I tried something like the following:
为此,我尝试了以下操作:
# @fn set_target_dynamic_crt
# @brief Sets the given target to use the dynamic version of the CRT (/MD or
# /MDd)
# @param ... A list of targets to which this setting should be applied.
function( set_target_dynamic_crt )
if ( MSVC )
message (WARNING ${CMAKE_BUILD_TYPE})
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set_target_properties ( ${ARGN} PROPERTIES COMPILE_FLAGS "/MDd" )
else()
set_target_properties ( ${ARGN} PROPERTIES COMPILE_FLAGS "/MD" )
endif()
endif()
endfunction()
However, this always chooses the release version (/MD
) and when I query for the build type (the message
call above) I get the empty string. (I suspect this is because I'm using the Visual Studio generator; I've seen more than one reference that says CMAKE_BUILD_TYPE
is for makefiles only...)
但是,这总是选择发布版本 ( /MD
),当我查询构建类型(message
上面的调用)时,我得到空字符串。(我怀疑这是因为我使用的是 Visual Studio 生成器;我已经看到不止一个参考资料说CMAKE_BUILD_TYPE
仅用于 makefile ......)
How can I set compile options like this per target?
如何为每个目标设置这样的编译选项?
回答by steveire
In CMake 2.8.12 I added a target_compile_options command to address this need:
在 CMake 2.8.12 中,我添加了一个 target_compile_options 命令来解决这个需求:
http://public.kitware.com/Bug/view.php?id=6493
http://public.kitware.com/Bug/view.php?id=6493
http://www.cmake.org/cmake/help/git-master/manual/cmake-generator-expressions.7.html
http://www.cmake.org/cmake/help/git-master/manual/cmake-generator-expressions.7.html
target_compile_options(tgt PRIVATE "/MD$<$<CONFIG:Debug>:d>")
See
看
for more relating to CMAKE_BUILD_TYPE and several reasons why the generator expression is better (eg IMPORTED target config mapping).
有关 CMAKE_BUILD_TYPE 的更多信息以及生成器表达式更好的几个原因(例如 IMPORTED 目标配置映射)。
回答by Fraser
The only option I know of for this scenario is to split your project into subdirectories on a per-target basis and use add_subdirectory
.
对于这种情况,我所知道的唯一选择是基于每个目标将您的项目拆分为子目录并使用add_subdirectory
.
Depending on how your project is currently set up, this could be a painful process I guess.
根据您的项目目前的设置方式,我猜这可能是一个痛苦的过程。
The result would be a top-level CMakeLists.txt that looked like e.g.
结果将是一个顶级的 CMakeLists.txt,看起来像
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(Test)
add_subdirectory(libB)
add_subdirectory(libA)
add_executable(main_exe "main.cpp")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
target_link_libraries(main_exe lib_a lib_b)
then libA/CMakeLists.txt
could specify MD
and MDd
flags:
然后libA/CMakeLists.txt
可以指定MD
和MDd
标记:
project(LibA)
add_library(lib_a a.cpp a.hpp)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")
and libB/CMakeLists.txt
for MT
and MTd
flags:
而libB/CMakeLists.txt
对于MT
和MTd
标志:
project(LibB)
add_library(lib_b b.cpp b.hpp)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
You can of course add all targets needing linked to the static CRT in the one subdirectory and CMakeLists.txt and all the dynamic CRT ones in the other if you have a lot of targets.
如果您有很多目标,您当然可以在一个子目录和 CMakeLists.txt 中添加所有需要链接到静态 CRT 的目标,并在另一个中添加所有动态 CRT。
回答by phb
CMAKE_BUILD_TYPE
is only valid for single-configuration generators. The multi-configuration generators (MSVC and Xcode) can build for multiple configurations in one build-directory and as such the CMAKE_BUILD_TYPE
flag wouldn't have a meaning.
CMAKE_BUILD_TYPE
仅对单配置生成器有效。多配置生成器(MSVC 和 Xcode)可以在一个构建目录中为多个配置构建,因此该CMAKE_BUILD_TYPE
标志没有意义。
The COMPILE_FLAGS target property does not distinguish different configurations (See kitware bugtrackerfor more information).
COMPILE_FLAGS 目标属性不区分不同的配置(有关更多信息,请参阅kitware bugtracker)。
A workaround would be to have two build-directories, similar to how people use the Makefile generators, and define an additional flag when building binaries for distribution. (ie, the Release configuration)
一种解决方法是拥有两个构建目录,类似于人们使用 Makefile 生成器的方式,并在构建二进制文件以进行分发时定义一个额外的标志。(即Release配置)
回答by kucer
Assume that I want to add -On
options to vmovq_n_u8.c and generate vmovq_O3.out and vmovq_O0.out. I had it done with target_compile_options
by following:
假设我想向-On
vmovq_n_u8.c添加选项并生成 vmovq_O3.out 和 vmovq_O0.out。我target_compile_options
通过以下方式完成了它:
add_executable(vmovq_O3.out vmovq_n_u8.c)
add_executable(vmovq_O0.out vmovq_n_u8.c)
target_compile_options(vmovq_O3.out PRIVATE -O3)
target_compile_options(vmovq_O0.out PRIVATE -O0)