diff --git a/bazel_ros2_rules/ros2/rosidl.bzl b/bazel_ros2_rules/ros2/rosidl.bzl index d432e4b7..1eacf76c 100644 --- a/bazel_ros2_rules/ros2/rosidl.bzl +++ b/bazel_ros2_rules/ros2/rosidl.bzl @@ -66,6 +66,18 @@ def _rosidl_generate_genrule_impl(ctx): args.add(ctx.attr.group) args.add_all(ctx.files.interfaces, map_each = _as_idl_tuple) inputs = ctx.files.interfaces + ctx.files.includes + + expected_outputs = [] + cpp_visibility_header_file = None + + # The cpp visibility header is not generated by rosidl generate, so we must + # handle its generation separately. + for generated_source in ctx.outputs.generated_sources: + if "cpp__visibility_control.hpp" in generated_source.path: + cpp_visibility_header_file = generated_source + else: + expected_outputs.append(generated_source) + ctx.actions.run_shell( tools = [ctx.executable._tool], arguments = [args], @@ -73,9 +85,73 @@ def _rosidl_generate_genrule_impl(ctx): command = "{} $@ > /dev/null".format( ctx.executable._tool.path, ), - outputs = ctx.outputs.generated_sources, + outputs = expected_outputs, ) + # This is a temporary hack to get the build working again. This should be + # redone so that the real template file from the ROS distribution is used, + # rather than our adaptation below. + # TODO(calderpg-tri) Replace this hack. + if cpp_visibility_header_file != None: + # This template is adapted directly from the mentioned template file. + cpp_visibility_header_template = ( + """ +// generated from rosidl_generator_cpp/resource/rosidl_generator_cpp__visibility_control.hpp.in +// generated code does not contain a copyright notice + +#ifndef {package_name_upper}__MSG__ROSIDL_GENERATOR_CPP__VISIBILITY_CONTROL_HPP_ +#define {package_name_upper}__MSG__ROSIDL_GENERATOR_CPP__VISIBILITY_CONTROL_HPP_ + +#ifdef __cplusplus +extern "C" +{{ +#endif + +// This logic was borrowed (then namespaced) from the examples on the gcc wiki: +// https://gcc.gnu.org/wiki/Visibility + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef __GNUC__ + #define ROSIDL_GENERATOR_CPP_EXPORT_{package_name} __attribute__ ((dllexport)) + #define ROSIDL_GENERATOR_CPP_IMPORT_{package_name} __attribute__ ((dllimport)) + #else + #define ROSIDL_GENERATOR_CPP_EXPORT_{package_name} __declspec(dllexport) + #define ROSIDL_GENERATOR_CPP_IMPORT_{package_name} __declspec(dllimport) + #endif + #ifdef ROSIDL_GENERATOR_CPP_BUILDING_DLL_{package_name} + #define ROSIDL_GENERATOR_CPP_PUBLIC_{package_name} ROSIDL_GENERATOR_CPP_EXPORT_{package_name} + #else + #define ROSIDL_GENERATOR_CPP_PUBLIC_{package_name} ROSIDL_GENERATOR_CPP_IMPORT_{package_name} + #endif +#else + #define ROSIDL_GENERATOR_CPP_EXPORT_{package_name} __attribute__ ((visibility("default"))) + #define ROSIDL_GENERATOR_CPP_IMPORT_{package_name} + #if __GNUC__ >= 4 + #define ROSIDL_GENERATOR_CPP_PUBLIC_{package_name} __attribute__ ((visibility("default"))) + #else + #define ROSIDL_GENERATOR_CPP_PUBLIC_{package_name} + #endif +#endif + +#ifdef __cplusplus +}} +#endif + +#endif // {package_name_upper}__MSG__ROSIDL_GENERATOR_CPP__VISIBILITY_CONTROL_HPP_ +""" # noqa + ) + + package_name = str(ctx.attr.group) + package_name_upper = package_name.upper() + + ctx.actions.write( + output = cpp_visibility_header_file, + content = cpp_visibility_header_template.format( + package_name = package_name, + package_name_upper = package_name_upper, + ), + ) + rosidl_generate_genrule = rule( attrs = dict( generated_sources = attr.output_list(mandatory = True), @@ -492,7 +568,8 @@ def rosidl_cc_library( """ include, root = _deduce_source_paths(group, "cpp") - generated_cc_headers = [] + visibility_header = "msg/rosidl_generator_cpp__visibility_control.hpp" + generated_cc_headers = ["{}/{}".format(root, visibility_header)] for ifc in interfaces: parent, basename = _deduce_source_parts(ifc) generated_cc_headers.append( @@ -507,6 +584,9 @@ def rosidl_cc_library( generated_cc_headers.append( "{}/{}/detail/{}__traits.hpp".format(root, parent, basename), ) + generated_cc_headers.append( + "{}/{}/detail/{}__type_support.hpp".format(root, parent, basename), + ) rosidl_generate_genrule( name = _make_private_name(name, "_gen"),