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

从qmake转CMake:如何实现调试与发布模式的依赖管理?

解决qmake转CMake的依赖管理适配问题

完全可以复现你描述的qmake依赖管理模式,核心是利用CMake的子项目构建和外部依赖导入分别对应调试/发布阶段,同时通过CMake内置路径变量解决include基准问题。

一、先解决路径适配问题

不要直接用相对路径引用.cmake文件,改用CMake的CMAKE_CURRENT_LIST_DIR变量(指向当前处理的CMakeLists.txt所在目录)拼接绝对路径,彻底规避基准路径混乱:
假设项目结构如下:

project_root/
├─ shared/
│  └─ CMakeLists.txt
└─ app/
   ├─ common/
   │  └─ CMakeLists.txt
   └─ CMakeLists.txt

在app/CMakeLists.txt中引用shared的配置时,写法如下:

include("${CMAKE_CURRENT_LIST_DIR}/../shared/CMakeLists.txt")

更灵活的方式是在根目录CMakeLists.txt中定义全局根路径变量:

set(PROJECT_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})

后续所有子项目都用${PROJECT_ROOT_DIR}/shared/CMakeLists.txt这类写法引用,完全消除相对路径歧义。

二、调试阶段:自动同步编译依赖(对应qmake include .pri)

直接把shared和common作为当前项目的子目录添加,CMake会自动在编译应用目标前先编译依赖库:
在app/CMakeLists.txt中添加:

# 添加shared静态库子项目,指定独立构建目录避免文件混乱
add_subdirectory(${PROJECT_ROOT_DIR}/shared ${CMAKE_BINARY_DIR}/shared_build)
# 添加app专属common静态库子项目
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common ${CMAKE_BINARY_DIR}/common_build)

# 链接应用目标到依赖库
add_executable(app_standalone main.cpp)
target_link_libraries(app_standalone PRIVATE shared common)

add_library(app_plugin1 MODULE plugin1.cpp)
target_link_libraries(app_plugin1 PRIVATE shared common)

这样只要编译应用的任意目标,CMake会自动检查shared和common是否需要重新编译,完全复现qmake中.pri文件的同步编译效果。

三、发布阶段:先编译库再链接(对应构建脚本预编译)

先单独构建shared和common并安装到指定目录,再让应用项目导入预编译库:

  1. 给库添加安装规则
    在shared/CMakeLists.txt和app/common/CMakeLists.txt末尾添加安装逻辑:
# shared的CMakeLists.txt
install(TARGETS shared ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
install(FILES shared.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)

# common的CMakeLists.txt
install(TARGETS common ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
install(FILES common.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)

然后用命令预编译安装:

# 编译并安装shared
cmake -S ./shared -B ./shared_build -DCMAKE_INSTALL_PREFIX=./install_dir
cmake --build ./shared_build --target install

# 编译并安装common
cmake -S ./app/common -B ./common_build -DCMAKE_INSTALL_PREFIX=./install_dir
cmake --build ./common_build --target install
  1. 应用项目导入预编译库
    在app/CMakeLists.txt中通过find_library直接定位预编译库:
# 定位预编译的shared和common库
find_library(SHARED_LIB NAMES shared PATHS ${INSTALL_DIR}/lib NO_DEFAULT_PATH)
find_library(COMMON_LIB NAMES common PATHS ${INSTALL_DIR}/lib NO_DEFAULT_PATH)

# 链接应用目标
add_executable(app_standalone main.cpp)
target_include_directories(app_standalone PRIVATE ${INSTALL_DIR}/include)
target_link_libraries(app_standalone PRIVATE ${SHARED_LIB} ${COMMON_LIB})

如果给库配置了Config.cmake文件(更规范的CMake依赖方式),也可以用find_package导入:

find_package(shared REQUIRED PATHS ${INSTALL_DIR})
find_package(common REQUIRED PATHS ${INSTALL_DIR})

add_executable(app_standalone main.cpp)
target_link_libraries(app_standalone PRIVATE shared::shared common::common)

四、用CMake选项一键切换调试/发布模式

添加配置选项,无需手动修改CMakeLists.txt即可切换两种模式:
在app/CMakeLists.txt开头添加:

option(BUILD_DEPENDENCIES_INTERNAL "Build shared and common as subprojects (debug mode)" ON)
set(INSTALL_DIR "${PROJECT_ROOT_DIR}/install_dir" CACHE PATH "Path to prebuilt shared/common libraries (release mode)")

if(BUILD_DEPENDENCIES_INTERNAL)
    # 调试模式:自动编译依赖
    add_subdirectory(${PROJECT_ROOT_DIR}/shared ${CMAKE_BINARY_DIR}/shared_build)
    add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common ${CMAKE_BINARY_DIR}/common_build)
else()
    # 发布模式:导入预编译库
    find_library(SHARED_LIB NAMES shared PATHS ${INSTALL_DIR}/lib NO_DEFAULT_PATH)
    find_library(COMMON_LIB NAMES common PATHS ${INSTALL_DIR}/lib NO_DEFAULT_PATH)
    
    # 将预编译库声明为CMake目标,统一后续链接逻辑
    add_library(shared STATIC IMPORTED)
    set_target_properties(shared PROPERTIES IMPORTED_LOCATION ${SHARED_LIB})
    target_include_directories(shared INTERFACE ${INSTALL_DIR}/include)

    add_library(common STATIC IMPORTED)
    set_target_properties(common PROPERTIES IMPORTED_LOCATION ${COMMON_LIB})
    target_include_directories(common INTERFACE ${INSTALL_DIR}/include)
endif()

# 后续所有应用目标的链接逻辑完全统一
add_executable(app_standalone main.cpp)
target_link_libraries(app_standalone PRIVATE shared common)

add_library(app_plugin1 MODULE plugin1.cpp)
target_link_libraries(app_plugin1 PRIVATE shared common)

调试时默认启用BUILD_DEPENDENCIES_INTERNAL=ON,自动同步编译依赖;发布时只需通过命令行传入参数切换:

cmake -S ./app -B ./app_build -DBUILD_DEPENDENCIES_INTERNAL=OFF -DINSTALL_DIR=./install_dir
cmake --build ./app_build

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 15:01:11