You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ExternalProject_Add中处理强依赖问题?

解决ExternalProject依赖中find_program提前检测的问题

问题描述

主项目依赖两个外部项目X和Y,Y同时依赖X。使用make构建时失败,原因是Y的CMake配置阶段通过find_program()查找X生成的二进制文件,若找不到该文件会触发致命错误。尝试给Y的ExternalProject_Add()添加DEPENDS X属性无效,传递路径变量也无法解决问题,且无法/不愿修改Y的CMakeLists.txt,寻求替代解决方案。

核心原因

ExternalProject_Add()的DEPENDS仅保证构建阶段的依赖顺序,但Y的配置阶段(cmake configure)会在X构建完成前执行——此时X的二进制文件尚未生成,导致find_program()检测失败。

解决方案

方法1:强制Y的配置阶段等待X完成安装

通过ExternalProject_Add_Step()给Y添加预配置步骤,确保Y的配置流程在X完成构建和安装后再执行,同时传递X的二进制路径给Y:

ExternalProject_Add(X
  ...
  INSTALL_COMMAND "${MAKE}" install  # 确保X安装到指定前缀目录
)

# 给Y添加等待X安装完成的步骤
ExternalProject_Add_Step(Y wait_for_X_install
  COMMAND ""
  DEPENDEES download
  DEPENDERS configure
  DEPENDS X
)

ExternalProject_Add(Y
  ...
  # 传递X的二进制路径给Y的配置流程
  CMAKE_ARGS 
    "-DX_BINARY_PATH=${CMAKE_INSTALL_PREFIX}/bin/x_binary"
    # 其他配置参数
)

方法2:通过CMAKE_PROGRAM_PATH传递搜索路径

将X的二进制输出目录加入Y的CMAKE_PROGRAM_PATH,让find_program()能找到目标文件,同时结合步骤依赖确保顺序:

ExternalProject_Add(X
  ...
  BINARY_DIR "${DEPS_DIR}/x-build"
  RUNTIME_OUTPUT_DIRECTORY "${GLOBAL_OUTPUT_PATH}"
)

ExternalProject_Add(Y
  DEPENDS X
  ...
  # 将X的二进制目录加入程序搜索路径
  CMAKE_ARGS 
    "-DCMAKE_PROGRAM_PATH=${GLOBAL_OUTPUT_PATH}"
    # 其他配置参数
)

# 强制Y的配置在X构建完成后执行
ExternalProject_Add_Step(Y reconfigure_after_X
  COMMAND ${CMAKE_COMMAND} --build <BINARY_DIR> --target reconfigure
  DEPENDEES download
  DEPENDERS configure
  DEPENDS X
)

针对SQLite3+PROJ示例的修改

结合你提供的代码,调整后可解决PROJ配置阶段找不到sqlite3二进制的问题:

cmake_minimum_required(VERSION 3.22)
project(TEST)

# Global settings
set(GLOBAL_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR}/install)
set(DEPS_DIR ${CMAKE_SOURCE_DIR}/deps)

# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${GLOBAL_OUTPUT_PATH})
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
    string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${GLOBAL_OUTPUT_PATH})
endforeach()

include(ExternalProject)
ExternalProject_Add(sqlite3
  GIT_REPOSITORY "https://github.com/sqlite/sqlite.git"
  GIT_TAG "master"
  UPDATE_COMMAND ""
  PATCH_COMMAND ""
  SOURCE_DIR "${DEPS_DIR}/sqlite"
  CONFIGURE_COMMAND ${DEPS_DIR}/sqlite/configure --all --prefix=${CMAKE_INSTALL_PREFIX} CFLAGS="-Os" SQLITE_THREADSAFE=2 BUILD_SHARED_LIBS=0 --disable-debug
  BUILD_COMMAND "${MAKE}"
  INSTALL_COMMAND "${MAKE}" install  # 将sqlite3安装到指定前缀
  TEST_COMMAND ""
)

ExternalProject_Add(proj
  DEPENDS sqlite3
  GIT_REPOSITORY "https://github.com/OSGeo/PROJ.git"
  GIT_TAG "master"
  UPDATE_COMMAND ""
  PATCH_COMMAND ""
  SOURCE_DIR "${DEPS_DIR}/proj"
  CMAKE_ARGS 
    "-DBUILD_SHARED_LIBS=0"
    "-DBUILD_TESTING=0"
    "-DBUILD_APPS=0"
    "-DSQLite3_LIBRARY_DIR=${CMAKE_INSTALL_PREFIX}/lib"
    "-DCMAKE_PROGRAM_PATH=${CMAKE_INSTALL_PREFIX}/bin"  # 加入sqlite3二进制搜索路径
  BUILD_COMMAND "${MAKE}"
)

# 强制PROJ配置阶段等待sqlite3安装完成
ExternalProject_Add_Step(proj wait_for_sqlite_install
  COMMAND ""
  DEPENDEES download
  DEPENDERS configure
  DEPENDS sqlite3
)

内容的提问来源于stack exchange,提问作者rbaleksandar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 19:44:52