使用CMake编译MongoDB与Qt项目时出现链接错误求助
问题:Windows下CMake编译Qt+mongocxx项目链接报错
在Windows系统中,使用CMake编译集成vcpkg编译的mongocxx与Qt的项目时,链接阶段出现大量未定义引用错误。已尝试切换编译器(MinGW→MSVC)、替换库文件等操作,均未解决问题。
我的CMake配置
cmake_minimum_required(VERSION 3.5) project(CmakeCBT VERSION 0.1 LANGUAGES CXX) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) include_directories("${CMAKE_CURRENT_LIST_DIR}/include") include_directories("${CMAKE_CURRENT_LIST_DIR}/bin") include_directories("${CMAKE_CURRENT_LIST_DIR}/lib") include_directories("${CMAKE_CURRENT_LIST_DIR}/share") find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) set(libbsoncxx_DIR "${CMAKE_CURRENT_LIST_DIR}/share/libbsoncxx") set(libmongocxx_DIR "${CMAKE_CURRENT_LIST_DIR}/share/libmongocxx") find_package(libbsoncxx REQUIRED) find_package(libmongocxx REQUIRED) set(PROJECT_SOURCES main.cpp startwindow.cpp startwindow.h startwindow.ui studentwindow.cpp studentwindow.h studentwindow.ui dbcontroller.cpp dbcontroller.h errors.h errors.cpp ) qt_add_executable(CmakeCBT MANUAL_FINALIZATION ${PROJECT_SOURCES} ) target_link_libraries(CmakeCBT PUBLIC "${CMAKE_CURRENT_LIST_DIR}/lib/bsoncxx.lib") target_link_libraries(CmakeCBT PUBLIC "${CMAKE_CURRENT_LIST_DIR}/lib/mongocxx.lib") target_link_libraries(CmakeCBT PUBLIC "${CMAKE_CURRENT_LIST_DIR}/lib/bson-1.0.lib") target_link_libraries(CmakeCBT PUBLIC "${CMAKE_CURRENT_LIST_DIR}/lib/mongoc-1.0.lib") target_link_libraries(CmakeCBT PUBLIC "${CMAKE_CURRENT_LIST_DIR}/lib/zlib.lib") target_link_libraries(CmakeCBT PRIVATE Qt${QT_VERSION_MAJOR}::Widgets) if(${QT_VERSION} VERSION_LESS 6.1.0) set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.CmakeCBT) endif() set_target_properties(CmakeCBT PROPERTIES ${BUNDLE_ID_OPTION} MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} MACOSX_BUNDLE TRUE WIN32_EXECUTABLE TRUE ) include(GNUInstallDirs) install(TARGETS CmakeCBT BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) if(QT_VERSION_MAJOR EQUAL 6) qt_finalize_executable(CmakeCBT) endif()
错误日志
[1/5 3.3/sec] Automatic MOC and UIC for target CmakeCBT [2/4 0.8/sec] Building CXX object CMakeFiles/CmakeCBT.dir/studentwindow.cpp.obj [3/4 0.9/sec] Building CXX object CMakeFiles/CmakeCBT.dir/startwindow.cpp.obj [4/4 1.1/sec] Linking CXX executable CmakeCBT.exe FAILED: CmakeCBT.exe cmd.exe /C "cd . && C:\Qt\Tools\mingw1120_64\bin\g++.exe -DQT_QML_DEBUG -g -mwindows CMakeFiles/CmakeCBT.dir/CmakeCBT_autogen/mocs_compilation.cpp.obj CMakeFiles/CmakeCBT.dir/main.cpp.obj CMakeFiles/CmakeCBT.dir/startwindow.cpp.obj CMakeFiles/CmakeCBT.dir/studentwindow.cpp.obj CMakeFiles/CmakeCBT.dir/dbcontroller.cpp.obj CMakeFiles/CmakeCBT.dir/model.cpp.obj CMakeFiles/CmakeCBT.dir/errors.cpp.obj -o CmakeCBT.exe -Wl,--out-implib,libCmakeCBT.dll.a -Wl,--major-image-version,0,--minor-image-version,0 D:/Qt/CMAKESBT/CmakeCBT/lib/bsoncxx.lib D:/Qt/CMAKESBT/CmakeCBT/lib/mongocxx.lib D:/Qt/CMAKESBT/CmakeCBT/lib/bson-1.0.lib D:/Qt/CMAKESBT/CmakeCBT/lib/mongoc-1.0.lib D:/Qt/CMAKESBT/CmakeCBT/lib/zlib.lib C:/Qt/6.6.0/mingw_64/lib/libQt6Widgets.a C:/Qt/6.6.0/mingw_64/lib/libQt6Gui.a C:/Qt/6.6.0/mingw_64/lib/libQt6Core.a -lmpr -luserenv -lmingw32 C:/Qt/6.6.0/mingw_64/lib/libQt6EntryPoint.a -lshell32 -ld3d11 -ldxgi -ldxguid -ld3d12 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ." C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/CmakeCBT.dir/dbcontroller.cpp.obj: in function `DBController::DBController()': D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:3: undefined reference to `__imp__ZN8mongocxx7v_noabi8instanceC1Ev' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:7: undefined reference to `__imp__ZN8mongocxx7v_noabi8instanceC1Ev' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:7: undefined reference to `__imp__ZN8mongocxx7v_noabi8instanceaSEOS1_' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:7: undefined reference to `__imp__ZN8mongocxx7v_noabi8instanceD1Ev' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:8: undefined reference to `__imp__ZN8mongocxx7v_noabi3uriC1EN7bsoncxx7v_noabi6string13view_or_valueE' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:11: undefined reference to `__imp__ZN8mongocxx7v_noabi7options10server_apiC1ENS2_7versionE' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:12: undefined reference to `__imp__ZN8mongocxx7v_noabi7options6client15server_api_optsENS1_10server_apiE' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:14: undefined reference to `__imp__ZN8mongocxx7v_noabi6clientC1ERKNS0_3uriERKNS0_7options6clientE' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/Qt/CMAKESBT/CmakeCBT/dbcontroller.cpp:14: undefined reference to `__imp__ZN8mongocxx7v_noabi6clientaSEOS1_' D:/Qt/CMAKESBT/CmakeCBT/include/bsoncxx/builder/basic/sub_document.hpp:85: undefined reference to `__imp__ZN7bsoncxx7v_noabi7builder4core8key_viewESt17basic_string_viewIcSt11char_traitsIcEE' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/CmakeCBT.dir/dbcontroller.cpp.obj: in function `std::enable_if<(!std::is_convertible<int, std::function<void (bsoncxx::v_noabi::builder::basic::sub_document)> >::value)&&(!std::is_convertible<int, std::function<void (bsoncxx::v_noabi::builder::basic::sub_array)> >::value), void>::type bsoncxx::v_noabi::builder::basic::impl::generic_append<int>(bsoncxx::v_noabi::builder::core*, int&&)': D:/Qt/CMAKESBT/CmakeCBT/include/bsoncxx/builder/basic/impl.hpp:55: undefined reference to `__imp__ZN7bsoncxx7v_noabi7builder4core6appendEi' C:/Qt/Tools/mingw1120_64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/CmakeCBT.dir/dbcontroller.cpp.obj:dbcontroller.c:(.rdata$.refptr._ZN12DBController10singleton_E[.refptr._ZN12DBController10singleton_E]+0x0): undefined reference to `DBController::singleton_' collect2.exe: error: ld returned 1 exit status ninja: build stopped: subcommand failed.
解决思路与方案
1. 确保库与编译器环境匹配
vcpkg编译mongocxx时,必须与当前项目使用的编译器完全一致:
- 若用MinGW编译项目,vcpkg需指定对应的triplet,比如
x64-mingw-static或x64-mingw-dynamic,重新编译mongocxx:vcpkg install mongocxx:x64-mingw-static - 切换编译器(如MSVC)时,必须同步用vcpkg针对MSVC的triplet(如
x64-windows)重新编译mongocxx,不能混用不同编译器编译的库。
2. 正确使用find_package的目标链接
不要手动指定.lib文件路径,find_package会自动处理依赖关系和链接顺序。替换手动链接的代码:
# 替换原来的手动target_link_libraries行 target_link_libraries(CmakeCBT PRIVATE libbsoncxx::libbsoncxx libmongocxx::libmongocxx)
这会自动包含所有依赖库(如bson-1.0、mongoc-1.0、zlib等),无需手动添加。
3. 添加正确的预编译宏
根据mongocxx库的编译类型(静态/动态),添加对应的预编译宏:
- 静态库:
add_definitions(-DMONGOCXX_STATIC -DBSONCXX_STATIC) - 动态库:
add_definitions(-DMONGOCXX_DYNAMIC -DBSONCXX_DYNAMIC)
vcpkg编译时默认的类型可通过triplet判断,-static结尾的是静态库,否则是动态库。
4. 修复DBController的静态成员定义
最后一个错误是DBController::singleton_未定义,需在dbcontroller.cpp中添加静态成员的定义:
DBController* DBController::singleton_ = nullptr;
确保头文件中声明的静态成员在cpp文件中有定义。
5. 清理CMake缓存后重新构建
修改CMake配置后,删除build目录下的所有文件,重新运行CMake生成构建文件,再执行编译,避免缓存导致的问题。
内容的提问来源于stack exchange,提问作者Никита Горчаков
相关产品推荐
相关产品推荐

