0
$\begingroup$

Rosanswers logo

Hello there,

I have been fighting for some time with CMakeLists trying to compile a ROS 2 Eloquent package (bar) depending on a pure cmake package (foo) using colcon but I get the following error:

<...>/bar.hpp:5:10: fatal error: foo/foo.hpp: No such file or directory  
 #include "foo/foo.hpp"

I've made a minimal repo showing my problem here: https://github.com/MarcTestier/ros2_cmake_test.

The install folder of the cmake package (foo) seems somewhat normal though, its folder tree looks like this:

install/foo/  
├── include  
│   └── foo  
│       ├── foo.hpp  
│       └── foo_export.h  
├── lib  
│   └── libfoo.so  
└── share  
    ├── colcon-core  
    │   └── packages  
    │       └── foo  
    └── foo  
        ├── cmake  
        │   ├── fooConfig.cmake  
        │   ├── fooConfigVersion.cmake  
        │   ├── fooTargets-noconfig.cmake  
        │   └── fooTargets.cmake  
        ├── hook  
        │   ├── cmake_prefix_path.dsv  
        │   ├── cmake_prefix_path.ps1  
        │   ├── cmake_prefix_path.sh  
        │   ├── ld_library_path_lib.dsv  
        │   ├── ld_library_path_lib.ps1  
        │   ├── ld_library_path_lib.sh  
        │   ├── pkg_config_path.dsv  
        │   ├── pkg_config_path.ps1  
        │   ├── pkg_config_path.sh  
        │   ├── pkg_config_path_multiarch.dsv  
        │   ├── pkg_config_path_multiarch.ps1  
        │   └── pkg_config_path_multiarch.sh  
        ├── package.bash  
        ├── package.dsv  
        ├── package.ps1  
        ├── package.sh  
        └── package.zsh   

It seems like the ROS 2 package (bar) has trouble finding the cmake package (foo) library and headers but find_package(foo) works.

I found an ugly solution (available in the repo here) which consists of 2 steps:

1.Manually add the include directory

get_filename_component(INSTALL_DIR ${CMAKE_INSTALL_PREFIX} DIRECTORY)
include_directories(${INSTALL_DIR}/foo/include/)

If I only perform step 1, I can find the header files but I get an error: /usr/bin/ld: cannot find -lfoo which I guess means that even though I do the following:

target_link_libraries(Bar foo)

Bar still can't properly find the foo library.

2.If on top of the first step I link directly against the .so file:

target_link_libraries(Bar "${INSTALL_DIR}/foo/lib/libfoo.so")

Now the packages can compile but the solution seems a bit ugly.

I'm out of idea and I can't tell if the problem comes from a pure cmake problem, colcon moving/linking stuff around or anything else so any suggestions are welcomed, thanks.


Originally posted by Marc Testier on ROS Answers with karma: 203 on 2020-02-18

Post score: 1

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

Package foo is exporting the library target foo in the foo:: namespace.

# Export targets.
set(export_targets ${export_targets};${PROJECT_NAME})
export(
  EXPORT export_${PROJECT_NAME}
  FILE "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Targets.cmake"
  NAMESPACE ${PROJECT_NAME}::
)

But package bar is trying to link against exported library target foo with no namespace.

## Declare a cpp executable
add_executable(Bar src/bar.cpp)
ament_target_dependencies(Bar rclcpp)
target_link_libraries(Bar foo)

Change it to foo::foo to match what package foo is exporting

target_link_libraries(Bar foo::foo)

In case you see this again, when debugging CMake packages not finding another package's headers I find it's helpful to use CMAKE_VERBOSE_MAKEFILE.

colcon build --event-handlers console_direct+ --cmake-args -DCMAKE_VERBOSE_MAKEFILE=TRUE

That showed foo's include directory wasn't being passed to the compiler, which suggested I should look at pure CMake issues first.

[ 50%] Building CXX object CMakeFiles/Bar.dir/src/bar.cpp.o
/usr/bin/c++   -I/tmp/ros2_cmake_test/bar/include -I/opt/ros/eloquent/include  -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/Bar.dir/src/bar.cpp.o -c /tmp/ros2_cmake_test/bar/src/bar.cpp

After fixing the target name, foo's include directory is correctly passed to the compiler and the build succeeds.

[ 50%] Building CXX object CMakeFiles/Bar.dir/src/bar.cpp.o
/usr/bin/c++   -I/tmp/ros2_cmake_test/bar/include -I/opt/ros/eloquent/include -isystem /tmp/ros2_cmake_test/install/foo/include  -Wall -Wextra -Wpedantic -std=gnu++14 -o CMakeFiles/Bar.dir/src/bar.cpp.o -c /tmp/ros2_cmake_test/bar/src/bar.cpp

Originally posted by sloretz with karma: 3061 on 2020-02-18

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by Marc Testier on 2020-02-18:
It works, thank you for the help!!

Comment by Thomas D on 2020-10-29:
Saved me too. Thanks @sloretz!

$\endgroup$

Your Answer

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