Conversation
build.rs emits a rustc-link-search path for every prefix from get_search_paths(), which reads AMENT_PREFIX_PATH, but declares only ROS_DISTRO as a rerun trigger. 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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
rclrs/build.rsemits arustc-link-searchpath for every prefixget_search_paths()returns fromAMENT_PREFIX_PATH, but declares onlyROS_DISTROas a reruntrigger. Once a build script emits any
rerun-ifline, Cargo reruns itonly 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 aftersourcing a workspace that adds an interface package, ros-env reruns and
compiles that package in, with a
#[link]to its typesupport library, but nobuild script offers the new prefix's
lib/to the linker:The library is on the new prefix.
cargo clean -p rclrs -p rosidl_runtime_rsfixes 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:
library not found)Cargo collects link search paths from every build script, so this repro links
once either crate reruns. The rosidl_runtime_rs companion is the one that
clears the symptom for everyone: every rclrs user also builds it, and crates
that use ros-env without rclrs get their search paths only from it.
This PR is still needed on its own terms.
rclrs/build.rsreadsAMENT_PREFIX_PATHand should declare it as a rerun trigger. Without that,rclrs keeps handing the linker the old prefixes, and an older copy of a
library left in one of them can be picked ahead of the new one.
Change
One
println!("cargo:rerun-if-env-changed={AMENT_PREFIX_PATH_ENV_VAR}"), usingament_rs's own constant, next to the
get_search_paths()call that reads it.Testing
cargo test -F default(RoboStack Lyrical withtest_msgsandexample_interfaces, Rust 1.98.1 stable, macOS arm64): 120 tests and 51doc-tests pass, the same as on
main.cargo clippy --no-deps --all-targets -F default -- -D warningsfails withthe same 123 findings on
mainand on this branch under clippy 0.1.98(the library's deref and doc-list lints). None of them are in
build.rs,so
maindoesn't pass this gate on current stable either.cargo fmt --check: clean. CI uses nightly rustfmt, which I didn't run.