# MRAA library inclusion in project

I won't pretend to be a ROS Linux or coding expert, but I've been stuck on getting my catkin_make to compile using the MRAA library from Intel. I'm using Intel's Up Board as my robot central controller. It will be eventually be doing SLAM and taking simple orders through a ROS message from a central computer elsewhere. Pretty standard. There are a few peripherals I want to connect to the Up Board by serial communication (SPI, specifically). At compile time the system breaks down when it tries to link to the MRAA library. It doesn't understand the references. So the way I see it, it's either a problem with the way I installed the library, or my CMakeLists.txt or package.xml is setup wrong. I've been through a lot of documentation, but cannot determine how to get the proper setup to link to the library.

catkin_make output:

[100%] Built target floorbot_generate_messages
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp: In function ‘int main(int, char**)’:
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:32:2: error: ‘mraa’ has not been declared
mraa::Spi * spiCom;
^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:32:14: error: ‘spiCom’ was not declared in this scope
mraa::Spi * spiCom;
^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:33:2: error: ‘mraa’ has not been declared
mraa::Spi * tooth;
^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:33:14: error: ‘tooth’ was not declared in this scope
mraa::Spi * tooth;
^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:35:15: error: expected type-specifier before ‘mraa’
spiCom = new mraa::Spi(0); // <---- portal to arduino (CS0)
^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:35:15: error: expected ‘;’ before ‘mraa’
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:36:14: error: expected type-specifier before ‘mraa’
tooth = new mraa::Spi(1);  // <---- portal to bluetooth (CS1)
^
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:36:14: error: expected ‘;’ before ‘mraa’
/home/floorbot/catkin_ws/src/floorbot/src/sojourner.cpp:54:50: error: ‘chatterCallback’ was not declared in this scope
ros::Subscriber sub = n.subscribe("chat", 1000, chatterCallback);
^
make[2]: *** [floorbot/CMakeFiles/sojourner.dir/src/sojourner.cpp.o] Error 1
make[1]: *** [floorbot/CMakeFiles/sojourner.dir/all] Error 2
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
floorbot@floorbot:~/catkin_ws$ CMakeLists.txt: cmake_minimum_required(VERSION 2.8.3) project(floorbot) find_package(catkin REQUIRED COMPONENTS roscpp std_msgs message_generation) find_package(Boost REQUIRED COMPONENTS system) #find_package(mraa REQUIRED) add_message_files(FILES commands.msg) generate_messages(DEPENDENCIES std_msgs) catkin_package(${catkin_CURRENT_SOURCE_DIR}
INCLUDE_DIRS include
LIBRARIES floorbot mraa
CATKIN_DEPENDS roscpp mraa std_msgs
message_runtime
DEPENDS system_lib mraa)

# include_directories(${catkin_INCLUDE_DIRS}) # include_directories(/home/mraa) # include_directories(/usr/include/mraa) # add_subdirectory(mraa) # add_library(mraa floorbot.cpp) add_executable(sojourner src/sojourner.cpp) add_dependencies(sojourner floorbot_generate_message_cpp${catkin_EXPORTED_TARGETS})
target_link_libraries(sojourner ${catkin_LIBRARIES})  package.xml: <?xml version="1.0"?> <package> <name>floorbot</name> <version>0.0.1</version> <description>The floorbot package</description> <maintainer email="floorbot@todo.todo">floorbot</maintainer> <license>TODO</license> <buildtool_depend>catkin</buildtool_depend> <build_depend>roscpp</build_depend> <build_depend ... edit retag close merge delete ## 1 Answer Sort by » oldest newest most voted target_link_libraries(sojourner${catkin_LIBRARIES})


In your current CMakeLists.txt at least, you're only linking against whatever catkin_LIBRARIES contains, and don't have any of the MRAA paths added to the compiler's include path. catkin_LIBRARIES whill not contain the MRAA libraries (as they are not catkin packages), and without the MRAA headers on your include path, the compiler will not know about any MRAA datastructures, functions, etc, so that's where the undeclared X errors are coming from.

How to link to third party library ? and How do I link a library in cmake? (note that explicitly setting the linker path is discouraged) are related, but just to reiterate:

1. install your dependency somewhere on your system. This could be in the 'normal' locations (ie: /usr/local/.., or perhaps even system wide, depending on whether you build this from source or install a package distributed via your system's package manager), your home directory or somewhere else.

2. make your CMakeLists.txt able to find your dependencies: some distribution-provided packages (ie: .debs on Debian/Ubuntu) provide CMake compatible files that allow you to use find_package(PKG_NAME). If no CMake files are available, try PkgConfig. If none of this is available / works, you could hard-code the path to the include and library director(y)(ies), but that should really be used as a last resort only.

3. finally, if you could use find_package(..), add the pkg_name_LIBRARIES and pkg_name_INCLUDE_DIRS variables to the relevant include_directories(..) and target_link_libraries(..) lines in your CMakeLists.txt. If you used PkgConfig, do the same, but the variable names might be slightly different. If you hard-coded things, I'd still recommend using variables with the same names that the find scripts would use, because that makes it easy to move to a find script in the future.

In your case, you'll want to make sure the directory containing the mraa.h file is on the include path, and that your sojourner binary is linked with the (I'm guessing here) mraa library. Note that the file will probably be called libmraa.so, but CMake expects only the proper name (ie: mraa).

Bonus points if, instead of hard-coding, you write a CMake find or config script for MRAA and use that.

PS: for some more information on the recommended ways for step 2, see How to do common tasks » Package format 2 (recommended) » C++ system library dependencies in the catkin documentation.

Edit:

I've tried gvdhoorn's suggestions and I still can't get it past [..]

For now, I wouldn't bother with doing things the 'proper' way. If all this is new to you, just do something like this in your CMakeLists.txt:

...

set (mraa_LIBRARIES "/full/path/to/libmraa.so")

...

include_directories(${catkin_INCLUDE_DIRS}${mraa_INCLUDE_DIRS})

...

...
target_link_libraries(sojourner ${catkin_LIBRARIES}${mraa_LIBRARIES})

...


I also wouldn't bother with adding anything to the catkin_package(..) statement for now. Get your binary to compile and link successfully. Afterwards, we can deal with the rest. Auto-detection ...

more

Thanks gvdhroon! I added

find_package(PkgConfig REQUIRED)
pkg_check_modules(mraa REQUIRED mraa)
include_directories(${mraa_INCLUDE_DIRS}) catkin_package(... LIBRARIES ... mraa ... DEPENDS ... mraa)  It took more careful reading of your links. ( 2016-11-14 15:52:53 -0500 )edit Good to hear you got it to work. Is your comment cut-off, or have you forgotten to also target_link_libraries(..) with mraa? ( 2016-11-15 01:43:54 -0500 )edit I actually did not have that line. I tried it with${mraa_LIBRARIES} in target_link_libraries and it make no difference with or without it. I still have plenty of errors, due to other things, but it ma crop up later when I get those bugs ironed out.

( 2016-11-15 09:54:22 -0500 )edit