Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for the crosstool-ng Raspberry Pi 2 toolchain #30948

Merged
merged 1 commit into from
Jan 29, 2016

Conversation

fabricedesre
Copy link
Contributor

This adds support for the armv7 crosstool-ng toolchain for the Raspberry Pi 2.

Getting the toolchain ready:
Checkout crosstool-ng from https://github.com/crosstool-ng/crosstool-ng
Build crosstool-ng
Configure the rpi2 target with |ct-ng armv7-rpi2-linux-gnueabihf|
Build the toolchain with |ct-build| and add the path to $toolchain_install_dir/bin to your $PATH

Then, on the rust side:
configure --target=armv7-rpi2-linux-gnueabihf && make && make install

To cross compile for the rpi2,
add $rust_install_path/lib to your $LD_LIBRARY_PATH, then use
rustc --target=armv7-rpi2-linux-gnueabihf -C linker=armv7-rpi2-linux-gnueabihf-g++ hello.rs

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nrc (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@nrc
Copy link
Member

nrc commented Jan 16, 2016

r? @alexcrichton

@rust-highfive rust-highfive assigned alexcrichton and unassigned nrc Jan 16, 2016
@MagaTailor
Copy link

On the rust side, Rpi2 is just a standard armhf target and +v7 can be turned on with the -C target-feature switch (the RustBuild armv7 binaries are already built this way).

As long as the custom targets are not officially recognized it will just cause problems during cargo builds.
Moreover it doesn't make sense to add targets named after just one brand - there's also

odroid, banana/orange pi, tegra, beaglebone, etc.

@fabricedesre
Copy link
Contributor Author

I didn't know about RustBuild, but that would work for me, once warricksothr/RustBuild#11 is fixed.
@alexcrichton, feel free to close this PR.

@fabricedesre
Copy link
Contributor Author

That would still be nice to have a non-android armv7 target in the tree I think however.

@alexcrichton
Copy link
Member

Awesome! I've wondered in the past if we'd end up grown a custom target here...

Before we land though I was wondering if you could help me understand this target triple a little better? Right now we're currently producing nightlies for two different ARM OSes:

  • arm-unknown-linux-gnueabi{,hf}
  • arm-linux-androideabi

I'm not personally aware of what ARM version they're using (e.g. v5, v6, v7, etc), but I think that the raspberry pi is using Linux, right? Along those lines, I'm curious how armv7-rpi2-linux-gnueabihf differs from arm-unknown-linux-gnueabihf. I'm not sure if LLVM or the standard library does much with a "known vendor" (aka rpi2 vs unknown), but I suspect that LLVM would indeed do things differently for the armv7 vs arm architecture.

With that, I wonder if arm-unknown-linux-gnueabihf would run "by default" on the raspberry pi? It may not use all newer features of the instruction set, but as @petevine pointed out I think those can be enabled with a target-feature flag (albeit not easily through Cargo).

If that's the case, though, would we benefit from a new target? It may be good to have a nice set of pre-defined defaults for the raspberry pi if it's common enough in any case.

@MagaTailor
Copy link

The only difference is armv7 instead of armv6 so accepting a target named rpi2 is bound to look like product placement while the existing armhf target is fully compatible with that device.

I did a few benchmarks to see whether the fact rlibs built for v6 had any negative impact on performance - none whatever. The most important thing when compiling your own code is to pass the correct target-cpu to llvm which no target-triple is going to address.

A more generic alternative would be to add a target named armv7-unknown-linux-gnueabihf (but there exist soft-float armv7 platforms too) so it can be used by any and all armv7 hard-float setups.

Simply using the latest binary builds from RustBuild fully addresses the cross-compilation issue, i.e. rlibs built for v7 even though, as I'd mentioned at the beginning, it's not necessary at all.

@fabricedesre
Copy link
Contributor Author

I still want to check why crosstool-ng has a specific rpi2 target in addition to the generic armv7.
And the rpi2 may be popular enough to justify a dedicated setup, especially if we can automate the target-cpu thing.

@MagaTailor
Copy link

The one that's popular due to the volume produced and the time it's been around is the original Rpi. It would make more sense to create a target for that. (incl. Rpi Zero!)

Rpi2 is just standard armv7 using a newer distro. It was introduced in response to much better alternatives available for the same money or even cheaper. In short, there's nothing special about it.

For your own use, and to make this patch at all meaningful, you should modify the target:

let mut base = super::linux_base::opts();
    base.cpu = "cortex-a7".to_string();

as well as add +neon to this and the other file.

Once you've done that you could post your results here to make llvm better on ARM.

@alexcrichton
Copy link
Member

Ok, so it sounds like arm-unknown-linux-gnueabihf does run on the raspberry pi by default? If I'm reading this correctly LLVM defaults to armv6 for that target (right?) and then it may emit less optimized code as it's going for a generic CPU instead of a specific one.

We've had a lot of cases in the past where only a few minor tweaks are made to codegen options for a target (e.g. a small delta from an existing target), so for now it sounds like it may be overkill to add a whole new target for some tweaks here and there.

@fabricedesre would it be possible to use the arm-unknown-linux-gnueabihf nightlies? Is there a drawback to doing so? (still trying to get the lay of the land here)

@joerg-krause
Copy link
Contributor

Have a look at the LLVM triple doc and the Clang cross compilation doc: LLVM does not understand the vendor rpi2 nor rpi.

LLVM defaults to arm1176jzf-s for hard-float platforms and to arm7tdmi otherwise.

@fabricedesre
Copy link
Contributor Author

Yes @alexcrichton we can use arm-unknown-linux-gnueabihf as a target. We can definitely live with that.
It still looks strange to me that we don't have a generic armv7 config, and a way to tweak cpu/fpu reasonnably (eg on the rpi2 cpu=cortex-a7 and fpu=neon-vfpv4).

@petevine I'll upload my results to the llvm bug soon.

@alexcrichton
Copy link
Member

Ah ok, now we may still want to add a dedicated armv7 target for CPUs with those features (e.g. ship an armv7 standard library) as opposed to only turning those features on selectively for each crate (via -C target-feature).

I'd be ok adding a armv7-unknown-linux-gnu target to the compiler at least

@MagaTailor
Copy link

@alexcrichton You could consider doing a modern armv7, i.e. hf including neon, with all popular SBC's in mind. To an unsuspecting user that can make a 2x-3x difference out of the box in microbenchmarks.
There could be neon caveats though: one and two.

@fabricedesre Thx, if you know anyone on a Cortex-A15 (e.g. XU4), please pass the request to them.

@alexcrichton
Copy link
Member

@fabricedesre ah if you want to rebase this and squash the commits I'll go ahead an r+. Per our offline chat we may not produce libstd binaries for this triple just yet, but we will hopefully start providing easier methods in the future to tweak these sorts of compilation options!

@MagaTailor
Copy link

@alexcrichton If you ever start distributing crates for this triple, just make sure bootstrapping with +neon doesn't break anything. I haven't had any problems so far and the linked issues probably shouldn't matter but better safe than sorry!

@alexcrichton
Copy link
Member

Ah yeah if we ever ship a snapshot for ARM then it'll likely be for older processors (not v7), so it's unlikely to have that problem I believe.

@MagaTailor
Copy link

True, but I was referring to this particular triple which is about to be accepted and then maybe get a libstd distributed too - there's a +neon in the .mk file so be careful with denormals! ;)

@alexcrichton
Copy link
Member

@petevine could you spell things out a bit more for me? Unfortunately I'm not too familiar with arm versions/features, so I don't know what the interactions are between armv7, neon, etc. Can you explicitly state the scenario that you're worried about?

@MagaTailor
Copy link

Sure, even though it's rather improbable it could affect rustc.

We're talking about turning on a set of simd instructions called NEON, the arm equivalent of sorts of SSE2, that unlike the latter, flushes denormals to zero and has lower precision than the default vfp.

@fabricedesre
Copy link
Contributor Author

@alexcrichton I squashed

@alexcrichton
Copy link
Member

@bors: r+ 63b4639

bors added a commit that referenced this pull request Jan 29, 2016
This adds support for the armv7 crosstool-ng toolchain for the Raspberry Pi 2.

Getting the toolchain ready:
Checkout crosstool-ng from https://github.com/crosstool-ng/crosstool-ng
Build crosstool-ng
Configure the rpi2 target with |ct-ng armv7-rpi2-linux-gnueabihf|
Build the toolchain with |ct-build| and add the path to $toolchain_install_dir/bin to your $PATH

Then, on the rust side:
configure --target=armv7-rpi2-linux-gnueabihf && make && make install

To cross compile for the rpi2,
add $rust_install_path/lib to your $LD_LIBRARY_PATH, then use
rustc --target=armv7-rpi2-linux-gnueabihf -C linker=armv7-rpi2-linux-gnueabihf-g++ hello.rs
@bors
Copy link
Contributor

bors commented Jan 29, 2016

⌛ Testing commit 63b4639 with merge 7bd87c1...

@bors bors merged commit 63b4639 into rust-lang:master Jan 29, 2016
@MagaTailor
Copy link

Cool, just don't let's forget to tell cargo about it! :)

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.

7 participants