如何使用CMake为特定构建配置中的特定目标设置特定的编译器标志?

时间:2012-04-17 22:08:13

标签: c++ visual-c++ cmake

我有一个CMakeLists,我希望使用动态版本的C运行时构建一些目标,以及使用静态版本的其他一些目标。

因为需要为每个目标设置,所以设置CMAKE_CXX_FLAGS_<Config>的默认方法不起作用;这覆盖了所有目标。

为此,我尝试了以下内容:

# @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()

但是,这总是选择发布版本(/MD),当我查询构建类型(上面的message调用)时,我得到空字符串。 (我怀疑这是因为我正在使用Visual Studio生成器;我看过多个引用,其中CMAKE_BUILD_TYPE仅适用于makefile ...)

如何为每个目标设置这样的编译选项?

4 个答案:

答案 0 :(得分:29)

在CMake 2.8.12中,我添加了一个target_compile_options命令来满足这个需求:

http://public.kitware.com/Bug/view.php?id=6493

http://www.cmake.org/cmake/help/git-master/manual/cmake-generator-expressions.7.html

target_compile_options(tgt PRIVATE "/MD$<$<CONFIG:Debug>:d>")

http://www.cmake.org/cmake/help/git-next/manual/cmake-buildsystem.7.html#build-specification-with-generator-expressions

有关CMAKE_BUILD_TYPE的更多信息以及生成器表达式更好的几个原因(例如,IMPORTED目标配置映射)。

答案 1 :(得分:2)

我知道此方案的唯一选择是按每个目标将项目拆分为子目录,并使用add_subdirectory

根据您当前设置项目的方式,我猜这可能是一个痛苦的过程。

结果将是顶级的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)

然后libA/CMakeLists.txt可以指定MDMDd标志:

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")
对于libB/CMakeLists.txtMT标记,

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")

当然,如果你有很多目标,你可以在一个子目录和CMakeLists.txt中添加所有需要链接到静态CRT的目标,在另一个子目录中添加所有动态CRT。

答案 2 :(得分:0)

CMAKE_BUILD_TYPE仅对单配置生成器有效。多配置生成器(MSVC和Xcode)可以在一个构建目录中构建多个配置,因此CMAKE_BUILD_TYPE标志没有意义。

COMPILE_FLAGS目标属性不区分不同的配置(有关详细信息,请参阅kitware bugtracker)。

解决方法是拥有两个构建目录,类似于人们使用Makefile生成器的方式,并在构建二进制文件时定义另一个标记以进行分发。 (即发布配置)

答案 3 :(得分:0)

假设我要向vmovq_n_u8.c添加-On选项,并生成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)