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

[RFC] ppc64le enablement #45340

Merged
merged 7 commits into from Aug 21, 2018
Merged

[RFC] ppc64le enablement #45340

merged 7 commits into from Aug 21, 2018

Conversation

CrystalGamma
Copy link
Contributor

This PR enables the ppc64le architecture (and, theoretically, also Big Endian ppc64, but it's broken).

Building the ppc64le-glibc bootstrap files was successfully tested on x86-64 and ppc64le-glibc (building them on ppc64le-musl fails because of some doubly-defined symbols).
Building the ppc64le-musl bootstrap files was tested on x86-64, ppc64le-glibc and ppc64le-musl.
This obviously includes building the ppc64le-glibc and ppc64le-musl stdenv.

I have written a short roadmap/overview for what's in the pipe for NixOS/nixpkgs on POWER: https://crystalgamma.github.io/nixpkgs-prs.html .

As for this particular PR, should the changes be broken up into smaller commits or is this fine?

@Ericson2314
Copy link
Member

Ericson2314 commented Aug 20, 2018

See also #44092, which I had every intention to merge once the remaining issues were fixed. In particular, that mentioned contrary to yours that the big endian variant is in fact a different earlier 64-bit attempt, in practice.

@CrystalGamma
Copy link
Contributor Author

CrystalGamma commented Aug 20, 2018

I didn't know a previous PR for POWER existed …

ppc64 is just one bit flip in the MSR (machine status register) away from ppc64le (just like 32-bit mode), so every ppc64le computer could (and I have every intention to at least try) run ppc64 code (even in the same OS if the kernel supports it, which Linux doesn't AFAIK). The author of the previous PR was right in that the firmware of older ppc64 hardware and pretty much all ppc32 hardware could only boot big-endian OSs. In fact OpenPower systems which are generally marketed as ppc64le hardware actually boot in big-endian mode AFAIK, and then switch to whatever the OS is compiled for. That's why I introduced a more general isPower inspection predicate (and endian-specific options can then check isBigEndian or isLittleEndian) for platforms.

I did see a GCC config option (--with-long-double-128) in that PR which could have saved me about 50h of my life had I known about it earlier. Using that allowed me to remove some hackery in glibc. (I can squash before merging, if that's desired)

You may note that this PR also allows you to build a musl stdenv, which the earlier one didn't, AFAICS.

# the float128 detection in cross-gcc and glibc is a little busted. since glibc doesn't compile without float128 support, fix it.
sed 's/-mfloat128/-mfloat128-type -mfloat128/g' -i libgcc/configure
# this file also includes totally unneeded headers which are not available in cross-compilation. remove them.
sed -E 's/#include <(string|stdlib|ctype).h>//' -i libgcc/config/rs6000/float128-ifunc.c
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably good to put the comment outside the string, so changing the explanation doesn't cause rebuilds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. So like this?

# the float128 detection in cross-gcc and glibc is a little busted. since glibc doesn't compile without float128 support, fix it.
+ "\nsed 's/-mfloat128/-mfloat128-type -mfloat128/g' -i libgcc/configure"
# this file also includes totally unneeded headers which are not available in cross-compilation. remove them.
+"\nsed -E 's/#include <(string|stdlib|ctype).h>//' -i libgcc/config/rs6000/float128-ifunc.c"

Anyway, it turns out this hack was also obsoleted by just using --with-long-double-128 --enable-softfloat and I just overlooked it when cleaning up …

@@ -325,6 +331,10 @@ stdenv.mkDerivation ({
]
++ optional (targetPlatform == hostPlatform && targetPlatform.libc == "musl") "--disable-libsanitizer"
++ optional (targetPlatform.isAarch64) "--enable-fix-cortex-a53-843419"
++ optionals (targetPlatform.isPower && targetPlatform.libc == "glibc") [
"--with-long-double-128"
"--enable-softfloat"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICS platform-flags only has --with-xyz=abc with a select few 'xyz'. Unless you'd like me to extend it …

(Also, __float128 being required is only for the combination glibc, little endian, 64 bits … I might actually want to check endianness and word size too …)

++ optionals (targetPlatform.isPower && targetPlatform.libc == "glibc") [
"--with-long-double-128"
"--enable-softfloat"
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to update pkgs/development/compilers/gcc/snapshot/default.nix too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do. BTW, is 'snapshot' supposed to hold any particular version? Or is it just updated whenever someone feels like it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's some arbitrary vcs revision. Should be newer than the rest so it would become the next release version, GCC 9 here.

@@ -47,6 +47,7 @@ in
"aarch64-linux" = stagesLinux;
"mipsel-linux" = stagesLinux;
"powerpc-linux" = /* stagesLinux */ stagesNative;
powerpc64le-linux = stagesLinux;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use " here and other such places for consistency

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you got them all but the one I commented on, haha :)

@CrystalGamma
Copy link
Contributor Author

So, I made the quotes consistent, removed an obsolete hack and updated the flags for gcc7, gcc8 and gcc-snapshot. I am not certain how to best abstract the flags into the platform definition using gcc/common/platform-flags.nix though.

@Ericson2314
Copy link
Member

Ericson2314 commented Aug 20, 2018

So for the 128-bit float, I'd add

(lib.optional
  (let tp = targetPlatform; in tp.isPower && tp.libc == "glibc" && tp.is64bit && tp.isLittleEndian)
  "--with-long-double-128")

the the concatentated list in https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/gcc/common/platform-flags.nix#L12

For --enable-softfloat, I'd need to know what that is used for. That is a multilib flag, and our wrapper scripts don't really play well with multilib. [I am working on packaging the GCC runtime libraries separately for a "nix-driven multilib", side-stepping this restriction.] So I think it be better to use --with-float and friends to force float support one way or the other, if possible.

@CrystalGamma
Copy link
Contributor Author

CrystalGamma commented Aug 20, 2018

I blindly copied the --enable-softfloat flag from the earlier PR. I assumed it was necessary because I had seen linker errors referencing 128-bit float emulation routines when dabbling in cross-building glibc. Thanks for making me challenge that hypothesis :D

I was thinking that maybe passing the --with-long-double-128 flag to all versions of GCC may cause failures in older versions. But since versions pre-7 didn't support little-endian ppc64 (IIRC), I guess it wouldn't matter either way …

@Ericson2314
Copy link
Member

Ericson2314 commented Aug 20, 2018

Sounds good! Did no --enable-softfloat work for cross then? Is this ready to merge?

@CrystalGamma
Copy link
Contributor Author

CrystalGamma commented Aug 21, 2018

It did. Should I squash these changes before merging?

@Ericson2314
Copy link
Member

Ericson2314 commented Aug 21, 2018

Glad to hear it! I can just "squash and merge", but if you want to divide things into more than 1 commit or something that's fine too. I'll check this again when I wake up.

@CrystalGamma
Copy link
Contributor Author

No, squashing is fine by me. Thanks for helping me bring support for more niche architectures to NixOS :)

@Ericson2314
Copy link
Member

Of course!

Copy link
Member

@dtzWill dtzWill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excited to see this landing, here's some feedback. Will read through the discussion/your website post more thoroughly in a bit.

@@ -61,11 +61,12 @@ stdenv.mkDerivation rec {
configureFlagsArray+=("--syslibdir=$out/lib")
'';

CFLAGS="-fstack-protector-strong" + lib.optionalString hostPlatform.isPower " -mlong-double-64";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't the same as only setting CFLAGS during configure-- have you checked the output is identical on x86_64? Hopefully doesn't matter but better safe than sorry....

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And just curious about why this flag is needed, but I haven't read through the discussion/your website yet so apologies if all this has been addressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rationale here was that since CFLAGS might contain a space now, it might show up as two options, one of which ./configure will not understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original problem is that long double defaults to 128-bits on ppc64le (even without --with-long-double-128 which is required for glibc interestingly) but musl wants 64-bit long double.

@@ -9,6 +9,9 @@ echo Patching the bootstrap tools...
if test -f $out/lib/ld.so.?; then
# MIPS case
LD_BINARY=$out/lib/ld.so.?
elif test -f $out/lib/ld64.so.?; then
# ppc64(le)
LD_BINARY=$out/lib/ld64.so.?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the musl unpack script need similar updating? Not sure what it's called in that situation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It certainly works without any additional changes, so I guess not …

dtzWill pushed a commit to dtzWill/nixpkgs that referenced this pull request Aug 23, 2018
* ppc64le enablement

* gcc, glibc: properly handle __float128

* lib/systems, stdenv: syntax cleanup

* gcc7: remove ugly hack

* gcc: add/update __float128 flags

* stdenv: add another pair of quotes for consistency

* gcc: move __float128 flag for ppc64le-glibc into common/platform-flags.nix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants