CMake,多个目标(asan tsan ..)而无需重新编译所有内容
CMake, multiple targets (asan tsan..) without having to recompile everything
目标
我想定义几个目标:
- make msan:使用带有内存清理器的 clang 编译代码
- make tsan:使用 clang 和 thread sanitizer 编译代码
- make : 用 gcc
编译代码
并且能够在它们之间轻松切换。
例如,我不希望每次切换时都重建我的所有对象,(当然我必须在第一次这样做,但稍后如果我修改一个文件并且我做了 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)
目标 我想定义几个目标:
- make msan:使用带有内存清理器的 clang 编译代码
- make tsan:使用 clang 和 thread sanitizer 编译代码
- make : 用 gcc 编译代码
并且能够在它们之间轻松切换。 例如,我不希望每次切换时都重建我的所有对象,(当然我必须在第一次这样做,但稍后如果我修改一个文件并且我做了 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)