我有一个使用cmake系统编译的项目。我使用
编译项目cd build
cmake .. # cmake stage
make # make stage
有时我想向 gcc 传递一个额外的标志
-fdiagnostics-json
,以便轻松解析诊断消息。通常我编译它们时没有这个标志。
每当我想更改输出时,我都可以在
CMakeLists.txt
中添加/删除它。问题是,每次修改CMakeLists.txt
时,我都需要从cmake ..
重新启动,并且整个项目都要重新构建,包括已经构建的目标文件。
有没有一种方法可以让我在
make
阶段有选择地将此标志添加到 gcc 中。我尝试了以下方法,但似乎不起作用
cmake ..
# then
make
# then
make CXXFLAGS="-fdiagnostics-format=json"
每当我想更改输出时,我都可以在 CMakeLists.txt 中添加/删除它。问题是,每次修改 CMakeLists.txt 时,我都需要从 cmake 重新启动..并且整个项目将被重建,包括已经构建的对象文件。
这是无法避免的。在所有目标文件都过时之后,您确实会更改编译器选项,因为编译器选项集已更改。
您不需要编辑
CMakeLists.txt
文件。您应该能够通过 cmake 缓存变量传递编译器选项,而无需修改 cmake 文件:
为目录中设置的项目全局添加选项
build
:
cmake -D "CMAKE_CXX_FLAGS=-fdiagnostics-format=json" -D "CMAKE_C_FLAGS=-fdiagnostics-format=json" build
重置选项:
cmake -U CMAKE_CXX_FLAGS -U CMAKE_C_FLAGS build
CMAKE_<LANG>_FLAGS
要仅为单个目标进行设置,您可以添加一个缓存变量,可以修改该变量以启用/禁用编译器标志。这应该只会导致您应用标志的目标需要重建,以及链接您的目标的二进制文件的任何重新链接(如果有)。
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
option(MY_TARGET_ENABLE_DIAGNOSTICS "Add -fdiagnostics-format=json compiler option to my_target" OFF)
if (MY_TARGET_ENABLE_DIAGNOSTICS)
target_compile_options(my_target PRIVATE -fdiagnostics-format=json)
endif()
endif()
启用该选项:
cmake -D MY_TARGET_ENABLE_DIAGNOSTICS=ON build
禁用该选项
cmake -D MY_TARGET_ENABLE_DIAGNOSTICS=OFF build
此外,可以在多个构建目录中设置精心设计的 cmake 项目,这将允许两个版本的构建文件并行存在。
这要求 cmake 项目不在源树中生成任何文件。
此方法适用于上述两种替代方案。不过,下面的命令假定是第二个选项。
在
src
和 build
中设置的项目的初始 cmake 配置
build_diagnostics
建设这两个项目
cmake -S src -B build
cmake -D MY_TARGET_ENABLE_DIAGNOSTICS=ON -S src -B build_diagnostics
这会并行地保留两种替代方案的构建文件,并且只会导致重新构建那些自上次在给定目录上构建以来已修改的文件。注意:
使用多配置 cmake 生成器,您甚至可以通过使用带有 cmake --build build
cmake --build build_diagnostics
的生成器表达式为诊断选项添加单独的配置。但
taget_compile_options
不是多配置 cmake 生成器。此外,它仅适用于 Unix Makefiles 生成器。然而,它确实使用了有据可查的 make 行为。即
覆盖变量的能力。 从专业角度来看,它确实比干净的 CMake 解决方案提供了更多的灵活性。这也是单行本。
如果您仍在阅读,请考虑一次性运行此内容。
问答单
Unix Makefiles
中生成的构建目录中找到。您要查找的变量是
CMakeFiles/your_project.dir/flags.make
(带下划线)。您可以使用您最喜欢的文本编辑器来更改 make in place 使用的标志。 (是的,有一条警告不要编辑该文件,请参阅上面的免责声明。)再次运行 CMake 将重新生成文件并撤消您的更改。
您还可以在命令行上传递变量。因为这将完全覆盖
CXX_FLAGS
中的变量,您可以使用 sed 读取文件并像这样调整变量
flags.make
或使用评论中Michaël
建议的稍微短一点的命令
make "$(sed -n 's/CXX_FLAGS.*/\0 -fdiagnostics-json/p' CMakeFiles/your_project.dir/flags.make)"