0
$\begingroup$

Rosanswers logo

So, due to some peculiarities of my project I am in need of compiling everything with compiler suite version 4.8 instead of the default compiler version that comes with Ubuntu 16.04 ( 5.4 ). I used update-alternatives to set the compiler version (gcc, g++ etc...) to 4.8. But when I execute catkin_make, the linker starts complaining about not being able to find symbols like ros::NodeHandle, ros::init, etc...

Everything compiles and links just fine if I use the default compiler version (but I really need to compile with version 4.8).

To make sure that this is not due to the peculiarities of my project and development environment I have installed a fresh Ubuntu 16.04 + ROS Kinetic on a virtual machine, created a workspace containing the roscpp_tutorials and made sure that the following command works out of the box:

catkin_make -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -j1

Which compiles everthing and works and its all smiles and sunshine.

Then I install the compiler version 4.8 as follows:

sudo apt-get install gcc-4.8 g++-4.8
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 100
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 100
sudo update-alternatives --set cc /usr/bin/gcc
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 100
sudo update-alternatives --set c++ /usr/bin/g++

I make sure to remove the directories build and devel from my catkin workspace:

secret_agent@CIA:~/top_secret/catkin_ws$ rm -rf build devel

And compile again:

secret_agent@CIA:~/top_secret/catkin_ws$ catkin_make -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -j1
Base path: /home/secret_agent/top_secret/catkin_ws
Source space: /home/secret_agent/top_secret/catkin_ws/src
Build space: /home/secret_agent/top_secret/catkin_ws/build
Devel space: /home/secret_agent/top_secret/catkin_ws/devel
Install space: /home/secret_agent/top_secret/catkin_ws/install
####
#### Running command: "cmake /home/secret_agent/top_secret/catkin_ws/src -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCATKIN_DEVEL_PREFIX=/home/secret_agent/top_secret/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/secret_agent/top_secret/catkin_ws/install -G Unix Makefiles" in "/home/secret_agent/top_secret/catkin_ws/build"
####
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using CATKIN_DEVEL_PREFIX: /home/secret_agent/top_secret/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /home/secret_agent/top_secret/catkin_ws/devel;/opt/ros/kinetic
-- This workspace overlays: /home/secret_agent/top_secret/catkin_ws/devel;/opt/ros/kinetic
-- Found PythonInterp: /usr/bin/python (found version "2.7.12") 
-- Using PYTHON_EXECUTABLE: /usr/bin/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/secret_agent/top_secret/catkin_ws/build/test_results
-- Found gmock sources under '/usr/src/gmock': gmock will be built
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Found gtest sources under '/usr/src/gmock': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.7.18
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - roscpp_tutorials
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'roscpp_tutorials'
-- ==> add_subdirectory(roscpp_tutorials)
-- Boost version: 1.58.0
-- Found the following Boost libraries:
--   date_time
--   thread
--   chrono
--   system
--   atomic
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- roscpp_tutorials: 0 messages, 1 services
-- Configuring done
-- Generating done
-- Build files have been written to: /home/secret_agent/top_secret/catkin_ws/build
####
#### Running command: "make -j1" in "/home/secret_agent/top_secret/catkin_ws/build"
####
/usr/bin/cmake -H/home/secret_agent/top_secret/catkin_ws/src -

...
...

make -f roscpp_tutorials/CMakeFiles/parameters.dir/build.make roscpp_tutorials/CMakeFiles/parameters.dir/depend
make[2]: Entering directory '/home/secret_agent/top_secret/catkin_ws/build'
cd /home/secret_agent/top_secret/catkin_ws/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/secret_agent/top_secret/catkin_ws/src /home/secret_agent/top_secret/catkin_ws/src/roscpp_tutorials /home/secret_agent/top_secret/catkin_ws/build /home/secret_agent/top_secret/catkin_ws/build/roscpp_tutorials /home/secret_agent/top_secret/catkin_ws/build/roscpp_tutorials/CMakeFiles/parameters.dir/DependInfo.cmake --color=
Scanning dependencies of target parameters
make[2]: Leaving directory '/home/secret_agent/top_secret/catkin_ws/build'
make -f roscpp_tutorials/CMakeFiles/parameters.dir/build.make roscpp_tutorials/CMakeFiles/parameters.dir/build
make[2]: Entering directory '/home/secret_agent/top_secret/catkin_ws/build'
[  8%] Building CXX object roscpp_tutorials/CMakeFiles/parameters.dir/parameters/parameters.cpp.o
cd /home/secret_agent/top_secret/catkin_ws/build/roscpp_tutorials && /usr/bin/c++   -DROSCONSOLE_BACKEND_LOG4CXX -DROS_BUILD_SHARED_LIBS=1 -DROS_PACKAGE_NAME=\"roscpp_tutorials\" -I/home/secret_agent/top_secret/catkin_ws/devel/include -I/opt/ros/kinetic/include -I/opt/ros/kinetic/share/xmlrpcpp/cmake/../../../include/xmlrpcpp  -O3 -DNDEBUG   -o CMakeFiles/parameters.dir/parameters/parameters.cpp.o -c /home/secret_agent/top_secret/catkin_ws/src/roscpp_tutorials/parameters/parameters.cpp
[ 10%] Linking CXX executable /home/secret_agent/top_secret/catkin_ws/devel/lib/roscpp_tutorials/parameters
cd /home/secret_agent/top_secret/catkin_ws/build/roscpp_tutorials && /usr/bin/cmake -E cmake_link_script CMakeFiles/parameters.dir/link.txt --verbose=1
/usr/bin/c++   -O3 -DNDEBUG   CMakeFiles/parameters.dir/parameters/parameters.cpp.o  -o /home/secret_agent/top_secret/catkin_ws/devel/lib/roscpp_tutorials/parameters  -L/opt/ros/kinetic/lib -rdynamic /opt/ros/kinetic/lib/libroscpp.so -lboost_filesystem -lboost_signals /opt/ros/kinetic/lib/libxmlrpcpp.so /opt/ros/kinetic/lib/librosconsole.so /opt/ros/kinetic/lib/librosconsole_log4cxx.so /opt/ros/kinetic/lib/librosconsole_backend_interface.so -llog4cxx -lboost_regex /opt/ros/kinetic/lib/libroscpp_serialization.so /opt/ros/kinetic/lib/librostime.so /opt/ros/kinetic/lib/libcpp_common.so -lboost_system -lboost_thread -lboost_chrono -lboost_date_time -lboost_atomic -lpthread -lconsole_bridge -lboost_date_time -lboost_thread -lboost_chrono -lboost_system -lboost_atomic -lpthread -lconsole_bridge -Wl,-rpath,/opt/ros/kinetic/lib: 
CMakeFiles/parameters.dir/parameters/parameters.cpp.o: In function `main':
parameters.cpp:(.text.startup+0x3d): undefined reference to `ros::init(int&, char**, std::string const&, unsigned int)'
parameters.cpp:(.text.startup+0xba): undefined reference to `ros::NodeHandle::NodeHandle(std::string const&, std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > > const&)'
parameters.cpp:(.text.startup+0x125): undefined reference to `ros::NodeHandle::getParam(std::string const&, std::string&) const'
parameters.cpp:(.text.startup+0x191): undefined reference to `ros::NodeHandle::getParam(std::string const&, std::string&) const'
parameters.cpp:(.text.startup+0x227): undefined reference to `ros::NodeHandle::hasParam(std::string const&) const'
parameters.cpp:(.text.startup+0x2a2): undefined reference to `ros::NodeHandle::hasParam(std::string const&) const'
parameters.cpp:(.text.startup+0x2c6): undefined reference to `ros::NodeHandle::getParam(std::string const&, std::string&) const'
parameters.cpp:(.text.startup+0x340): undefined reference to `ros::NodeHandle::setParam(std::string const&, char const*) const'
parameters.cpp:(.text.startup+0x388): undefined reference to `ros::NodeHandle::deleteParam(std::string const&) const'
parameters.cpp:(.text.startup+0x3d0): undefined reference to `ros::NodeHandle::hasParam(std::string const&) const'
parameters.cpp:(.text.startup+0x469): undefined reference to `ros::NodeHandle::searchParam(std::string const&, std::string&) const'
parameters.cpp:(.text.startup+0x59c): undefined reference to `ros::NodeHandle::getParam(std::string const&, int&) const'
parameters.cpp:(.text.startup+0x5b8): undefined reference to `ros::NodeHandle::getParam(std::string const&, int&) const'
parameters.cpp:(.text.startup+0x60e): undefined reference to `ros::console::initializeLogLocation(ros::console::LogLocation*, std::string const&, ros::console::levels::Level)'
parameters.cpp:(.text.startup+0x6bd): undefined reference to `ros::console::initializeLogLocation(ros::console::LogLocation*, std::string const&, ros::console::levels::Level)'
parameters.cpp:(.text.startup+0x763): undefined reference to `ros::console::initializeLogLocation(ros::console::LogLocation*, std::string const&, ros::console::levels::Level)'
parameters.cpp:(.text.startup+0x80f): undefined reference to `ros::console::initializeLogLocation(ros::console::LogLocation*, std::string const&, ros::console::levels::Level)'
collect2: error: ld returned 1 exit status
roscpp_tutorials/CMakeFiles/parameters.dir/build.make:123: recipe for target '/home/secret_agent/top_secret/catkin_ws/devel/lib/roscpp_tutorials/parameters' failed
make[2]: *** [/home/secret_agent/top_secret/catkin_ws/devel/lib/roscpp_tutorials/parameters] Error 1
make[2]: Leaving directory '/home/secret_agent/top_secret/catkin_ws/build'
CMakeFiles/Makefile2:519: recipe for target 'roscpp_tutorials/CMakeFiles/parameters.dir/all' failed
make[1]: *** [roscpp_tutorials/CMakeFiles/parameters.dir/all] Error 2
make[1]: Leaving directory '/home/secret_agent/top_secret/catkin_ws/build'
Makefile:141: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j1" failed

Boom! This looks very weird to me because ros::init and ros::NodeHandle are part of roscpp which is included in the compilation command generated, it is just the linker that refuses to find it:

  /usr/bin/c++   -O3 -DNDEBUG   CMakeFiles/parameters.dir/parameters/parameters.cpp.o  -o /home/secret_agent/top_secret/catkin_ws/devel/lib/roscpp_tutorials/parameters  -L/opt/ros/kinetic/lib -rdynamic /opt/ros/kinetic/lib/libroscpp.so -lboost_filesystem -lboost_signals /opt/ros/kinetic/lib/libxmlrpcpp.so /opt/ros/kinetic/lib/librosconsole.so /opt/ros/kinetic/lib/librosconsole_log4cxx.so /opt/ros/kinetic/lib/librosconsole_backend_interface.so -llog4cxx -lboost_regex /opt/ros/kinetic/lib/libroscpp_serialization.so /opt/ros/kinetic/lib/librostime.so /opt/ros/kinetic/lib/libcpp_common.so -lboost_system -lboost_thread -lboost_chrono -lboost_date_time -lboost_atomic -lpthread -lconsole_bridge -lboost_date_time -lboost_thread -lboost_chrono -lboost_system -lboost_atomic -lpthread -lconsole_bridge -Wl,-rpath,/opt/ros/kinetic/lib:

Any one knows why this is not working or what I am missing? I have searched for the answer to similar questions on this forum and on google but no luck :(


Originally posted by Martin Peris on ROS Answers with karma: 5625 on 2019-08-14

Post score: 2

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

So digging a little deeper, I found out that this might be due to ABI incompatibility between gcc-4.8 and gcc-5.

If the linker is complaining that it can not find a reference to ros::init, is because it can really not find it. Looking at the library /opt/ros/kinetic/lib/libroscpp.so we can see the references to ros::init are actually there:

secret_agent@CIA:~/top_secret/catkin_ws/build/roscpp_tutorials$ readelf -Ws /opt/ros/kinetic/lib/libroscpp.so | grep ros4init
  1968: 0000000000130950   566 FUNC    GLOBAL DEFAULT   12 _ZN3ros4initERKSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_ESaIS8_EERKS7_j
  2303: 0000000000130170  2010 FUNC    GLOBAL DEFAULT   12 _ZN3ros4initERiPPcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj
  2448: 000000000012da80   403 FUNC    GLOBAL DEFAULT   12 _ZN3ros4initERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_St4lessIS6_ESaISt4pairIKS6_S6_EEERSA_j

Lets look at the object file that we are trying to link:

secret_agent@CIA:~/top_secret/catkin_ws/build/roscpp_tutorials$ nm CMakeFiles/parameters.dir/parameters/parameters.cpp.o | grep ros4init
             U _ZN3ros4initERiPPcRKSsj

Aha!!! The reference generated for ros::init by gcc-4.8 does not match the reference for ros::init in libroscpp! So, the linker is going bananas and rightfully so!!

This is because libroscpp has been compiled with Ubuntu 16.04 default compiler without old ABI backwards compatibility (if I am not mistaken this would be achieved by the flag -D_GLIBCXX_USE_CXX11_ABI=0.

Obviously, compiling the code with the default version (gcc-5) generates the correct references and the linker is happy.

So, I guess my only option would be to compile ROS from source code and pray that all system libraries are ABI compatible with gcc-4.8 which is not practical for my project.

Tough luck -_-


Originally posted by Martin Peris with karma: 5625 on 2019-08-15

This answer was ACCEPTED on the original site

Post score: 2

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.