-
Notifications
You must be signed in to change notification settings - Fork 27
linux-cross: use glibc-2.14/gcc-4.8 for the arm toolchain #69
Changes from 4 commits
2a8a424
2004de6
3b19b3a
65cdb54
c12d174
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# `linux-cross` | ||
|
||
This image is used to cross compile libstd/rustc to targets that run linux but are not the | ||
`x86_64-unknown-linux-gnu` triple which is the "host" triple. | ||
|
||
To cross compile libstd/rustc we need a C cross toolchain: a cross gcc and a cross compiled libc. | ||
For some targets, we use crosstool-ng to build these toolchains ourselves instead of using the ones | ||
packaged for Ubuntu because: | ||
|
||
- We can control the glibc version of the toolchain. In particular, we can lower its version as much | ||
as possible, this lets us generate libstd/rustc binaries that run in systems with old glibcs. | ||
- We can create toolchains for targets that don't have an equivalent package available in Ubuntu. | ||
|
||
crosstool-ng uses a `.config` file, generated via a menuconfig interface, to specify the target, | ||
glibc version, etc. of the toolchain to build. Because this menuconfig interface requires user | ||
intervention we store pre-generated `.config` files in this repository to keep the `docker build` | ||
command free of user intervention. | ||
|
||
The next section explains how to generate a `.config` file for a new target, and the one after that | ||
contains the changes, on top of the default toolchain configuration, used to generate the `.config` | ||
files stored in this repository. | ||
|
||
## Generating a `.config` file | ||
|
||
If you have a `linux-cross` image lying around you can use that and skip the next two steps. | ||
|
||
- First we spin up a container and copy `build_toolchain_root.sh` into it. All these steps are | ||
outside the container: | ||
|
||
``` | ||
# Note: We use ubuntu:15.10 because that's the "base" of linux-cross Docker image | ||
$ docker run -it ubuntu:15.10 bash | ||
$ docker ps | ||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | ||
cfbec05ed730 ubuntu:15.10 "bash" 16 seconds ago Up 15 seconds drunk_murdock | ||
$ docker cp build_toolchain_root.sh drunk_murdock:/ | ||
``` | ||
|
||
- Then inside the container we build crosstool-ng by simply calling the bash script we copied in the | ||
previous step: | ||
|
||
``` | ||
$ bash build_toolchain_root.sh | ||
``` | ||
|
||
- Now, inside the container run the following command to configure the toolchain. To get a clue of | ||
which options need to be changed check the next section and come back. | ||
|
||
``` | ||
$ ct-ng menuconfig | ||
``` | ||
|
||
- Finally, we retrieve the `.config` file from the container and give it a meaningful name. This is | ||
done outside the container. | ||
|
||
``` | ||
$ docker drunk_murdock:/.config arm-linux-gnueabi.config | ||
``` | ||
|
||
- Now you can shutdown the container or repeat the two last steps to generate a new `.config` file. | ||
|
||
## Toolchain configuration | ||
|
||
Changes on top of the default toolchain configuration used to generate the `.config` files in this | ||
directory. The changes are formatted as follows: | ||
|
||
``` | ||
$category > $option = $value -- $comment | ||
``` | ||
|
||
## `arm-linux-gnueabi.config` | ||
|
||
For targets: `arm-unknown-linux-gnueabi` | ||
|
||
- Path and misc options > Prefix directory = /x-tools/${CT_TARGET} | ||
- Target options > Target Architecture = arm | ||
- Target options > Architecture level = armv5t -- (*) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just confirming, but this is still armv5t instead of armv6? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (same with armv7-a below instead of armv6) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I thought you concluded, from this comment, that this default architecture level doesn't affect the C libraries we build, apart from glibc, because we always pass the I'm OK with changing both to armv6 though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yeah sorry I shall clarify. So in general this probably doesn't matter if it's too old. This option affects basically only how the support libraries are compiled, like libgcc and glibc. We don't ship glibc, so if you use a different one at runtime which is appropriately compiled, then you'll just naturally pick up the optimizations. Now we do ship some things compiled by gcc, like jemalloc/libbacktrace, but we compile them at rust-build-time which means we can change the codegen there (to armv6). I think that we'll pull in some bits from libgcc statically, however, which here would be compiled with armv5 but only only run on armv6 systems. So with that in mind, it's probably best to compile with armv6. I realized, though, that this probably matters a lot for C++. We do ship all of libstdc++ as we link it statically to the compiler for the compilers that we ship. So if we start shipping ARM compilers we can perhaps benefit quite a bit from using armv6 here instead of armv5 (because libstdc++ in theory will be faster). Most of this rationale is the same for armv7 below, although there is probably definitely matters. We're linking to libgcc with Rust and pulling in some bits statically most likely, and if they're armv7 bits and running on an armv6 machine we're likely to run into problems. So all in all it's probably just best to make sure these are always the same, hopefully it won't bite us later! |
||
- Target options > Floating point = software (no FPU) -- (*) | ||
- Operating System > Target OS = linux | ||
- Operating System > Linux kernel version = 3.2.72 -- Precise kernel | ||
- C-library > glibc version = 2.14.1 | ||
- C compiler > gcc version = 4.9.3 | ||
- C compiler > C++ = ENABLE -- to cross compile LLVM | ||
|
||
## `arm-linux-gnueabihf.config` | ||
|
||
For targets: `arm-unknown-linux-gnueabihf`, `armv7-unknown-linux-gnueabihf` | ||
|
||
- Path and misc options > Prefix directory = /x-tools/${CT_TARGET} | ||
- Target options > Target Architecture = arm | ||
- Target options > Architecture level = armv7-a -- (*) | ||
- Target options > Use specific FPU = vfpv3-d16 -- (*) | ||
- Target options > Floating point = hardware (FPU) -- (*) | ||
- Target options > Default instruction set mode (thumb) -- (*) | ||
- Operating System > Target OS = linux | ||
- Operating System > Linux kernel version = 3.2.72 -- Precise kernel | ||
- C-library > glibc version = 2.14.1 | ||
- C compiler > gcc version = 4.9.3 | ||
- C compiler > C++ = ENABLE -- to cross compile LLVM | ||
|
||
(*) These options have been selected to match the configuration of the arm toolchains shipped with | ||
Ubuntu 15.10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've found that not having a bunch of intermediate artifacts can hugely reduce the size of docker containers, could this be done as part of each step? Some examples I've done in the past are:
(or something like that)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great tip! I'll try to condense these commands as much as possible.