ros-tooling / cross_compile

A tool to build ROS and ROS2 workspaces for various targets
Apache License 2.0
188 stars 60 forks source link

Cross-compile orocos_kdl with Eigen3 #181

Closed dodsonmg closed 4 years ago

dodsonmg commented 4 years ago

I am cross compiling ROS2 for a FreeBSD-based research platform. I have a cmake toolchain file, which seems to be working well in most respects.

When colcon goes to build orocos_kdl, however, it falls over when including Eigen3 headers (specifically GeneralProducts.h). I get a bunch of errors associated with pointer casts, which is related to the compiler used for my research platform.

It appears to be pulling native rather than cross-compiled Eigen headers (they're all prefixed with /usr/include/eigen3/Eigen). I do have a cross-compiled version of Eigen, with the same headers it's looking for, in my sysroot (which is specified in my toolchain file).

The CMakeList.txt file in the orocos_kdl package has a find_package(Eigen3 QUIET) statement, and I can't seem to convince it to find the FindEigen3.cmake file in my cross-compiled directory. As a result, it doesn't find my cross-compiled Eigen3 header files.

Any other experience with this or advice?

piraka9011 commented 4 years ago

Have you checked your CMAKE_PREFIX_PATH and LD_LIBRARY_PATHs? Maybe the environment you run cross_compile in could be reading some local env variables? Maybe posting an example toolchain could help debug. The search procedure for CMake's find_package might also shed some light on your situation.

dodsonmg commented 4 years ago

Here is a link to the cmake toolchain file:

https://gist.github.com/dodsonmg/b19442c8aa2a4eebe7e970a4768fe4d7

My CLI invocation is:

colcon build --packages-up-to orocos_kdl \
--cmake-args -DCMAKE_TOOLCHAIN_FILE=/home/broomstick/ros2_dashing_min/CrossToolchain.cmake \
-DBUILD_TESTING=NO \
-DTHIRDPARTY=ON \
--no-warn-unused-cli

The ocoros_kdl CMakeList.txt file has the following line, which is (I think) where I'm having trouble: find_package(Eigen3 QUIET)

My cross-compiled FindEigen3.cmake is located here: /home/broomstick/cheri/eigen/cmake/FindEigen3.cmake

My cross-compiled Eigen3 headers are located here: /home/broomstick/cheri/output/sdk/sysroot128/opt/cheri/eigen/include/eigen3/Eigen/Core

As you can see from the cmake toolchain file, the sysroot points here: /home/broomstick/cheri/output/sdk/sysroot128

I have tried to set CMAKE_PREFIX_PATH and CMAKE_MODULE_PATH to point to the FindEigen3.cmake file without success.

traversaro commented 4 years ago

The ocoros_kdl CMakeList.txt file has the following line, which is (I think) where I'm having trouble: find_package(Eigen3 QUIET)

Which version of orocos_kdl are you using? As far as I can see from the master version, there is a line (https://github.com/orocos/orocos_kinematics_dynamics/blob/master/orocos_kdl/CMakeLists.txt#L48) that is:

find_package(Eigen 3 QUIET)

note that there is a space between Eigen and 3, meaning that if you want that call to succeed you need to provide a FindEigen.cmake or EigenConfig.cmake file.

dodsonmg commented 4 years ago

CMAKE_PREFIX_PATH appears to be my problem.

Specifically, my SYSROOT was not deep enough for the search procedure used by find_package (I guess that make sense, since it only points to the root...). As a result, find_package was not finding the FindEigen3.cmake from my cross-compiled Eigen. Instead, it was finding my native Eigen3Config.cmake and then including my native Eigen header files.

My SYSROOT is /home/broomstick/cheri/output/sdk/sysroot128.

A CMAKE_PREFIX_PATH of ${SYSROOT}/usr/local/cheri found my FindEigen3.cmake file, located in ${CMAKE_PREFIX_PATH}/share/eigen3/cmake.

In response to @traversaro, I was using orocos_kdl from the vanilla ROS2 installation (https://github.com/ros2/orocos_kinematics_dynamics.git).

I cloned the repository directly from orocos, as you suggested, and had slightly different problems. Because I don't have a (native or cross-compiled...) FindEigen.cmake or EigenConfig.cmake, it wasn't finding anything.

Interestingly, even though the CMakeList.txt cloned directly from orocos uses find_package(Eigen 3 QUIET) (i.e., with a [space] between Eigen and 3), it still has a fallback to the in-repository copy of FindEigen3.cmake (note, not FindEigen.cmake):

https://github.com/orocos/orocos_kinematics_dynamics/blob/5145b19a7ed52cec59af9d6e626cb323f22b1b85/orocos_kdl/CMakeLists.txt#L48-L52