chapter04.a - 梳理依赖是如何创建的

我认为的依赖有两种:

  1. 文件依赖(sources)既有同级依赖(比如 add_custom_commandDEPENDS 参数),又有 targets 到 sources 的依赖。
  2. target 依赖是一种 targets 之间的同级依赖关系。

Target 依赖

创建 target 可以用 add_executable/add_library/add_custom_target。前面两个都默认包含在 all 中,而最后一个默认不包含在 all 中。此外,add_custom_target 如果给的是命令,而不是依赖文件,则创建的 targets 永远处于“需要被构建”的状态;如果给的是文件,则就只是文件依赖。

可以用 add_dependencies 来创建 targets 之间的依赖。

文件依赖

如果 target 或者 command(由 add_custom_command 创建)依赖一个源文件,这个文件找不到、但是又被标记了 GENERATED 属性,则会想办法去生成这个文件。

创建 target 的时候没有给全源文件不要紧,可以用 去追加源文件。

在源文件中添加头文件看似没有意义,实际上是增加了依赖文件,在这个文件需要由自定义命令在构建时生成时很有用。

Note

使用 add_custom_targetadd_custom_command 时一定要正确写上 OUTPUT/DEPENDS/BYPRODUCTS

Warning

文件依赖在跨目录时不太好用,处理起来很棘手。最好是在当前目录解决。

文件依赖中给出的文件既可以相对于本文件夹对应的 build 目录,又可以相对于本文件夹对应的 source 目录。CMake 更偏好前者。

文件依赖并不是很好处理,幸运的是,我们随时可以将文件依赖转换成 target 依赖!

https://stackoverflow.com/questions/46795065/cmake-have-a-target-depend-on-a-generated-file-in-a-subdirectory 网页给的代码中依赖了 subdir/foo.{h,cpp},但实际上因为有 target 的出现,对 subdir/foo.h 的依赖是多余的。不过对 .cpp 文件还是得有源码依赖,否则不能正常生成。最好的处理方法其实还是在子文件夹编译成目标文件,直接在当前目录的 CMakeLists.txt 中写链接规则。