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

CMake构建C++20共享库时静态成员变量未定义引用问题

解决CMake构建下DLL静态成员变量未定义引用问题

问题根源

你的问题出在全局定义了BUILD宏,导致编译可执行文件时,头文件中的API被解析为__declspec(dllexport)而非__declspec(dllimport)。这会让链接器认为可执行文件需要导出A::member,而非从DLL中导入该符号,最终引发未定义引用错误。

修复方案

修改CMakeLists.txt,仅为DLL目标添加BUILD宏,并使用目标级别的链接指令替代全局链接:

cmake_minimum_required(VERSION 3.20)

# 构建DLL库,仅为该目标添加BUILD宏
add_library(sharedLib SHARED dll/dll.cpp dll/dll.h)
target_compile_definitions(sharedLib PRIVATE BUILD)

# 构建可执行文件,并链接DLL库
add_executable(exec main.cpp)
target_link_libraries(exec PRIVATE sharedLib)

原理说明

  • target_compile_definitions(sharedLib PRIVATE BUILD):仅在编译sharedLib时定义BUILD宏,此时DLL的.cpp文件会将类A标记为__declspec(dllexport),正确导出静态成员A::member。
  • 编译可执行文件exec时,BUILD宏未定义,头文件中的API会被设置为__declspec(dllimport),告诉编译器从DLL中导入A::member符号。
  • 使用target_link_libraries替代全局的link_libraries,是CMake推荐的目标级依赖管理方式,避免全局设置带来的意外问题。

验证

修改后重新执行构建流程:

mkdir build && cd build
cmake ..
cmake --build .

运行生成的exec,将正确输出10。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:26:08