使用cmake有条件地生成源输入文件

时间:2011-07-11 12:16:10

标签: c++ gcc makefile cmake precompiled-headers

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

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

  1. 在整个源代码树上运行我的自定义工具(python脚本)。它在一些子目录中生成precompiled.h头文件。它的目的是扫描* .h和* .cpp用于#include并将它们移动到常见的precompiled.h文件。
  2. 仅在precompiled.h文件在步骤1之后发生更改时生成GCC的预编译头文件(g++ -c precompiled.h -o precompiled.h.gch)。
  3. 构建过时的目标(在第2步之后,因为我想使用.gch文件)
  4. 我设法添加依赖项,所以每当我构建任何目标时,我的python脚本的目标都会被执行(这很难看,因为现在每个目标都必须依赖于单个global_init目标)。此外,我可以修改我的python脚本,因此它不会在没有必要时修改precompiled.h。

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

    1. 执行python脚本 - > precompiled.h可以更新
    2. 检查precompiled.h时间戳,如果它更新 - > build precompiled.h.gch
    3. 标准编译步骤
    4. 我在许多地方看过,但是cmake(和make)计算依赖关系的方式似乎太弱而无法完成这项任务。

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

1 个答案:

答案 0 :(得分:6)

以下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.hprecompiled.h包含的其他标头上的precompiled.h.gchCMAKE_CURRENT_BINARY_DIR目录中生成precompiled.h。 由于预编译的头生成需要python脚本更新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_DIR开关的默认头中。包含precompiled.h.gch的{​​{1}}将添加为包含目录。当包含precompiled.h时,gcc将从那里获取precompiled.h.gch。(参见implicitly)。

最后,对generate_precompiled的目标依赖性确保在必要时更新预编译的头。