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

如何用CMake为同一静态库设置不同编译选项适配可执行与共享库

静态库同时支持可执行程序与共享库的CMake配置方案

要满足可执行程序使用非PIC静态库、共享库使用PIC静态库的需求,核心思路是生成两个独立的静态库目标,分别配置不同的编译选项,再对应链接到可执行程序和共享库中。

配置方案(跨平台兼容版)

cmake_minimum_required(VERSION 3.26)
project(mve)
set(CMAKE_CXX_STANDARD 17)

# 1. 生成不带位置无关代码的静态库,供可执行程序使用
add_library(staticLib STATIC library.h library.cpp)

# 2. 生成带位置无关代码的静态库,供共享库使用
add_library(staticLibPIC STATIC library.h library.cpp)
# 用CMake内置属性设置PIC,跨平台兼容(替代手动加-fPIC)
set_target_properties(staticLibPIC PROPERTIES POSITION_INDEPENDENT_CODE ON)

# 3. 可执行程序链接非PIC静态库
add_executable(exe main.cpp)
target_link_libraries(exe PUBLIC staticLib)

# 4. 共享库链接PIC静态库
add_library(sharedLib SHARED lib.h lib.cpp)
target_link_libraries(sharedLib PUBLIC staticLibPIC)

关键说明

  • 为什么要分两个静态库:共享库要求所有被链接的代码必须是位置无关的(PIC),否则会出现编译错误;而可执行程序直接链接静态库时,不需要PIC,这样能生成性能更优的可执行文件。
  • 跨平台兼容性:使用POSITION_INDEPENDENT_CODE属性而非手动添加-fPIC,CMake会自动根据目标平台生成对应的编译选项(比如Windows无需额外选项,Linux/macOS自动添加对应参数)。

优化编译速度(可选)

如果项目源文件较多,不想重复编译两次,可以用OBJECT库作为中间层,复用编译结果:

cmake_minimum_required(VERSION 3.26)
project(mve)
set(CMAKE_CXX_STANDARD 17)

# 创建OBJECT库,仅编译源文件不生成库
add_library(staticLibObj OBJECT library.h library.cpp)
add_library(staticLibObjPIC OBJECT library.h library.cpp)
set_target_properties(staticLibObjPIC PROPERTIES POSITION_INDEPENDENT_CODE ON)

# 基于OBJECT库生成两个静态库
add_library(staticLib STATIC $<TARGET_OBJECTS:staticLibObj>)
add_library(staticLibPIC STATIC $<TARGET_OBJECTS:staticLibObjPIC>)

# 后续链接逻辑和之前一致
add_executable(exe main.cpp)
target_link_libraries(exe PUBLIC staticLib)

add_library(sharedLib SHARED lib.h lib.cpp)
target_link_libraries(sharedLib PUBLIC staticLibPIC)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:03:18