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

问题描述 投票:0回答:1

我有一个目录树,其中特定已知类型(例如 .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} )

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

build cmake
1个回答
3
投票

您可以使用

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"
)

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

foreach(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}
    )
endforeach()

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

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 开始支持这一点。

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

© www.soinside.com 2019 - 2024. All rights reserved.