如何使用CMake ExternalProject_Add构建仅含Makefile的本地外部项目
问题根因
ExternalProject_Add 默认会执行一套完整的外部项目生命周期流程:下载 → 更新 → 打补丁 → 配置 → 构建 → 安装 → 测试,同时会自动生成一套默认的临时工作目录结构(即报错信息中出现的mylib-prefix/src/mylib路径)。
最初的调用仅指定了BINARY_DIR和BUILD_COMMAND,既没有提供下载相关参数,也没有指定本地源码路径,CMake自然会触发下载步骤的校验报错。当手动设置SOURCE_DIR后,CMake默认会假设外部项目使用CMake构建,自动执行CMake配置流程,检查目录下的CMakeLists.txt文件,因此触发第二个报错。
正确配置方案
要让CMake仅执行指定目录下的现有Makefile、不触发多余默认操作,需要显式关闭所有不需要的生命周期步骤,同时明确指定源码/构建目录为第三方库的实际存放路径:
- 必须同时设置
SOURCE_DIR和BINARY_DIR为第三方库Makefile所在的本地目录,对于原生Makefile项目,两个路径可以设为同一个值 - 将下载、更新、补丁、配置这几个不需要的步骤的命令显式设为空字符串,阻断CMake的默认行为,其中
CONFIGURE_COMMAND ""是核心配置,设置后CMake不会再检查目录下是否存在CMakeLists.txt,也不会执行自动配置动作 - 自定义
BUILD_COMMAND为需要执行的make命令,可根据需要添加并行编译参数 - 自定义
INSTALL_COMMAND为需要的产物拷贝规则,直接在命令中把编译生成的库/可执行文件复制到指定的二进制输出目录即可
完整配置示例如下:
# 先引入ExternalProject依赖模块 include(ExternalProject) ExternalProject_Add(mylib # 指向第三方库存放Makefile的实际本地路径 SOURCE_DIR ${CMAKE_SOURCE_DIR}/mylib/sdk BINARY_DIR ${CMAKE_SOURCE_DIR}/mylib/sdk # 关闭所有不需要的默认流程 DOWNLOAD_COMMAND "" UPDATE_COMMAND "" PATCH_COMMAND "" CONFIGURE_COMMAND "" # 自定义构建命令:进入指定目录执行make BUILD_COMMAND make -j$(nproc) # 自定义安装步骤:将构建产物拷贝到目标二进制目录 INSTALL_COMMAND cp ${CMAKE_SOURCE_DIR}/mylib/sdk/output/libmylib.a ${CMAKE_BINARY_DIR}/lib/ )
效果说明
上述配置生效后,CMake不会再自动生成mylib-prefix之类的临时目录,也不会执行路径推断、自动配置等多余操作,只会在构建阶段进入指定目录执行make,构建完成后执行定义的拷贝安装步骤,完全匹配预期流程。
内容的提问来源于stack exchange,提问作者Brydon Gibson
相关产品推荐
相关产品推荐

