@@ -46,100 +46,140 @@ ament_index_prefixes = aspect(
4646Recursively aggregates AmentIndex prefixes from dependencies into one provider.
4747"""
4848
49- def _ament_index_share_files_impl (ctx ):
50- # declare that a "package" with the given name exists
49+ def _ament_index_files_impl (ctx ):
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
69- for file in src .files .to_list ():
70- sp = file .short_path
71- if sp .startswith (ctx .attr .strip_prefix ):
72- sp = sp [len (ctx .attr .strip_prefix ):]
61+ if ctx .attr .subdirectory == "lib" :
62+ exe_file = src .files_to_run .executable
7363 symlink_path = paths .join (
7464 ctx .attr .prefix ,
75- "share " ,
65+ "lib " ,
7666 ctx .attr .package_name ,
77- sp ,
67+ exe_file . basename ,
7868 )
79- runfiles_symlinks [symlink_path ] = file
69+ root_symlinks [symlink_path ] = exe_file
70+ else :
71+ for file in src .files .to_list ():
72+ sp = file .short_path
73+ if sp .startswith (ctx .attr .strip_prefix ):
74+ sp = sp [len (ctx .attr .strip_prefix ):]
75+ symlink_path = paths .join (
76+ ctx .attr .prefix ,
77+ ctx .attr .subdirectory ,
78+ ctx .attr .package_name ,
79+ sp ,
80+ )
81+ root_symlinks [symlink_path ] = file
8082
8183 return [
8284 AmentIndex (prefix = ctx .attr .prefix ),
8385 DefaultInfo (
84- runfiles = ctx .runfiles (root_symlinks = runfiles_symlinks ),
86+ runfiles = ctx .runfiles (root_symlinks = root_symlinks ),
8587 ),
8688 ]
8789
88- ament_index_share_files = rule (
90+ _ament_index_files = rule (
8991 attrs = dict (
9092 package_name = attr .string (mandatory = True ),
9193 srcs = attr .label_list (
9294 mandatory = True ,
9395 allow_empty = False ,
9496 allow_files = True ,
9597 ),
98+ subdirectory = attr .string (default = "share" ),
9699 # A prefix is required because the shim can't prepend the runfiles
97100 # root to AMENT_PREFIX_PATH
98101 prefix = attr .string (default = "ament_index_share_files" ),
99102 strip_prefix = attr .string (default = "" ),
100103 ),
101- implementation = _ament_index_share_files_impl ,
104+ implementation = _ament_index_files_impl ,
102105 output_to_genfiles = True ,
103106 provides = [AmentIndex ],
104107)
105- """
106- Creates an ament resource index and share/ directory for a single package.
107-
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.
114-
115- d = ament_index_cpp::get_package_share_directory("package_name")
116- file = join(d, "short_path of file")
117-
118- Note that this works only when bazel creates runfiles links,
119- and not just a *.runfiles_manifest (which it might do on an unsupported
120- platform like Windows, or with `--nobuild_runfile_links`).
121-
122- Note that the same `package_name` for ROS 2 packages should not be used
123- in multiple different rules spread across multiple Bazel packages.
124- This is called "overriding", and it's not currently supported.
125- Currently if the two calls to `ament_index_share_files` also have
126- the same value for "prefix", then a target depending on both may
127- be able to find resources from both rules, but that behavior is not
128- guaranteed.
129- TODO(sloretz) detect and error when a target is given two ament indexes
130- with the same package.
131-
132- Args:
133- package_name: name of a ROS 2 package to which these share files belong
134- srcs: files to put into the share directory
135- prefix: optional prefix to give to the generated runfiles.
136- strip_prefix: optional prefix to strip from the short_path of the files
137-
138- Provides:
139- AmentIndex: a prefix path where the ament resource index was generated.
140- DefaultInfo: folders and symlinked files to add to the runfiles of a
141- dependent target.
142-
143- See https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md
144- for further reference.
145- """ # noqa
108+
109+ def ament_index_share_files (name , package_name , srcs , prefix = "ament_index_share_files" , strip_prefix = "" , ** kwargs ):
110+ """Creates an ament resource index and share/ directory for a single package.
111+
112+ Files in `srcs` will be added to `<prefix>/share/<package_name>/`.
113+ A target depending on this one will be able to access the files in the
114+ share directory using the package's share directory joined with the
115+ files they expect.
116+
117+ d = ament_index_cpp::get_package_share_directory("package_name")
118+ file = join(d, "short_path of file")
119+
120+ Note that this works only when bazel creates runfiles links,
121+ and not just a *.runfiles_manifest (which it might do on an unsupported
122+ platform like Windows, or with `--nobuild_runfile_links`).
123+
124+ Note that the same `package_name` for ROS 2 packages should not be used
125+ in multiple different rules spread across multiple Bazel packages.
126+ This is called "overriding", and it's not currently supported.
127+ Currently if the two calls to `ament_index_share_files` also have
128+ the same value for "prefix", then a target depending on both may
129+ be able to find resources from both rules, but that behavior is not
130+ guaranteed.
131+ TODO(sloretz) detect and error when a target is given two ament indexes
132+ with the same package.
133+
134+ Args:
135+ package_name: name of a ROS 2 package to which these share files belong
136+ srcs: files to put into the share directory
137+ prefix: optional prefix to give to the generated runfiles.
138+ strip_prefix: optional prefix to strip from the short_path of the files
139+
140+ Provides:
141+ AmentIndex: a prefix path where the ament resource index was generated.
142+ DefaultInfo: folders and symlinked files to add to the runfiles of a
143+ dependent target.
144+
145+ See https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md
146+ for further reference.
147+ """ # noqa
148+ _ament_index_files (
149+ name = name ,
150+ package_name = package_name ,
151+ srcs = srcs ,
152+ subdirectory = "share" ,
153+ prefix = prefix ,
154+ strip_prefix = strip_prefix ,
155+ ** kwargs
156+ )
157+
158+ def ament_index_executables (name , package_name , srcs , prefix = "ament_index_share_files" , ** kwargs ):
159+ """Creates an ament resource index that exposes Bazel-built executables under
160+ `<prefix>/lib/<package_name>/`, enabling launch_ros.actions.Node(package=...,
161+ executable=...) to find them without a colcon install space.
162+
163+ When added to the `data=` of a ros_launch() target, the shim injects
164+ `<prefix>` into AMENT_PREFIX_PATH so ROS 2 libexec lookup succeeds:
165+
166+ launch_ros.actions.Node(package="my_pkg", executable="my_node")
167+ # resolves to: <prefix>/lib/my_pkg/my_node ✓
168+
169+ Args:
170+ package_name: the ROS 2 package name (must match Node(package=...))
171+ srcs: Bazel labels of the executable targets to expose
172+ prefix: optional directory prefix for the generated runfiles tree
173+
174+ Provides:
175+ AmentIndex: a prefix path where the ament resource index was generated.
176+ DefaultInfo: symlinks and marker files for all executables.
177+ """ # noqa
178+ _ament_index_files (
179+ name = name ,
180+ package_name = package_name ,
181+ srcs = srcs ,
182+ subdirectory = "lib" ,
183+ prefix = prefix ,
184+ ** kwargs
185+ )
0 commit comments