Skip to content

fix(build): rerun the build script when AMENT_PREFIX_PATH changes - #31

Open
rosterloh wants to merge 1 commit into
ros2-rust:mainfrom
rosterloh:build/rerun-on-ament-prefix-path
Open

rosterloh wants to merge 1 commit into
ros2-rust:mainfrom
rosterloh:build/rerun-on-ament-prefix-path

Conversation

@rosterloh

Copy link
Copy Markdown
Contributor

Problem

build.rs emits a rustc-link-search path for every prefix on
AMENT_PREFIX_PATH, but declares only ROS_DISTRO and build.rs as rerun
triggers. Once a build script emits any rerun-if line, Cargo reruns it
only for the listed triggers. So the search paths stay whatever they were
on the first build.

ros-env does declare rerun-if-env-changed=AMENT_PREFIX_PATH. So after
sourcing a workspace that adds an interface package, ros-env reruns and
compiles that package in, with a #[link] to its typesupport library, but no
build script offers the new prefix's lib/ to the linker:

ld: library not found for -leit_capture_interfaces__rosidl_typesupport_c

The library is on the new prefix. cargo clean -p rclrs -p rosidl_runtime_rs
fixes it, which is how it has been worked around.

Reproduction

A crate depending on rclrs 0.8.0 and ros-env 0.3.0, in a fresh target
directory:

  1. Build with only the base ROS environment sourced → ok.
  2. Source a workspace that adds an interface package, rebuild without cleaning.
Build step 2
crates.io rclrs 0.8.0 + rosidl_runtime_rs 0.7.0 fails (library not found)
this PR only links
the rclrs companion only links
both links

Either change alone is enough, because Cargo collects link search paths from
every build script. Both are proposed because each crate reads the variable
and should say so; a crate using rosidl_runtime_rs without rclrs would
otherwise keep stale paths.

Change

One println!("cargo:rerun-if-env-changed={AMENT_PREFIX_PATH}"), inside the
not(use_ros_shim) block where the variable is actually read.

Testing

  • The reproduction above (ROS 2 Lyrical, RoboStack, macOS arm64).
  • cargo test --workspace and -F=serde, cargo clippy --workspace --all-targets -- -D warnings,
    cargo fmt --check: all pass.

build.rs emits a rustc-link-search path for every prefix on
AMENT_PREFIX_PATH, but declares only ROS_DISTRO and build.rs as rerun
triggers. Once a build script emits any rerun-if line, Cargo reruns it only
for the listed triggers, so the search paths stay whatever they were on the
first build.

Reproduced with a crate that depends on rclrs 0.8.0 and ros-env 0.3.0: build
it, source a workspace that adds an interface package, and rebuild without
`cargo clean`. ros-env declares rerun-if-env-changed=AMENT_PREFIX_PATH, so it
reruns and compiles the new package in, with a #[link] to its typesupport
library. rclrs and rosidl_runtime_rs, which emit the per-prefix link search
paths, do not rerun, so the final link fails with
"library not found for -l<pkg>__rosidl_typesupport_c" although the library is
on the new prefix. With this change the rebuild links.

Assisted-by: Claude Code:claude-opus-5-5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant