我有一个项目main_project
。它取决于两个库 - libA
和libB
,而每个库依赖于lib_common
。
图形项目的结构如下所示:
main_project
|
+-libA
| |
| +-CMakeLists.txt
|
+-libB
| |
| +-CMakeLists.txt
|
+-lib_common
| |
| +-CMakeLists.txt
|
+-CMakeLists.txt
由于libA
使用lib_common
,因此在add_subdirectory(lib_common)
libA
内拨打CMakeLists.txt
非常自然。但libB
也取决于lib_common
。如果我再次将它放在子目录中,它将编译两次。我不想要那个。此外,我希望保持所有子项目的清洁和自包含 - 这就是为什么我不想将lib_common
置于顶级main_project
' s {{ 1}}(因为CMakeLists.txt
与lib_common
没有任何关系。)
我有哪些选择?
答案 0 :(得分:1)
我会在项目结构中再添加一个抽象级别:
app
- 这是针对可执行文件以及属于它们的所有内容,lib
- 应用程序的库。顶级CMakeLists.txt
只知道有两个不同的东西,app
子项目和lib
子项目。示例目录结构如下所示:
FooProject
|-- app
| |-- CMakeLists.txt
| `-- src
| `-- foo.cpp
|-- CMakeLists.txt
`-- lib
|-- CMakeLists.txt
|-- libA
| |-- CMakeLists.txt
| |-- inc
| | `-- bar.h
| `-- src
| `-- bar.cpp
|-- libB
| |-- CMakeLists.txt
| |-- inc
| | `-- baz.h
| `-- src
| `-- baz.cpp
`-- lib_common
|-- CMakeLists.txt
|-- inc
| `-- common_tool.h
`-- src
`-- common_tool.cpp
顶级CMakeLists.txt
仅包含以下内容:
cmake_minimum_required(VERSION 2.8)
project(FooProject)
add_subdirectory(lib)
add_subdirectory(app)
app/CMakeLists.txt
应该知道有一个lib
文件夹,您可以在其中包含标题,可执行文件取决于libA
和libB
:
project(foo)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../lib)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src FOO_SOURCES)
add_executable(foo ${FOO_SOURCES})
add_dependencies(foo libA libB)
target_link_libraries(foo libA libB)
install(TARGETS foo RUNTIME DESTINATION bin ARCHIVE DESTINATION bin)
lib/CMakeLists.txt
可以将libA
,libB
和lib_common
绑定在一起:
cmake_minimum_required(VERSION 2.8)
add_subdirectory(lib_common)
add_subdirectory(libA)
add_subdirectory(libB)
我们假设lib_common
没有依赖关系,因此lib/lib_common/CMakeLists.txt
不会在其文件夹之外看到:
project(lib_common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src LIBCOMMON_SOURCES)
add_library(lib_common ${LIBCOMMON_SOURCES})
在此示例中,lib/libA/CMakeLists.txt
和lib/libB/CMakeLists.txt
内容几乎完全相同,只处理lib_common
:
project(libA)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc ${CMAKE_CURRENT_SOURCE_DIR}/..)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src LIBA_SOURCES)
add_library(libA ${LIBA_SOURCES})
add_dependencies(libA lib_common)
target_link_libraries(libA lib_common)
install(TARGETS libA LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
在此示例中,您可以将lib
子项目称为 clean and self-contained 。
答案 1 :(得分:0)
我认为这是一个相当标准的CMake解决方案:
# toplevel CMakeLists.txt
add_subdirectory(libA)
add_subdirectory(libB)
add_subdirectory(lib_common)
# libA CmakeLists.txt
add_library(libA ${LIBA_SOURCES})
target_link_libraries(libA lib_common)
和libB
类似。
您不必在add_subdirectory(lib_common)
之前调用add_subdirectory(libA)
,CMake会自动处理依赖关系管理。