如何在 CMake 中强制指定目标构建顺序

5

我刚刚接手一堆使用 CMake 构建的糟糕项目。我对 CMake 毫无了解,而且我怀疑之前的维护者也一样。

我需要强制控制项目之间的构建顺序。它过去是这样的:

=== BUILD TARGET foo1 OF PROJECT bar ...
=== BUILD TARGET foo2 OF PROJECT bar ...
=== BUILD TARGET foo3 OF PROJECT bar ...

我需要添加一个项目和相关依赖项(在不同的目标中而非上述目标)。但是代码中有很多问题。
# don't change the library order, it will break xyz  
target_link_libraries(foo3 other1 foo2 other2 foo1 other3)

正如你所猜想的,在我的更改后,我现在获得了...
=== BUILD TARGET foo1 OF PROJECT bar ...
=== BUILD TARGET foo3 OF PROJECT bar ...

foo3无法构建,因为foo2的头文件未被复制、安装或其他操作。我相信,如果我能强制CMake在foo3之前触发foo2,问题就会得到解决。

然而,我尝试过:

target_link_libraries(foo3 foo2)

无济于事,我仍然看到foo3foo2之前触发。

我还尝试了

add_dependencies(foo3 foo2)

那么,我的问题:

  • 我能看到CMake必须内部构建的依赖关系图吗?
  • 如果出现了循环,我该如何知道并找到它?
  • 我是否可以强制指定目标构建的顺序?
  • 在构建顺序方面是否还有其他需要注意的地方?

1
调用add_dependencies(foo3 foo2)应该强制在构建foo3之前构建foo2目标。至少,在没有反向依赖关系的情况下是这样的。调用target_link_libraries(foo3 foo2)也应该可以工作。 "我能看到CMake内部必须构建的依赖关系图吗?" - CMake只为构建工具(例如Makefile)生成文件。从您使用的构建工具中请求依赖项图。 "我可以强制目标构建的顺序吗?" - 除了依赖项(直接或间接)外,我不知道其他方法。 - Tsyvarev
这个答案展示了如何获取CMake目标的依赖关系图。为了调试实际的依赖关系,请尝试从干净的构建树中单独构建每个目标。 - Botje
@Botje,这是一个很棒的第一步。图表肯定会有所帮助! - Jeffrey
同时检查并修复由 cmake -Wdev 产生的任何警告。 - Botje
1个回答

4

CMake是一种声明式的构建系统。

虽然您在CMakeLists.txt文件中编写的CMake程序以纯命令方式执行,但它们构建的构建系统是声明式的。

这意味着您无法控制目标的构建顺序。您只需指定要完成的任务,而不是如何完成。这已经被抽象化了。

唯一的方法是在目标中添加依赖项。首先,在构建依赖目标之前,将构建所有依赖项。

您可以通过像“target_link_libraries”和“target_sources”这样的命令添加依赖项。您可以使用非常通用的“add_dependencies”添加更多与基本C / C ++编程不相关的文件。


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