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
[RFC] ppc64le enablement #45340
Conversation
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. |
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 |
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.
Probably good to put the comment outside the string, so changing the explanation doesn't cause rebuilds.
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.
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" |
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.
It would be nice to leverage https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/compilers/gcc/common/platform-flags.nix for these, or at least the first.
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.
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" | ||
] |
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.
Don't forget to update pkgs/development/compilers/gcc/snapshot/default.nix too
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.
Will do. BTW, is 'snapshot' supposed to hold any particular version? Or is it just updated whenever someone feels like it?
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.
Yeah it's some arbitrary vcs revision. Should be newer than the rest so it would become the next release version, GCC 9 here.
pkgs/stdenv/default.nix
Outdated
@@ -47,6 +47,7 @@ in | |||
"aarch64-linux" = stagesLinux; | |||
"mipsel-linux" = stagesLinux; | |||
"powerpc-linux" = /* stagesLinux */ stagesNative; | |||
powerpc64le-linux = stagesLinux; |
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.
Use "
here and other such places for consistency
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 think you got them all but the one I commented on, haha :)
1a29c6a
to
e7453cb
Compare
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. |
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 |
I blindly copied the I was thinking that maybe passing the |
Sounds good! Did no |
It did. Should I squash these changes before merging? |
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. |
No, squashing is fine by me. Thanks for helping me bring support for more niche architectures to NixOS :) |
Of course! |
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.
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"; |
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.
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....
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.
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.
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.
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.
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.
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.? |
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.
Does the musl unpack script need similar updating? Not sure what it's called in that situation.
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.
It certainly works without any additional changes, so I guess not …
* 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
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?