我可以使用cmake脚本使用同一自定义程序通过嵌套目录结构处理多个文件吗?

时间:2019-07-17 09:49:16

标签: build cmake

我有一个目录树,其中某些已知类型的文件(例如.in)位于该树的各个文件夹中。任务是调用每个已知类型的文件一次的已知自定义程序(例如 process_it ),并将此文件作为参数传递:

process_it a/b/c/file.in

,它将产生a/b/c/file.out

我们已经将cmake用于该项目的常规C ++构建。是否有可能,以及如何扩展CMakeLists.txt并获得这种处理?

我目前只编写了一个python脚本来迭代文件夹并调用处理程序。可以将此脚本作为自定义命令添加到CMakeLists.txt中,并且效果很好,可以在$ {OUTPUT}文件夹中生成文件,最初缺少该文件:

add_custom_command(OUTPUT ${OUTPUT}
   COMMAND python ARGS scan_current_dir_and_do_naive_processing.py
   WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} )

但是该脚本需要很长时间才能运行,因为它是单线程的,并且不关心输入不变时重用现有输出的情况。

1 个答案:

答案 0 :(得分:2)

您可以使用file(GLOB_RECURSE)收集要处理的文件列表:

file(GLOB_RECURSE
    # Result variable
    list_in_files
    # Return paths relative current source directory
     RELATIVE ${CMAKE_CURRENT_SOURCE_DIRECTORY}
    # Collect all ".in" files in the current source directory
    "${CMAKE_CURRENT_SOURCE_DIRECTORY}/*.in"
)

然后为找到的每个文件创建一个具有适当OUTPUT和DEPENDS的自定义命令:

for(in_file ${list_in_files})
    # Obtain relative path of the output file.
    string(REGEX REPLACE "in$" "out" out_file ${in_file})
    # Create custom command which generates {out_file} from the {in_file}
    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${out_file}
        COMMAND <process-file> <...arguments...>
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${in_file}
    )
endfor()

请注意,您需要具有一些目标来“消费”这些自定义命令中的OUTPUT文件。 (否则,为什么需要这些文件?)。如果出于某种原因只想拥有它们,则可以创建以下自定义目标:

add_custom_target(generate_all_files
    # build this target by default (on `make all` or `make`)
    ALL
    DEPENDS ${list_out_files}
)

这假设您添加了行

 # add absolute path of the output file to the list
 list(APPEND list_out_files "${CMAKE_CURRENT_BINARY_DIR}/${out_file}")

到上一个for循环。


如果您希望CMake自动发现新的.in文件(和已删除的文件),则可以对CONFIGURE_DEPENDS使用附加的file(GLOB_RECURSE)。从CMake 3.12开始支持。

请注意,此功能可能不适用于某些生成器,并且每次构建项目时都会消耗时间来扫描目录。