Cmake 依赖于同一库的多个子项目

Cmake 依赖于同一库的多个子项目,cmake,Cmake,我有一个项目main\u项目。它依赖于两个库——libA和libB,而这两个库又分别依赖于libu common 从图形上看,项目的结构如下所示: main_project | +-libA | | | +-CMakeLists.txt | +-libB | | | +-CMakeLists.txt | +-lib_common | | | +-CMakeLists.txt | +-CMa

我有一个项目
main\u项目
。它依赖于两个库——
libA
libB
,而这两个库又分别依赖于
libu common

从图形上看,项目的结构如下所示:

main_project
   |
   +-libA
   |   |
   |   +-CMakeLists.txt
   |
   +-libB
   |   |
   |   +-CMakeLists.txt
   |
   +-lib_common
   |   |
   |   +-CMakeLists.txt
   |
   +-CMakeLists.txt
由于
libA
使用
lib\u common
libA
CMakeLists.txt中调用
add\u子目录(lib\u common)
非常自然。但是
libB
也依赖于
lib\u common
。如果我再次将其放入子目录,它将编译两次。我不想那样。此外,我还想保持所有子项目的整洁和独立性-这就是为什么我不想将
lib_common
放在顶级
main_项目
CMakeLists.txt
(因为
lib_common
main_项目没有任何关系)


我有哪些选择?

我认为这是一个相当标准的CMake解决方案:

# toplevel CMakeLists.txt
add_subdirectory(libA)
add_subdirectory(libB)
add_subdirectory(lib_common)

对于
libB
,也类似


添加子目录(libA)
之前,无需调用
添加子目录(libu common)
,CMake会自动处理依赖项管理。

我会在项目结构中再添加一个抽象级别:

  • 应用程序
    -这适用于可执行文件以及属于它们的所有内容
  • 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
libu common
连接在一起:

cmake_minimum_required(VERSION 2.8)

add_subdirectory(lib_common)
add_subdirectory(libA)
add_subdirectory(libB)
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\u common
没有依赖项,因此
lib/lib\u 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\u common

cmake_minimum_required(VERSION 2.8)

add_subdirectory(lib_common)
add_subdirectory(libA)
add_subdirectory(libB)
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
子项目可以称为干净且独立的。

依赖项是通过
add\u dependency
target\u link\u库添加的。无需从leaf CMakeLists.txt调用
add_子目录