如何使用现代 CMake 安装捆绑的接口依赖项?
How do I Install bundled interface dependencies with modern CMake?
在Modern CMake中安装捆绑接口依赖项的正确方法是什么?
我有一个库MyLib
,它对libDep
具有接口依赖性(MyLib.hpp
包含#include <libDep.h>
(。任何依赖于MyLib
的东西也传递地取决于libDep
。
libDep
是从要点中获取的单个标头,因此我已将其包含在MyLib
源代码树的一部分
$ tree
.
├── CMake
│ ├── MyLibConfig.cmake.in
│ └── modules
│ └── FindlibDep.cmake
├── CMakeLists.txt
├── include
│ └── MyLib
│ └── MyLib.hpp
├── src
│ └── MyLib.cpp
└── third_party
└── libDep
└── libDep.h
我想用myLib
安装libDep
,在像include/MyLib/third_party/libDep
这样的路径中。
这是MyLib
的CMakeLists
cmake_minimum_required(VERSION 3.3.0)
Project(MyLib
DESCRIPTION "Library with bundled interface dependency"
LANGUAGES CXX)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/modules)
# Find LibDep dependency
find_package(libDep REQUIRED)
# MyLib library
add_library(MyLib STATIC
${CMAKE_SOURCE_DIR}/src/MyLib.cpp)
target_include_directories(MyLib
PUBLIC $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include/MyLib>
PUBLIC $<INSTALL_INTERFACE:include/MyLib>)
target_link_libraries(MyLib
INTERFACE libDep)
MyLib
将libDep
与FindlibDep.cmake
位于CMAKE_MODULE_PATH
find_path(LibDep_INCLUDE_DIR
NAMES LibDep.hpp
PATHS third_party/libDep)
PATH_SUFFIXES Mylib/third_party/libDep)
mark_as_advanced(LibDep_FOUND LibDep_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibDep
REQUIRED_VARS
LibDep_INCLUDE_DIR
)
if(LibDep_FOUND)
set(LibDep_INCLUDE_DIRS ${LibDep_INCLUDE_DIR})
endif()
if(LibDep_FOUND AND NOT TARGET MyLib::LibDep)
add_library(MyLib::LibDep INTERFACE IMPORTED)
set_target_properties(MyLib::LibDep PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${LibDep_INCLUDE_DIR})
endif()
我安装MyLib
喜欢
install(TARGETS MyLib
EXPORT MyLibTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(MyLibConfigVersion.cmake)
install(EXPORT MyLibTargets
FILE MyLibTargets.cmake
NAMESPACE MyLib::
DESTINATION lib/cmake/MyLib)
configure_file(CMake/MyLibConfig.cmake.in MyLibConfig.cmake @ONLY)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/MyLibConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/MyLibConfigVersion.cmake"
DESTINATION lib/cmake/MyLib)
install(DIRECTORY ${MyLib_PUBLIC_INCLUDE_DIR}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# Package with CPack
include(InstallRequiredSystemLibraries)
include(CPack)
MyLibConfig.cmake.in
声明了对libDep
的依赖关系
include(CMakeFindDependencyMacro)
# Dependencies
add_library(libDep REQUIRED)
# Add the targets file
include("${CMAKE_CURRENT_LIST_DIR}/MyLibTargets.cmake")
libDep
被安装到MyLib
树中
install(DIRECTORY ${libDep_INCLUDE_DIRS}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/MyLib/third_party)
我复制了查找模块
install(FILES
${CMAKE_MODULE_PATH}/FindlibDep.cmake
DESTINATION lib/cmake/MyLib)
不幸的是,MyLib
的用户默认看不到FindlibDep.cmake
$ cmake ..
CMake Error at /usr/share/cmake-3.10/Modules/CMakeFindDependencyMacro.cmake:48 (find_package):
By not providing "FindlibDep.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "libDep", but
CMake did not find one.
Could not find a package configuration file provided by "libDep" with any
of the following names:
libDepConfig.cmake
libDep-config.cmake
Add the installation prefix of "libDep" to CMAKE_PREFIX_PATH or set
"libDep_DIR" to a directory containing one of the above files. If "libDep"
provides a separate development package or SDK, be sure it has been
installed.
Call Stack (most recent call first):
/usr/local/lib/cmake/MyLib/MyLibConfig.cmake:5 (find_dependency)
CMakeLists.txt:9 (find_package)
-- Configuring incomplete, errors occurred!
用户可以手动查找FindlibDep.cmake
并将其添加到其CMAKE_MODULE_PATH
但这不是必需的。
此问题的复制可在 GitHub 上找到。
您需要将 PROJECT_ 变量用于源 dir 而不是 CMAKE_ 变量:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMake/modules)
PROJECT_SOURCE_DIR从最近执行的 project(( 指令(在本例中为库(获取源目录。
您还应该将当前CMAKE_MODULE_PATH添加到新路径中,如上所示。
相关文章:
- 如何从C++中的依赖类型中获得它所依赖的类型
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 将依赖名称显式标记为类型名和模板的奇怪之处
- Visual C++GC接口如何启用它以及要包含哪个库
- Windows.h与GLFW.h的接口
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- C++GTKMM gui循环依赖关系
- 通过ccmake在cmake中缓存依赖选项
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 提供与TMP和SFINAE的通用接口
- 为重写std::exception的库生成swig接口时出错
- 内联如何影响模块接口中的成员函数
- 如何使用现代 CMake 安装捆绑的接口依赖项?
- 具有依赖于实现的成员函数类型的多个静态接口
- 是库依赖问题可以通过接口避免
- 依赖注入 + 完全虚拟与接口
- 切换到c++ 11时,是否需要重新编译所有在接口中使用STL的依赖库?
- 接口的集合相互依赖
- 使用C++中的接口进行依赖项注入