CMake,多个目标(asan tsan ..)而无需重新编译所有内容

CMake, multiple targets (asan tsan..) without having to recompile everything

目标 我想定义几个目标:

并且能够在它们之间轻松切换。 例如,我不希望每次切换时都重建我的所有对象,(当然我必须在第一次这样做,但稍后如果我修改一个文件并且我做了 make 然后 make asan 它应该只重新编译这个文件对于每个目标)

到目前为止我做了什么

我已经设法从根目录创建了这些目标,但每次我都必须执行 make clean 并重新编译。

option(CLANG_MSAN "Enable Clang memory sanitizer" OFF)
if (CLANG_MSAN)
    set (CMAKE_CXX_FLAGS "-g -fsanitize=address -fno-omit-frame-pointer")
endif()

add_custom_target(asan
    COMMAND ${CMAKE_COMMAND}
    -DCLANG_MSAN=ON
    -DCMAKE_CXX_COMPILER=clang++
    -DCMAKE_C_COMPILER=clang)

是否可以用 CMake 做这样的事情?

是,但使用多个构建目录:

  • 为每个配置创建一个构建目录。
  • 使用您需要的参数在您的构建目录中配置您的项目。例如。 cmake -DCMAKE_COMPILER=clang -DCMAKE_C_FLAGS="-fsanitize=thread" .. 或您问题中的内容。
  • 如果您切换构建目录,则您更改了设置。

这意味着外源构建,CMake 无论如何都鼓励这种构建。

我相信您应该可以使用 ExternalProject 模块来实现这一点。您可以添加三个外部项目,一个用于 msan,一个用于 tsan,一个用于基本 GCC 构建。这两个消毒剂构建将被标记为 EXCLUDE_FROM_ALL 1.

它们三个的 CMakeLists 可以通过 include() 共享公共部分。

像这样:

根目录CMakeLists.txt

ExternalProject_Add(msan
  EXCLUDE_FROM_ALL 1
  SOURCE_DIR msan
  CMAKE_GENERATOR ...
)

ExternalProject_Add(tsan
  EXCLUDE_FROM_ALL 1
  SOURCE_DIR tsan
  CMAKE_GENERATOR ...
)

ExternalProject_Add(normal
  SOURCE_DIR src
  CMAKE_GENERATOR ...
)

src/CMakeLists.txt

include(common.cmake)

src/common.cmake

# Normal CMake code for your project
add_library(...)

msan/CMakeLists.txt

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address -fno-omit-frame-pointer")

include(../src/common.cmake)