我有好几个项目(所有项目都是从同一个源树结构中使用CMake构建的)都使用了自己的数十种支持库。
所以我想到了一个问题,如何在CMake中正确设置它。到目前为止,我仅发现CMake如何正确地在目标之间创建依赖关系,但是我仍然在设置具有全局依赖关系(项目级别确实了解全部)或具有本地依赖关系(每个子级别目标仅处理其目标)之间进行挣扎自己的依赖项)。
这里是我的目录结构的简化例子,我现在想出了使用CMake和本地依赖性(例子中只有一个可执行的项目,App1但也有更多的实际,App2,App3等):
Lib
+-- LibA
+-- Inc
+-- a.h
+-- Src
+-- a.cc
+-- CMakeLists.txt
+-- LibB
+-- Inc
+-- b.h
+-- Src
+-- b.cc
+-- CMakeLists.txt
+-- LibC
+-- Inc
+-- c.h
+-- Src
+-- c.cc
+-- CMakeLists.txt
App1
+-- Src
+-- main.cc
+-- CMakeLists.txt
Lib / LibA / CMakeLists.txt
include_directories(Inc ../LibC/Inc)
add_subdirectory(../LibC LibC)
add_library(LibA Src/a.cc Inc/a.h)
target_link_libraries(LibA LibC)
Lib / LibB / CMakeLists.txt
include_directories(Inc)
add_library(LibB Src/b.cc Inc/b.h)
Lib / LibC / CMakeLists.txt
include_directories(Inc ../LibB/Inc)
add_subdirectory(../LibB LibB)
add_library(LibC Src/c.cc Inc/c.h)
target_link_libraries(LibC LibB)
App1 / CMakeLists.txt(为便于复制,我在此处生成源/头文件)
cmake_minimum_required(VERSION 2.8)
project(App1 CXX)
file(WRITE "Src/main.cc" "#include \"a.h\"\n#include \"b.h\"\nint main()\n{\na();\nb();\nreturn 0;\n}")
file(WRITE "../Lib/LibA/Inc/a.h" "void a();")
file(WRITE "../Lib/LibA/Src/a.cc" "#include \"c.h\"\nvoid a()\n{\nc();\n}")
file(WRITE "../Lib/LibB/Inc/b.h" "void b();")
file(WRITE "../Lib/LibB/Src/b.cc" "void b() {}")
file(WRITE "../Lib/LibC/Inc/c.h" "void c();")
file(WRITE "../Lib/LibC/Src/c.cc" "#include \"b.h\"\nvoid c()\n{\nb();\n}")
include_directories(
../Lib/LibA/Inc
../Lib/LibB/Inc
)
目前,我更喜欢本地依赖项变体,因为它更易于使用。我只使用给出源级别的依赖关系,使用给出include_directories()链接级别的依赖关系,使用target_link_libraries()CMake级别给出依赖关系add_subdirectory()。
这样,您就无需知道支持库之间的依赖关系,并且-有了CMake级别的“包含”,您最终只会使用真正使用的目标。可以肯定的是,您只需使所有包含目录和目标都为全局已知,然后让编译器/链接器将其余的分类即可。但这对我来说似乎是一种腹胀。
我还尝试使用a Lib/CMakeLists.txt来处理Lib目录树中的所有依赖关系,但是最终我进行了很多if ("${PROJECT_NAME}" STREQUAL ...)检查,并遇到了一个问题,即如果不给出至少一个源文件,就无法创建将目标分组的中间库。