-
Notifications
You must be signed in to change notification settings - Fork 126
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
Misc cleanup in the rosidl generator extensions #662
Conversation
I don't see these failures in my focal container, but the PR job is the first one ever on Jammy https://build.ros2.org/job/Rpr__rosidl__ubuntu_jammy_amd64/1 . I'll try making a Jammy container and reproducing there. |
I get the same test failures on Jammy, with and without this PR - so they're not caused by it. Still, those will need to be fixed for green CI. |
71ba58a
to
eb98af1
Compare
@ros-pull-request-builder retest this please |
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 did a review of this, and I left two comments inline. Both of them are really questions since I'm not that familiar with how all of this works. It may be a good idea to get another review from someone like @hidmic before going ahead with this.
if(NOT rosidl_generate_interfaces_SKIP_INSTALL) | ||
ament_export_dependencies(${_pkg_name}) | ||
endif() |
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 is my first time looking at this code, so take this with a grain of salt. If we stop calling ament_export_dependencies
for the recursive dependencies, can't we get into a situation where we aren't including the correct targets? That is, if msg package A depends on msg package B, shouldn't it express that dependency to things depending on A? Or is there another mechanism that will cause that to automatically happen?
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.
rosidl_generate_interfaces()
already calls ament_export_dependencies()
on these. This removes rosidl_generator_c
doing it an extra time.
${rosidl_generate_interfaces_TARGET} | ||
${rosidl_generate_interfaces_TARGET}${_target_suffix}) |
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.
It's unclear to me why we need both of these. Could you explain a bit more (and maybe add a comment)?
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.
When a package calls rosidl_generate_interfaces(foobar
they're passing in a name to create for a top-level interface generation target. That target name is passed to the individual generators in the variable ${rosidl_generate_interfaces_TARGET}
. Each generator creates their own target to do message generation, and they all do the same pattern where they define a variable called _target_suffix
and then make their generator specific target with the name ${rosidl_generate_interfaces_TARGET}${_target_suffix}
. The second add_dependencies()
target is making the top level target depend on the generator specific target. That way, any other target that depends on the top level target will wait until all generators finish before being built. That's part of how targets can use generated messages in the same package.
rosidl_generator_cpp
only generates headers, so it's library target is a header only library, which in CMake is an INTERFACE
library. CMake doesn't provide a way for an INTERFACE
library to directly depend on a file, so there's nothing to make targets who depend on the INTERFACE
library wait for the header files to be generated. To solve this, rosidl_generator_cpp
creates an extra custom target called ${rosidl_generate_interfaces_TARGET}__cpp
. CMake does allow custom targets to depend on generated files, and that's all this one does. The first add_dependency()
makes the generator's INTERFACE
library depend on that custom target so that anyone who depends on the library will wait to be built until the headers are generated.
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.
Added comments explaining these in 8a433e9
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
8a433e9
to
c43822e
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.
Only a couple nits. Overall LGTM
PRIVATE "ROSIDL_GENERATOR_C_BUILDING_DLL_${PROJECT_NAME}") | ||
endif() | ||
target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix} | ||
PRIVATE "ROSIDL_GENERATOR_C_BUILDING_DLL_${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.
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.
Oh oops. I read that header wrong.
Interestingly CMake has a target property for this already called DEFINE_SYMBOL
. It adds the compiler definition <target_name>_EXPORTS
by default, setting the property changes it. I changed it to use that property instead in 519066b
|
||
install( | ||
TARGETS ${rosidl_generate_interfaces_TARGET}${_target_suffix} | ||
EXPORT ${rosidl_generate_interfaces_TARGET}${_target_suffix} | ||
EXPORT export_${rosidl_generate_interfaces_TARGET}${_target_suffix} |
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 nit: why add an export_
suffix here but not for rosidl_generator_c
?
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 inconsistent. Added export_
in 368d022
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
PRIVATE "ROSIDL_TYPESUPPORT_INTROSPECTION_C_BUILDING_DLL_${PROJECT_NAME}") | ||
endif() | ||
target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix} | ||
PRIVATE "ROSIDL_TYPESUPPORT_INTROSPECTION_C_BUILDING_DLL_${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.
@sloretz shall we use DEFINE_SYMBOL
here too?
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.
PRIVATE "ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_BUILDING_DLL") | ||
endif() | ||
target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix} | ||
PRIVATE "ROSIDL_TYPESUPPORT_INTROSPECTION_CPP_BUILDING_DLL") |
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 same about using DEFINE_SYMBOL
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.
PRIVATE "ROSIDL_GENERATOR_C_BUILDING_DLL_${PROJECT_NAME}") | ||
endif() | ||
set_property(TARGET ${rosidl_generate_interfaces_TARGET}${_target_suffix} | ||
PROPERTY DEFINE_SYMBOL "ROSIDL_GENERATOR_C_BUILDING_DLL_${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.
@sloretz unconditionally? I'm OK with that, though talking about DLLs outside Windows is awkward.
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.
Looks that way. If you build rcl
with -DCMAKE_VERBOSE_MAKEFILE=ON
all the compiler invocations have -Drcl_EXPORTS
passed to them; which is the default value of DEFINE_SYMBOL
.
Signed-off-by: Shane Loretz <sloretz@osrfoundation.org>
This PR cleans up a few things I've noticed while looking at the generator code for another task
find_package()
dependencies needed by generated codetarget_compile_definitions(...BUILDING_DLL...)
line in anif(WIN32)
block because it's unnecessary. The visibility header seems to do stuff on other platforms too..._TARGETS${_target_suffix}
variable created byrosidl_export_typesupport_targets()
.rosidl_export_typesupport_targets()
where it wasn't alreadyif(NOT _generated_headers...
checks - because they don't seem to do anything. In all places I saw them there was another place further up or down that wasn't guarded and would have raised a CMake error if that variable actually was empty (either theadd_library()
oradd_custom_target()
commands).target_link_libraries()
instead ofament_target_dependencies()
Is ament_target_dependencies() still necessary? ament/ament_cmake#292 in the generator code (There are a few other places it's used in this repo still, but they weren't part of the generators so I didn't include them in this PR)rosidl_generator_c_FOUND
with checks that the target that generator generates is found - because that's the important thing.find_packaging()
the generators they depend on before registering their own extensions in their "extras.cmake" filetarget_link_libraries()
to the generated target of the other rather than hard-coding the directory it's likely to create in the build folderament_export_dependencies(...)
whenSKIP_INSTALL
is used.