Skip to content

Disambiguate ARM hard-float vs soft-float (and WASM threads) target triples#154

Merged
dzbarsky merged 2 commits into
hermeticbuild:mainfrom
pcrumley:pcrumley/arm-float-abi
Jun 26, 2026
Merged

Disambiguate ARM hard-float vs soft-float (and WASM threads) target triples#154
dzbarsky merged 2 commits into
hermeticbuild:mainfrom
pcrumley:pcrumley/arm-float-abi

Conversation

@pcrumley

Copy link
Copy Markdown
Contributor

Problem

The generated toolchains select() on per-triple config_settings whose constraints came from triple_to_rust_constraint_set()cpu, os, libc, but no float-ABI or WASM-threads bit. So 7 groups of triples projected to identical constraint sets (the arm/armv7 × gnu/musl eabi/eabihf pairs, thumbv8m.main-none-eabi/eabihf, aarch64-unknown-none/-softfloat, and wasm32-wasip1/wasm32-wasip1-threads), and building for a matching platform failed with Illegal ambiguous match on configurable attribute "target_triple".

Fix

New constraints in rs/platforms/constraints/BUILD.bazel: a float_abi setting (hardfloat default / softfloat) and a wasm_threads setting (wasm_threads_off default / wasm_threads_on). The defaults are the conventional/plain variant so existing platforms resolve unchanged; the other variant opts in explicitly.

triple_to_rust_constraint_set (rs/platforms/triples.bzl) appends a disambiguator only when a triple has a sibling that is also in the target set and projects to the same base constraint set — a genuine collision. This covers the eabieabihf, -softfloat-suffix, and -threads-suffix encodings. Scoping to actual base-set equality leaves lone targets untouched and skips pairs that already differ (e.g. thumbv7em-none-eabi/eabihf, which rules_rust already maps to distinct CPUs), so non-annotated consumers keep resolving. The targets list is threaded through to the config-settings, platforms, and toolchain projections so a custom triple subset stays self-consistent. No change to the select() construction is needed — unique config settings disambiguate on their own.

New Starlark suite in rs/platforms/triples_test.bzl asserts the uniqueness invariant over all triples, that each colliding pair is separated by a distinct disambiguator, and that lone targets gain none. README "Cross ABI target details" documents the new constraints.

Verification

//rs/platforms:all and //rs/private:all tests pass. @default_rust_toolchains//:all loads with distinct aarch64_unknown_none vs _softfloat toolchains. bazel cquery across all eight previously-colliding platforms resolves cleanly with no ambiguous match. config:arm-unknown-linux-musleabi[…, musl, softfloat] vs musleabihf[…, musl, hardfloat]. Non-ARM/non-WASM config settings and platforms are unaffected. No triples removed and no consumer-facing tags/attributes changed.

proposed fix for #153

@pcrumley pcrumley marked this pull request as draft June 17, 2026 00:13
@pcrumley pcrumley marked this pull request as ready for review June 17, 2026 00:52
@dzbarsky

Copy link
Copy Markdown
Member

@pcrumley Hello again :) My apologies for this papercut - it's a gap I've been aware of but was putting off because the right home for these constraints is in https://github.com/bazel-contrib/platforms_contrib which is getting actively built out. (cc @fmeum) But since you've hit this, I think it's fine if we fix it here and later alias to contrib + deprecate these constraints; it's not the end of the world

Could you take a look at my suggestions and check if it's doable to simplify?

Comment thread rs/platforms/triples.bzl
return constraints

def triple_to_constraint_set(target_triple, targets = None):
constraints = triple_to_rust_constraint_set(target_triple, targets)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why the mechanism above is different from the one below, can we just follow the pattern below, it seems easier to reason about?

@pcrumley pcrumley Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah the reason is you do need to call out to a helper to see if there is a sibling triple, however, you can keep the inline in here and only have at sibling logic be a helper.

Comment thread rs/platforms/triples_test.bzl Outdated
# representative non-ARM triple. thumbv7em-none-{eabi,eabihf} are included
# because rules_rust already maps them to distinct CPUs (armv7e-m vs armv7e-mf),
# so they do not collide and tagging them would break non-annotated consumers.
_LONE_TRIPLES = [

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could just have a simple rust target that we transition to all target triples as more of an integration test vs this testing internals?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it would be too heavy to have to pull in a toolchain for every target platform, and for some of the platforms you get cc toolchain errors for even very simple targets. I think i figured out a way that still actually iterates over all of triples and doesn't just sort of test the own internal logic of it. This test is still a red-green test from this change

Replace the triple->constraint-set unit test with an integration test
that transitions a probe across all target triples and fails on the same
ambiguous-match error the bug produced.

Inline triple_to_rust_constraint_set to match triple_to_constraint_set:
drop _base_rust_constraint_set and _disambiguator_constraint; the
collision check now compares rules_rust's own mapping for a triple vs its
sibling. Constraint sets are unchanged.
@dzbarsky dzbarsky merged commit f5ef8a6 into hermeticbuild:main Jun 26, 2026
0 of 10 checks passed
dzbarsky added a commit that referenced this pull request Jun 26, 2026
This simplifies the target-triple disambiguation added by #154.
`triple_to_rust_constraint_set` now appends `hardfloat` for target
triples ending in `eabihf`, appends `softfloat` for target triples
ending in `eabi`, and handles the AArch64 soft-float and WASM thread
target triples directly. The `wasm32-unknown-emscripten`
`config_setting` also specializes the overlapping CPU and
operating-system cases in the `binary_ext` and `dylib_ext` selects.
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.

2 participants