首页 > 解决方案 > CMake:根据 C 宏定义有选择地重新编译 C++ 程序模块

问题描述

我有一个包含几个模块的程序,比如:moduleA、moduleB 和 moduleC。而且我还有一个头文件 debug_flags.h 我在其中定义了三个宏:

#define DEBUG_MODULE_A 1
#define DEBUG_MODULE_B 0
#define DEBUG_MODULE_C 0

当 DEBUG_MODULE_X 设置为 1 时,会为模块 X 启用其他调试功能(如详细日志记录、将中间结果保存到文件等)。

目前,每当我更改 DEBUG_MODULE_X 的值时,所有三个模块都会重新编译(这非常昂贵)。相反,我只想重建模块 X(因为 DEBUG_MODULE_X 宏仅用于模块 X)。

一种解决方案是使用三个不同的头文件:

debug_flags_A.h -> defines DEBUG_MODULE_A
debug_flags_B.h -> defines DEBUG_MODULE_B
debug_flags_C.h -> defines DEBUG_MODULE_C

这将分别包含在模块 A、B 和 C 中。然而,使用该解决方案,我必须经常在头文件之间跳转以在开发过程中启用/禁用模块的调试(我有超过 3 个模块)。而且我也不清楚目前启用了哪些调试标志。

理想情况下,我希望在单个头文件中定义所有调试标志,但以某种方式强制 CMake 仅重新编译相关模块(即那些 DEBUG_MACRO_X 已更改的模块)。这有可能吗?

我不确定这是否有帮助:可以从模块 X 中包含 debug_flags.h,如下所示:

#define INCLUDE_FROM_MODULE_X
#include "debug_flags.h"

然后,在 debug_flags.h 中,我们知道这个头文件是从哪个模块中包含的。也许,通过使用这些信息,我们可以以某种方式触发选择性重新编译??

标签: c++ccmakemacros

解决方案


为什么不让 CMake 在编译时为您添加定义:

cmake_minimum_required(VERSION 3.0)
project(debugflags)

add_library(moduleA STATIC moduleA.cpp)
add_library(moduleB STATIC moduleB.cpp)
add_library(moduleC STATIC moduleC.cpp)

target_compile_definitions(moduleA PRIVATE DEBUG_MODULE_A)
# target_compile_definitions(moduleB PRIVATE DEBUG_MODULE_B)
target_compile_definitions(moduleC PRIVATE DEBUG_MODULE_C)

(取消)注释其中一个会target_compile_definitions重新编译该模块。如果您需要跨模块调试标志,您可以执行以下操作:

if(DEBUG_MODULE_A)
  target_compile_definitions(moduleA PRIVATE DEBUG_MODULE_A)
  target_compile_definitions(moduleA2 PRIVATE DEBUG_MODULE_A)
endif(DEBUG_MODULE_A)

并设置相应的 CMake 变量。


推荐阅读