-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix numerous inconsistencies in ament-cmake-docs w.r.t installation of linkage, and target installation #3805
Fix numerous inconsistencies in ament-cmake-docs w.r.t installation of linkage, and target installation #3805
Conversation
@@ -29,7 +29,7 @@ The basic outline of the ``CMakeLists.txt`` of an ament package contains: | |||
|
|||
.. code-block:: cmake | |||
|
|||
cmake_minimum_required(VERSION 3.5) | |||
cmake_minimum_required(VERSION 3.14) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, the PR reflects the current state of the system best, as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it's just a matter of when/how you set the INTERFACE_INCLUDE_DIRECTORIES property.
EXPORT my_libraryTargets | ||
LIBRARY DESTINATION lib | ||
ARCHIVE DESTINATION lib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]>
Signed-off-by: Ryan Friedman <[email protected]>
Signed-off-by: Chris Lalancette <[email protected]>
b0fce5c
to
6bf7149
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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 create
generator 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 DESTINATION
back tobin
for 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 <[email protected]> Signed-off-by: Chris Lalancette <[email protected]> (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 <[email protected]> Signed-off-by: Chris Lalancette <[email protected]> (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 <[email protected]> Signed-off-by: Chris Lalancette <[email protected]> (cherry picked from commit 42ccd72) Co-authored-by: Ryan <[email protected]>
…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 <[email protected]> Signed-off-by: Chris Lalancette <[email protected]> (cherry picked from commit 42ccd72) Co-authored-by: Ryan <[email protected]>
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 create
could 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.