2015-09-09 119 views
5

我正在嘗試使用CMake鏈接庫(BNO055 Driver)。由於BNO055驅動程序不使用CMake,大約一年沒有改變,我決定下載源文件並將它們放入我的項目中。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 Github39a6196
Build Log

+0

你使用'$ { CMAKE_SOURCE_DIR}/bno055/bno055.c'文件構建'bno055'庫,所以您不應該使用該文件來構建'imc-server'可執行文件。此外,最好使用庫目標名稱作爲可執行文件:'target_link_libraries(imc-server bno055)'的鏈接。至於外部項目'mraa',你還需要明確的目標依賴關係來正確鏈接它:'add_dependencies(imc-server mraa)'。 – Tsyvarev

+0

@Tsyvarev好的,我剛剛添加了BNO055文件到可執行文件(所以沒有lib或bno055鏈接)。不過,我仍然收到未定義的函數錯誤。我也取消了所有mraa代碼的註釋,並且我也遇到了這些函數未定義的函數錯誤。有什麼我在這裏基本失蹤? [提交更改=> 39a6196](https://github.com/Noah-Huppert/Inertial-Motion-Capture/tree/39a6196e48623c76323b92d37bf6e811c22f3ad5/imc-server) –

+0

哪些源代碼正在編譯,何時出現錯誤?精確的錯誤信息(至少對於一個功能)會很有幫助。 – Tsyvarev

回答

4

問題是,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); 
} 
0

從SOURCE_FILES中刪除標題。

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

CMake應該自己找到需要的標題。其他包括被發現include_directories

+1

問題是我必須將bno055 include包裝在' extern「C」{}「' –

+0

也許你可以發表你自己的答案,它會更明顯 – lelloman