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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:03:52