-
Notifications
You must be signed in to change notification settings - Fork 497
Set symbol visibility to hidden for rclcpp #638
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,7 +49,7 @@ namespace node_interfaces | |
| class NodeBaseInterface; | ||
| } // namespace node_interfaces | ||
|
|
||
| class ClientBase | ||
| class RCLCPP_PUBLIC ClientBase | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain why? We explicitly avoided this, choosing to make each method public manually. We've had issues making these public on Windows due to the std data structures which are private members of the class.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's a sample error I ran into while running rclcpp package with visibility set to hidden. Is there any other way to handle this instead of making the class visible?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think adding it to the class may be required, but you need to test it on Windows too, because I think it might be in conflict. If you do leave the public in the class declaration, then the
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed all the inner RCLCPP_PUBLIC keywords from the modified classes. Will request @thomas-moulard to run this on windows CI for a quick check |
||
| { | ||
| public: | ||
| RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(ClientBase) | ||
|
|
||
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.
Needs to be rclcpp?
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 am trying to reuse the configure_rcl macro in ros2/rcl. This is in a way similar to how the configure_rmw_library macro is being reused in rmw_fastrtps and other packages. The single macro takes care of both C and C++ code
Uh oh!
There was an error while loading. Please reload this page.
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 not possible because they are not part of the same shared library. See doc here: https://gcc.gnu.org/wiki/Visibility
edit:
You have two SOs librcl.so and librcl_cpp.so.
When you build librcl.so, you can access both any public symbol of any dependency and any internal symbol, even private ones (because they are part of the same library).
Same thing when you build librcl_cpp.so. You can access your own symbols and any public one but not private symbols from another lib like e.g. librcl.so.
By re-using the macro, you are actually allowing librcl_cpp.so to access librcl.so private symbols which will not work.
Removing the duplication is doable but you'ld need something like that:
This would significantly increase the scope of this change so I won't recommend for this to be done in this PR.
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.
A possible alternative may be to use the CMake standard macro
generate_export_headerand theDEFINE_SYMBOLtarget property.See ros/console_bridge#43 for a use in a ROS-related repo, and https://bitbucket.org/osrf/gazebo/issues/2262/symbol-visibility-issues-in-windows for a related issue in Gazebo.
Uh oh!
There was an error while loading. Please reload this page.
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.
Quick note: This is the way in which we are sharing the "configure_rcl" macro from rcl to rclcpp: https://github.com/ros2/rmw/blob/master/rmw/CMakeLists.txt#L62-L65
I am not sure if sharing just the macro is allowing librcl_cpp.so to access librcl.so private symbols, I am guessing it is not.
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.
The critical part is in https://github.com/ros2/rcl/pull/391/files#diff-19c13a4e66284bae327c94111b226946R71, in which you are defining the
RCL_BUILDING_DLLmacro also for compilation units that are not part of thercl. The effect will be that when including https://github.com/ros2/rcl/blob/aa4ac7d06cc5e59d693408260868edb004154b69/rcl/include/rcl/visibility_control.h as part of a compilation unit outside of rcl,RCL_PUBLIC(in Windows) will have the value__declspec(dllexport)instead of the correct__declspec(dllimport). This is exactly the problem described in https://bitbucket.org/osrf/gazebo/issues/2262/symbol-visibility-issues-in-windows .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 personally don't like the generated code approach (I prefer a single, checked-in boil-plate file) and a custom define.
As the others said, you can do this, but only for the visibility compiler options, not the visibility compiler definition.
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 the inputs @thomas-moulard , @traversaro and @wjwwood. I have removed the target definition specific code in configure_rcl in ros2/rcl#391 . This is because each rcl or rclcpp has its own target definition specified in the CMakeList. For eg:
https://github.com/ros2/rclcpp/blob/master/rclcpp/CMakeLists.txt#L112-L115
https://github.com/ros2/rclcpp/blob/master/rclcpp_action/CMakeLists.txt#L38-L41
Is this a reasonable solution? Do you think we should have a separate configure_rclcpp for rclcpp packages?
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 probably a bit OT in this PR, but for the sake of clarity: the generated header file (both CMake's and the example linked by @thomas-moulard ) is useful for supporting the case in which a library is compiled as a static library under Windows. Without that, in any downstream compilation unit
RCLCPP_PUBLICis always defined as__declspec(dllimport)and this annotation will generate a Visual Studio error LNK2019 if the RCLCPP library is a actually compiled as static. A possible alternative without having a generated file is to have an additional logic that definesRCLCPP_PUBLICas an empty macro ifRCLCPP_STATICis defined, but then it is necessary some kind of build system logic to make sure thatRCLCPP_STATICis always defined (even downstream) if RCLCPP is build as static, for example a conditionaltarget_compile_definitions(rclcpp PUBLIC RCLCPP_STATIC)called only if the library is built is static, or similar.See ros/console_bridge#40 (comment) for a similar comment.