Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为CMake构建过程本身添加_custom_command()?_Cmake_Add Custom Command - Fatal编程技术网

如何为CMake构建过程本身添加_custom_command()?

如何为CMake构建过程本身添加_custom_command()?,cmake,add-custom-command,Cmake,Add Custom Command,是否有任何方法可以执行与add_custom_命令(当某个文件发生更改时运行外部脚本)等效的操作,但在CMake脚本执行过程中应该运行某些操作?(即,用于依赖关系图生成。) 我们将源代码文件分为多个子库,还有一些配置文件列出了哪个源文件与哪个库一起使用。(这些配置文件的格式由我们使用的另一个工具固定。)目前,我们运行一个自定义外部脚本,该脚本解析这些配置文件并写入新文件,然后由CMake构建过程加载这些文件,以提供要传递给add_library()的文件名列表。这意味着每次添加/删除源文件时,我

是否有任何方法可以执行与add_custom_命令(当某个文件发生更改时运行外部脚本)等效的操作,但在CMake脚本执行过程中应该运行某些操作?(即,用于依赖关系图生成。)

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

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

在搜索中,我确实找到了建议使用configure_file()的位置,但这并没有说明如何调用外部configfile解析器脚本

把我的评论变成答案

是重新触发配置过程的正确选择。和用于在配置步骤中运行命令

以下是您描述中步骤的抽象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\u process()
      中的命令行参数,则应使用当前二进制目录中生成的
      .tmp
      版本
  • execute\u process()
    可以做很多事情
    • 我使用它回显到
      stdout
      ,并将输出写入文件
    • 默认的
      工作目录
      这里是当前的二进制目录
  • file()
    读取源文件列表
    • 每个路径都是完整的,换行分隔
  • 我已按目的将生成的文件写入二进制输出目录
    • 只需删除整个二进制输出目录,即可简化干净的构建
    • CMake对此有内置支持;它将首先在当前源中搜索没有绝对路径的源文件,然后在当前二进制目录中搜索
  • 我没有使用源文件属性
    • 因为只有在源代码由以前的构建步骤生成时,才需要这样做
    • 而且,当源文件列表中的文件丢失时,CMake本身将无法识别

configure_file()
是重新触发配置过程的正确选择。和用于在配置步骤中运行命令。@Florian您能详细说明一下吗?我不太明白如何将configure_file()/execute_process()/add_library()调用串在一起以获得一个工作的重建。为了详细说明,我需要比注释所能接受的文本多一点的文本。因此,我添加了所有内容——包括一段代码片段——作为答案。希望这有助于展示如何在CMake中实现这一点。