CMake嵌入SQLite3合并包失败求助:QMake可正常运行
解决CMake嵌入SQLite3单文件版的LNK2019链接错误
问题场景
在CMake构建的简单可执行项目中,嵌入SQLite3单文件版(sqlite3.c/sqlite3.h)时出现链接错误,但同目录下的test.c/test.h模块可正常编译运行;使用QMake构建完全相同的代码结构却能正常工作。
报错信息
main.cpp.obj:-1: error: LNK2019: unresolved external symbol sqlite3_open referenced in function main
项目目录结构
CMakeLists.txt main.cpp sqlite/ |- sqlite3.c |- sqlite3.h test/ |- test.c |- test.h
原因分析
- 语言编译不匹配:原CMakeLists.txt指定项目仅支持CXX(C++)语言,
sqlite3.c是纯C代码,CMake会用C编译器编译它,导致C函数名被C的名称修饰规则修改,链接时无法匹配main.cpp中引用的原始C函数名。 - 不必要的头文件添加:
add_executable中加入了头文件(sqlite3.h、test.h),这是多余操作,CMake会自动通过include_directories找到头文件,无需手动添加到源文件列表。
解决方案
方案1:直接修正CMakeLists.txt
修改项目语言为同时支持C和C++,并移除add_executable中的头文件:
cmake_minimum_required(VERSION 3.10) # 同时支持C和C++语言 project(sqlite_test LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sqlite ${CMAKE_CURRENT_SOURCE_DIR}/test) # 仅添加源文件,移除头文件 add_executable(sqlite_test main.cpp sqlite/sqlite3.c test/test.cpp )
方案2:将SQLite编译为静态库(更规范)
把sqlite3.c编译成静态库,再链接到主程序:
cmake_minimum_required(VERSION 3.10) project(sqlite_test LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sqlite ${CMAKE_CURRENT_SOURCE_DIR}/test) # 编译sqlite3为静态库 add_library(sqlite3 STATIC sqlite/sqlite3.c) # 主程序链接静态库 add_executable(sqlite_test main.cpp test/test.cpp) target_link_libraries(sqlite_test sqlite3)
为什么QMake能正常工作?
QMake会自动识别源文件的后缀(.c/.cpp),分别调用C和C编译器编译,避免了C函数名被C修饰的问题,因此无需额外配置即可正常链接。
内容的提问来源于stack exchange,提问作者user2366975
相关产品推荐
相关产品推荐

