子文件夹中的各种库,如何将它们导出到父级
Various libs in subfolders, how do I export them to the parent?
>我有一个这样的代码文件夹结构:
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
。如何导出用于链接到libB
的libA.a
输出路径以及相应的包含路径?
此外,如何将该数据传递给主项目的父CMakeLists.txt
?
我个人没有这样做过,所以这个答案可能只是一个起点,但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}"
)
这种方法很酷的地方在于,如果操作得当,您可以根据需要将任意数量的库链接在一起,而不必担心依赖项的组合爆炸并包含目录。
@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 )
project/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 )
project/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 )
如您所见
- 您需要在主
CMakeLists.txt
文件中知道您还需要libA
.我故意反转add_subdirectory()
调用,以表明使用target_link_libraries()
时顺序无关紧要(有点允许目标前向声明)。 - 您不再需要本地
include_directories()
调用,它是target_include_directories()
的隐式部分。 - 有了
target_include_directories(... PUBLIC ...)
这些包含路径是自我传播的。 - 您无需添加
${CMAKE_CURRENT_SOURCE_DIR}
前缀,这些是默认值。 - 我只是将源/头文件直接添加到
add_executable()
/add_library()
调用中,以实现此示例代码的紧凑性。通常,我也会将它们放在局部变量中。 -
libB
不是独立的,但您可以更改它,例如通过将add_subdirectory( ../libA libA )
添加到其CMakeLists.txt
文件中。显然,您必须从主CMakeLists.txt
中删除add_subdirectory( lib/libA )
。 - 如果要稍微优化 CMake 处理,则不应重复
project()
命令。如果您仍然希望libA
自给自足,您可以在cmake_minimum_required(VERSION 3.0)
/project( libA )
调用周围添加if ( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
/endif()
。
CMake 知道你构建的所有目标,因此无需将信息导出到父级。您只需告诉 CMake libB 链接 libA 和 CMake 负责在链接器命令行上放置正确的路径。因此,只需在libB/CMakeLists中将libA指定为libB的链接依赖项.txt:
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)
- 如何将更多文件夹添加到c++include路径
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 如何在文档文件夹中创建目录
- "assimp/config.h"找不到,但它在文件夹中
- C++入门 5 版:类消息和文件夹
- 我可以在 Arduino 的库文件夹之外安装库吗?
- 如何按文件扩展名引用文件夹中的文件
- 在QTreeView中仅显示共享驱动器和文件夹
- 加载与引用 .NET DLL 位于同一文件夹中的引用的 .NET DLL 时"Not found"异常
- 介子复制/安装头文件到输出目录并保持文件夹结构
- vcruntime.h 从 Windows 包含文件夹中丢失?
- 在文件夹迭代上实现 RAII
- 使用 Powershell 命令将 cpp 文件的文件夹编译为 GNU 的 g++
- 使文件夹中的所有文件可供所有项目(子目录)访问
- 无法使用 CMake 从其他文件夹添加源文件
- 如何在安卓工作室中将c ++头文件从一个文件夹导入到另一个文件夹?
- 如何从Windows控制台调用.exe(C++)以在不同的目录(或任何目录)中创建文件夹?
- 如何识别项目是 QT 中的文件还是文件夹