Fix numerous inconsistencies in ament-cmake-docs w.r.t installation of linkage, and target installation - #3805
Conversation
| .. code-block:: cmake | ||
|
|
||
| cmake_minimum_required(VERSION 3.5) | ||
| cmake_minimum_required(VERSION 3.14) |
There was a problem hiding this comment.
Let's require cmake 3.14 so we can take advantage of the default ARCHIVE install directory that GNUInstallDirs provides in CMake >=3.14. This can safely be backported to humble.
| PUBLIC | ||
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
| $<INSTALL_INTERFACE:include>) | ||
| "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>") |
There was a problem hiding this comment.
This matches what colcon recommends for the build interface: https://colcon.readthedocs.io/en/released/user/overriding-packages.html#install-headers-to-a-unique-include-directory
The install interface is set during installation instead, which is cleaner because you only need to type it once.With target_include_directories, if you have multiple libraries, the previous approach created a lot of code duplication.
There was a problem hiding this comment.
I'm fairly certain we also need the INSTALL_INTERFACE generator, updated to be include/${PROJECT_NAME}. I can't remember the specifics, but I'm pretty sure you need both to handle all situations, and all of our core code currently does this. @sloretz do you remember why we need both the BUILD_INTERFACE and the INSTALL_INTERFACE generator here?
There was a problem hiding this comment.
Removed the changes from this PR in b0fce5c, now it matches exactly what the colcon docs show for both setting the include directories for the target as well as installing the header files.
There was a problem hiding this comment.
@sloretz do you remember why we need both the BUILD_INTERFACE and the INSTALL_INTERFACE generator here?
target_include_directories(foolib ... $<BUILD_INTERFACE:...> makes sure other targets in the same package are able to include headers from the current package's source space by just depending on foolib. $<INSTALL_INTERFACE:...> makes sure targets in downstream packages are able to include this package's headers from the install space by just depending on foolib.
Based on the docs it looks like we could safely replace $<INSTALL_INTERFACE:...> with install(TARGET ... INCLUDES DESTINATION ...). Both are adding the paths to the headers in the install space to INTERFACE_INCLUDE_DIRECTORIES on the installed target.
There was a problem hiding this comment.
All right, that's fair.
That said, I do think we should stick for now with making this PR update to what we are actually doing in our sources, which is to use the INSTALL generator. As I said in my overall comment, we can think about switching away from that, but that should be done in the code first, then the documentation can follow.
There was a problem hiding this comment.
Ok, the PR reflects the current state of the system best, as-is.
There was a problem hiding this comment.
Yep, it's just a matter of when/how you set the INTERFACE_INCLUDE_DIRECTORIES property.
| TARGETS my_library my_node | ||
| EXPORT my_libraryTargets | ||
| LIBRARY DESTINATION lib | ||
| ARCHIVE DESTINATION lib |
There was a problem hiding this comment.
CMake 3.14 minimum allows us to stop specifying LIBRARY and ARCHIVE dirs since they default to this when using GNUInstallDirs. Now, we only recommend changing values that MUST be overridden from defaults.
| RUNTIME DESTINATION bin | ||
| INCLUDES DESTINATION include | ||
| RUNTIME DESTINATION lib/${PROJECT_NAME} | ||
| INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} |
There was a problem hiding this comment.
Instead of hard coding include, I use the one from GNUInstallDirs. This could give more flexibility for packaging maintainers, but should not change current behavior.
There was a problem hiding this comment.
This has been changed back due potential risks for GNUInstallDirs. Now, the only modification is the addition of ${PROJECT_NAME} which fixes the inconsistency with colcon
| Take special care to override the default RUNTIME directory for nodes. This allows the nodes to be started with ``ros2 run``. | ||
| Additionally, the include directory is custom to support overlays in ``colcon``. | ||
|
|
||
| Add all the nodes and libraries for your project to the ``TARGETS`` argument. |
There was a problem hiding this comment.
I feel like this is important to add and demonstrate, otherwise you get people calling install multiple times, once for each target, not realizing you can add multiple targets to the export set.
clalancette
left a comment
There was a problem hiding this comment.
Thanks for opening this! We definitely need this update.
I've added a couple of comments below.
| PUBLIC | ||
| $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
| $<INSTALL_INTERFACE:include>) | ||
| "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>") |
There was a problem hiding this comment.
I'm fairly certain we also need the INSTALL_INTERFACE generator, updated to be include/${PROJECT_NAME}. I can't remember the specifics, but I'm pretty sure you need both to handle all situations, and all of our core code currently does this. @sloretz do you remember why we need both the BUILD_INTERFACE and the INSTALL_INTERFACE generator here?
|
|
||
| .. code-block:: cmake | ||
|
|
||
| include(GNUInstallDirs) |
There was a problem hiding this comment.
I think we shouldn't do this, at least not yet.
That is, what I think we should do first is to update this document to reflect our current best practices. Since we don't use GNUInstallDirs in most places in the core sources, I would suggest not doing that here. Also, my understanding is that GNUInstallDirs will have some knock-on effects, like on RHEL and Windows (see ros2/rosidl#754). Because of those things, let's stick with the regular install stanza for now.
If we want to explore using GNUInstallDirs, we can definitely do that, but I think we'd want to have that conversation elsewhere, probably in a issue on https://github.com/ros2/ros2
There was a problem hiding this comment.
Can do, I'd rather get the glaring issues fixed with header and executable installs not aligning with the needs of colcon overlays and ros2 CLI node search path, then we can cover GNUInstallDirs later. Thanks for the cross-reference.
There was a problem hiding this comment.
Removed usage of GNUInstallDirs in b0fce5c
* Nodes need a special RUNTIME directory to be recognized by ROS 2 CLI * The order of creating the export set and using it was not intuitive * target_link_libraries was missing linkage type which is not recommended * It did not show to install nodes and libraries at the same time * The installation of headers was overly complex since the install directory is the same for all headers * HAS_LIBRARY_TARGET wasn't explained that it's only needed if you are installing libraries Signed-off-by: Ryan Friedman <ryanfriedman5410+github@gmail.com>
Signed-off-by: Ryan Friedman <ryanfriedman5410+github@gmail.com>
Signed-off-by: Chris Lalancette <clalancette@gmail.com>
b0fce5c to
6bf7149
Compare
clalancette
left a comment
There was a problem hiding this comment.
@Ryanf55 FYI, I just pushed a commit here which somewhat redoes what you did.
In particular:
- I put us back to cmake minimum of 3.8, since that is what our
ros2 pkg creategenerator creates right now. - I've removed most of the discussion about installing executables and nodes. While I do think we should add that in, I also think that it should be in an entirely new section explicitly discussing that. Once we get this in, I'll go ahead and open a new PR with those changes.
- I ended up changing the
RUNTIME DESTINATIONback tobinfor the library section. On Windows, it is actually imperative that libraries go intobin, otherwise they aren't considered DLL artifacts. This is the main reason why we need a separate section for executables, since they go into a different place.
With those changes, I'm happy with this, so I'll approve. But I'd like to hear your opinion on this PR as-is before I go ahead and merge.
LGTM, sounds like a plan. Your changes look good. |
Thanks for the quick review! I'll go ahead and merge this (and backport to the stable distributions), and then I'll open up a new PR in a little while here. |
…f linkage, and target installation (#3805) * Fix numerous inconsistencies in ament-cmake-docs * Nodes need a special RUNTIME directory to be recognized by ROS 2 CLI * The order of creating the export set and using it was not intuitive * target_link_libraries was missing linkage type which is not recommended * It did not show to install nodes and libraries at the same time * The installation of headers was overly complex since the install directory is the same for all headers * HAS_LIBRARY_TARGET wasn't explained that it's only needed if you are installing libraries * Updates from review. Signed-off-by: Ryan Friedman <ryanfriedman5410+github@gmail.com> Signed-off-by: Chris Lalancette <clalancette@gmail.com> (cherry picked from commit 42ccd72)
…f linkage, and target installation (#3805) * Fix numerous inconsistencies in ament-cmake-docs * Nodes need a special RUNTIME directory to be recognized by ROS 2 CLI * The order of creating the export set and using it was not intuitive * target_link_libraries was missing linkage type which is not recommended * It did not show to install nodes and libraries at the same time * The installation of headers was overly complex since the install directory is the same for all headers * HAS_LIBRARY_TARGET wasn't explained that it's only needed if you are installing libraries * Updates from review. Signed-off-by: Ryan Friedman <ryanfriedman5410+github@gmail.com> Signed-off-by: Chris Lalancette <clalancette@gmail.com> (cherry picked from commit 42ccd72)
…f linkage, and target installation (#3805) (#3810) * Fix numerous inconsistencies in ament-cmake-docs * Nodes need a special RUNTIME directory to be recognized by ROS 2 CLI * The order of creating the export set and using it was not intuitive * target_link_libraries was missing linkage type which is not recommended * It did not show to install nodes and libraries at the same time * The installation of headers was overly complex since the install directory is the same for all headers * HAS_LIBRARY_TARGET wasn't explained that it's only needed if you are installing libraries * Updates from review. Signed-off-by: Ryan Friedman <ryanfriedman5410+github@gmail.com> Signed-off-by: Chris Lalancette <clalancette@gmail.com> (cherry picked from commit 42ccd72) Co-authored-by: Ryan <ryanfriedman5410+github@gmail.com>
…f linkage, and target installation (#3805) (#3811) * Fix numerous inconsistencies in ament-cmake-docs * Nodes need a special RUNTIME directory to be recognized by ROS 2 CLI * The order of creating the export set and using it was not intuitive * target_link_libraries was missing linkage type which is not recommended * It did not show to install nodes and libraries at the same time * The installation of headers was overly complex since the install directory is the same for all headers * HAS_LIBRARY_TARGET wasn't explained that it's only needed if you are installing libraries * Updates from review. Signed-off-by: Ryan Friedman <ryanfriedman5410+github@gmail.com> Signed-off-by: Chris Lalancette <clalancette@gmail.com> (cherry picked from commit 42ccd72) Co-authored-by: Ryan <ryanfriedman5410+github@gmail.com>

Relates to ros2/ros2cli#845
It would be a good idea to make these changes to an autogenerated package and check the includes are still working as expected. I understand the other tutorials and
ros2 pkg createcould also use an update to match, and can do that work once we're happy with it.This work was contributed on behalf of AeroVironment, Inc.