2015-09-09 41 views
5

Sto tentando di utilizzare CMake per collegare una libreria (BNO055 Driver). Poiché il driver BNO055 non utilizza CMake e non è stato modificato per circa un anno, ho deciso di scaricare i file sorgente e inserirli nel mio progetto.CMake "riferimento alla funzione non definito"

Quindi utilizzo CMake per creare una libreria e collegarla.

Il problema è che il collegamento non sembra funzionare. Quando compilo il progetto ottengo un errore undefined reference to <function>, dove <function> è una funzione definita dal driver BNO055.

Sto creando o collegando la libreria in modo errato?
Devo fare qualcos'altro per definire queste funzioni?

Per non incollare in 200 righe di codice, ecco uno main.cpp semplificato che produce lo stesso errore del numero reale main.cpp. Se volete vedere la vera main.cpp seguono il muggito di collegamento al repository 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) 

relativa Parte di costruzione Log

[ 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

+0

Si utilizza '$ { CMAKE_SOURCE_DIR}/bno055/bno055.c' per la libreria build 'bno055', quindi non dovresti usare quel file per costruire l'eseguibile' imc-server'. Inoltre, è meglio usare il nome di destinazione della libreria per il link che è eseguibile: 'target_link_libraries (imc-server bno055)'. Per quanto riguarda il progetto esterno 'mraa', hai anche bisogno di dipendenze di destinazione esplicite per il corretto collegamento con esso:' add_dependencies (imc-server mraa) '. – Tsyvarev

+0

@Tsyvarev Ok, ho appena aggiunto i file BNO055 all'eseguibile (quindi nessuna lib o collegamento per bno055). Tuttavia sto ancora ricevendo errori di funzione non definiti. Ho anche decommentato tutto il codice mraa e sto ottenendo errori di funzione non definiti anche per quelle funzioni. C'è qualcosa che mi manca fondamentalmente qui? [Conferma con le modifiche => 39a6196] (https://github.com/Noah-Huppert/Inertial-Motion-Capture/tree/39a6196e48623c76323b92d37bf6e811c22f3ad5/imc-server) –

+0

Quale origine viene compilata quando si verifica un errore? Sarebbe utile un messaggio di errore preciso (almeno per una funzione). – Tsyvarev

risposta

4

Il problema era che la libreria BNO055 era scritta in C e il mio programma era scritto in C++.

ho imparato che per usare una funzione definita in un programma C, in un programma C++, si deve avvolgere il includere della libreria C in un blocco extern "C" {} in questo modo:

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

Rimuovere l'intestazione da SOURCE_FILES.

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

CMake dovrebbe trovare da solo l'intestazione richiesta. Ulteriori elementi sono trovati da include_directories

+1

Il problema era che dovevo includere l'inclusione di bno055 in un ' extern "C" {} "' –

+0

forse potresti pubblicare la tua risposta, sarebbe più visibile – lelloman

Problemi correlati