子文件夹中的各种库,如何将它们导出到父文件夹?

时间:2016-04-26 17:44:03

标签: c++ cmake

我有一个像这样的代码文件夹结构:

project/
  CMakeLists.txt
  src/
    project.cpp
  lib/
    libA/
      CMakeLists.txt
      src/
        libA.cpp
      include/
        libA.h
    libB/
      CMakeLists.txt
      src/
        libB.cpp
      include/
        libB.h

现在,libA完全是独立的,所以我有CMakeLists.txt类似于此:

cmake_minimum_required(VERSION 2.8)
project ( libA )
set ( LIBA_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE )
include_directories ( include/ )

file (GLOB LIBA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}
  src/libA.cpp
  )
add_library         ( libA STATIC ${LIBA_SOURCES} )

但是,libB取决于libA。如何导出用于链接到libA.a的{​​{1}}输出路径以及相应的包含路径?

此外,如何将该数据传递给主项目的父libB

3 个答案:

答案 0 :(得分:2)

我个人没有这样做,所以这个答案可能只是一个起点,但Qt使用cmake并且能够将所有包含目录和库依赖关系绑定到每个“模块”(库)中。如果你完成了,那么你可以简单地做

add_executable(myExe ...)
target_link_libraries(myExe libB)

到主cmake项目中的可执行文件。

查看Qt脚本,您需要设置的内容(对于每个库):

add_library(libA ...)
set_target_properties(libA PROPERTIES
    "INTERFACE_LINK_LIBRARIES" "${LIBRARIES_LIBA_DEPENDS_ON}"
    "INTERFACE_INCLUDE_DIRECTORIES" "${LIBA_INCLUDE_DIRECTORIES}"
)

然后是libB

add_library(libB ...)
set_target_properties(libB PROPERTIES
    "INTERFACE_LINK_LIBRARIES" "libA"
    "INTERFACE_INCLUDE_DIRECTORIES" "${LIBB_INCLUDE_DIRECTORIES}"
)

这种方法很酷的一点是,如果操作正确,你可以将任意数量的库链接在一起,而不必担心依赖关系的组合爆炸,包括dirs。

答案 1 :(得分:1)

CMake了解您构建的所有目标,因此无需将信息导出到父级。您只需告诉CMake libB链接libA和CMake负责在链接器命令行上放置正确的路径。因此,只需将libA指定为libB / CMakeLists.txt中的libB的链接依赖项:

target_link_libraries(libB libA)

对于包含路径,您需要在顶级项目/ CMakeLists.txt中沿着以下行设置父项中的变量:

set(LIBA_INCLUDES libA/include)
set(LIBB_INCLUDES libB/include)

然后在子项目CMakeList.txt文件中引用它们。

或者,您可以在libB / CMakeLists.txt文件中使用相对路径:

include_directories(../libA/include)

答案 2 :(得分:1)

采取@epicbrew和@NicolasHolthaus的答案/评论我只是想展示一个完整的例子将如何在更新版本的CMake中展示,并讨论一些含义:

<强>项目/的CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project( project )

add_subdirectory( lib/libB )
add_subdirectory( lib/libA )

add_executable( project src/project.cpp )
target_link_libraries( project libB )

<强>项目/ LIB / LIBA /的CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project( libA )

add_library( libA STATIC src/libA.cpp include/libA.h )
target_include_directories( libA PUBLIC include )

<强>项目/ LIB / libB /的CMakeLists.txt

add_library( libB STATIC src/libB.cpp  include/libB.h )
target_include_directories( libB PUBLIC include )
target_link_libraries( libB libA )

如你所见

  1. 您需要在主CMakeLists.txt文件中知道您还需要libA。我故意颠倒add_subdirectory()调用,以表明在使用target_link_libraries()时(顺序允许目标前向声明),顺序无关紧要。
  2. 您不再需要本地include_directories()来电,而是target_include_directories()的隐含部分。
  3. 使用target_include_directories(... PUBLIC ...)这些包含路径是自我传播的。
  4. 您无需添加${CMAKE_CURRENT_SOURCE_DIR}前缀,这些是默认值。
  5. 我刚刚将源/头文件直接添加到add_executable() / add_library()调用,以获得此示例代码的紧凑性。通常我也会把它们放在局部变量中。
  6. libB不是独立的,但你可以改变它,例如将add_subdirectory( ../libA libA )添加到其CMakeLists.txt文件中。显然,您必须从主add_subdirectory( lib/libA )中删除CMakeLists.txt
  7. 如果您想稍微优化CMake处理,则不应重复project()命令。如果您仍希望libA能够自给自足,则可以在if ( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) / endif()来电时添加cmake_minimum_required(VERSION 3.0) / project( libA )