CMake编译C++项目遇bmp2系列C函数未定义引用错误求助
问题:链接BMP280 C库到C++共享库时出现未定义引用错误
问题背景
我正在开发一个通过C硬件库(BMP280)访问传感器的C++程序,需要先将测量代码编译为Linux共享库libwsh.so,再链接到测试可执行文件main。当前CMakeLists能成功编译库目标wsh,但编译main时出现链接错误。
当前CMakeLists.txt内容
project(weather-station-hardware-driver) message(STATUS "Selected C Compiler: ${CMAKE_C_COMPILER}") message(STATUS "Selected C++ Compiler: ${CMAKE_CXX_COMPILER}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(CMAKE_CXX_STANDARD 20) include(FetchContent) FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.1/json.tar.xz) FetchContent_Declare(bmp2 GIT_REPOSITORY https://github.com/BoschSensortec/BMP2-Sensor-API.git) FetchContent_MakeAvailable(json bmp2) add_library(wsh SHARED src/library.cpp src/bmp280.cpp src/bmp280.hpp) set_target_properties(wsh PROPERTIES LINKER_LANGUAGE CXX) target_link_libraries(wsh PUBLIC i2c) target_include_directories(wsh PUBLIC ${bmp2_SOURCE_DIR}) add_executable(main src/main.cpp) target_link_libraries(main PRIVATE wsh nlohmann_json::nlohmann_json)
链接错误信息
: && /usr/bin/c++ -g CMakeFiles/main.dir/src/main.cpp.o -o ../bin/main -Wl,-rpath,/home/fabro122/workspace/intellij/weather-station-webserver/native/hardware-driver/bin ../bin/libwsh.so -li2c && : /usr/bin/ld: ../bin/libwsh.so: undefined reference to `bmp2_get_config' /usr/bin/ld: ../bin/libwsh.so: undefined reference to `bmp2_init'
bmp2_get_config和bmp2_init是${bmp2_SOURCE_DIR}中的C函数,我尝试过添加target_link_directories(wsh PUBLIC ${bmp2_SOURCE_DIR})、用extern "C"包裹头文件、直接编译可执行文件等方法,均无效。
相关源文件
main.cpp
#include <iostream> #include <nlohmann/json.hpp> #include "library.hpp" using namespace std; using namespace wsh; namespace wsh { // 非侵入式宏用于避免共享库依赖nlohmann/json.hpp NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Measurement, temperature, pressure, humidity, airQuality, ambientLight) } int main() { Measurement data = doMeasurement(); nlohmann::json j = data; cout << j << endl; return 0; }
library.cpp(原标注为library.hpp,实际是实现文件)
#include "library.hpp" #include "bmp280.hpp" wsh::Measurement wsh::doMeasurement() { auto allData = Measurement(); bmp280 bmp; return allData; }
bmp280.cpp
#include "bmp280.hpp" #include <bmp2.h> namespace wsh { BMP2_INTF_RET_TYPE i2c_read(uint8_t reg_addr, uint8_t* reg_data, uint32_t length, void* intf_ptr) { return 0; } BMP2_INTF_RET_TYPE i2c_write(uint8_t reg_addr, const uint8_t* reg_data, uint32_t length, void* intf_ptr) { return 0; } bmp280::bmp280() { // device和address在.hpp中定义 device.chip_id = address; device.intf = BMP2_I2C_INTF; device.read = i2c_read; device.write = i2c_write; bmp2_init(&device); // 配置传感器 bmp2_config conf{}; bmp2_get_config(&conf, &device); } }
解决方案
问题核心是:你只引入了BMP2库的头文件路径,但没有实际链接BMP2的编译产物。FetchContent拉取BMP2-Sensor-API后,该库自带CMakeLists,会自动生成bmp2目标,直接链接即可。
修改后的CMakeLists.txt:
project(weather-station-hardware-driver) message(STATUS "Selected C Compiler: ${CMAKE_C_COMPILER}") message(STATUS "Selected C++ Compiler: ${CMAKE_CXX_COMPILER}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) set(CMAKE_CXX_STANDARD 20) include(FetchContent) FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.1/json.tar.xz) FetchContent_Declare(bmp2 GIT_REPOSITORY https://github.com/BoschSensortec/BMP2-Sensor-API.git) FetchContent_MakeAvailable(json bmp2) add_library(wsh SHARED src/library.cpp src/bmp280.cpp src/bmp280.hpp) set_target_properties(wsh PROPERTIES LINKER_LANGUAGE CXX) # 直接链接bmp2库目标,保留原有的i2c链接 target_link_libraries(wsh PUBLIC i2c bmp2) # 无需单独设置include目录,bmp2目标已通过INTERFACE_INCLUDE_DIRECTORIES暴露头文件路径 add_executable(main src/main.cpp) target_link_libraries(main PRIVATE wsh nlohmann_json::nlohmann_json)
额外检查:如果bmp2.h未自带extern "C"兼容处理,需要在C++代码中包含时手动包裹:
extern "C" { #include <bmp2.h> }
多数硬件库头文件已处理该兼容问题,优先尝试链接库目标,若仍报错再添加此包裹。
内容的提问来源于stack exchange,提问作者fabro122
相关产品推荐
相关产品推荐

