Universal Robots+

URTool to Support c++11

Is there a plan to create a new tool chain to support c++11?
Current cpp compiler in URTool3 is very old.

2 Likes

Topic moved to Feature Requests.

@ocohen For now, you can simply ship the right libstdc++ with your URCap and edit the c++ app RPATH or LD_LIBRARY_PATH in a bash file that calls your c++ app.

@mohamedgamal.abdelha if I link it manually I get:

libstdc++.so: undefined reference to '_Unwind_GetIPInfo@GCC_4.2.0'

Do you have any suggestions?

Hi,
Is there any progress in this topic? Anyone who managed to compile and run c++11 code on the robot, feel free to share the instruction steps here :slight_smile:

We’ve managed to build our c++11/14 daemon through static linking.
Something like the following CMakeLists.txt example:

cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(example_cpp14 VERSION 0.0.1 LANGUAGES CXX)

include_directories(include
  lib/include
  ...
)

add_executable(${PROJECT_NAME}
  src/main_cpp14.cpp
  lib/src/lib_cpp14.cpp
  ...
)

target_link_libraries(${PROJECT_NAME}
  PUBLIC
    # the following library list order is crucial!
    xmlrpc_server_abyss++
    xmlrpc_server_abyss
    xmlrpc_server_pstream++
    xmlrpc_server
    xmlrpc_abyss
    xmlrpc_server++
    xmlrpc++
    xmlrpc
    xmlrpc_packetsocket
    xmlrpc_xmlparse
    xmlrpc_xmltok
    xmlrpc_util
    curl
    pthread
)

set_target_properties(${PROJECT_NAME}
  PROPERTIES
    CXX_STANDARD 14
    CXX_STANDARD_REQUIRED ON
    COMPILE_FLAGS "-m32 -march=i686"
    LINK_FLAGS "-m32 -static-libstdc++ -static-libgcc -static"
)

install(
  TARGETS ${PROJECT_NAME}
  RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/../src/main/resources/com/example_company/example_urcap_cpp14/impl/daemon
)

Of course you need all the 32-bit static librariy files, i.e. *.a libraries to successfully compile through cmake.

1 Like

Hi Alessandro

Just following up on your post about the compilation of your code supporting c++11, because I am not sure I understand everything.

According to your post, you’re using cmake. Are you still using the compilers coming with urtool? Are you not using scons anymore in your process?
Would it mean then that in your compilation process, you are first compiling your daemon with cmake and then compiling your urcap with maven?

Thank you in advance for answers.

Hello Francois,

I’m using an external cmake project which is compiled through the default linux compiler (e.g. gcc version 8.3.0 in my case).
I’m not using scons any longer, but I have not automated the compilation process inside maven yet.
So I build the daemon executable externally, and thanks to the install macro I get the same behavior of the scons compilation (in terms of output location of the executable). Be aware that you will need to call the install macro manually to make it works.
And as you have imagined I later build the URCap with maven (without the scons instructions), and I can avoid recompiling the cmake project from now on if I don’t make any changes there.

Enjoy

1 Like

Hello Alessandro

Thank you very much for your explanations! I’ll give it a try.

Hi Alessandro, hi all,

So I tried as far as I could to build a c++11/14 daemon through static linking but I am stuck now and I don’t know how to go on.

I followed Alessandro’s guidances as most as possible:

  • I am working with the latest URCap Starter Package with sdk 1.9.0. The native gcc compiler version here is 5.4.0. My daemon just implements an empty main function returning 0 without including anything for now.

  • I downloaded the latest gcc source code and after some time managed to build the 32 bit static libraries to link the daemon to, thanks to the native compiler of the URCap Starter Package. I ran the “make install” command into a dedicated folder that I copied within my daemon data structure.
    – So, first question here, is that the right way to do so? Obviously not exactly as I am not managing to make my daemon work for now.
    – Alessandro is working with gcc version 8.3.0. Should I thus update my native compiler to build the gcc source code and to run cmake with to build the daemon afterwards? Or should I just replace the native compiler of the URCap Starter package with the gcc version I am building and work with it from now on?

  • I wrote then my CMakeLists.txt such as:

cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)

project(HelloWorld VERSION 0.0.1 LANGUAGES CXX)

include_directories(
.
./link_to_headers_of_gcc
)

link_directories(
./link_to_32_bit_static_libs_of_gcc
)

add_executable(${PROJECT_NAME}
HelloWorld.cpp
)

set_target_properties(${PROJECT_NAME}
PROPERTIES
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
COMPILE_FLAGS “-m32 -march=i686”
LINK_FLAGS “-m32 -static-libstdc++ -static-libgcc -static”
)

Doing such, I can compile and run the “empty” daemon. But as soon as I am including in my code iostream for instance, I am fighting with include errors, iostream including files that include files… I tried to add in the CMakeLists.txt file more include paths from my new gcc install folder but I am then getting this kind of errors when compiling, which makes me stop trying:

error: there are no arguments to ‘__is_constructible’ that depend on a template parameter, so a declaration of ‘__is_constructible’ must be available [-fpermissive]
: public __bool_constant<__is_constructible(_Tp, _Args…)>

or

error: ‘__builtin_addressof’ was not declared in this scope

Looking at the net, I have the feelings that these errors are due to multiple gcc version conflicts. I did not manage to solve them, one error bringing the other one.
– I am basically stuck here and don’t manage to move forward. What can I do to make it work?

  • Let’s imagine now that I can run c++11 compliant code now. I need thus afterwards to add in my CMakeLists.txt file the following:

target_link_libraries(${PROJECT_NAME}
PUBLIC
xmlrpc_server_abyss++
xmlrpc_server_abyss
xmlrpc_server_pstream++
xmlrpc_server
xmlrpc_abyss
xmlrpc_server++
xmlrpc++
xmlrpc
xmlrpc_packetsocket
xmlrpc_xmlparse
xmlrpc_xmltok
xmlrpc_util
curl
pthread
)

I copied these libraries from the “urtool” framework installed in the URCap Starter Package into a dedicated folder located alongside my daemon. My CMakeLists.txt file looks now like that:

cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)

project(HelloWorld VERSION 0.0.1 LANGUAGES CXX)

include_directories(
.
./link_to_headers_of_gcc
./link_to_headers_of_urtool
)

link_directories(
./link_to_32_bit_static_libs_of_gcc
./link_to_libs_of_urtool
)

add_executable(${PROJECT_NAME}
HelloWorld.cpp
)

target_link_libraries(${PROJECT_NAME}
PUBLIC
xmlrpc_server_abyss++
xmlrpc_server_abyss
xmlrpc_server_pstream++
xmlrpc_server
xmlrpc_abyss
xmlrpc_server++
xmlrpc++
xmlrpc
xmlrpc_packetsocket
xmlrpc_xmlparse
xmlrpc_xmltok
xmlrpc_util
curl
pthread
)

set_target_properties(${PROJECT_NAME}
PROPERTIES
CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
COMPILE_FLAGS “-m32 -march=i686”
LINK_FLAGS “-m32 -static-libstdc++ -static-libgcc -static”
)

– It looks like that it is working (without the static linking of the 32 bit gcc libraries). But is that the best way to do it?

Thanks in advance for your answers.

Hi everyone,
I’m trying the solution describe in this topic, but I get this error:

AbyssServer.cpp:(.text+0xa9): undefined reference to xmlrpc_c::registry::…`

in add_executable I added all the src in the daemon example, including AbyssServer.cpp and XMLRPCMethods.cpp

Could you help me?

Hi All,

We were able to build C++11 code on a regular 32-bit ubuntu 18.04 LTS virtual machine (not used the UR cross-compiler or any libraries provided by that package) and then included the dependent system libraries in the same folder where the daemon is located.
We did not use any static linking; instead we used a shell script to start the daemon with the correct LD_LIBRARY_PATH environment variable in order to find the required dependencies.

To find the dependencies, we used the ldd command on the compiler machine (ubuntu 18.04):

ldd MyDaemon

To run the daemon, we used the following shell script (in the same folder where the daemon is located):

#!/bin/bash
trap 'kill -TERM $PID' TERM INT
LD_LIBRARY_PATH=`pwd` `pwd`/MyDaemon &
PID=$!
wait $PID
trap - TERM INT
wait $PID
EXIT_STATUS=$?

Instead of starting the daemon executable directly, we start the shell script.

I hope this helps.

1 Like