rust-osdev / cargo-xbuild

Automatically cross-compiles the sysroot crates core, compiler_builtins, and alloc.
Apache License 2.0
258 stars 25 forks source link

More x*? #18

Open WildCryptoFox opened 5 years ago

WildCryptoFox commented 5 years ago

At least xrun and xdoc would be nice. Maybe an xdo $command to run arbitrary cargo-* with the appropriate environment configured. Is there any reason why xbuild doesn't act like xargo and cover all bases?

phil-opp commented 5 years ago

Sure, I'm happy to merge PRs for additional subcommands.

When forking xargo I tried to minimize functionality as much as possible (e.g. remove configurability, support for building std, support for rustdoc, etc) to keep it maintainable for me. In the course of this I also decided to only implement an xbuild command since I didn't want to maintain something that I don't use. However adding back support for rustdoc would be fine with me, I think it it just required an additional environment variable.

IsaacWoods commented 5 years ago

What would xrun do? If you're using cargo-xbuild to cross-compile something, you probably won't be able to run it on the host system?

berkus commented 5 years ago

@IsaacWoods I'm using xargo run to build and run my kernel in qemu (by using .cargo/config to specify which commands to run, see for example here). I expect cargo xrun to work in a similar way.

WildCryptoFox commented 5 years ago

Hmm. export RUSTFLAGS="--sysroot $HOME/path/to/target/sysroot"; export RUSTDOCFLAGS=$RUSTFLAGS after having done an xbuild results in cargo * just working.

Is there any reason why rustup shouldn't be the one accepting custom targets and updating the sysroots as rust is updated? IIUC we only need the sysroot built to match the compiler.

phil-opp commented 5 years ago

Interesting idea. We could extend rustup to support rustup target add path/to/your/target.json, which rebuilds the sysroot for that target and adds it to its global sysroot. On rustup update, rustup just rebuilds everything. This would mean that built-in targets and custom targets would almost work the same and we could use normal cargo for both. I like it!

Implementation-wise, we would need to do the following: Currently rustc/cargo make custom targets unique by adding a hash of the canonical path to the JSON file (e.g. x86_64-blog_os-2134893102489). We could change this to generate the hash from the file's content instead. Then any change to our target JSON would cause a target mismatch, which leads to a cannot find core error again. So we need to run rustup target add … again. To avoid trashing the sysroot with old targets, rustup could remember the path of target JSON for each custom target and remove old targets with the same path on each rustup target add ….

WildCryptoFox commented 5 years ago

@phil-opp Rustup is already wrapping cargo/rustc to add its +version feature, so it could do that check. Avoiding the manual re-add.

phil-opp commented 5 years ago

@james-darkfox You mean automatically compiling the target if it is not part of the sysroot already?

WildCryptoFox commented 5 years ago

@phil-opp I mean automatically following the changes of the target.json. Still need to add each custom target file for tracking.

phil-opp commented 5 years ago

Sounds reasonable.

Maybe open a thread on https://internals.rust-lang.org/ or an issue at https://github.com/rust-lang-nursery/rustup.rs to hear what the rust/rustup devs think about your idea?

WildCryptoFox commented 5 years ago

@phil-opp rust-lang-nursery/rustup.rs/issues/1538

WildCryptoFox commented 5 years ago

@phil-opp If they have an issue with the added complexity, it might be better to just have an xargo/xbuild that does only the libcore-etc without trying to do cargo's job. Just build the target and put the artifacts in the chosen sysroot. Then rustup would only need to decide when to call it. Basically whenever rust-src or the target.json change.

How much more effort would it take to support a custom std, as xargo supports?

WildCryptoFox commented 5 years ago

In the meantime... The following skips the unexpected core-rebuilding and sysroot-wide lockfile. I.e. cargo run in one shell shouldn't block other use of cargo *.

#!/bin/sh

# . update-sysroot [TARGET]
# TARGET defaults to x86_64-sel4-robigalia

unset RUSTFLAGS RUSTDOCFLAGS

TARGET=${1:-x86_64-sel4-robigalia}

which cargo-xrustc && SYSROOT=$(cargo xrustc --target $TARGET -- --print sysroot) \
  || which xargo && SYSROOT=$(xargo rustc --target $TARGET -- --print sysroot)

export RUSTFLAGS="--sysroot $SYSROOT"
export RUSTDOCFLAGS="$RUSTFLAGS"

unset TARGET SYSROOT
phil-opp commented 5 years ago

If they have an issue with the added complexity, it might be better to just have an xargo/xbuild that does only the libcore-etc without trying to do cargo's job. Just build the target and put the artifacts in the chosen sysroot.

This should be easily possible.

How much more effort would it take to support a custom std, as xargo supports?

I don't know, I never needed std for my custom targets. But if the std building of xargo still works with current nightlies, it shouldn't be to difficult to just copy the corresponding code from xargo.

phil-opp commented 5 years ago

The following skips the unexpected core-rebuilding and sysroot-wide lockfile. I.e. cargo run in one shell shouldn't block other use of cargo *.

Nice! If using cargo-xbuild, I would configure it to use a global sysroot, otherwise it only works for a single project. Also, do normal non-no_std crates still work?

WildCryptoFox commented 5 years ago

@phil-opp At least my build.rs still works. So I'll take that as a yes.