1

有什么方法可以做相当于 add_custom_command (在某个文件更改时运行外部脚本),但是对于应该在 CMake 脚本执行本身期间运行的东西?(即,用于依赖图生成。)

我们将源代码文件拆分为多个子库,并且配置文件列出了哪个源文件与哪个库一起使用。(这些配置文件的格式由我们使用的另一个工具固定。)目前,我们运行一个自定义外部脚本来解析这些配置文件并写入新文件,然后由 CMake 构建过程加载以提供文件名列表传递给 add_library()。这意味着每次添加/删除源文件时,我们需要记住在重新运行 CMake 之前重新运行 prebuild 命令,然后重新启动 build 命令。

我知道 CMake 可以识别它需要重新运行自己,所以我希望我们可以让 CMake 1)识别配置文件已更改 2)重新运行配置文件解析器 3)加载新文件列表 4)使用新文件列表重新生成依赖关系树 5) 最后启动包含新文件的实际构建/编译过程。...所有这些都来自标准构建命令,而无需手动运行外部配置文件解析器或手动重新运行 CMake 命令,并且在配置文件未更改时无需执行。

在搜索中,我确实找到了这个问题,建议使用 configure_file() ,但这并没有解决如何调用外部配置文件解析器脚本。

4

1 回答 1

3

将我的评论变成答案

configure_file()是重新触发配置过程的正确选择。并且execute_process()用于在配置步骤中运行命令。

这是您描述中步骤的抽象 CMake 片段:

function(my_add_library_from_cfg _target _cfg_file)
    # Retrigger configuration process each time config file changes
    get_filename_component(_cfg_name "${_cfg_file}" NAME)
    configure_file("${_cfg_file}" "${_cfg_name}.tmp")

    # Generating sources and file list
    execute_process(
        COMMAND ${CMAKE_COMMAND} -E echo "#define FOO" 
        OUTPUT_FILE foo.c
    )
    execute_process(
        COMMAND ${CMAKE_COMMAND} -E echo "foo.c"
        OUTPUT_FILE files.lst
    )

    # Reading file list and add library
    file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/files.lst" _sources_lst)
    add_library(${_target} ${_sources_lst} "${_cfg_file}")
endfunction(my_add_library_from_cfg)
  • configure_file()每次给定.cfg文件更改 时都会重新触发 CMake
    • 如果您实际上将该.cfg文件用作命令行参数,execute_process()则应使用.tmp当前二进制目录中生成的版本
  • execute_process()可以做很多事情
    • 我用它来回stdout显并将输出写入文件
    • 这里的默认WORKING_DIRECTORY是当前的二进制目录
  • file()读入源文件列表
    • 每个完整路径,换行符分隔
  • 我已按目的将生成的文件写入二进制输出目录
    • 它使干净的构建更容易,只需删除整个二进制输出目录
    • CMake 对此有内置支持;它将首先在当前源中搜索没有绝对路径的源文件,然后在当前二进制目录中搜索
  • 而且我没有使用GENERATED源文件属性
    • 因为只有在之前的构建步骤生成源时才需要这样做
    • 当实际上缺少源文件列表中的文件时,CMake 本身将不再识别
于 2015-09-19T19:18:13.877 回答