21

我有一个 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

4 回答 4

39

在 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 目标配置映射)。

于 2014-01-05T03:28:17.410 回答
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.txtforMTMTd标志:

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 目标。

于 2012-04-17T23:43:59.260 回答
0

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

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

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

于 2012-04-17T22:17:35.817 回答
0

假设我想向-Onvmovq_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)

于 2019-11-12T12:06:10.997 回答