本文介绍了在cmake中,如何以可扩展的方式指定子目录的依赖关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设源树是这种结构:

  / 
| - lib1
| | - src.cpp
| | - lib1.h
| | - CMakeLists.txt
|
| - lib2
| | - src.cpp
| | - lib2.h
| | - CMakeLists.txt
|
| - lib3
| | - src.cpp
| | - lib3.h
| | - CMakeLists.txt
|
| - app
| | - src.cpp
| | - CMakeLists.txt
|
| - CMakeLists.txt

假设:


  1. lib1具有函数f();

  2. lib2具有使用f()的函数g();

  3. app / src.cpp使用函数g();

  4. 没有人使用lib3。

我想:


  1. 在app / CMakeLists.txt中,它只链接到lib2。这里的逻辑是,app / src.cpp只使用g(),所以在编写app / src.cpp时,我们不能指定对lib1的依赖,因为它是lib2的实现细节。所以根据这个逻辑,在app / CMakeLists.txt中,它不能有任何与lib1有关的,即它既不包括lib1的include_directories,lib1的add_subdirectory,也不是lib1的target_link_libraries等。

  2. 因为没有人使用lib3,它甚至不会被构建。这需要自动完成。所以手动add_subdirectory为lib1和lib2但不是lib3不是一个聪明的方法。你可以想象,如果我们有一个非常大的源代码树与复杂的树结构和依赖和数百个可执行文件在数百个不同的子目录。如果我只想构建其中的几个,那么我不想打扰建立未使用的库。

所以我的问题是:有没有办法以可扩展的方式编写CMakeLists.txt文件以满足上述要求?

解决方案

/ div>

对于1个问题:



lib2 / CMakeLists.txt 您应该输入:

  target_link_libraries(lib2 lib1)

并在app / CMakeLists.txt中:

  target_link_libraries lib2)

现在如果你尝试构建应用程序,CMake将检查lib2是否是最新的,如果不重建lib1和lib2。



对于2个问题:



可以使用保护 add_subdirectory(lib3)调用if()基于 / code>变量。



另一种方式 - 在lib3 / CMakeLists.txt中:

  add_library(lib3 $ {SRCS} EXCLUDE_FROM_ALL)

不将 lib3 目标添加到全部目标中。如果你试图根据它创建一些东西,或者手动发出 make lib3 ,这个目标仍然会被构建。


Suppose the source tree is in this structure:

/
 |- lib1
 |  |- src.cpp
 |  |- lib1.h
 |  |- CMakeLists.txt
 |
 |- lib2
 |  |- src.cpp
 |  |- lib2.h
 |  |- CMakeLists.txt
 |
 |- lib3
 |  |- src.cpp
 |  |- lib3.h
 |  |- CMakeLists.txt
 |
 |- app
 |  |- src.cpp
 |  |- CMakeLists.txt
 |
 |- CMakeLists.txt

Suppose:

  1. lib1 has function f();
  2. lib2 has function g() which uses f();
  3. app/src.cpp uses function g();
  4. Nobody uses lib3.

I want:

  1. in app/CMakeLists.txt, it only link to lib2. The logic here is, app/src.cpp only uses g(), so when writing app/src.cpp, we can't specify the dependency to lib1 because it is implementation detail of lib2. So according to this logic, in app/CMakeLists.txt, it can't have anything related to lib1, i.e. it neither include_directories of lib1, add_subdirectory of lib1, nor target_link_libraries of lib1, etc.
  2. Since nobody uses lib3, it won't even be built. This needs to be done automatically. So manually add_subdirectory for lib1 and lib2 but not lib3 is not a clever way. You can imagine if we have a very large source tree with complicated tree structure and dependencies and hundreds of executables in hundreds of different subdirectories. If I only want to build several of them, then I don't want to bother building unused libraries at all.

So my question is: is there a way to write the CMakeLists.txt files in a scalable way to satisfy the above requirements? If not, then is there some similar tools that can do this?

Thanks.

解决方案

For the 1 question:

In lib2/CMakeLists.txt you should put this:

target_link_libraries(lib2 lib1)

And in app/CMakeLists.txt:

target_link_libraries(app lib2)

Now if you try to build app, CMake will check if lib2 is up to date and if not - rebuild lib1 and lib2.

For the 2 question:

You can guard add_subdirectory(lib3) invocation with if() block based on option() variable.

Another way - in lib3/CMakeLists.txt:

add_library(lib3 ${SRCS} EXCLUDE_FROM_ALL)

This would make CMake to not adding lib3 target into all target. This target will still be built if you are trying to build something depending on it, or issue make lib3 manually.

这篇关于在cmake中,如何以可扩展的方式指定子目录的依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 17:16