-
Notifications
You must be signed in to change notification settings - Fork 26
linux-cross: use glibc-2.14/gcc-4.8 for the arm toolchain #69
Conversation
Thanks @japaric! Do you know if it'd be possible to not use the crosstool-ng project? It seems like that's a massive dependency to pull in and we just need to change glibc versions, right? |
We need glibc <2.17 to remove the dep on the secure_getenv symbol. Trusty can't be used because it ships with an arm gcc-4.8/glibc-2.19 toolchainh. Precise can't be used because it ships with an x86_64/arm gcc-4.6/glibc-2.16 toolchain and, IIRC, we need >=gcc-4.8 to (cross) compile LLVM. And I haven't seen too many packaged arm toolchains. There is linaro, but their oldest release is gcc-4.8/eglibc-2.17; also they use crostool-ng to generate their toolchains :-).
IMO, it's as massive as depending on a PPA package. If we package the crosstool-ng generated arm toolchain in a PPA package and use that package in the Docker images, it wouldn't be different from this mips-gnu toolchain dependency. |
Right yeah we gotta build glibc somehow, was just hoping it would look like "download glibc and build it" rather than using crosstool-ng. I guess if crosstool is the standard way to build compilers we may as well use it. Two questions:
|
Oh, I haven't really thought about that because in my mind gcc and glibc always come in a single
The newest gcc crosstool-ng can build is 5.2, and the oldest glibc it can build is 2.8.
Sorry, I should have pointed out the documentation I wrote more clearly! crosstool-ng provides a |
In the past I've actually followed these instructions for just downloading and building gcc plus glibc, but they unfortunately don't always work. For example I couldn't get glibc 2.14.1 (like in this PR) to build. The gcc build, however, seems pretty reliable! Maybe there's just a small delta of what needs to be done to get glibc to build?
I know at least in the past we've been burned by situations like this though. I think it looked something like:
So there may be situations where even though we need no new symbols in 2.14 if something changed between 2.13 and 2.14 we may end up relying on 2.14 anyway. Now that being said, it may not be the case at all here!
Ah ok, thanks! That looks reasonable for reconstructing this at least. It seems these configs could be generated inside the docker container, right? I'll put some comments inline about the selections. So I guess all in all, it may be worth trying to find some instructions to build glibc manually, but I wouldn't try too hard. It looks like crosstool-ng works well and if it extends to all the other platforms we may want to do that as well. |
RUN /bin/bash build_arm_toolchain.sh arm-linux-gnueabi | ||
RUN /bin/bash build_arm_toolchain.sh arm-linux-gnueabihf | ||
USER root | ||
RUN rm -rf /build |
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:
RUN /bin/bash build_arm_toolchain.sh arm-linux-gnueabi && rm -rf /build
(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.
I've found that not having a bunch of intermediate artifacts can hugely reduce the size of docker containers
Great tip! I'll try to condense these commands as much as possible.
Hmm, those instructions seem a little off. AFAIK you can't compile gcc without having compiled glibc first unless you explicitly disable thread support and that's the reason most gcc+glibc builds are performed in two stages/passes. See Linux from Scratch which builds gcc twice.
Were you using gcc-5 to build glibc-2.14.1? It seems glibc configure script doesn't allow that:
I don't know if glibc-2.14 can't be compiled with gcc-5 or it's just that the configure script doesn't accept that version because gcc-5 didn't exist when glibc-2.14 was released.
Perhaps we should state in the website that the binaries are guaranteed to run on systems with glibc >=2.14, but it may work in systems with older glibcs but those are not officially supported?
If we generate them inside the docker container then the person that called |
Yeah the instructions had a crazy sequencing of building half of gcc, some of glibc, some more of gcc, then the rest of glibc, or something like that. I was indeed trying out gcc-5 and was manually tweaking the version checks in the configure script, but there was other weirdness down the road that I wasn't able to get past and I ended up giving up pretty quickly.
Sounds good to me. Out of curiosity, what made you choose 2.14? Is that just what the system you're running on happens to use?
Ah yeah sorry I just mean that we can spin up a half-bulit image, run the manual configuration, copy out the configuration, and then run the full build again. |
That actually sounds like the normal instructions to me :P.
😢
The test arm system I have is running precise which has gcc-4.6/glibc-2.15. So I tried that built that combination first with crosstool-ng. And it worked! But building LLVM requires gcc >=4.8, so I bumped gcc to 4.8. But crosstool-ng couldn't build gcc-4.8/glibc-2.15 :-/, so I tried downgrading glibc to 2.14 and the build succeeded! So I just settled on that combination :P.
That's certainly doable! |
pushed some commits:
|
|
||
- 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 comment
The 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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
Although now that I think about it I'm not sure it matters all that much. This largely only affects glibc, and we're not distributing glibc, so...
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 -march
flag to gcc when compiling them. But, perhaps, my guess about your conclusion was wrong!
I'm OK with changing both to armv6 though.
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.
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!
I def agree with this. Pushed a commit changing the arch level to armv6. |
linux-cross: use glibc-2.14/gcc-4.8 for the arm toolchain
Exciting! |
Ahhh, I got here too late :P. The |
Ah ok, the build is still running locally but I haven't hit that one just yet so that may be why. |
This should fix the arm half of rust-lang/rust#30966.
I've tested this by cross compiling std to the 3 arm targets and checking that the produced rlibs don't have an undefined symbol to
secure_getenv
.I'm pretty sure this image can also be used to cross compile rustc to arm, but it requires patching compiler-rt first. I'll test that and discuss the compiler-rt patch with Alex.
r? @alexcrichton