2

我在 C++ 项目中使用 cmake。我想在 GCC 中使用预编译的头文件。

我想运行cmake一次,然后在运行时make,我希望执行以下操作:

  1. 在整个源代码树上运行我的自定义工具(python 脚本)。它在一些子目录中生成 precompiled.h 头文件。其目的是扫描 *.h 和 *.cpp 以查找#include,并将它们移动到常见的 precompiled.h 文件中。
  2. g++ -c precompiled.h -o precompiled.h.gch仅当 precompiled.h 文件在步骤 1 之后发生更改时,才生成 GCC 的预编译头文件 ( )。
  3. 构建过时的目标(在第 2 步之后。因为我想使用 .gch 文件)

我设法添加了依赖项,所以每当我构建任何目标时,都会执行我的 python 脚本的目标(这很丑,因为现在每个目标都必须依赖于单个 global_init 目标)。我也可以修改我的 python 脚本,所以它不会在不需要时修改 precompiled.h。

但我不知道下一步该做什么。有没有办法告诉 cmake 它应该运行我的自定义脚本并在确定是否必须创建 precompiled.h.gch 之后?现在它总是被构建(这个文件包含许多#include,所以它需要一些时间)。基本上:

  1. 执行 python 脚本 -> precompiled.h 可能会更新
  2. 检查 precompiled.h 时间戳以及它是否较新 -> 构建 precompiled.h.gch
  3. 标准编译步骤

我看过很多地方,但是 cmake(和 make)计算依赖项的方式似乎太弱了,无法完成这项任务。

在这个问题中: lazy c++ 编译总是在lazycpp 执行之后发生。在我的情况下,这不是最佳选择。

4

1 回答 1

7

以下 CMake 命令可以作为您项目的起点:

add_custom_target(scanner COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/scanner.py"
    COMMENT "Scanning include files ..."
    WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")

此命令涵盖第 1 步。它会调用您的 python 脚本,该脚本可能会precompiled.h更新CMAKE_CURRENT_SOURCE_DIR.

add_custom_command(OUTPUT precompiled.h.gch
    COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} 
    -c "${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h" -o precompiled.h.gch
    DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h"
    IMPLICIT_DEPENDS CXX "${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h")

add_custom_target(generate_precompiled DEPENDS
    "${CMAKE_CURRENT_BINARY_DIR}/precompiled.h.gch")

add_dependencies(generate_precompiled scanner)

这些命令涵盖了第 2 步。预编译的头文件是使用自定义命令生成的,该命令依赖于precompiled.h隐含地依赖于包含的其他头文件precompiled.hprecompiled.h.gchCMAKE_CURRENT_BINARY_DIR目录中生成。因为预编译的头文件生成需要precompiled.h通过 python 脚本更新,所以我们在 target 上添加了一个目标级别的依赖scanner

include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})

add_executable(main main.cpp)

set_target_properties(main PROPERTIES COMPILE_FLAGS "-include precompiled.h -H")

add_dependencies(main generate_precompiled)

这些命令添加了生成可执行文件的标准编译步骤main-include预编译的头文件作为 gcc开关的默认头文件包含在内。CMAKE_CURRENT_BINARY_DIRwhich contains被precompiled.h.gch添加为包含目录。precompiled.h.gch当包含 precompiled.h 时,gcc将从那里获取(请参阅使用预编译头文件)。

Finally the target dependency on generate_precompiled ensures that the precompiled header is updated if necessary.

于 2011-07-11T20:59:07.450 回答