chapter04.a - 梳理依赖是如何创建的
我认为的依赖有两种:
- 文件依赖(sources)既有同级依赖(比如
add_custom_command
的DEPENDS
参数),又有 targets 到 sources 的依赖。 - 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_target
和 add_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 中写链接规则。