ros-perception / laser_geometry

Provides the LaserProjection class for turning laser scan data into point clouds.
BSD 3-Clause "New" or "Revised" License
157 stars 114 forks source link

[ros2] Hard-coded Eigen3 include path in laser_geometryExport.cmake results in an error during cross-compilation #94

Open lcschaeper opened 6 months ago

lcschaeper commented 6 months ago

Expected Behavior

Error-free compilation of ROS2 packages that depend on laser_geometry (e.g. nav2_costmap_2d) while using different Eigen3 header paths during the compilation of laser_geometry compared to the compilation of the dependent package.

Current Behavior

The Eigen3 header path is hard-coded through adding the Eigen3_INCLUDE_DIRS path to target_include_directories() in the CMakeLists.txt file. This results in a CMake Error in case the Eigen3 header path is different compared to the compilation of laser_geometry, because the header path gets hard-coded into the install/laser_geometry/share/laser_geometry/cmake/laser_geometryExport.cmake file.

Possible Solution

Remove line 25 from the CMakeLists.txt in the rolling, jazzy and ros2 branches due to the given redundancy and backporting the updated CMakeLists.txt file to the humble and iron branches to resolve this issue for all active releases.

Steps to Reproduce

  1. Clone the laser_geometry package into a local workspace
  2. Compile the package using colcon build
  3. Check the install/laser_geometry/share/laser_geometry/cmake/laser_geometryExport.cmake file if the hard-coded path /usr/include/eigen3 appears in the INTERFACE_INCLUDE_DIRECTORIES statement.

Detailed Description

The path to the Eigen3 headers is currently specified by adding the Eigen3_INCLUDE_DIRS path in the target_include_directories() statement of the CMakeLists.txt file. By using the Eigen3_INCLUDE_DIRS path in target_include_directories(), this path is hard-coded in the install/laser_geometry/share/laser_geometry/cmake/laser_geometryExport.cmake file: INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/laser_geometry;/usr/include/eigen3;${_IMPORT_PREFIX}/include"

If the code is executed on the build system or the path of the Eigen3 headers is identical to the build system, this problem does not occur. However, if you cross-compile with precompiled ROS2 packages, which in my case were generated by a Yocto build process, the hard-coded Eigen3 header path generates a compilation error because the laser_geometry package was compiled and installed with a different Eigen3 header path. The following error occurs:

CMake Error in CMakeLists.txt:
Imported target "laser_geometry::laser_geometry" includes non-existent path "<removed-build-host-path>/laser-geometry/2.4.0-2-r0/recipe-sysroot/usr/include/eigen3" in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include: 
* The path was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and references files it does not provide.

The problem occurred when I cross-compiled the nav2_costmap_2d package (which depends on this package) with ROS2 Humble and the corresponding Yocto SDK. I noticed that the Eigen3 header path is also hard-coded when I natively compile this package with ROS2 Humble or Rolling. In addition, the Eigen3 headers are included twice in the Rolling, Jazzy and ros2 branches in the CMakeLists.txt file. In the CMakeLists.txt file in line 25:

${Eigen3_INCLUDE_DIRS}

and by the if/else statement from line 31 onwards:

if(TARGET Eigen3::Eigen)
  target_link_libraries(laser_geometry PUBLIC Eigen3::Eigen)
else()
  target_include_directories(laser_geometry PUBLIC ${Eigen3_INCLUDE_DIRS})
endif()

Both statements can be removed separately without causing a compilation error. Therefore, I would assume that the statements are redundant to each other. The second statement from line 31 prevents the hardcoded path from being written in the laser_geometryExport.cmake file in case target_link_libraries(laser_geometry PUBLIC Eigen3::Eigen) can be used.

I assume that the Eigen3_INCLUDE_DIRS path should not be hard-coded in laser_geometryExport.cmake as mentioned in the following issue of the libeigen repo: With CMake, import CMake as a target instead of setting the include directories. To fix this, I would suggest removing line 25 from the CMakeLists.txt in the rolling, jazzy and ros2 branches due to the given redundancy and backporting the updated CMakeLists.txt file to the humble and iron branches to resolve this issue for all active releases.