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

无顶层CMakeLists.txt时,如何链接依赖lib1的lib2两个CMake项目

问题

假设有两个CMake库:lib1和lib2,其中lib2依赖lib1。如何在不将它们纳入同一个总CMake项目的前提下实现链接?即仅保留两个CMakeLists.txt(分别对应lib1和lib2),且不存在用于关联它们的顶层CMakeLists.txt。

项目结构如下:

cmake_agnostic_root/
|-- lib1/
|   |-- src/
|   |-- include/
|   |-- CMakeLists.txt
|-- lib2/
|   |-- src/
|   |-- include/
|   |-- CMakeLists.txt
|-- (此层级不得有CMakeLists.txt)

我认为只需在lib2的CMakeLists.txt中配置即可引入lib1。我已尝试以下方法但均未成功:

  1. add_subdirectory:
    在lib2的CMakeLists.txt中添加如下代码:
add_subdirectory(../lib1 lib1)

但lib2仍无法找到lib1的头文件。

  1. ExternalProject:
    在lib2的CMakeLists.txt中添加如下代码:
include(ExternalProject)

ExternalProject_Add(
  lib1
  SOURCE_DIR ../lib1
)

我可能误用了该命令,因为示例中它多用于下载Git仓库,但我需要使用与lib2同级的本地lib1文件夹。

我哪里出错了?

补充说明:我希望在lib2目录下调用cmake时,能触发lib1的构建并将其用于lib2的构建。


解决方案

为什么add_subdirectory没生效?

用add_subdirectory的思路没问题,但你漏了头文件路径配置和库链接的关键步骤,而且得先确保lib1的CMakeLists.txt配置正确。

首先给lib1的CMakeLists.txt补全必要配置,让它能导出头文件和目标:

cmake_minimum_required(VERSION 3.10)
project(lib1)

# 编译lib1库
add_library(lib1 STATIC src/lib1.cpp)

# 把lib1的include目录设为PUBLIC,这样依赖它的项目会自动继承这个路径
target_include_directories(lib1 PUBLIC include)

然后修改lib2的CMakeLists.txt,添加add_subdirectory后,显式链接lib1:

cmake_minimum_required(VERSION 3.10)
project(lib2)

# 添加lib1的源码目录,第二个参数是指定lib1的构建输出目录,避免和lib2的构建文件混在一起
add_subdirectory(../lib1 lib1_build)

# 编译lib2库
add_library(lib2 STATIC src/lib2.cpp)

# 链接lib1,因为lib1用了PUBLIC的include目录,这里会自动把lib1的头文件路径传给lib2
target_link_libraries(lib2 PRIVATE lib1)

这样在lib2目录下运行cmake构建时,会自动触发lib1的编译,lib2也能正常找到lib1的头文件并完成链接。

关于ExternalProject的误用

ExternalProject确实支持本地目录,但它的逻辑是在构建阶段才去编译外部项目,而CMake的配置阶段没法获取到外部项目的产物信息,所以你直接加了ExternalProject_Add后,lib2还是找不到头文件和库。

如果一定要用这个方案,得手动指定lib1的安装路径,再手动引入头文件和库:

cmake_minimum_required(VERSION 3.10)
project(lib2)

include(ExternalProject)

ExternalProject_Add(
  lib1
  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../lib1
  BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib1_build
  # 指定lib1的安装目录,方便后续引用
  CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/lib1_install
)

# 让lib2等lib1编译完成再构建
add_dependencies(lib2 lib1)

# 编译lib2
add_library(lib2 STATIC src/lib2.cpp)

# 手动引入lib1的头文件路径
target_include_directories(lib2 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/lib1_install/include)

# 手动链接lib1的库文件(注意库文件名要和实际生成的一致)
target_link_libraries(lib2 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/lib1_install/lib/lib1.a)

这种方式比add_subdirectory麻烦很多,所以优先推荐第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 00:25:32