rust-overlay: Fix cross-compilation #347
Open
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.
This PR addresses two shortcomings in #222. rust-overlay works wonderfully if we use the
targetsargument:But if we request the same through the generic nixpkgs cross-compilation mechanism, it fails to evaluate entirely:
Here I'm requesting
rustChannels.stable.rustwithhostPlatformstill set to my platform, e.g. x86_64, andtargetPlatformset toaarch64-unknown-none. The reason this fails is because we're trying to look up the extensions forpkg.rust.target.aarch64-unknown-none, instead ofpkg.rust.target.x86_64-unknown-linux-gnu(which is what we'll actually fetch and use).So this seems like a very clear typo; there is no situation where we'd want to look up extensions or components for the targetPlatform, it should always be the hostPlatform (matching the package we'll download and unpack). The reason this hasn't been spotted until now is likely that for many target platforms, like
aarch64-multiplatform, the key did exist and the code succeeded (even if by looking at the wrong key).However, fixing this is not entirely enough. It will now evaluate and build, but the resulting sysroot still lacks rust-std for
aarch64-unknown-none(which we do get if we useoverride { targets = [ "aarch64-unknown-none" ]; }). From looking at #222 I see that the way this works is we fetchpkg.rustfor BOTH platforms, and then we merge the two sysroots, and because of the order, the sysroot for the host platform ends up overriding most of the files (except for notably rust-std).I find this very problematic: for once, it doesn't work for targets (like
aarch64-unknown-none) that have rust-std but not a whole toolchain. I also very much doubt sysroots are designed to be merged like that; a sysroot should only be merged with its extensions, not other sysroots. It also consumes unnecessary disk space / bandwidth downloading the whole toolchain when just rust-std is enough.So, the second commit makes the second Nix snippet behave identically to the first one:
hostTargetsnow contains onlyhostPlatform, not thetargetPlatform, which is instead added implicitly to thetargetsargument (assuming the platforms are different).