Disambiguate ARM hard-float vs soft-float (and WASM threads) target triples#154
Conversation
|
@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? |
| return constraints | ||
|
|
||
| def triple_to_constraint_set(target_triple, targets = None): | ||
| constraints = triple_to_rust_constraint_set(target_triple, targets) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
| # 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 = [ |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
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.
Problem
The generated toolchains
select()on per-tripleconfig_settings whose constraints came fromtriple_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 (thearm/armv7×gnu/musleabi/eabihfpairs,thumbv8m.main-none-eabi/eabihf,aarch64-unknown-none/-softfloat, andwasm32-wasip1/wasm32-wasip1-threads), and building for a matching platform failed withIllegal ambiguous match on configurable attribute "target_triple".Fix
New constraints in
rs/platforms/constraints/BUILD.bazel: afloat_abisetting (hardfloatdefault /softfloat) and awasm_threadssetting (wasm_threads_offdefault /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 theeabi↔eabihf,-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, whichrules_rustalready maps to distinct CPUs), so non-annotated consumers keep resolving. Thetargetslist is threaded through to the config-settings, platforms, and toolchain projections so a custom triple subset stays self-consistent. No change to theselect()construction is needed — unique config settings disambiguate on their own.New Starlark suite in
rs/platforms/triples_test.bzlasserts 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:alland//rs/private:alltests pass.@default_rust_toolchains//:allloads with distinctaarch64_unknown_nonevs_softfloattoolchains.bazel cqueryacross all eight previously-colliding platforms resolves cleanly with no ambiguous match.config:arm-unknown-linux-musleabi→[…, musl, softfloat]vsmusleabihf→[…, 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