【问题标题】:Code generator generating its own CMake files and targets代码生成器生成自己的 CMake 文件和目标
【发布时间】:2018-09-28 13:46:43
【问题描述】:

假设我有一个脚本,它生成一组源文件,这些文件构成了我想在CMakeLists.txt 中链接的目标。如果后者知道文件名,那么通常的add_custom_target()add_custom_command() 命令将可以使用生成的文件作为目标源。

不过,我们假设只有生成器脚本知道文件名和位置。如何生成目标库,以便父 CMakeLists.txt 可以在不知道实际文件名的情况下链接它?

请注意,依赖主题不在此问题的范围内,因为脚本自己知道何时重新生成。这不是 CMake 的最佳用法,但在这个用例中已经足够了。

想法 #1

该脚本还使用include(generated.cmake) 生成一个包含在父文件中的generated.cmake 文件。问题:CMake 找不到 generated.cmake,因为它在配置时不存在。

想法 #2

与想法 #1 类似,但使用 execute_process() 调用脚本,以便在配置时出现 generated.cmake。问题:在后续构建中不再调用该脚本,因此忽略了对其输入的可能更改。

想法 #3

脚本传回一个目标和文件列表,该列表以某种方式被父 CMakeLists.txt 考虑。到目前为止,我找不到这样做的方法。

【问题讨论】:

  • stackoverflow.com/a/25482963/1945549 显示了一种重新触发配置步骤的方法,即特定文件更改时的execute_process() 命令。它让我更接近我的目标,但我面临的问题是我不知道所有相关的输入文件(因为脚本本身解析输入文件以派生其他输入文件)。
  • “问题:在后续构建中不再调用该脚本,因此忽略了对其输入的可能更改。”。问题显然与依赖项跟踪有关,这 “请注意,依赖项主题不在此问题的范围内”相矛盾。那么依赖跟踪是否相关?
  • @Tsyvarev:感谢您指出这个矛盾。我目前正在研究一种解决方案,该解决方案实际上使用execute_process() 调用脚本并让脚本“发布”其识别的输入文件,以便父CMake 文件可以将它们添加到目录的CMAKE_CONFIGURE_DEPENDS 属性中。待定稿后,我会尽可能详尽地描述它。
  • 命令add_executable 要求在配置步骤中指定所有源文件。由于您不知道由脚本生成的源文件,因此除了在配置阶段调用该脚本并使用例如收集生成的文件之外别无他法。 file(GLOB)。所以你的“想法#1”和“想法#2”是不可避免的。该问题中对此进行了描述:stackoverflow.com/questions/44076307/…。生成脚本的依赖跟踪只是另一个问题,由您引用的问题描述。
  • @Tsyvarev,我有点用了你的建议,但最终用脚本本身生成的 CMake 文件替换了 file(GLOB)(见我的回答)。

标签: cmake code-generation


【解决方案1】:

我提出的解决方案最终是所有三个想法的混合。

解决方案#1的问题

execute_process() 实际上确保generated_targets.cmake 在配置时存在。

解决方案 #2 和 #3 的问题

this answer to "Add dependency to the CMake-generated build-system itself" 中所述,可以编辑CMAKE_CONFIGURE_DEPENDS 目录属性以添加触摸重新触发配置步骤的文件。

关键的成功因素是这个属性可以在初始execute_process()调用之后设置,以便脚本可以识别并列出其输入依赖项(在输出文件中),然后添加到CMAKE_CONFIGURE_DEPENDS,因此也解决了输入依赖问题。

产生的伪代码

# The script generates:
# - <output_dir>/cmake/input_files
# - <output_dir>/cmake/generated_targets.cmake
execute_process(
  COMMAND myScript
    --output-dir ${CMAKE_CURRENT_BINARY_DIR}/generated
)

# Mark the input files as configure step dependencies so that the execute_process
# commands are retriggered on input file change.
file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/generated/cmake/input_files _input_files)

set_property(
  DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
    ${_input_files}
)

# Add the generated CMake targets.
include(${CMAKE_CURRENT_BINARY_DIR}/generated/cmake/generated_targets.cmake)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 2018-10-06
    • 2017-09-07
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多