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
相关产品推荐
相关产品推荐

