多个子项目取决于相同的库

时间:2017-06-30 15:03:23

标签: cmake

我有一个项目main_project。它取决于两个库 - libAlibB,而每个库依赖于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.txtlib_common没有任何关系。)

我有哪些选择?

2 个答案:

答案 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文件夹,您可以在其中包含标题,可执行文件取决于libAlibB

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可以将libAlibBlib_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.txtlib/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会自动处理依赖关系管理。