ament / ament_cmake Goto Github PK
View Code? Open in Web Editor NEWSupporting CMake packages for working with ament
License: Apache License 2.0
Supporting CMake packages for working with ament
License: Apache License 2.0
Follow up of ros2/ros2#414.
A common pattern is to create a system test with a system under test and a gtest to poke it remotely.
The gtest is a part of the system test and will not work on it's own so should not be registered with it's own ctest target, but otherwise should be built the same way as ament_add_gtest.
The workaround is to add the executable and manually link it against GTEST_LIBRARIES. Since we're providing a function it would be nice to either have an argument to not autoregister it as a standalone test, or a second function to support this use case.
ament_cmake
function, let's call it ament_target_compile_options(target_name)
, which can be called after every add_library
or add_executable
call to set the compile option for each targetament_target_compile_options
ament_add_library/executable
(optional - see 3)ament_add_library/executable
or add ament_target_compile_options
after every add_library/executable
calladd_test
?There's a function in launch_testing that picks a ROS_DOMAIN_ID between 1 and 100 that's unique on a given machine that's used to run launch_tests in isolation.
I'd like to use the same mechanism to allow ament_cmake_test's run_test.py to provide isolation for gtests and pytests. run_test.py. I'd like to accomplish this by doing the following:
Before I start, I want to find out if anybody has strong opinions about this. @tfoote first mentioned solving this problem here ros2/launch#251 (review)
With CMake 3.3.1 (from brew on OSX), I get many warnings like this:
CMake Warning (dev) at /Users/gerkey/ros2_ws/install/share/ament_cmake_core/cmake/symlink_install/ament_cmake_symlink_install_targets.cmake:74 (get_property):
Policy CMP0026 is not set: Disallow use of the LOCATION target property.
Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The LOCATION property should not be read from target
"geometry_msgs__rosidl_typesupport_introspection_cpp". Use the target name
directly with add_custom_command, or use the generator expression
$<TARGET_FILE>, as appropriate.
Call Stack (most recent call first):
/Users/gerkey/ros2_ws/install/share/ament_cmake_core/cmake/symlink_install/install.cmake:34 (ament_cmake_symlink_install_targets)
/Users/gerkey/ros2_ws/install/share/rosidl_typesupport_introspection_cpp/cmake/rosidl_typesupport_introspection_cpp_generate_interfaces.cmake:110 (install)
/Users/gerkey/ros2_ws/install/share/ament_cmake_core/cmake/core/ament_execute_extensions.cmake:38 (include)
/Users/gerkey/ros2_ws/install/share/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake:148 (ament_execute_extensions)
CMakeLists.txt:38 (rosidl_generate_interfaces)
This warning is for project developers. Use -Wno-dev to suppress it.
Seems that we should either set CMP0026
or stop accessing the LOCATION
property in that way.
I am writing tests for my company's ros2 project.In order to run the test,I must launch other processess,such as realsense_ros2_camera
.I use ament test --only-packages my_package
to run the test.
In ros,we can use .test
to launch other processess and run the test automatically.
Is there any way to implement such a function in ros2?
Can't specify dependencies with ament_target_dependencies when adding a target via the cmake command add_test-
Error:
ament_target_dependencies() the first argument must be a valid target name
Call Stack (most recent call first):
ament_auto_package()
only supports two options, INSTALL_TO_PATH
and INSTALL_TO_SHARE
:
https://github.com/ament/ament_cmake/blob/master/ament_cmake_auto/cmake/ament_auto_package.cmake#L44
ament_package()
supports the options CONFIG_EXTRAS
, and CONFIG_EXTRAS_POST
:
https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/cmake/core/ament_package.cmake#L72
Presumably we'd want ament_auto_package
to support the same options, or am I missing some subtle build stuff?
create an ament_metapackage()
macro similar to catkin_metapackage()
to allow people to migrate them more easily. In the meantime we'll recommend to create classic ament_packages
This would be useful for setuptools generated python packages, so that they can make proper use of install_requires
in the setuptools script. One advantage of that, is that scripts will fail at runtime and warn you that 'package: ...' is not found on the python path. It uses pkg_resources
to find those dependencies.
Right now, it seems it finds everything except ament_cmake_python
packages (e.g. rclpy
) and message packages. Given that eggs are created for setuptools packages, possibly the thing to do is to write a temporary setuptools script and execute that instead of installing files directly?
The environment hook library_path.sh
does not get automatically added by ament_cmake
.
I am using the original composition demo as an example:
https://github.com/ros2/demos/tree/master/composition
In a simpler version of this demo composition_min.tar.gz the line:
ament_append_value AMENT_ENVIRONMENT_HOOKS "$AMENT_CURRENT_PREFIX/share/composition/environment/library_path.sh"
is missing from install/share/composition/local_setup.sh
which results in install/lib
being missing from LD_LIBRARY_PATH
.
library_path.sh
will only be added to AMENT_ENVIRONMENT_HOOKS
when rosidl_generate_interfaces(${PROJECT_NAME} "srv/LoadNode.srv")
is used in the cmake.
Blocks #178
I would expect target_link_libraries(my_target ${a_dependency_INTERFACES})
to link my_target
against all targets exported by a_dependency
if it used ament_export_interfaces()
, but currently this only works if the "export" name is the same as the target name. The variable ..._INTERFACES
is unusable if that assumption is violated.
This likely to happen because the ament_export_interfaces
also expects users to call install(TARGETS ... EXPORT name )
which is what gives the "export" it's name. For example, it looks like rosbag2_transport
violates this assumption.
ament_export_interfaces()
expects a list of "export" names as arguments.ament_package()
hook uses those names to call install(EXPORT ...)
to install the "export"s. This is fine.<project>Config.cmake
hook uses those names to include()
the installed exports. This is also fine.<project>Config.cmake
hook creates a variable ${PROJECT_NAME}_INTERFACES
containing <project>::<export>
. This is a problem
${..._INTERFACES}
will get an error like:
CMake Error at CMakeLists.txt:11 (add_executable):
Target "my_target" links to target "a_dependency::export_some_target" but the target was not
found. Perhaps a find_package() call is missing for an IMPORTED target, or
an ALIAS target is missing?
It seems likely that any fix for this will involve changing the ament_export_interfaces()
api. One option is to give it the targets that have been installed in an "export" so it can append those to the ..._INTERFACES
variable.
include(CTest)
with enable_testing()
(#150)
if(BUILD_TESTING)
option(BUILD_TESTING "..." ON)
below enable_testing()
would achieve the desired behavior; however, when running colcon test
we end up getting a bunch of warnings: e.g.$ colcon test --packages-select rcutils
...
--- stderr: rcutils
Cannot find file: /home/jp.samper/ros2_ws/build/rcutils/DartConfiguration.tcl
Problem reading custom configuration: /home/jp.samper/ros2_ws/build/rcutils/CTestCustom.ctest
Cannot find file: /home/jp.samper/ros2_ws/build/rcutils/DartConfiguration.tcl
---
CTestCustom.ctest
warning is coming from line 27 of ament_cmake_test-extras.cmake
ctest
invocation because of the -D ExperimentalTest
.
-D ExperimentalTest
from colcon_cmake
(https://github.com/colcon/colcon-cmake/blob/master/colcon_cmake/task/cmake/test.py#L71) would get rid of the warnings--ctest-args -D ExperimentalTest
to enable itcolcon
users using CDash? And how disruptive would it be to disable CDash by default and provide an option to enable it?Trying:
ament build --cmake-args -C `pwd`/config.cache
and getting back an error. At a first glance, presumably because there is a post-humourously added -DCMAKE_INSTALL_PREFIX
added after the -C instruction.
Running cmake because arguments have changed.
==> '. /mnt/mervin/workspaces/ecl_ws/build/ecl_license/cmake__build.sh && /usr/bin/cmake /mnt/mervin/workspaces/ecl_ws/src/ecl_tools/ecl_license -DBUILD_TESTING=0 -C /mnt/mervin/workspaces/ecl_ws/config.cache -DCMAKE_INSTALL_PREFIX=/mnt/mervin/workspaces/ecl_ws/install' in '/mnt/mervin/workspaces/ecl_ws/build/ecl_license'
loading initial cache file /mnt/mervin/workspaces/ecl_ws/config.cache
CMake Error: The source directory "/mnt/mervin/workspaces/ecl_ws/config.cache" is a file, not a directory.
I honestly haven't looked at this in detail yet - wondering if this has been tried and I'm just naive of what the method is, or I need to dive in and fix some bits.
At present, from the crystal
ros2 workspace, there are 43 instances of visibility_control.h*
:
$ cd ros2_ws/src
$ find . -name 'visibility_control.h*' | wc -l
43
Only one is the *.em
template file; the others only seem differ by the license header and the macro prefixes.
I could understand wanting to use project-specific visibility if it changes from project to project, but if it doesn't, wouldn't it make more sense to centralize them?
ament_cmake
seems like a good candidate, as it's a build dependency, and thus something like this:
#include <ament_cmake/visibility_control.h>
AMENT_EXPORT
AMENT_IMPORT
AMENT_PUBLIC
// etc.
seems fine to me?
Related comment:
ros2/rcpputils#4 (comment)
Since ament_target_dependencies
uses the non-keyword call to target_link_libraries
, by CMP0023, the keyword version is not allowed as well. This prevents me from declaring other target dependencies as PRIVATE
or PUBLIC
. Would it be desireable and/or straightforward to allow this, maybe just by adding a keyword option to ament_target_dependencies
?
I am using ament for ros2 and when I build using colcon the ament python files are executed with python2 and many errors arise. One such error is shown below:
Traceback (most recent call last):
File "/opt/ros/dashing/share/ament_cmake_core/cmake/package_templates/templates_2_cmake.py", line 21, in <module>
from ament_package.templates import get_environment_hook_template_path
File "/opt/ros/dashing/lib/python3.6/site-packages/ament_package/templates.py", line 43
def get_prefix_level_template_names(*, all_platforms=False):
^
SyntaxError: invalid syntax
CMake Error at /opt/ros/dashing/share/ament_cmake_core/cmake/ament_cmake_package_templates-extras.cmake:41 (message):
execute_process(/usr/bin/python2
/opt/ros/dashing/share/ament_cmake_core/cmake/package_templates/templates_2_cmake.py
/home/sudo-panda/Workspaces/eve_ros2/build/quanergy_client_ros/ament_cmake_package_templates/templates.cmake)
returned error code 1
Call Stack (most recent call first):
/opt/ros/dashing/share/ament_cmake_core/cmake/ament_cmake_coreConfig.cmake:38 (include)
/opt/ros/dashing/share/ament_cmake/cmake/ament_cmake_export_dependencies-extras.cmake:15 (find_package)
/opt/ros/dashing/share/ament_cmake/cmake/ament_cmakeConfig.cmake:38 (include)
CMakeLists.txt:7 (find_package)
Is there anyway to force ament to use python3 to build itself.
I also tried to resolve the error by removing the *
from the parameter list (bad idea, I know) but then another syntax error in a different place popped up.
Is it possible to determine inside a cmake file whether it was called via ament or directly via cmake ?
As a ros2 developer I also want to skip tests that are specified using ament_add_gmock()
.
Currently, the SKIP_TEST
option is only available for ament_add_gtest()
I'm interested in replacing multiple find_package()
calls in a package with a single call to ament_auto_find_build_dependencies
.
I noticed that in the implementation it is making find_package
calls with QUIET
, whereas I have been using it with REQUIRED
. Indeed REQUIRED
seems to be the standard thing in our code.
What is the reasoning for using QUIET
? Would changing it to REQUIRED
make sense?
I tried to use multiple DDS Vendors / use ament the right way in my project: https://github.com/firesurfer/ros2_simple_logger/blob/multiple/CMakeLists.txt
In this package I try to generate the messages and link to them. It worked before I tried to use multiple DDS middlewares. Now I get this linker error:
libros2_simple_logger_lib__rmw_opensplice_cpp.a(SimpleLoggerSubscriber.cpp.o): In function `rosidl_message_type_support_t const* rosidl_generator_cpp::get_message_type_support_handle<ros2_simple_logger::msg::LoggingMessage_<std::allocator<void> > >()':
/home/firesurfer/workspace/ros2_ws/install/include/rosidl_typesupport_opensplice_cpp/impl/rosidl_generator_cpp/message_type_support.hpp:52: undefined reference to `rosidl_message_type_support_t const* rosidl_typesupport_opensplice_cpp::get_message_type_support_handle_opensplice<ros2_simple_logger::msg::LoggingMessage_<std::allocator<void> > >()'
Could you point out what I'm doing wrong ?
ament_target_dependencies
includes headers by plainly using target_include_directories
:
Would it make sense to change this to be:
target_include_directories(${target} SYSTEM
PUBLIC ${ordered_include_dirs})
(i.e. https://cmake.org/cmake/help/v3.0/command/target_include_directories.html)
My use case is that I like to turn on as many warnings as possible for my own development. However, when I start depending on other packages, I get so many warnings that my signal to noise ratio becomes extremely low.
In files like https://github.com/ament/ament_cmake/blob/master/ament_cmake_export_libraries/cmake/ament_cmake_export_libraries-extras.cmake.in and https://github.com/ament/ament_cmake/blob/master/ament_cmake_export_include_directories/cmake/ament_cmake_export_include_directories-extras.cmake.in there are variables along the lines of @PROJECT_NAME@_LIBRARIES
which are appended to. Since they are not reset at the beginning of the file, this can cause issues when the variables have been populated ahead of calling the relevant find_package command, for example by ROS1 libraries.
Do you think it would make sense to clear the variables at the top of these files, to help avoid collisions?
It would be useful to get a list of exported targets from a find_package
- something that I do not think CMake currently provides for (e.g. see this stack overflow thread.
I expect it would be easy to get ament to include a variable, e.g. foo_EXPORTS
, to make this easier. This would be far better than relying on documentation/conventions/digging around share/<project>/cmake
to work out what's exported by a package.
If this is useful, I can submit a PR.
Python paths are not being correctly set when working with overlay workspaces and --symlink-install
option: the code of the underlay is still used after sourcing an overlay. The issue was spotted when using ament
through colcon
.
Example using ros2cli
(code for https://github.com/ros2/ros2cli cloned at ~/ros2cli_ws/src
; using ROS Crystal installed from binaries):
source /opt/ros/crystal/setup.bash
which ros2 # Points to /opt/ros/crystal/bin/ros2, which is OK
cd ~/ros2cli_ws
colcon build --symlink-install
source ~/ros2cli_ws/install/setup.bash # also tried with local_setup; no difference
which ros2 # Points to ~/ros2cli_ws/install/ros2cli/bin/ros2, which is OK
ros2 topic list # This uses the code in the underlay in `/opt/ros/crystal`, which is wrong.
PYTHONPATH
seems to be alright after sourcing both workspaces; the overlay (~/ros2cli_ws
) comes before the underlay (/opt/ros/crystal
):
PYTHONPATH=/home/juan/ros2cli_ws/install/ros2lifecycle/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2service/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2topic/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2srv/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2run/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2pkg/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2param/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2node/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2multicast/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2msg/lib/python3.6/site-packages:/home/juan/ros2cli_ws/install/ros2cli/lib/python3.6/site-packages:/opt/ros/crystal/lib/python3.6/site-packages
The problem seems to be sys.path
inside python:
>>> import sys
>>> sys.path
['', '/home/juan/ros2cli_ws/install/ros2lifecycle/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2service/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2topic/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2srv/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2run/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2pkg/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2param/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2node/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2multicast/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2msg/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/install/ros2cli/lib/python3.6/site-packages', '/opt/ros/crystal/lib/python3.6/site-packages', '/home/juan/ros2cli_ws/build/ros2lifecycle', '/home/juan/ros2cli_ws/build/ros2service', '/home/juan/ros2cli_ws/build/ros2topic', '/home/juan/ros2cli_ws/build/ros2srv', '/home/juan/ros2cli_ws/build/ros2run', '/home/juan/ros2cli_ws/build/ros2pkg', '/home/juan/ros2cli_ws/build/ros2param', '/home/juan/ros2cli_ws/build/ros2node', '/home/juan/ros2cli_ws/build/ros2multicast', '/home/juan/ros2cli_ws/build/ros2msg', '/home/juan/ros2cli_ws/build/ros2cli', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/dist-packages', '/usr/lib/python3/dist-packages']
In other words, /opt/ros/crystal*
is before ~/ros2cli_ws/build*
; therefore, the underlay code is the one being executed.
Repeating the build steps above without --symlink-install
option yields the following sys.path
:
>>> import sys
>>> sys.path
['', '/home/juan/testing/ros2cli_ws/install/ros2lifecycle/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2service/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2topic/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2srv/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2run/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2pkg/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2param/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2node/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2multicast/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2msg/lib/python3.6/site-packages', '/home/juan/testing/ros2cli_ws/install/ros2cli/lib/python3.6/site-packages', '/opt/ros/crystal/lib/python3.6/site-packages', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/juan/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/wx-3.0-gtk3']
As the actual python code is copied into the install space, the overlay code is the one used in this case which is OK.
I have a ROS 2 package that uses ament_cmake_auto
to take care of installing its libraries and executables (amcl)
This causes the executables to be installed like this:
https://github.com/ament/ament_cmake/blob/dde5df8104073ff47aa96e482118adb6a03323f5/ament_cmake_auto/cmake/ament_auto_package.cmake#L62..L69
ROS 2 packages are currently being updated to install to "libexec" instead of bin.
Is it appropriate to add an option to ament_cmake_auto
to install executables to lib/${PROJECT_NAME}
? It seems to be something that may be useful in other projects, but perhaps the functionality is too ROS-specific to belong in this package?
Specific example and discussion at stonier/ecl_core#72.
I've got a multi-package project that I'm working on migrating from ROS1 catkin.
The project topology is
A(library) -> B(executable) -> C(plugin), D(plugin), E(plugin)...
Packages A and B build just fine, but when I try to reference B_INCLUDE_DIRS in package C, it's not what I expect.
Currently, I have ament_export_include_dirs(include)
in package B CMakeLists.
My understanding is that when C is built, B_INCLUDE_DIRS should be just /home/.../workspace/install/include
, but when I output it to screen, it contains /opt/ros/ardent/include/home/.../workspace/install/include/home/.../workspace/install/include
.
If I remove the ament_export_include_dirs(include)
from package B so no include dirs are exported, then B_INCLUDE_DIRS (when building C) contains /opt/ros/ardent/include/home/.../workspace/install/include/
Working on Ubuntu 16.04 64-bit.
I was able to successfully build and run the full ros2 and tests before I started migrating this project.
If necessary, I can provide the CMakeLists files.
This manifested in this pr: ros2/rviz#243
Basically, the urdf from somewhere like /usr/include
(not sure exactly where from) when they should have been found in the workspace where rviz was being built.
Catkin had a way to deal with this by sorting include directories by workspace folder order, placing all include paths outside of any of the workspaces last in the order. ament_cmake
should provide a function to emulate this behavior in order to better support overlaying.
@mikaelarguedas or @dirk-thomas feel free to add more details if you have them.
Also, this new function should either be used everywhere or at least where it has been a problem before, and in either case the pr linked above should be fixed with this function as well.
AC:
This is meant for internal development documentation, not final end user docs.
Look for William's existing documentation
May I ask if it's possible to force CMake to link with RPATHs?
Here's my current attempt:
https://github.com/EricCousineau-TRI/repro/blob/50b26e2/ros/ros2_bazel_prototype/NOTES.md
Some commentary:
rclcpp
, rcl
, rcutils
, std_msgs
).Random editorial: TTBOMK, the ROS packaging philosophy is to strip the RPATHs to permit hot-swapping libs; however, I would still like to make C++ binaries fully specified without needing special environment variables, esp. relevant to usage with Bazel (relates ).
May tangentially relate ros2/ros2#457
BTW Please let me know if I'm using "RPATH" terminology incorrectly... I more-or-less just pattern match when I see this word + shell commands.
UPDATE: Posted an update in colcon/colcon-bazel#14 about using Bazel to resolve the paths, and some rmw
stuff.
I've got the current set of ros2 repos (plus one or two) on my machine. I'm getting an error when I try to source my workspace as follows.
> call install\setup.bat
The input line is too long.
The syntax of the command is incorrect.
By setting COLCON_TRACE
, I was able to track down the failure point to rqt_publisher
, and, ikn particular, during the addition of environment hooks.
This line in particular seems to be the issue. I expanded my variable and found that the number of characters in it is indeed approaching the limit for the windows command prompt line length limit (which is 8191 due to siliness).
I'm not entirely sure what to do about this, so I figured I'd open an issue to discuss a good way to fix it. I'm perfectly willing to patch this, but I would like to probe @dirk-thomas's brain for a good suggestion as to which approach I should take.
The ament_add_test
(and related) macros have options like ENV
and APPEND_ENV
, where you can pass multiple environment variables to be set in the environment or appended to the environment of the test. For example:
ament_add_test(test_name
# other arguments...
ENV FOO=bar PING=C:\pong;C:\pow
)
The problem is that on Windows the PATH-like values are separated with ;
. Because of this CMake parses these as lists. So the value for the ENV
argument above becomes a list like this:
FOO=bar
PING=C:\pong
C:\pow
When what we wanted was:
FOO=bar
PING=C:\pong;C:\pow
This is complicated by the fact that these need to be passed through a few layers, e.g. ament_add_nose
-> ament_add_test
-> python run_test.py <arguments>
.
I tried (in #65 and ros2/rclpy#13) to escape the ;
as \;
and I tried using quoting around the PATH-like string to make CMake avoid interpretting it as a list, but I was not able to do it. Perhaps I was doing it wrong. I ended up working around the issue by not passing a list of path's, but instead appending a single element to one env var.
Either way, there is no clear way to do this in a way that works on Windows of which I am aware. We may need to consider changing the design of the interface to accommodate the functionality.
Implicitly linking a library through ament_cmake by importing a package that uses ament_export_libraries
will cause that library target's INTERFACE_LINK_LIBRARIES to be ignored.
Say I create a library with
cmake_minimum_required(VERSION 3.5)
project(ProjectA)
add_library(LibA my_library.cpp)
target_link_libraries(LibA PUBLIC systemLib)
# ...
ament_export_libraries(LibA)
ament_package()
Then including this library downstream with:
ament_target_dependencies(LibB LibA)
will cause a link-time error, as systemLib
is not recursively linked.
On the other hand, this does cause systemLib
to get linked:
find_package(ProjectA REQUIRED)
target_link_libraries(LibB ProjectA::LibA)
It is expected that ament_cmake will respect the standard interface link property.
I have a CMake build that builds several ament packages. Currently each subproject calls
find_package(ament_cmake REQUIRED)
Which fails the build with this error message:
CMake Error at ~/ros2-linux/share/ament_cmake_core/cmake/ament_cmake_uninstall_target-extras.cmake:35 (add_custom_target):
add_custom_target cannot create target "uninstall" because another target
with the same name already exists. The existing target is a custom target
created in source directory
"~/Jenkins/workspace/Branch-OI7ZPASJZEV3XGQWBFQY2PEQXIELKYENI5G6JZQZXQR3CPC6F5NA@2/tests/eclipseProject/algos/testsProto/subscriber/ros".
See documentation for policy CMP0002 for more details.
Call Stack (most recent call first):
~/ros2-linux/share/ament_cmake_core/cmake/ament_cmake_coreConfig.cmake:30 (include)
~/ros2-linux/share/ament_cmake/cmake/ament_cmake_export_dependencies-extras.cmake:15 (find_package)
~/ros2-linux/share/ament_cmake/cmake/ament_cmakeConfig.cmake:30 (include)
algos/testsProto/subscriberDefault/ros/CMakeLists.txt:16 (find_package)
I would expect the amen_cmakeConfig.cmake to check whether ament_cmake was already found, and in that case not do anything, or something like that.
Version is 0.4.0
The incorrect behavior occurs on OS X and Linux. Building any package which installs a shared library with the following CMake snippet:
install(
TARGETS my_shared_library
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
Will install the .dylib
or .so
files to <prefix>/bin
rather than <prefix>/lib
if the symbolic link install is used. With the normal CMake install files are installed as expected. It's probably related to this part of the behavior of CMake's install(...)
macro:
http://www.cmake.org/cmake/help/v3.0/command/install.html
The code:
install(TARGETS myExe mySharedLib myStaticLib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
install(TARGETS mySharedLib DESTINATION /some/full/path)will install myExe to /bin and myStaticLib to /lib/static. On non-DLL platforms mySharedLib will be installed to /lib and /some/full/path. On DLL platforms the mySharedLib DLL will be installed to /bin and /some/full/path and its import library will be installed to /lib/static and /some/full/path.
This can be reproduced by building the latest (currently windows branches, but soon master) ros2 workspace with the --symlink-install
option. This wasn't a problem before because a line was previously excluded from the install(...)
call which hid the problem:
install(
TARGETS rosidl_typesupport_introspection_cpp
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
However, the above snippet is not sufficient on Windows, since the .dll
files are then not installed, but just the .lib
files.
Continuing on the thread from https://groups.google.com/forum/#!topic/ros-sig-ng-ros/bhAMgFCIOnE, MSVC has a powerful debugger but ament makes it difficult to use it. Running in RelWithDebInfo mode allows basic debugging, but it diminishes the utility of Visual Studio: https://github.com/geoffviola/undefined_behavior_study.
It would be nice if ament named libraries differently based on the CMAKE_BUILD_TYPE. Boost libraries have a standard on suffixes it applies to libraries: http://www.boost.org/doc/libs/1_63_0/more/getting_started/windows.html#library-naming. Also, conan addressed this problem: conan-io/conan#330.
Maybe, when the a library is exported, it does something like
set_target_properties(${TARGET_NAME} PROPERTIES DEBUG_POSTFIX "D")
set_target_properties(${TARGET_NAME} PROPERTIES RELEASE_POSTFIX "S")
@clalancette noticed that if building in isolated mode, the LD_LIBRARY_PATH
does not get set when only using ament_export_interfaces(...)
and not ament_export_libraries(...)
.
See stonier/ecl_core#73 for context and discussion.
Seems redundant to have to additionally set the export_libraries
, is this intended?
See the code below
ament_cmake/ament_cmake_core/cmake/symlink_install/install.cmake
Lines 15 to 21 in 4e46886
The argument signature
is not documentated at all.
Currently if someone calls install(DIRECTORY)
with a PATTERN ...
option it falls through the symlink install wrapper and just uses the built-in CMake install()
function.
Normally I would say that not supporting that is ok, but since the ament_python_install_*
functions call install like this:
install(
DIRECTORY "${ARG_PACKAGE_DIR}/"
DESTINATION "${PYTHON_INSTALL_DIR}/${package_name}"
PATTERN "*.pyc" EXCLUDE
PATTERN "__pycache__" EXCLUDE
)
That means the Python code is not symlink'ed. Therefore I think we should implement this.
This was particularly confusing because parts of a package will get symlink installed and others will not.
Implement symlinks via built-in mklink
console command that apparently has minimum restrictions.
ament.py test
can build and run gtests on an empty workspace. However after a workspace has been populated, any subsequent runs will fail to find gtest.lib
:
11>InitializeBuildStatus:
Creating "ament_index_cpp_utest.dir\Debug\ament_in.4C53B27F.tlog\unsuc
cessfulbuild" because "AlwaysCreate" was specified.
CustomBuild:
All outputs are up-to-date.
ClCompile:
All outputs are up-to-date.
Link:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\link.
exe /ERRORREPORT:QUEUE /OUT:"C:\dev\ros2\build\ament_index_cpp\Debug\a
ment_index_cpp_utest.exe" /INCREMENTAL /NOLOGO kernel32.lib user32.lib
gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib co
mdlg32.lib advapi32.lib gtest.lib gtest_main.lib Debug\ament_index_cpp
.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /mani
fest:embed /Debug /PDB:"C:/dev/ros2/build/ament_index_cpp/Debug/ament_
index_cpp_utest.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPA
T /IMPLIB:"C:/dev/ros2/build/ament_index_cpp/Debug/ament_index_cpp_ute
st.lib" /MACHINE:X64 /machine:x64 /debug ament_index_cpp_utest.dir\De
bug\utest.obj
11>LINK : fatal error LNK1104: cannot open file 'gtest.lib' [C:\dev\ros2\bu
ild\ament_index_cpp\ament_index_cpp_utest.vcxproj]
11>Done Building Project "C:\dev\ros2\build\ament_index_cpp\ament_index_cpp
_utest.vcxproj" (default targets) -- FAILED.
4>Done Building Project "C:\dev\ros2\build\ament_index_cpp\ament_index_cpp
_utest.vcxproj.metaproj" (default targets) -- FAILED.
2>Done Building Project "C:\dev\ros2\build\ament_index_cpp\ALL_BUILD.vcxpr
oj.metaproj" (default targets) -- FAILED.
1>Done Building Project "C:\dev\ros2\build\ament_index_cpp\ament_index_cpp
.sln" (default targets) -- FAILED.
Build FAILED.
"C:\dev\ros2\build\ament_index_cpp\ament_index_cpp.sln" (default target)
(1) ->
"C:\dev\ros2\build\ament_index_cpp\ament_index_cpp_utest.vcxproj.metapro
j" (default target) (4) ->
"C:\dev\ros2\build\ament_index_cpp\ament_index_cpp_utest.vcxproj" (defau
lt target) (11) ->
(Link target) ->
LINK : fatal error LNK1104: cannot open file 'gtest.lib' [C:\dev\ros2\
build\ament_index_cpp\ament_index_cpp_utest.vcxproj]
0 Warning(s)
1 Error(s)
Time Elapsed 00:00:03.56
<== Command 'C:\dev\ros2\build\ament_index_cpp\cmake__build.bat C:\Program Files
(x86)\MSBuild\14.0\bin\amd64\msbuild.EXE /m C:\dev\ros2\build\ament_index_cpp\a
ment_index_cpp.sln' failed with exit code '1'
C:\dev\ros2>
In the migration guide it says:
The CATKIN_DEPENDS and DEPENDS arguments are passed to the new function
ament_export_dependencies
.
This statement doesn't quite work out in practice in all situations. In particular, catkin's DEPENDS
arguments could create find-able dependencies on the fly from xxx_INCLUDE_DIRS
and xxx_LIBRARIES
.
DEPENDS (list of strings) โ a list of CMake projects which this project depends on. Since they might not be find_packagable or lack a pkg-config file their INCLUDE_DIRS and LIBRARIES are passed directly. This requires that it has been find_package-ed before and all variables (_FOUND, _INCLUDE_DIRS, etc.) have the same case as this argument.
Ament's seem to exactly require a CMake find-package module lying around somewhere. From ament_export_dependencies.cmake:
Each package name must be find_package()-able with the exact same case.
Will there be any provision for doing similar with ament, or is the recommendation to create something like a FindFoo.cmake module and pass it into ament_package(CONFIG_EXTRAS ...)
? If the latter, might be worth a mention in the migration guide.
For example, catkin had an assumption that make is being used so using generators other than make isn't well supported in catkin. Please consider making sure things such as this work from the start with new software.
An explanation of what a resource is within this context, and why it is important, would help people with different experience who are not familiar with the purpose or need for the indexing capability. Possibly with some additional examples. I think the mention of Rviz plugins is a bit weak at the moment due to lack of these definitions.
for example, if I understand what this indexing does, it sounds like a tool to replace Process which may be an issue for larger organizations. In our design process, resources are defined within System Design Documents. These docs in turn have to be approved through Design Review with the customer prior to writing code, and changes need to go through a change order process during development. In the research programs we manage (which include ROS and other middleware systems) it was been determined through experience that the simplest way to communicate resources is to have it defined in a document which can be linked or emailed as appropriate. So if I have the document, what do I need a tool for?
Is there any implementation in ament which can download data (like .pcd files) similar to catkin_download ?
Currently ament_cmake
does not set PKG_CONFIG_PATH
for searching for pkg config files. This is relevant for plain cmake libraries that install *.pc
files to install/lib/pkgconfig
.
At the moment, I am setting PKG_CONFIG_PATH
manually in CMakeLists.txt
by
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CMAKE_INSTALL_PREFIX}/lib/pkgconfig")
in projects that depend on plain cmake libraries which install pkg-config files. However, this is limited to packages of the same workspace.
ament
should append install/lib/pkgconfig
of workspaces to PKG_CONFIG_PATH
.
See the comment and code below
ament_cmake/ament_cmake_core/cmake/core/ament_package.cmake
Lines 39 to 40 in 4e46886
ament_cmake/ament_cmake_core/cmake/core/ament_package.cmake
Lines 84 to 89 in 4e46886
I get these warning all over the place when compiling on windows. This iterates over a couple of libraries such as ddsutil
, ddsserialization
, etc.
CMake Warning at C:/dev/ros2_src/install/share/std_msgs/cmake/ament_cmake_export_libraries-extras.cmake:116 (message):
Package 'std_msgs' exports library 'ddsuser' which couldn't be found
Call Stack (most recent call first):
C:/dev/ros2_src/install/share/std_msgs/cmake/std_msgsConfig.cmake:30 (include)
CMakeLists.txt:14 (find_package)
It looks to me I am not sourcing something correctly.
When trying to find_package(rviz_common)
, I get the following error
CMake Error in CMakeLists.txt:
Imported target "rviz_common::rviz_common" includes non-existent path
"/home/jenkins-agent/workspace/packaging_linux/ws/install/include"
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.
This happens when I try to build using osrf/ros2:nightly
docker image or just use https://ci.ros2.org/view/packaging/job/packaging_linux/lastSuccessfulBuild/artifact/ws/ros2-package-linux-x86_64.tar.bz2
directly.
I believe the problem is that the binary packages are built in a certain location on the CI machine. When they get extracted to the new location in the docker image or on my local machine, the path is now incorrect. It seems there is a variable used in the setup scripts (COLCON_CURRENT_PREFIX
) that is supposed to override the as-built path, but it doesn't seem to work for the INTERFACE_INCLUDE_DIRECTORIES
variable.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.