Skip to content

Commit f092114

Browse files
author
Francisco Rossi
committed
Minor tweaks on and extract generate_file to common
1 parent 892206d commit f092114

6 files changed

Lines changed: 63 additions & 47 deletions

File tree

bazel_ros2_rules/lib/extensions.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def _local_ros2_implementation(module_ctx):
3939
"rosidl_default_generators",
4040
"service_msgs",
4141
"unique_identifier_msgs",
42+
"xacro", # required by the ros_xacro rule in xacro.bzl
4243
]
4344

4445
underlay = find_local_ros2_distribution(module_ctx)

bazel_ros2_rules/lib/private/common.bzl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@ def interfaces_filegroup(name, share_directory):
3535
], allow_empty = True),
3636
)
3737

38+
def _generate_file_impl(ctx):
39+
out = ctx.actions.declare_file(ctx.label.name)
40+
ctx.actions.write(out, ctx.attr.content, ctx.attr.is_executable)
41+
return [DefaultInfo(
42+
files = depset([out]),
43+
data_runfiles = ctx.runfiles(files = [out]),
44+
)]
45+
46+
generate_file = rule(
47+
attrs = {
48+
"content": attr.string(mandatory = True),
49+
"is_executable": attr.bool(default = False),
50+
},
51+
output_to_genfiles = True,
52+
implementation = _generate_file_impl,
53+
)
54+
"""Writes a string to a file at build time."""
55+
3856
def incorporate_rmw_implementation(kwargs, env_changes, rmw_implementation):
3957
target = REPOSITORY_ROOT + ":%s_cc" % rmw_implementation
4058
kwargs["data"] = kwargs.get("data", []) + [target]

bazel_ros2_rules/lib/private/ros_py.bzl

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ load(
1515
)
1616
load(
1717
":common.bzl",
18+
"generate_file",
1819
"incorporate_rmw_implementation",
1920
)
2021
load(
@@ -23,6 +24,8 @@ load(
2324
"RUNTIME_ENVIRONMENT",
2425
)
2526

27+
_WORKSPACE_NAME = Label(REPOSITORY_ROOT + ":ros2").workspace_name
28+
2629
def ros_import_binary(
2730
name,
2831
executable,
@@ -144,24 +147,7 @@ def _add_deps(existing, new):
144147
deps.append(dep)
145148
return deps
146149

147-
def _generate_file_impl(ctx):
148-
out = ctx.actions.declare_file(ctx.label.name)
149-
ctx.actions.write(out, ctx.attr.content, ctx.attr.is_executable)
150-
return [DefaultInfo(
151-
files = depset([out]),
152-
data_runfiles = ctx.runfiles(files = [out]),
153-
)]
154-
155-
_generate_file = rule(
156-
attrs = {
157-
"content": attr.string(mandatory = True),
158-
"is_executable": attr.bool(default = False),
159-
},
160-
output_to_genfiles = True,
161-
implementation = _generate_file_impl,
162-
)
163-
164-
_LAUNCH_PY_TEMPLATE = """
150+
_LAUNCH_PY_TEMPLATE = """\
165151
import os
166152
import sys
167153
@@ -170,7 +156,7 @@ from python.runfiles import runfiles as runfiles_api
170156
assert __name__ == "__main__"
171157
runfiles = runfiles_api.Create()
172158
launch_file = runfiles.Rlocation({launch_respath}) # noqa
173-
ros2_bin = runfiles.Rlocation("ros2/ros2")
159+
ros2_bin = runfiles.Rlocation("{ros2_rlocation}")
174160
args = [ros2_bin, "launch", launch_file] + sys.argv[1:]
175161
os.execv(ros2_bin, args)
176162
"""
@@ -215,8 +201,9 @@ def ros_launch(
215201

216202
content = _LAUNCH_PY_TEMPLATE.format(
217203
launch_respath = repr(launch_respath),
204+
ros2_rlocation = _WORKSPACE_NAME + "/ros2",
218205
)
219-
_generate_file(
206+
generate_file(
220207
name = main,
221208
content = content,
222209
visibility = ["//visibility:private"],

bazel_ros2_rules/lib/private/xacro.bzl

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""
33

44
load("@bazel_ros2_rules//lib:ament_index.bzl", "ament_index_share_files")
5+
load(":common.bzl", "generate_file")
56
load(":distro.bzl", "REPOSITORY_ROOT")
67
load(":ros_py.bzl", "ros_py_binary")
78

@@ -10,20 +11,6 @@ load(":ros_py.bzl", "ros_py_binary")
1011
# formats correctly without manual string manipulation.
1112
_WORKSPACE_NAME = Label(REPOSITORY_ROOT + ":xacro").workspace_name
1213

13-
def _xacro_generate_file_impl(ctx):
14-
out = ctx.actions.declare_file(ctx.label.name)
15-
ctx.actions.write(out, ctx.attr.content, is_executable = True)
16-
return [DefaultInfo(
17-
files = depset([out]),
18-
data_runfiles = ctx.runfiles(files = [out]),
19-
)]
20-
21-
_xacro_generate_file = rule(
22-
attrs = {"content": attr.string(mandatory = True)},
23-
output_to_genfiles = True,
24-
implementation = _xacro_generate_file_impl,
25-
)
26-
2714
# Runner script template. The outer dload shim (from ros_py_binary) has
2815
# already set AMENT_PREFIX_PATH to include both system and user-package
2916
# prefixes (all absolute via $RUNFILES_DIR) before this script runs. What is
@@ -41,7 +28,7 @@ os.execv(xacro_bin, [xacro_bin] + sys.argv[1:])
4128
"""
4229

4330
def _ros_xacro_impl(ctx):
44-
output = ctx.actions.declare_file(ctx.attr.name + ".urdf")
31+
output = ctx.actions.declare_file(ctx.label.name + ".urdf")
4532
args = ctx.actions.args()
4633
args.add(ctx.file.src)
4734
args.add("-o", output)
@@ -62,9 +49,9 @@ _ros_xacro_rule = rule(
6249
doc = "The main .urdf.xacro file to process.",
6350
),
6451
"data": attr.label_list(
65-
allow_files = [".xacro"],
52+
allow_files = True,
6653
default = [],
67-
doc = "Additional .xacro files included via relative paths.",
54+
doc = "Additional files included via relative paths (e.g. .xacro, .yaml).",
6855
),
6956
"xacro_args": attr.string_list(
7057
default = [],
@@ -80,7 +67,7 @@ _ros_xacro_rule = rule(
8067
implementation = _ros_xacro_impl,
8168
)
8269

83-
def ros_xacro(name, src, data = [], ros_packages = {}, xacro_args = [], visibility = None, **kwargs):
70+
def ros_xacro(name, src, data = [], ros_packages = {}, xacro_args = [], visibility = None):
8471
"""Transforms a .urdf.xacro file into a .urdf file.
8572
8673
User-defined packages are declared inline via the ros_packages dict. Each
@@ -107,10 +94,11 @@ def ros_xacro(name, src, data = [], ros_packages = {}, xacro_args = [], visibili
10794
Args:
10895
name: target name; the output file is named <name>.urdf
10996
src: the .urdf.xacro source file
110-
data: additional .xacro files included via relative paths
111-
(i.e. plain <xacro:include filename="other.xacro"/>);
112-
must be listed here so Bazel sandboxes them and tracks
113-
them as dependencies for incremental rebuilds
97+
data: additional files included via relative paths
98+
(e.g. plain <xacro:include filename="other.xacro"/>
99+
or referenced .yaml configs); must be listed here so
100+
Bazel sandboxes them and tracks them as dependencies
101+
for incremental rebuilds
114102
ros_packages: dict mapping ROS package name to list of share files;
115103
files are stripped of the calling package's path prefix
116104
automatically before being placed under share/<pkg>/
@@ -133,7 +121,7 @@ def ros_xacro(name, src, data = [], ros_packages = {}, xacro_args = [], visibili
133121
runner_data = [REPOSITORY_ROOT + ":xacro"] + pkg_targets
134122

135123
runner_main = "_{}_runner_main.py".format(name)
136-
_xacro_generate_file(
124+
generate_file(
137125
name = runner_main,
138126
content = _XACRO_RUNNER_TEMPLATE.format(
139127
xacro_rlocation = _WORKSPACE_NAME + "/xacro",

ros2_example_bazel_installed/ros2_example_xacro/example.urdf.xacro

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
<xacro:include filename="$(find my_robot)/urdf/macros.xacro"/>
77
<!-- Should be able to bring `.xacros` installed in the system (via `realsense2_description` for this example)-->
88
<xacro:include filename="$(find realsense2_description)/urdf/_d435i.urdf.xacro"/>
9-
<!-- Should be able to retrieve xacro args-->
10-
<xacro:arg name="sim" default="true" />
11-
<xacro:property name="sim_mode" value="$(arg sim)"/>
12-
<sim>${sim_mode}</sim>
9+
<!-- Should be able to retrieve xacro args-->
10+
<xacro:arg name="sim" default="true" />
11+
<xacro:property name="sim_mode" value="$(arg sim)"/>
12+
<sim>${sim_mode}</sim>
13+
<!-- Instantiate the D435i sensor to verify $(find realsense2_description) actually resolved. -->
14+
<link name="base_link"/>
15+
<xacro:sensor_d435i parent="base_link" name="head_camera" use_nominal_extrinsics="true">
16+
<origin xyz="0 0 0" rpy="0 0 0"/>
17+
</xacro:sensor_d435i>
1318
</robot>

ros2_example_bazel_installed/ros2_example_xacro/test/xacro_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,25 @@ def test_relative_include_expanded():
3838
)
3939

4040

41+
def test_system_package_include_resolved():
42+
"""$(find realsense2_description) is resolved and its macros are expanded.
43+
44+
Verifies that ros_xacro sets AMENT_PREFIX_PATH so xacro can find
45+
system-installed ROS packages. The D435i macro from
46+
realsense2_description is instantiated in the example xacro; if the
47+
include had not resolved, xacro would have exited non-zero and the
48+
output URDF would not exist.
49+
"""
50+
content = _read_urdf()
51+
assert 'name="head_camera_link"' in content, (
52+
"Expected D435i links from realsense2_description in output:\n"
53+
+ content
54+
)
55+
56+
4157
if __name__ == "__main__":
4258
test_sim_arg_is_substituted()
4359
test_local_package_macros_expanded()
4460
test_relative_include_expanded()
61+
test_system_package_include_resolved()
4562
print("All tests passed.")

0 commit comments

Comments
 (0)