Reputation: 4280
I am attempting to use CMake to link a library(BNO055 Driver). Since the BNO055 Driver doesn't use CMake and it hasn't been changed for about a year I decided to just download the source files and put them in my project.
I then use CMake to create a library and link it.
The issue is that the link does not seem to be working. When I compile the project I get a undefined reference to <function>
error, where <function>
is a function defined by the BNO055 driver.
Am I creating or linking the library incorrectly?
Do I need to do something else to define these functions?
For the sake of not pasting in 200 lines of code, here is a simplified main.cpp
that produces the same error as the real main.cpp
. If you would like to see the real main.cpp
follow the link bellow to the Github repo
#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)
Relevant Part of Build 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
Upvotes: 8
Views: 7840
Reputation: 4280
The problem was that the BNO055 library was written in C, and my program was written in C++.
I learned that to use a function defined in a C program, in a C++ program, you have to wrap the include of the C library in an extern "C" {}
block like so:
extern "C" {
#include "bno055.h"
}
#include "mraa.hpp"
struct bno055_t bno055;
mraa::I2c *i2c(0);
int main() {
bno055_init(&bno055);
i2c->address(0x29);
}
Upvotes: 15
Reputation: 2825
Remove the header from your SOURCE_FILES.
set(SOURCE_FILES ${SOURCE_FILES}
# ${CMAKE_SOURCE_DIR}/bno055/bno055.h
${CMAKE_SOURCE_DIR}/bno055/bno055.c)
CMake should find the required header by itself. Additional includes are found by include_directories
Upvotes: 0