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

将Meson项目(jose)作为依赖库集成到CMake项目遇阻求助

将Meson项目(jose库)集成到CMake项目的解决方案

问题背景

我需要将一个Meson项目(具体为jose库)集成到使用CMake构建的项目中。此前了解到当前推荐使用FetchContent,但该方法仅适用于CMake项目,无法适配这类“非CMake”项目,也未找到示例中运行Meson的方式。

于是尝试使用ExternalProject_Add,它可完成jose的配置与构建,但存在问题:需将jose库添加到target_link_libraries中,可CMake配置项目时该库尚未构建。我认为需在全局CMake配置阶段完成jose构建,遂尝试execute_process和ExternalProject_Add_Step但未成功,代码如下:

ExternalProject_Add(
  jose
  UPDATE_COMMAND ""
  PATCH_COMMAND ""

  SOURCE_DIR  ${CMAKE_CURRENT_SOURCE_DIR}/jose

  # Configure
  CONFIGURE_HANDLED_BY_BUILD true
  CONFIGURE_COMMAND meson setup ${CMAKE_CURRENT_SOURCE_DIR}/jose --prefix=${INSTALL_DIR} --pkg-config-path ${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-linux/lib/pkgconfig

  BUILD_COMMAND ninja

  INSTALL_COMMAND ""
  TEST_COMMAND ""

)

set(jose_BINARY_DIR "${BINARY_DIR}")
ExternalProject_Add_Step(jose build
    COMMENT "Building jose project..."
    COMMAND ${CMAKE_COMMAND} --build ${jose_BINARY_DIR}
    RESULT_VARIABLE jose_build_result
    OUTPUT_QUIET
    DEPENDEES download update
    WORKING_DIRECTORY ${jose_BINARY_DIR}
)

add_dependencies(${CMAKE_PROJECT_NAME} jose)

目前遇到两个问题:

  1. target_link_libraries仍会在jose构建完成前尝试查找该库
  2. 若从target_link_libraries中移除jose(测试用),ExternalProject_Add_Step会报错,提示add_custom_command尝试添加重复自定义规则(jose-build.rule)

疑问:

  1. 使用ExternalProject_Add_Step的方向是否正确?
  2. 若正确,如何让它在target_link_libraries评估前执行?

问题解答

1. 使用ExternalProject_Add_Step的方向是否正确?

不正确。ExternalProject_Add本身已经内置了build步骤,手动添加同名的build步骤会导致重复规则冲突,这就是你遇到第二个问题的核心原因。不需要额外调用ExternalProject_Add_Step定义build流程,原配置已经会自动处理构建环节。

CMake的配置阶段与构建阶段是分离的,target_link_libraries在配置阶段就会尝试解析库路径,而ExternalProject_Add默认在构建阶段才执行外部项目构建。解决这个矛盾有两种可靠方案:

方案一:配置阶段直接构建jose

跳过ExternalProject_Add,用execute_process在CMake配置时就运行Meson和Ninja完成jose的构建,确保配置阶段结束时库已存在:

# 定义jose的目录路径
set(JOSE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jose")
set(JOSE_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/jose-build")
set(JOSE_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/jose-install")

# 执行Meson配置
execute_process(
  COMMAND meson setup ${JOSE_SOURCE_DIR} ${JOSE_BUILD_DIR} --prefix=${JOSE_INSTALL_DIR} --pkg-config-path ${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-linux/lib/pkgconfig
  RESULT_VARIABLE MESON_SETUP_RESULT
  ERROR_VARIABLE MESON_SETUP_ERROR
)
if(NOT MESON_SETUP_RESULT EQUAL 0)
  message(FATAL_ERROR "Meson配置失败: ${MESON_SETUP_ERROR}")
endif()

# 执行Ninja构建
execute_process(
  COMMAND ninja -C ${JOSE_BUILD_DIR}
  RESULT_VARIABLE NINJA_BUILD_RESULT
  ERROR_VARIABLE NINJA_BUILD_ERROR
)
if(NOT NINJA_BUILD_RESULT EQUAL 0)
  message(FATAL_ERROR "Ninja构建失败: ${NINJA_BUILD_ERROR}")
endif()

# 执行安装(按需启用)
execute_process(
  COMMAND ninja -C ${JOSE_BUILD_DIR} install
  RESULT_VARIABLE NINJA_INSTALL_RESULT
  ERROR_VARIABLE NINJA_INSTALL_ERROR
)
if(NOT NINJA_INSTALL_RESULT EQUAL 0)
  message(FATAL_ERROR "Ninja安装失败: ${NINJA_INSTALL_ERROR}")
endif()

# 查找并链接jose库
find_library(JOSE_LIBRARY NAMES jose PATHS ${JOSE_INSTALL_DIR}/lib)
find_path(JOSE_INCLUDE_DIR NAMES jose/jose.h PATHS ${JOSE_INSTALL_DIR}/include)

target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${JOSE_INCLUDE_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${JOSE_LIBRARY})

方案二:使用IMPORTED目标延迟库解析

如果希望保留增量构建特性,可创建IMPORTED目标,通过依赖关系让主项目等待外部项目构建,同时用属性指定路径,CMake会延迟到构建阶段再实际查找库:

set(INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/jose-install")
set(JOSE_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/jose-build")

ExternalProject_Add(
  jose
  UPDATE_COMMAND ""
  PATCH_COMMAND ""
  SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jose"
  BINARY_DIR "${JOSE_BUILD_DIR}"
  CONFIGURE_COMMAND meson setup ${CMAKE_CURRENT_SOURCE_DIR}/jose ${JOSE_BUILD_DIR} --prefix=${INSTALL_DIR} --pkg-config-path ${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/x64-linux/lib/pkgconfig
  BUILD_COMMAND ninja -C ${JOSE_BUILD_DIR}
  INSTALL_COMMAND ninja -C ${JOSE_BUILD_DIR} install
  TEST_COMMAND ""
)

# 创建导入式目标
add_library(jose::jose STATIC IMPORTED GLOBAL)
add_dependencies(jose::jose jose)

# 设置目标属性(路径会在构建阶段生效)
set_target_properties(jose::jose PROPERTIES
  IMPORTED_LOCATION "${INSTALL_DIR}/lib/libjose.a"
  INTERFACE_INCLUDE_DIRECTORIES "${INSTALL_DIR}/include"
)

# 链接到主项目
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE jose::jose)

针对你遇到的具体问题的修复

  • 问题1:方案一通过配置阶段提前构建解决;方案二通过IMPORTED目标延迟库解析解决。
  • 问题2:删除手动添加的ExternalProject_Add_Step(jose build)代码块,避免重复定义构建规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:35:34