我有一个目录树,其中包含放置在该树内各个文件夹中的某些已知类型(例如 .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} )
但是,该脚本需要很长时间才能运行,因为它是单线程的,并且在输入未更改时不关心重用现有输出。
最佳答案
您可以使用 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()
请注意,您需要有一些 目标 (s) 从这些自定义命令“使用”输出文件。 (否则,您为什么需要这些文件?)。如果您出于某种原因只想拥有它们,您可以创建以下自定义目标:
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 起支持此功能。请注意,此功能可能不适用于某些生成器,并且每次构建项目时都会消耗时间扫描目录。
关于build - 我可以有一个 cmake 脚本来使用相同的自定义程序处理嵌套目录结构上的多个文件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57073069/