@@ -47,25 +47,17 @@ Recursively aggregates AmentIndex prefixes from dependencies into one provider.
4747"""
4848
4949def _ament_index_share_files_impl (ctx ):
50- # declare that a "package" with the given name exists
5150 package_marker_path = paths .join (
5251 ctx .attr .prefix ,
5352 "share/ament_index/resource_index/packages/" ,
5453 ctx .attr .package_name ,
5554 )
5655 package_marker_out = ctx .actions .declare_file (package_marker_path )
57- ctx .actions .write (
58- output = package_marker_out ,
59- content = "" ,
60- )
56+ ctx .actions .write (output = package_marker_out , content = "" )
6157
62- # Symlink sources into the share directory
63- runfiles_symlinks = {
64- package_marker_path : package_marker_out ,
65- }
58+ root_symlinks = {package_marker_path : package_marker_out }
6659
6760 for src in ctx .attr .srcs :
68- # src is a target that could have multiple files
6961 for file in src .files .to_list ():
7062 sp = file .short_path
7163 if sp .startswith (ctx .attr .strip_prefix ):
@@ -76,21 +68,36 @@ def _ament_index_share_files_impl(ctx):
7668 ctx .attr .package_name ,
7769 sp ,
7870 )
79- runfiles_symlinks [symlink_path ] = file
71+ root_symlinks [symlink_path ] = file
72+
73+ for exe in ctx .attr .executables :
74+ exe_file = exe .files_to_run .executable
75+ if exe_file == None :
76+ continue
77+ symlink_path = paths .join (
78+ ctx .attr .prefix ,
79+ "lib" ,
80+ ctx .attr .package_name ,
81+ exe_file .basename ,
82+ )
83+ root_symlinks [symlink_path ] = exe_file
8084
8185 return [
8286 AmentIndex (prefix = ctx .attr .prefix ),
8387 DefaultInfo (
84- runfiles = ctx .runfiles (root_symlinks = runfiles_symlinks ),
88+ runfiles = ctx .runfiles (root_symlinks = root_symlinks ),
8589 ),
8690 ]
8791
8892ament_index_share_files = rule (
8993 attrs = dict (
9094 package_name = attr .string (mandatory = True ),
9195 srcs = attr .label_list (
92- mandatory = True ,
93- allow_empty = False ,
96+ allow_empty = True ,
97+ allow_files = True ,
98+ ),
99+ executables = attr .label_list (
100+ allow_empty = True ,
94101 allow_files = True ,
95102 ),
96103 # A prefix is required because the shim can't prepend the runfiles
@@ -103,14 +110,17 @@ ament_index_share_files = rule(
103110 provides = [AmentIndex ],
104111)
105112"""
106- Creates an ament resource index and share/ directory for a single package.
113+ Creates an ament resource index for a single ROS 2 package.
114+
115+ Files in `srcs` are symlinked under `<prefix>/share/<package_name>/`,
116+ enabling ament_index lookups such as `get_package_share_directory()`.
117+
118+ Executable targets in `executables` are symlinked under
119+ `<prefix>/lib/<package_name>/`, enabling
120+ `launch_ros.actions.Node(package=..., executable=...)` to find Bazel-built
121+ binaries without a colcon install space.
107122
108- This creates both a package marker for a package, and a share directory
109- for that package.
110- Files in `srcs` will be added to `share/package_name`.
111- A target depending on this one will be able to access the files in the
112- share directory using the package's share directory joined with the
113- files they expect.
123+ Both can be used together in a single rule invocation.
114124
115125 d = ament_index_cpp::get_package_share_directory("package_name")
116126 file = join(d, "short_path of file")
@@ -130,10 +140,11 @@ TODO(sloretz) detect and error when a target is given two ament indexes
130140with the same package.
131141
132142Args:
133- package_name: name of a ROS 2 package to which these share files belong
143+ package_name: name of a ROS 2 package
134144 srcs: files to put into the share directory
145+ executables: executable targets to expose under lib/
135146 prefix: optional prefix to give to the generated runfiles.
136- strip_prefix: optional prefix to strip from the short_path of the files
147+ strip_prefix: optional prefix to strip from the short_path of srcs files
137148
138149Provides:
139150 AmentIndex: a prefix path where the ament resource index was generated.
0 commit comments