CMake:动态添加依赖项到 add_custom_command

8
我有一个CMake项目,其中包含许多子项目。每个子项目都可以使用我提供的函数(通过调用add_custom_command)生成包含某些特定信息的小型文本文件。在最后一步,我希望将所有这些文件组合成一个大的文本文件。
我创建了一个自定义命令来搜索创建的文件(全部在一个位置)并将它们合并。问题是,我希望此最终步骤依赖于在子项目中完成的所有小步骤,但我实际上不知道将提供多少个文件。
我的最终命令如下:
add_custom_command(OUTPUT combination.txt
                   COMMAND create combination.txt from all files from /path/)

我的“为每个子项目创建小文本文件”的命令如下:

add_custom_command(OUTPUT /path/${sub_project_name}.txt
                   COMMAND create /path/${sub_project_name}.txt)

当我创建那些小文件时,我想做的是让"combination.txt"依赖于/path/${sub_project_name}.txt。

所以我希望能够:

add_dependency(combination.txt /path/${sub_project_name}.txt)

然而,这仅适用于目标文件。

我还尝试过使用set_source_files_properties和OBJECT_DEPENDS,但似乎不起作用(也许它是用于add_target的cpp文件?)

我看到使其工作的最后一种方法是使用缓存变量来累积所有这些小文件的路径,然后像这样使用它:

add_custom_command(OUTPUT combination.txt
                   COMMAND create combination.txt from all files from /path/
                   DEPENDS ${all_small_files_list})

但这是我最不想做的事情。

1个回答

6

你可以使用add_custom_target与正确的依赖关系定义来替代使用add_custom_command(这样它就不会每次都被构建)。

add_custom_target(project
                   COMMAND touch project.txt)

add_custom_target(project2
                   COMMAND touch project2.txt)

add_custom_target(combination
                   COMMAND cat project.txt project2.txt > combination.txt)

add_dependencies(combination project2)
add_dependencies(combination project)

add_executable(t t.c)
add_dependencies(t combination.txt)

再次提醒:请确保使用add_custom_targetDEPENDS参数来创建真正的依赖链,以使项目目标和组合目标变得过时。

更新:我太草率了。实际上,cmake(至少到2.8.9)对依赖项的工作方式如下:通过调用add_dependencies,您无法添加自定义命令的OUTPUT(即生成的)文件作为依赖项。您只能通过使用DEPENDS指令在add_custom_command的输出上对add_custom_target进行依赖。也就是说,这样做可以解决问题:

add_custom_command(OUTPUT project.txt
                   COMMAND uptime >> project.txt MAIN_DEPENDENCY t2.c)
add_custom_target(project DEPENDS project.txt)

add_custom_target(combination
                   COMMAND cat project.txt project2.txt > combination.txt)
add_dependencies(combination project)

这将使组合目标始终重新生成,因为它没有MAIN_DEPENDENCYDEPENDS,但允许使用add_dependencies

它会工作,但不完全符合预期: 每次我调用make时,所有目标(combination、project和project2)都将被重建 - 因此文件将被重新生成。 这不像它本应该的那样好 ;)对我来说,期望的行为是除非必要,否则不重新生成任何文件。根据CMake的文档 - add_custom_target每次都会被构建。 我希望有一个像add_custom_command一样的解决方案 - 只有在任何依赖项更改时才会构建。 - Michał Walenciak
你在生成project.txt的依赖项中使用了什么?我认为cmake-doc想表达的是,custom_target始终会被检查是否需要重新构建,至少对我来说是这样。 - Patrick B.
你提供的解决方案是可行的,但有一个缺点:每次输入“make combination”时,都会启动一个cat命令。这是多余的 ;) 请看一下add_custom_target的描述:“add_custom_target:添加一个没有输出的目标,因此它将始终被构建。(...)该目标没有输出文件,即使命令尝试创建与目标名称相同的文件,它也始终被视为过时。” - Michał Walenciak
即使我在自定义目标中添加DEPENDS关键字,它也只会调用指定目标的构建规则,而不会阻止构建系统每次构建自定义目标。 - Michał Walenciak
我同意Michael的观点,当我有两个add_custom_targets时,我无法使一个依赖于另一个。 - netskink
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接