ros2-for-arm/ros2

Update documentation for cross compilation

Closed this issue · 7 comments

dgoel commented

The cross compilation fails for internal dependencies of FAST-RTPS if the toolchain requires a sysroot to work, and if that sysroot is specified using CMAKE_TOOLCHAIN_FILE. See PR #216 for details. While this change gets merged upstream, I propose to update the documentation so that the corresponding fix can be applied manually (if needed).

Here's the link to the proposed documentation change:
dgoel/ros2_arm_wiki@2eb8864

Thanks!

Hello,

I have no error when cross-compiling fastrtps in ament. Even though I use/set CMAKE_TOOLCHAIN_FILE. I get the package compiled and the binaries are for the correct architecture. So the toolchain file seems to be taken into account. Even if your patch in FastRTPS seems legitimate, I am not sure to understand why this is working on my side (I am not using a sysroot so I guess all the necessary libraries are available in my toolchain..)

dgoel commented

The bug happens if the toolchain requires a sysroot to work. If that case, the compiler detection fails as cmake tries to compile a dummy program without adding sysroot to the compile command.

Hi @dgoel ,
I also have no error when I'm cross-compiling with a sysroot (I use it to enable python). Can you give us more info to understand/reproduce your issue ? (toolchain, ament build cmd, toolchainfile, ...)

dgoel commented

I am using a custom toolchain and sysroot using open-embedded.

The ament command is exactly the same as mentioned in your wiki except that my toolchain file is different. Here it is anyway:

export CROSS_COMPILE=arm-oe-linux-gnueabi-
src/ament/ament_tools/scripts/ament.py \
    build \
    --force-cmake-configure \
    --cmake-args -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=`pwd`/arm_toolchainfile.cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
    -DTHIRDPARTY=ON --

Here's my toolchain file:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER $ENV{CROSS_COMPILE}gcc)
set(CMAKE_CXX_COMPILER $ENV{CROSS_COMPILE}g++)
set(CMAKE_SYSROOT /path/to/sysroot)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2" CACHE STRING "" FORCE)

# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${CMAKE_CURRENT_LIST_DIR}/install)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# This assumes that pthread will be available on the target system
# (this emulates that the return of the TRY_RUN is a return code "0"
set(THREADS_PTHREAD_ARG "0"
  CACHE STRING "Result from TRY_RUN" FORCE)

And here's the error that I get without my proposed patch:

....
-- Check for working C compiler: /usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc
-- Check for working C compiler: /usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc -- broken
-- Configuring incomplete, errors occurred!
See also "/mnt/store/ros2/arm_ws/build/fastrtps/external/fastcdr/CMakeFiles/CMakeOutput.log".
See also "/mnt/store/ros2/arm_ws/build/fastrtps/external/fastcdr/CMakeFiles/CMakeError.log".
CMake Error at /usr/share/cmake-3.5/Modules/CMakeTestCCompiler.cmake:61 (message):
  The C compiler
  "/usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc"
  is not able to compile a simple test program.

  It fails with the following output:

   Change Dir: /mnt/store/ros2/arm_ws/build/fastrtps/external/fastcdr/CMakeFiles/CMakeTmp

  

  Run Build Command:"/usr/bin/make" "cmTC_d3157/fast"

  /usr/bin/make -f CMakeFiles/cmTC_d3157.dir/build.make
  CMakeFiles/cmTC_d3157.dir/build

  make[1]: Entering directory
  '/mnt/store/ros2/arm_ws/build/fastrtps/external/fastcdr/CMakeFiles/CMakeTmp'


  Building C object CMakeFiles/cmTC_d3157.dir/testCCompiler.c.o

  
  /usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc
  -o CMakeFiles/cmTC_d3157.dir/testCCompiler.c.o -c
  /mnt/store/ros2/arm_ws/build/fastrtps/external/fastcdr/CMakeFiles/CMakeTmp/testCCompiler.c


  Linking C executable cmTC_d3157

  /usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_d3157.dir/link.txt
  --verbose=1

  
  /usr/bin/arm-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc
  CMakeFiles/cmTC_d3157.dir/testCCompiler.c.o -o cmTC_d3157 -rdynamic

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot open crt1.o: No such file or directory

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot open crti.o: No such file or directory

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot open crtbegin.o: No such file or directory

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot open crtend.o: No such file or directory

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot open crtn.o: No such file or directory

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot find -lgcc

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot find -lgcc_s

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot find -lc

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot find -lgcc

  
  /usr/libexec/arm-oe-linux-gnueabi/gcc/arm-oe-linux-gnueabi/5.2.0/real-ld:
  error: cannot find -lgcc_s

  collect2: error: ld returned 1 exit status

  CMakeFiles/cmTC_d3157.dir/build.make:97: recipe for target 'cmTC_d3157'
  failed

  make[1]: *** [cmTC_d3157] Error 1

  make[1]: Leaving directory
  '/mnt/store/ros2/arm_ws/build/fastrtps/external/fastcdr/CMakeFiles/CMakeTmp'


  Makefile:126: recipe for target 'cmTC_d3157/fast' failed

  make: *** [cmTC_d3157/fast] Error 2

  

  

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt


CMake Error at cmake/dev/eprosima_libraries.cmake:120 (message):
  Cannot configure Git submodule fastcdr
Call Stack (most recent call first):
  CMakeLists.txt:197 (find_eprosima_package)


-- Configuring incomplete, errors occurred!
See also "/mnt/store/ros2/arm_ws/build/fastrtps/CMakeFiles/CMakeOutput.log".
See also "/mnt/store/ros2/arm_ws/build/fastrtps/CMakeFiles/CMakeError.log".

<== Command '. /mnt/store/ros2/arm_ws/build/fastrtps/cmake__build.sh && /usr/bin/cmake /mnt/store/ros2/arm_ws/src/eProsima/Fast-RTPS -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/mnt/store/ros2/arm_ws/arm_toolchainfile.cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DTHIRDPARTY=ON -DCMAKE_INSTALL_PREFIX=/mnt/store/ros2/arm_ws/install' failed in '/mnt/store/ros2/arm_ws/build/fastrtps' with exit code '1'
<== Command '. /mnt/store/ros2/arm_ws/build/fastrtps/cmake__build.sh && /usr/bin/cmake /mnt/store/ros2/arm_ws/src/eProsima/Fast-RTPS -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/mnt/store/ros2/arm_ws/arm_toolchainfile.cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DTHIRDPARTY=ON -DCMAKE_INSTALL_PREFIX=/mnt/store/ros2/arm_ws/install' failed in '/mnt/store/ros2/arm_ws/build/fastrtps' with exit code '1'

As you can see, the compiler check fails because sysroot is not passed through when cmake tries to compile a simple, test program.

Let me know if you need any other information.

Thanks!

Thanks for the details, last time I got this issue of compiler check fail was went I tried to compile a library for Nuttx. So I used

set(CMAKE_FORCE_C_COMPILER $ENV{CROSS_COMPILE}gcc cortex_m_compiler)
set(CMAKE_FORCE_CXX_COMPILER $ENV{CROSS_COMPILE}g++ cortex_m_compiler)

to avoid the compiler check as the test program was using undefined function/compiler parameters.

dgoel commented

I did try forcing the compiler but that didn't work either, and I got the same error as above. Further, cmake discourages the use of this feature:

https://cmake.org/cmake/help/v3.5/module/CMakeForceCompiler.html

Discouraged. Avoid using this module if possible. It will be deprecated by a future version of CMake once alternatives have been provided for all toolchain file use cases.

Cmake 3.6 introduced a new feature (CMAKE_TRY_COMPILE_TARGET_TYPE ) to skip such checks but I am using cmake 3.5.1 (default on ubuntu 16.04).

This has been fixed in eProsima (see the above referenced issue)