In cmake, how to specify dependencies of subdirectories in a scalable way?

微笑、不失礼 提交于 2019-12-04 04:21:19

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/9439865/in-cmake-how-to-specify-dependencies-of-subdirectories-in-a-scalable-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!