CMake nested libraries
CMake nested libraries
我有一个 c++ 项目,其中我的executable
取决于我的core library
,而该库依赖于另一个外部库,libtorrent
它是否有任何相关性。
问题是我无法弄清楚如何设置我的CMakeLists.txt,我已经搜索了几天,但无济于事。
主要思想是core library
和executable
位于单独的 git 存储库上,因此该库不是可执行文件的子 git 模块。
最好我能够使用 ExternalProject_Add 将core library
添加到executable
但是当我这样做时,executable
抱怨它对核心库再次使用的libtorrent
一无所知。将libtorrent
的标头添加到可执行文件中是不够的,我还需要将executable
链接到libtorrent
。但是我为什么要编译core library
,因为我只需要再次将core library
的所有依赖项添加到executable
。
如果有人可以指出如何设置一个使用具有其他依赖项的核心库和使用核心库的可执行文件的项目的正确方向。
通常,这用目标和它们之间的链接表示。
您的设置可能如下所示:
# core cmake file
find_package(LibtorrentRasterbar REQUIRED)
add_library(core_lib file1.cpp file2.cpp file3.cpp ...)
target_link_libraries(core_lib PUBLIC LibtorrentRasterbar::torrent-rasterbar) # see below
# app cmake file
find_package(core_lib) # find it elsewhere
add_executable(app file1.cpp file2.cpp file3.cpp ...)
target_link_libraries(exec PRIVATE core_lib::core_lib)
如果核心需要在其标头中创建新库,则应将它们添加到core_lib
的依赖项中。任何公共需求都会传递到用户,例如app
目标。
与外部库或构建树的偏差使用find_library
表示。它可以是安装在根目录中的库,安装在项目子目录中的用户目录中,也可以只是库的构建树。在您的情况下,查找构建树可能是您想要的。
然后,由于您的core_lib
库位于另一个项目中,我建议查看如何从构建树或安装中导出目标,以便find_package(core_lib)
工作。
不幸的是,Libtorrent
似乎没有正确支持 CMake,因此找不到包Libtorrent
,也不会定义目标Libtorrent::torrent-rasterbar
。
有一些方法可以通过尝试他们的FindLibtorrentRasterbar.cmake
来解决。
看看他们的查找模块,很明显它并没有考虑到现代cmake。如果文件支持链接到其目标,则必须在末尾添加这些行:
if(LibtorrentRasterbar_FOUND)
set(LibtorrentRasterbar_LIBRARY_DEPS "${LibtorrentRasterbar_LIBRARIES}")
list(REMOVE_ITEM LibtorrentRasterbar_LIBRARY_DEPS ${LibtorrentRasterbar_LIBRARY})
if(LibtorrentRasterbar_USE_STATIC_LIBS)
add_library(LibtorrentRasterbar::torrent-rasterbar STATIC IMPORTED GLOBAL)
else()
add_library(LibtorrentRasterbar::torrent-rasterbar SHARED IMPORTED GLOBAL)
endif()
set_target_properties(LibtorrentRasterbar::torrent-rasterbar PROPERTIES
IMPORTED_LOCATION ${LibtorrentRasterbar_LIBRARY}
INTERFACE_LINK_LIBRARIES ${LibtorrentRasterbar_LIBRARY_DEPS}
INTERFACE_COMPILE_DEFINITIONS ${LibtorrentRasterbar_DEFINITIONS}
INTERFACE_INCLUDE_DIRECTORIES ${LibtorrentRasterbar_INCLUDE_DIRS}
)
endif()
我没有提到的一个细节是,find_package
不会尝试找到依赖项的包。为此,请创建一个如下所示的自定义配置文件:
# cmake/core_lib-config.cmake.in
include(CMakeFindDependencyMacro)
# this line is just like a find_package
# but made for transitivity
find_dependency(LibtorrentRasterbar)
include("${CMAKE_CURRENT_LIST_DIR}/core_lib-targets.cmake")
然后将导出更改为输出core_lib-targets.cmake
而不是通常的配置:
# this is the new config file with the add_dependency
configure_file(
cmake/core_lib-config.cmake.in
core_lib-config.cmake
@ONLY
)
# the new config file will include this target file
install(EXPORT core_lib_targets
NAMESPACE core_lib::
FILE core_lib-targets.cmake
DESTINATION lib/cmake/core_lib)
# export the current build tree
export(
EXPORT core_lib_targets
NAMESPACE core_lib::
FILE "${CMAKE_CURRENT_BINARY_DIR}/core_lib-targets.cmake"
)
- C++ MFC Libraries in Travis CI
- Ardunio Uart class & Libraries
- Nested static_cast and const_cast
- DataStax C++ Cassandra Nested UDTs
- 在 R 中调用"multi file C++ code with external libraries referenced"
- 链接 boost 库时"Error while loading shared libraries"引发的,除了我无法使用 root 访问权限来修复它
- CMake nested libraries
- 如何处理"Cmake Error: Unable to find the requested Boost libraries"?
- Bjarne Stroustrup在他的FAQ中"foundation libraries"是什么意思?
- Connflicting C++ libraries
- Windows Boost 1.64 VS2017 missing Python libraries
- 单元测试环境中的"java.lang.UnsatisfiedLinkError: *.so: Can't find dependent libraries"
- 为什么C++不支持"nested-comment"?
- dlmopen and C++ libraries
- Linking libraries CMake
- "Nested" 带括号的类模板参数推导:GCC vs. clang
- 模板尾部结构抬高"incomplete type in nested name specifier"
- 如何创建可供src/code和lib/libraries访问的全局对象
- ex.nested try-catch中的什么()更改
- "directory containing symbolic versions of my app's shared libraries"的位置(ndk-stack)