通过vcpkg分发的非CMake库对接CMake:选配置文件还是查找模块?
问题解答
一、优先选择CMake配置文件而非查找模块
- 配置文件随包分发,与库的二进制、头文件一同放在vcpkg安装目录中,vcpkg会自动将其路径加入
CMAKE_PREFIX_PATH,CMake无需额外配置即可找到,完全契合vcpkg的自动包管理逻辑,私有注册表场景下维护成本更低。 - 查找模块(
Find<my-package>.cmake)需要用户手动放置到CMake模块路径,不符合vcpkg自动化管理的初衷,尤其不适用于私有包的分发场景。 - 配置文件能更好地和vcpkg依赖管理配合:vcpkg已完成依赖的安装调度,配置文件只需专注于导入库目标,无需重复用
find_dependency(除非依赖未通过vcpkg管理,而你已经用vcpkg管依赖,可直接简化)。
二、非CMake构建项目编写CMake配置文件的步骤
你需要手动编写3个核心文件,放置到vcpkg安装目录的share/<my-package>下:
1. <my-package>-config-version.cmake
用于告知CMake库的版本,支持find_package(<my-package> REQUIRED VERSION x.x.x)版本校验:
set(PACKAGE_VERSION "1.0.0") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() set(PACKAGE_VERSION_COMPATIBLE TRUE) if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) set(PACKAGE_VERSION_EXACT TRUE) endif() endif()
2. <my-package>-targets.cmake
核心文件,定义CMake目标,关联头文件目录与库文件路径(以Windows静态库为例,Debug/Release分离):
# 定义头文件根目录 set(MY_PACKAGE_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../include") # 导入Debug版本库目标 add_library(my-package::my-package-debug STATIC IMPORTED) set_target_properties(my-package::my-package-debug PROPERTIES IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_LIST_DIR}/../../lib/debug/my-package.lib" INTERFACE_INCLUDE_DIRECTORIES "${MY_PACKAGE_INCLUDE_DIRS}" ) # 导入Release版本库目标 add_library(my-package::my-package-release STATIC IMPORTED) set_target_properties(my-package::my-package-release PROPERTIES IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_LIST_DIR}/../../lib/release/my-package.lib" INTERFACE_INCLUDE_DIRECTORIES "${MY_PACKAGE_INCLUDE_DIRS}" ) # 定义通用目标,自动根据构建配置切换Debug/Release add_library(my-package::my-package INTERFACE IMPORTED) target_link_libraries(my-package::my-package INTERFACE $<$<CONFIG:Debug>:my-package::my-package-debug> $<$<CONFIG:Release>:my-package::my-package-release> )
如果是动态库,Windows下需额外设置IMPORTED_IMPLIB属性,Linux/macOS则直接用IMPORTED_LOCATION,同时注意配置动态库的运行时路径。
3. <my-package>-config.cmake
用于加载Targets文件,按需处理依赖:
# 加载预定义的库目标 include("${CMAKE_CURRENT_LIST_DIR}/<my-package>-targets.cmake") # 若库有额外依赖(如依赖zlib且已通过vcpkg管理),可添加以下代码: # find_dependency(ZLIB REQUIRED) # target_link_libraries(my-package::my-package INTERFACE ZLIB::ZLIB)
三、在vcpkg portfile.cmake中添加配置文件安装逻辑
修改你的portfile.cmake,将上述3个CMake文件复制到vcpkg的包安装目录:
vcpkg_download_distfile(ARCHIVE URLS "https://你的私有仓库地址/my-package-v1.0.0.zip" FILENAME "my-package-v1.0.0.zip" SHA512 替换为你的压缩包SHA512哈希值 ) vcpkg_extract_source_archive_ex( OUT_SOURCE_PATH SOURCE_PATH ARCHIVE ${ARCHIVE} ) # 安装头文件 file(INSTALL "${SOURCE_PATH}/include" DESTINATION "${CURRENT_PACKAGES_DIR}") # 安装库文件 file(INSTALL "${SOURCE_PATH}/lib/debug" DESTINATION "${CURRENT_PACKAGES_DIR}/lib") file(INSTALL "${SOURCE_PATH}/lib/release" DESTINATION "${CURRENT_PACKAGES_DIR}/lib") # 安装CMake配置文件 file(INSTALL "${SOURCE_PATH}/cmake/<my-package>-config.cmake" DESTINATION "${CURRENT_PACKAGES_DIR}/share/<my-package>") file(INSTALL "${SOURCE_PATH}/cmake/<my-package>-config-version.cmake" DESTINATION "${CURRENT_PACKAGES_DIR}/share/<my-package>") file(INSTALL "${SOURCE_PATH}/cmake/<my-package>-targets.cmake" DESTINATION "${CURRENT_PACKAGES_DIR}/share/<my-package>") # 可选:安装版权文件 file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
四、客户端集成示例
客户端CMakeLists.txt中只需简单调用:
find_package(my-package REQUIRED) target_link_libraries(你的客户端项目名 PRIVATE my-package::my-package)
vcpkg清单模式会自动将包的share目录加入CMAKE_PREFIX_PATH,CMake可直接找到你的配置文件。
内容的提问来源于stack exchange,提问作者Michael Ngarimu
相关产品推荐
相关产品推荐

