如何在CMakeLists中通过CMake命令下载安装二进制依赖文件
如何通过CMake下载部署预编译二进制依赖
不需要额外引入第三方工具,CMake内置的ExternalProject_Add就可以实现需求,核心思路是跳过模块默认的源码编译流程,只保留下载解压步骤,再把路径对接给find_package即可。
核心配置逻辑
ExternalProject_Add默认执行「下载-解压-配置-编译-安装」的完整源码构建流程,针对预编译二进制包,只要把配置、编译、安装三个步骤的执行命令设为空值,模块就会只执行下载解压操作:
- 用
URL参数指定预编译压缩包的获取地址,建议必须搭配URL_HASH填写文件校验值,避免下载到损坏或被篡改的包 - 用
SOURCE_DIR指定压缩包解压后的存放路径,统一放在构建目录的第三方依赖文件夹下即可,不要污染源码目录 - 给
CONFIGURE_COMMAND、BUILD_COMMAND、INSTALL_COMMAND三个参数传空字符串,直接跳过所有源码构建环节
基础配置示例:
include(ExternalProject) ExternalProject_Add(precompiled_xxx URL 替换为目标预编译压缩包的对应地址 URL_HASH SHA256=替换为压缩包对应的实际SHA256校验值 SOURCE_DIR ${CMAKE_BINARY_DIR}/third_party/xxx # 跳过源码构建全流程 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" )
对接find_package的配置
下载解压完成后,需要让find_package能准确定位到依赖文件,分两种场景处理:
- 预编译包自带官方CMake配置文件(一般存放在包内的
lib/cmake/目录下):直接给find_package传PATHS参数指向该配置目录即可,记得添加依赖关系,保证包下载完成后再执行查找逻辑:
# 声明依赖顺序,确保先完成包下载再执行查找 add_library(xxx_dep_wrapper INTERFACE) add_dependencies(xxx_dep_wrapper precompiled_xxx) find_package(xxx REQUIRED PATHS ${CMAKE_BINARY_DIR}/third_party/xxx/lib/cmake/xxx NO_DEFAULT_PATH ) target_link_libraries(xxx_dep_wrapper INTERFACE xxx::xxx_lib)
- 预编译包没有提供CMake配置文件:不需要硬套
find_package,直接手动创建IMPORTED导入目标,指定解压目录下的头文件路径、库文件路径即可;如果需要区分Debug/Release版本,可以分别用IMPORTED_LOCATION_DEBUG、IMPORTED_LOCATION_RELEASE参数配置对应版本的库文件路径。
常见适配注意点
- 跨平台适配:用
if(WIN32)、if(APPLE)、if(UNIX AND NOT APPLE)条件判断块,分别给不同平台配置对应预编译包的地址、校验值、文件路径即可 - Windows动态库处理:如果依赖带dll动态库,添加一个构建后自定义命令,自动把dll拷贝到可执行文件的输出目录,避免运行时找不到依赖库:
add_custom_command(TARGET 你的项目可执行目标 POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_BINARY_DIR}/third_party/xxx/bin/xxx.dll" $<TARGET_FILE_DIR:你的项目可执行目标> DEPENDS precompiled_xxx )
- 版本选择:如果使用CMake 3.11及以上版本,也可以换用
FetchContent模块实现相同效果,配置参数和上述逻辑完全一致,区别是FetchContent在CMake配置阶段就完成下载,ExternalProject_Add在项目构建阶段执行下载,按需选择即可。
内容的提问来源于stack exchange,提问作者harsh
相关产品推荐
相关产品推荐

