【问题标题】:CMake "undefined reference to function"CMake“未定义的函数引用”
【发布时间】:2015-12-06 00:42:00
【问题描述】:

我正在尝试使用 CMake 链接库 (BNO055 Driver)。由于 BNO055 驱动程序不使用 CMake 并且大约一年没有更改,我决定只下载源文件并将它们放入我的项目中。

然后我使用 CMake 创建一个库并链接它。

问题是链接似乎不起作用。编译项目时出现undefined reference to <function> 错误,其中<function> 是BNO055 驱动程序定义的函数。

我是否不正确地创建或链接库?
我需要做其他事情来定义这些函数吗?

为了不粘贴 200 行代码,这里有一个简化的main.cpp,它会产生与真正的main.cpp 相同的错误。如果你想查看真正的main.cpp,请点击下面的链接到 Github 仓库

#include "bno055.h"
#include "mraa.hpp"

struct bno055_t bno055;
mraa::I2c *i2c(0);

int main() {
    bno055_init(&bno055);
    i2c->address(0x29);
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.4)
project(imc-server)

# CMake
# -- Config
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")

# Global
# -- Include
include(ExternalProject)

# BNO055
# -- Include
include_directories(${CMAKE_SOURCE_DIR}/bno055)

set(SOURCE_FILES ${SOURCE_FILES}
        ${CMAKE_SOURCE_DIR}/bno055/bno055.h
        ${CMAKE_SOURCE_DIR}/bno055/bno055.c)

# MRAA
# -- Build
externalProject_add(mraa
        GIT_REPOSITORY https://github.com/intel-iot-devkit/mraa.git
        GIT_TAG        v0.7.5
)

# Compile
# -- Source
set(SOURCE_FILES ${SOURCE_FILES}
        main.cpp)

# -- Create
add_executable(imc-server ${SOURCE_FILES})
add_dependencies(imc-server mraa)

构建日志的相关部分

[ 90%] Linking CXX executable imc-server
CMakeFiles/imc-server.dir/test.cpp.o: In function `main':
/home/noah/Documents/Inertial-Motion-Capture/imc-server/test.cpp:8: undefined reference to `bno055_init(bno055_t*)'
CMakeFiles/imc-server.dir/test.cpp.o: In function `mraa::I2c::address(unsigned char)':
/usr/local/include/mraa/i2c.hpp:99: undefined reference to `mraa_i2c_address'
collect2: error: ld returned 1 exit status
make[2]: *** [imc-server] Error 1
make[1]: *** [CMakeFiles/imc-server.dir/all] Error 2
make: *** [all] Error 2

Project Github(39a6196)
Build Log

【问题讨论】:

  • 您使用${CMAKE_SOURCE_DIR}/bno055/bno055.c 文件构建bno055 库,因此您不应将该文件用于构建imc-server 可执行文件。此外,最好使用库目标名称来链接可执行文件:target_link_libraries(imc-server bno055)。至于外部项目mraa,您还需要明确的目标依赖关系才能正确链接:add_dependencies(imc-server mraa)
  • @Tsyvarev 好的,我刚刚将 BNO055 文件添加到了可执行文件中(所以没有 lib 或 bno055 的链接)。但是我仍然收到未定义的函数错误。我还取消了所有 mraa 代码的注释,并且这些函数也出现未定义的函数错误。这里有什么我从根本上想念的吗? Commit with changes => 39a6196
  • 编译哪个源,什么时候出错?准确的错误信息(至少对于一个功能)会有所帮助。
  • @Tsyvarev 事实上,这是 CMake 构建日志的结尾部分。 Pastebin
  • 如构建日志所示,函数 (mraa_i2c_address) 是在 mraa 库中定义的,而不是在 bno055 库中定义的。您需要与该库 (target_link_libraries(imc-server libmraa.so) 链接并添加与 mraa 目标 (add_dependencies(imc-server mraa)) 的依赖关系。

标签: c++ c cmake clion


【解决方案1】:

问题是 BNO055 库是用 C 编写的,而我的程序是用 C++ 编写的。

我了解到要使用在 C 程序中定义的函数,在 C++ 程序中,您必须将 C 库的包含包装在 extern "C" {} 块中,如下所示:

extern "C" {
    #include "bno055.h"
}
#include "mraa.hpp"

struct bno055_t bno055;
mraa::I2c *i2c(0);

int main() {
    bno055_init(&bno055);
    i2c->address(0x29);
}

【讨论】:

    【解决方案2】:

    从您的 SOURCE_FILES 中删除标题。

    set(SOURCE_FILES ${SOURCE_FILES}
            # ${CMAKE_SOURCE_DIR}/bno055/bno055.h
            ${CMAKE_SOURCE_DIR}/bno055/bno055.c)
    

    CMake 应该自己找到所需的标头。 include_directories

    发现了其他包含

    【讨论】:

    • 问题是我必须将 bno055 包含在 extern "C" {}"
    • 也许你可以发布你自己的答案,它会更明显
    猜你喜欢
    • 2012-10-07
    • 2012-10-14
    • 1970-01-01
    • 2020-06-26
    • 2020-10-29
    • 1970-01-01
    • 2018-01-01
    • 2016-08-21
    相关资源
    最近更新 更多