Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
3d0bae1
Add first shot
mvukov Feb 21, 2026
96ec63b
Make proto_to_ros2_msg_aspect return Ros2InterfaceInfo
mvukov Feb 22, 2026
a5b1229
Add ros_package_name to Ros2InterfaceInfo
mvukov Feb 22, 2026
bb2858b
Work out cpp_proto_ros2_interface_library
mvukov Feb 22, 2026
d4cf96b
Merge branch 'main' of github.com:mvukov/rules_ros2 into feature/prot…
mvukov Feb 24, 2026
ac40a31
use com_google_protobuf i.s.o. rules_proto
mvukov Feb 25, 2026
0fa359a
Add proto-ros conversion
mvukov Feb 28, 2026
23b6c62
Fix nits
mvukov Feb 28, 2026
f5baae9
Fix protobuf generators
mvukov Feb 28, 2026
59c0e07
Use protobuf-python from Bazel
mvukov Feb 28, 2026
75bcd02
Add protobuf bzl dep
mvukov Feb 28, 2026
58472b4
Clean up code duplication in protobuf.bzl
mvukov Mar 1, 2026
f416ab8
Factor out common parts in generators
mvukov Mar 1, 2026
79f244c
Clean up naming
mvukov Mar 1, 2026
fce594a
Ensure the message name is correct
mvukov Mar 1, 2026
50b7da3
Update docs
mvukov Mar 1, 2026
5fb24b5
Add support for enums
mvukov Mar 1, 2026
f95604b
Disable oneof and maps
mvukov Mar 5, 2026
8b52ab2
Move proto related stuff to ros2/protobuf
mvukov Mar 7, 2026
b1f5a62
Generated converters: void (const In&, out* out)
mvukov Mar 7, 2026
d9cbcbe
Add automatic proto timestamp <> ros time conversion
mvukov Mar 8, 2026
1c1b1f0
Fix mappings
mvukov Mar 8, 2026
cf8006d
Optimize converter
mvukov May 25, 2026
53d48fe
Merge branch 'main' of github.com:mvukov/rules_ros2 into feature/prot…
mvukov May 28, 2026
c95d669
rm common runtime and fix dependency propagation
mvukov May 29, 2026
b2ad254
Rename FromRos to ToProto
mvukov May 29, 2026
50e6293
Add missing CcInfo import
mvukov May 29, 2026
9aec90d
Import cc_common
mvukov May 29, 2026
9362930
Disable repeated bytes in proto
mvukov May 29, 2026
dd8fb69
Update docs
mvukov May 29, 2026
a9537cb
Add proto_ros2_interface_library rule
mvukov May 29, 2026
f7b4d1a
Add readme and reject nested messages
mvukov Jun 1, 2026
7ccf4e4
Fix ros_package_name collision across Bazel packages
mvukov Jun 2, 2026
947da6b
Respect proto_source_root
mvukov Jun 2, 2026
77e4f51
Fix nit
mvukov Jun 3, 2026
b52ed6c
Add tests for proto_to_ros2_msg
mvukov Jun 4, 2026
47fd033
Clean up tests
mvukov Jun 4, 2026
8cd78f0
Reject file-level enum definitions in proto_to_ros2_msg
mvukov Jun 4, 2026
2279bc8
Fix dummy_one test proto
mvukov Jun 4, 2026
6a132b2
Add support for deprecated fields
mvukov Jun 7, 2026
5312156
Add a plan for sized arrays
mvukov Jun 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ bazel_dep(name = "libyaml", version = "0.2.5")
bazel_dep(name = "lz4", version = "1.10.0.bcr.1")
bazel_dep(name = "nlohmann_json", version = "3.12.0.bcr.1")
bazel_dep(name = "platforms", version = "1.1.0")
bazel_dep(name = "protobuf", version = "33.5", repo_name = "com_google_protobuf")
bazel_dep(name = "pybind11_bazel", version = "3.0.0")
bazel_dep(name = "readerwriterqueue", version = "1.0.6")
bazel_dep(name = "rules_cc", version = "0.2.16")
Expand Down
2 changes: 2 additions & 0 deletions repositories/deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

load("@bazel_features//:deps.bzl", "bazel_features_deps")
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
load("@googletest//:googletest_deps.bzl", "googletest_deps")
load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
load("@rules_shell//shell:repositories.bzl", "rules_shell_dependencies", "rules_shell_toolchains")
Expand All @@ -16,3 +17,4 @@ def ros2_deps():
rules_shell_toolchains()
rules_foreign_cc_dependencies()
googletest_deps()
protobuf_deps()
8 changes: 8 additions & 0 deletions repositories/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,14 @@ def ros2_workspace_repositories():
],
)

maybe(
http_archive,
name = "com_google_protobuf",
sha256 = "440848dffa209beb8a04e41cc352762e44f8e91342b2a43aab6af9b30713c2f6",
strip_prefix = "protobuf-33.5",
urls = ["https://github.com/protocolbuffers/protobuf/archive/refs/tags/v33.5.tar.gz"],
)

def ros2_repositories():
"""Import ROS 2 repositories."""

Expand Down
1 change: 1 addition & 0 deletions ros2/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
load("@rules_python//python:pip.bzl", "whl_filegroup")
load("@rules_ros2_pip_deps//:requirements.bzl", "requirement")

exports_files([
"action.bzl",
Expand Down
37 changes: 21 additions & 16 deletions ros2/interfaces.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

load("@bazel_skylib//lib:paths.bzl", "paths")
load("@com_github_mvukov_rules_ros2//ros2:cc_opts.bzl", "C_COPTS")
load("@com_google_protobuf//bazel/common:proto_info.bzl", "ProtoInfo")
load("@rules_cc//cc:defs.bzl", "CcInfo", "cc_common")
load("@rules_cc//cc:toolchain_utils.bzl", "find_cpp_toolchain")
load("@rules_python//python:defs.bzl", "PyInfo", "py_library")
Expand All @@ -26,6 +27,7 @@ Ros2InterfaceInfo = provider(
fields = [
"info",
"deps",
"ros_package_name",
],
)

Expand All @@ -43,6 +45,7 @@ def _ros2_interface_library_impl(ctx):
for dep in ctx.attr.deps
],
),
ros_package_name = ctx.label.name,
),
]

Expand Down Expand Up @@ -141,7 +144,7 @@ IdlAdapterAspectInfo = provider("TBD", fields = [
])

def _idl_adapter_aspect_impl(target, ctx):
package_name = target.label.name
package_name = target[Ros2InterfaceInfo].ros_package_name
srcs = target[Ros2InterfaceInfo].info.srcs
idl_files, idl_tuples = _run_adapter(ctx, package_name, srcs)
return [
Expand All @@ -154,14 +157,15 @@ def _idl_adapter_aspect_impl(target, ctx):
idl_adapter_aspect = aspect(
implementation = _idl_adapter_aspect_impl,
attr_aspects = ["deps"],
required_providers = [Ros2InterfaceInfo],
attrs = {
"_adapter": attr.label(
default = Label("@ros2_rosidl//:rosidl_adapter_app"),
executable = True,
cfg = "exec",
),
},
required_providers = [[ProtoInfo], [Ros2InterfaceInfo]],
required_aspect_providers = [Ros2InterfaceInfo],
provides = [IdlAdapterAspectInfo],
)

Expand Down Expand Up @@ -291,13 +295,13 @@ def _get_compilation_contexts_from_deps(deps):
return [dep[CcInfo].compilation_context for dep in deps]

def _get_compilation_contexts_from_aspect_info_deps(deps, aspect_info):
return [dep[aspect_info].cc_info.compilation_context for dep in deps]
return [dep[aspect_info].cc_info.compilation_context for dep in deps if aspect_info in dep]

def _get_linking_contexts_from_deps(deps):
return [dep[CcInfo].linking_context for dep in deps]

def _get_linking_contexts_from_aspect_info_deps(deps, aspect_info):
return [dep[aspect_info].cc_info.linking_context for dep in deps]
return [dep[aspect_info].cc_info.linking_context for dep in deps if aspect_info in dep]

def _compile_cc_generated_code(
ctx,
Expand Down Expand Up @@ -367,7 +371,7 @@ def _compile_cc_generated_code(
)

def _c_generator_aspect_impl(target, ctx):
package_name = target.label.name
package_name = target[Ros2InterfaceInfo].ros_package_name
srcs = target[Ros2InterfaceInfo].info.srcs
adapter = target[IdlAdapterAspectInfo]

Expand Down Expand Up @@ -492,14 +496,14 @@ c_generator_aspect = aspect(
fragments = ["cpp"],
)

def _cc_generator_impl(ctx, aspect_info):
def cc_generator_impl(ctx, aspect_info):
cc_info = cc_common.merge_cc_infos(
direct_cc_infos = [dep[aspect_info].cc_info for dep in ctx.attr.deps],
)
return [cc_info]

def _c_ros2_interface_library_impl(ctx):
return _cc_generator_impl(ctx, CGeneratorAspectInfo)
return cc_generator_impl(ctx, CGeneratorAspectInfo)

c_ros2_interface_library = rule(
attrs = {
Expand Down Expand Up @@ -535,7 +539,7 @@ _TYPESUPPORT_INTROSPECION_GENERATOR_CPP_OUTPUT_MAPPING = [
]

def _cpp_generator_aspect_impl(target, ctx):
package_name = target.label.name
package_name = target[Ros2InterfaceInfo].ros_package_name
srcs = target[Ros2InterfaceInfo].info.srcs
adapter = target[IdlAdapterAspectInfo]

Expand Down Expand Up @@ -648,15 +652,15 @@ cpp_generator_aspect = aspect(
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
),
},
required_providers = [Ros2InterfaceInfo],
required_aspect_providers = [IdlAdapterAspectInfo],
required_providers = [[ProtoInfo], [Ros2InterfaceInfo]],
required_aspect_providers = [[Ros2InterfaceInfo], [IdlAdapterAspectInfo]],
provides = [CppGeneratorAspectInfo],
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
fragments = ["cpp"],
)

def _cpp_ros2_interface_library_impl(ctx):
return _cc_generator_impl(ctx, CppGeneratorAspectInfo)
return cc_generator_impl(ctx, CppGeneratorAspectInfo)

cpp_ros2_interface_library = rule(
attrs = {
Expand Down Expand Up @@ -686,7 +690,7 @@ def _get_py_srcs(files):
return [f for f in files if f.path.endswith(".py")]

def _py_generator_aspect_impl(target, ctx):
package_name = target.label.name
package_name = target[Ros2InterfaceInfo].ros_package_name
srcs = target[Ros2InterfaceInfo].info.srcs
adapter = target[IdlAdapterAspectInfo]

Expand Down Expand Up @@ -779,32 +783,33 @@ def _py_generator_aspect_impl(target, ctx):
*relative_path_parts[0:]
)

py_deps = [dep for dep in ctx.rule.attr.deps if PyGeneratorAspectInfo in dep]
py_info = PyGeneratorAspectInfo(
cc_info = cc_common.merge_cc_infos(
direct_cc_infos = [compilation_info.cc_info] + [
dep[PyGeneratorAspectInfo].cc_info
for dep in ctx.rule.attr.deps
for dep in py_deps
],
),
dynamic_libraries = depset(
direct = [dynamic_library],
transitive = [
dep[PyGeneratorAspectInfo].dynamic_libraries
for dep in ctx.rule.attr.deps
for dep in py_deps
],
),
transitive_sources = depset(
direct = _get_py_srcs(all_outputs),
transitive = [
dep[PyGeneratorAspectInfo].transitive_sources
for dep in ctx.rule.attr.deps
for dep in py_deps
],
),
imports = depset(
direct = [py_import_path],
transitive = [
dep[PyGeneratorAspectInfo].imports
for dep in ctx.rule.attr.deps
for dep in py_deps
],
),
linker_inputs = compilation_info.cc_info.linking_context.linker_inputs,
Expand Down
4 changes: 2 additions & 2 deletions ros2/plugin_aspects.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Ros2InterfaceCollectorAspectInfo = provider(

def create_interface_struct(target):
return struct(
package_name = target.label.name,
package_name = target[Ros2InterfaceInfo].ros_package_name,
srcs = target[Ros2InterfaceInfo].info.srcs,
)

Expand Down Expand Up @@ -155,7 +155,7 @@ def create_dynamic_library(ctx, **kwargs):
return dynamic_library

def _ros2_idl_plugin_aspect_impl(target, ctx):
package_name = target.label.name
package_name = target[Ros2InterfaceInfo].ros_package_name
cc_info = target[CppGeneratorAspectInfo].cc_info
dynamic_library = create_dynamic_library(
ctx,
Expand Down
36 changes: 36 additions & 0 deletions ros2/protobuf/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
load("@com_github_mvukov_rules_ros2//ros2:cc_defs.bzl", "ros2_cpp_library")
load("@rules_python//python:defs.bzl", "py_binary", "py_library")
load("@rules_ros2_pip_deps//:requirements.bzl", "requirement")

exports_files([
"protobuf.bzl",
])

py_library(
name = "proto_to_ros2",
srcs = ["proto_to_ros2.py"],
deps = [
"@com_google_protobuf//:protobuf_python",
],
)

py_binary(
name = "proto_to_ros2_msg",
srcs = ["proto_to_ros2_msg.py"],
visibility = ["//visibility:public"],
deps = [
":proto_to_ros2",
"@com_google_protobuf//:protobuf_python",
],
)

py_binary(
name = "proto_to_ros2_converter",
srcs = ["proto_to_ros2_converter.py"],
visibility = ["//visibility:public"],
deps = [
":proto_to_ros2",
"@com_google_protobuf//:protobuf_python",
requirement("empy"),
],
)
Loading
Loading