r-universe-org / help

Support and bug tracker for R-universe
https://docs.r-universe.dev/
8 stars 2 forks source link

Install aarch64-apple-darwin target of Rust toolchain for cross-compile #340

Closed yutannihilation closed 5 months ago

yutannihilation commented 5 months ago

I saw this comment and tried to cross-compile my Rust-powered package for arm64 macOS.

https://github.com/r-universe-org/help/issues/97#issuecomment-1880221054

But, it currently fails because the R-universe's runner doesn't have aarch64-apple-darwin target installed.

https://github.com/r-universe/yutannihilation/actions/runs/7442778977/job/20246753858

error[E0463]: can't find crate for `core`
  |
  = note: the `aarch64-apple-darwin` target may not be installed
  = help: consider downloading the target with `rustup target add aarch64-apple-darwin`
error[E0463]: can't find crate for `compiler_builtins`
error[E0463]: can't find crate for `core`

Is it possible to make the target available for builds that use Rust? Just like the case of the GNU toolchain on Windows, we can probably run rustup add in Makevars, but it's nice if it's pre-installed.

jeroen commented 5 months ago

Thanks I had forgotten. fixed it now here: https://github.com/r-universe-org/build-and-check/commit/4fe6f6e43031da9462c4d08dc3db90fee24ea5dd

It looks like string2path now passes: https://github.com/r-universe/yutannihilation/actions/runs/7446364778/job/20256571487

In order to help packages that simply call cargo build without a target, I also tried to set the correct default target for the cross-compile step like so:

rustup default stable-aarch64-apple-darwin

However this resulted in an error error: command failed: 'cargo': Bad CPU type in executable (os error 86). So seemingly this changes the entire toolchain, not just the target.

Do you know if there is a way to tell rustup/cargo to target by default aarch64-apple-darwin?

yutannihilation commented 5 months ago

Oh, cool!!! Thanks so much.

So seemingly this changes the entire toolchain, not just the target.

Yes, rustup default is a command to set the default toolchain, not target.

❯ rustup default -h    
rustup.exe-default 
Set the default toolchain

Do you know if there is a way to tell rustup/cargo to target by default aarch64-apple-darwin?

It seems there are no handy way for target like rustup default, but it seems we can configure it by putting these lines into $CARGO_HOME/config.toml (I haven't tried it yet). As this is the least priority of configuration, this is less likely to accidentally overwrite users' configuration.

[build]
target = "aarch64-apple-darwin"

c.f. https://stackoverflow.com/questions/49453571/how-can-i-set-default-build-target-for-cargo

Or, setting CARGO_TARGET envvar might also work.

c.f., https://doc.rust-lang.org/cargo/reference/environment-variables.html#configuration-environment-variables

I'm not sure if this affects the location of the artifact, which accordingly requires users to tweak LIBDIR (i.e. ./rust/target/release vs ./rust/target/aarch64-apple-darwin/release). I need to test.

yutannihilation commented 5 months ago

I'm not sure if this affects the location of the artifact, which accordingly requires users to tweak LIBDIR (i.e. ./rust/target/release vs ./rust/target/aarch64-apple-darwin/release)

Hmm, it seems both ways cause this and there's no way to handle the change of the location of the artifact transparently. There are several proposals related to this (e.g. https://github.com/rust-lang/cargo/issues/6100, https://github.com/rust-lang/rfcs/pull/3371), but, at the moment, the package needs to be cross-compile-aware.

I doubt arm64 macOS runners become available soon, considering they have repeatedly delayed the roadmap (c.f. https://github.com/actions/runner-images/issues/2187). But, ultimately, the crosss-compile is a temporary workaround until it eventually comes. So, IMHO, it's fine to impose the effort to package authors at this stage.

jeroen commented 5 months ago

I found a hack to make it work I think.

I added the following shim (wrapper) for cargo to the PATH on the macos cross environment: https://github.com/r-universe-org/prepare-macos/blob/master/shims/cargo.sh

The shim both overrides the default target and then copies the aarch64-apple-darwin to the parent dir afterwards.

yutannihilation commented 5 months ago

Looks good to me!