CMake and QIbuild
You can use CMake or qibuild in your projects.
|Helloworld||RAPP + CMake||Helloworld|
|Helloworld||RAPP + NAOqi + qibuild||qiHelloworld|
|Helloworld Static||RAPP + CMake||Helloworld static|
|Face detection||RAPP + NAOqi + CMake||Face detection|
|Face detection||RAPP + NAOqi + qibuild||qiFace detection|
|Say Services||RAPP + NAOqi + CMake||Say services|
The above tutorials use either full static linking, or a mix of static and shared libraries. Please see each individual tutorial for more details.
Aldebaran's OPEN NAO version is: Gentoo 18.104.22.168-rt31-aldebaran-rt It runs on an i686 Intel(R) Atom(TM) CPU Z530 @ 1.60GH (although that depends on your robot model). It appears to support C++11/14 but it uses older versions of GLIBC.
OPEN Nao has a file
/home/nao/naoqi/preferences/autoload.ini in which you can set the modules/libraries to be loaded.
# autoload.ini # # Use this file to list the cross-compiled modules that you wish to load. # You must specify the full path to the module, python module or program. [user] #the/full/path/to/your/liblibraryname.so # load liblibraryname.so [python] #the/full/path/to/your/python_module.py # load python_module.py [program] #the/full/path/to/your/program # load program
In the above example, we can use the user mode to load a library.
However, OPEN Nao does NOT respect the RPATH for
that when librapp uses RPATH to define where it should load its own libraries from,
it is ignored.
Most of NAO's system libraries are under
/usr/lib/* (such as boost, ssl and crypto)
- libboost_system.so.1.55.0 (libc6) => /usr/lib/libboost_system.so.1.55.0
- libssl.so.1.0.0 (libc6) => /usr/lib/libssl.so.1.0.0
- libcrypto.so.1.0.0 (libc6) => /usr/lib/libcrypto.so.1.0.0
- libstdc++.so => /usr/lib/libstdc++.so.6.0.14
- libc.so.6 (libc6, OS ABI: Linux 2.6.9) => /lib/libc.so.6
If we take a peek at the
libstdc++ we can see that:
- it supports up to
- it supports up to
Unfortunatelly, C++11/14 and the modern compilers (gcc-4.9, g++-4.9) have higher ABI's:
- for C++ we have
- for C (used by boost and ssl) we have
ATOM CPU flags and optimisation
For ATOM (NAO) use full atom flags:
-O2 -ffast-math -mfpmath=sse -m32 -march=atom
-O2 -ffast-math -mfpmath=sse -ftree-loop-if-convert -m32 -march=atom
-Ofast -funroll-loops -mfpmath=sse -m32 -march=atom, for 4.4 and 4.5 versions
-Ofastis replaced with
Illegal Instruction from libboost_system1.55.so
There is an illegal instruction coming from epoll related to
This is most likely because it comtains an instruction which will not work on ATOM CPU.
If we want to static link with boost we must either:
- build libboost for ATOM cpu (regardless of version) and then static link against it
- or use the libraries from the robot (which have already been built for ATOM)
How To Setup
This tutorial assumes that you have all dependencies installed, and that you already built the librapp.a as a static library using:
git clone https://github.com/rapp-project/rapp-api.git mkdir -p rapp-api/cpp/build && cd rapp-api/cpp/build cmake .. -DOPEN_NAO=ON
Static linking is the easy way out: we bundle with our app everything: boost, ssl, stdc++, libc. This on its own accord creates certain issues:
- libc requires at runtime the
dl(dlopen, dlsym) often seen as
-ldleven if we statically link
- static link to libc disables
getaddressbyhostnameand disables some network functionality.
- the default solution is to rely on IP addresses and not hostnames
Here we use:
- a static
libboost_system(we have copied the version of libboost_system from NAO to our machine)
- a static
librappwhich we created earlier using the
- a static
libpthreadfrom our machine
- a static
libcryptobecause there is a miss-match in the ABI on the robot
- a static
- all static
The conventional way is to use shared linraries which are dynamically loaded when executing. NOTE here we have to set the RPATH to the shared librapp, else it won't be found. The issues with this approach are:
- Your application must be built using the same library versions or there will be an ABI miss-match.
- Your building platform (computer or VM) must have the same libc (GLIBC) version as the one on the robot
- Your building platform must have the same boost version as the one on the robot.
The advantages are:
- You don't have to rebuild anything for ATOM cpu, the shared libraries on your NAO are already optimised for that.
- Your binary will be considerably smaller since you're only shipping your code and not the libraries.
However, using RAPP API when we do not statically link with boost, we will get miss-matched GLIBC ABI.
./app.dyn: /usr/lib/libcrypto.so.1.0.0: no version information available (required by ./app.dyn) ./app.dyn: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./app.dyn) ./app.dyn: /usr/lib/libssl.so.1.0.0: no version information available (required by ./app.dyn) ./app.dyn: /usr/lib/libcrypto.so.1.0.0: no version information available (required by /home/nao/.lib/librapp.0.7.so) ./app.dyn: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/nao/.lib/librapp.0.7.so) ./app.dyn: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by /home/nao/.lib/librapp.0.7.so) ./app.dyn: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by /home/nao/.lib/librapp.0.7.so) ./app.dyn: /usr/lib/libssl.so.1.0.0: no version information available (required by /home/nao/.lib/librapp.0.7.so) ./app.dyn: /usr/lib/libssl.so.1.0.0: no version information available (required by /home/nao/.lib/librapp.0.7.so)
Hybrid Mode = ON
We can mix and match static and dynamic libraries. This still produces a large file which only relies on NAO's boost and threads. If you do not want SSL/TLS or you want don't care about ABI warnings, you can also skip them.
Now we end up with a 859Kb executable, a considerable improvement in size, but we have sacrificed compatability with SSL/TLS. The executable when run will warn you about ABI miss-match during runtime:
./app.mixed: /usr/lib/libcrypto.so.1.0.0: no version information available (required by ./app.mixed) ./app.mixed: /usr/lib/libssl.so.1.0.0: no version information available (required by ./app.mixed)
If you only use HTTP for communicating with the cloud, then there is no issue (TLS won't be used).
You can contact us on Gitter: