Summary
ros2/ament.bzl only installs .msg files into the ament share directory. .srv and .action definition files are silently skipped, which breaks any tool that relies on runtime type introspection (e.g. foxglove_bridge, ros2 service call, ros2 interface show).
Root cause
In _create_ament_setup (ament.bzl), the loop that symlinks IDL sources into share/<pkg>/msg/ has an early-exit guard:
```python
for src in idl.srcs:
if src.extension != "msg":
continue # .srv and .action files are never installed
src_file = ctx.actions.declare_file(
paths.join(prefix_path, "share", package_name, "msg", src.basename),
)
...
idl_manifest_contents.append(paths.join("msg", src.basename))
```
A ros2_interface_library like rcl_interfaces has both .msg and .srv in its srcs, but only the .msg files end up in the ament prefix tree. Service definitions (DescribeParameters.srv, GetParameters.srv, etc.) are missing entirely.
Observed symptoms
When launching foxglove_bridge (or any node that discovers service endpoints), the bridge logs one warning per service type on every node it discovers:
```
[WARN] no .msg definition for rcl_interfaces/srv/DescribeParameters_Request, falling back to IDL
[WARN] Could not find definition for type rcl_interfaces/srv/DescribeParameters: rcl_interfaces/srv/DescribeParameters_Request
[WARN] no .msg definition for rcl_interfaces/srv/GetParameters_Request, falling back to IDL
[WARN] Could not find definition for type rcl_interfaces/srv/GetParameters: rcl_interfaces/srv/GetParameters_Request
... (one pair per service type, per discovered node)
```
The same problem affects type_description_interfaces/srv/GetTypeDescription and any other package whose ros2_interface_library target includes .srv or .action files.
Fix
Route each source file into its matching subdirectory (msg/, srv/, action/) instead of hardcoding msg/:
```python
for src in idl.srcs:
if src.extension not in ("msg", "srv", "action"):
continue
subdir = src.extension
src_file = ctx.actions.declare_file(
paths.join(prefix_path, "share", package_name, subdir, src.basename),
)
ctx.actions.symlink(output = src_file, target_file = src)
outputs.append(src_file)
idl_manifest_contents.append(paths.join(subdir, src.basename))
```
A PR with this change is attached.
Summary
ros2/ament.bzlonly installs.msgfiles into the ament share directory..srvand.actiondefinition files are silently skipped, which breaks any tool that relies on runtime type introspection (e.g.foxglove_bridge,ros2 service call,ros2 interface show).Root cause
In
_create_ament_setup(ament.bzl), the loop that symlinks IDL sources intoshare/<pkg>/msg/has an early-exit guard:```python
for src in idl.srcs:
if src.extension != "msg":
continue # .srv and .action files are never installed
src_file = ctx.actions.declare_file(
paths.join(prefix_path, "share", package_name, "msg", src.basename),
)
...
idl_manifest_contents.append(paths.join("msg", src.basename))
```
A
ros2_interface_librarylikercl_interfaceshas both.msgand.srvin itssrcs, but only the.msgfiles end up in the ament prefix tree. Service definitions (DescribeParameters.srv,GetParameters.srv, etc.) are missing entirely.Observed symptoms
When launching
foxglove_bridge(or any node that discovers service endpoints), the bridge logs one warning per service type on every node it discovers:```
[WARN] no .msg definition for rcl_interfaces/srv/DescribeParameters_Request, falling back to IDL
[WARN] Could not find definition for type rcl_interfaces/srv/DescribeParameters: rcl_interfaces/srv/DescribeParameters_Request
[WARN] no .msg definition for rcl_interfaces/srv/GetParameters_Request, falling back to IDL
[WARN] Could not find definition for type rcl_interfaces/srv/GetParameters: rcl_interfaces/srv/GetParameters_Request
... (one pair per service type, per discovered node)
```
The same problem affects
type_description_interfaces/srv/GetTypeDescriptionand any other package whoseros2_interface_librarytarget includes.srvor.actionfiles.Fix
Route each source file into its matching subdirectory (
msg/,srv/,action/) instead of hardcodingmsg/:```python
for src in idl.srcs:
if src.extension not in ("msg", "srv", "action"):
continue
subdir = src.extension
src_file = ctx.actions.declare_file(
paths.join(prefix_path, "share", package_name, subdir, src.basename),
)
ctx.actions.symlink(output = src_file, target_file = src)
outputs.append(src_file)
idl_manifest_contents.append(paths.join(subdir, src.basename))
```
A PR with this change is attached.