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

A selection of cross-compiling fixes #39420

Merged
merged 11 commits into from May 3, 2018
Merged

Conversation

bgamari
Copy link
Contributor

@bgamari bgamari commented Apr 24, 2018

Motivation for this change

Allow a variety of core packages to be cross-compiled. This is a batch of patches pulled from my larger batch in #30882. Many of the rest were kindly merged by @dtzWill. The few that remain after this will require a bit more work.

I've been using these to cross-compile ARMv7 NixOS images for several months now.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option build-use-sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

@bgamari
Copy link
Contributor Author

bgamari commented Apr 24, 2018

Sadly I can't build this with nox-review; it fails with Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS, presumably due to the very large size of the build.

@dtzWill
Copy link
Member

dtzWill commented Apr 24, 2018

Yay! And bumping initial heap size might help there?

Apologies for not checking myself, but just making sure: have you checked if these are still needed?

I think AR fixes, and curl fix (why do we set cc/cxx at all?) are needed, but itd be good to know what is/isn't. I trust they were needed when you wrote them but lots has changed :D.

On mobile, will look through these when at a computer next :).

@@ -37,7 +39,10 @@ in stdenv.mkDerivation rec {
"--with-systemd=$(out)/etc/systemd/system"
"--enable-libmount-mount"
]
++ lib.optional (stdenv ? glibc) "--with-rpcgen=${stdenv.glibc.bin}/bin/rpcgen";
++ lib.optional (stdenv ? glibc) "--with-rpcgen=${stdenv.glibc.bin}/bin/rpcgen"
++ stdenv.lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
Copy link
Member

Choose a reason for hiding this comment

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

This should be unconditional. But is it even still needed now that we export that environment variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Huh, indeed this doesn't appear to be necessary any more yet I thought I had already kicked out the patches that proved to be redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll drop this patch.

@@ -20,6 +20,7 @@ in stdenv.mkDerivation rec {
prePatch = ''
tar -xaf $debian
patches="$(cat debian/patches/series | sed 's,^,debian/patches/,') $patches"
substituteInPlace Makefile --replace "AR = ar" "AR = ${stdenv.cc.targetPrefix}ar"
Copy link
Member

Choose a reason for hiding this comment

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

I sort of like "AR ?= ar" if that works, but silly nit.

Copy link
Member

Choose a reason for hiding this comment

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

FWIW it might be best (if you disagree nevermind it's basically the same) if instead of patching the Makefile we just add "AR:=${stdenv.cc.targetPrefix}ar", or "AR:=$(AR)" actually, to makeFlags?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have absolutely no opinion. I will happily do whatever you all deem best.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wow, I am slightly embarrassed to admit that I had no idea that make variables given on the command-line override definitions in the Makefile. Yes, overriding seems like a significantly better option.

Copy link
Member

Choose a reason for hiding this comment

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

Or is this := overriding =?

Copy link
Member

Choose a reason for hiding this comment

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

To be clear, I didn't know this either, and I approve of @dtzWill's approach.

Copy link
Member

Choose a reason for hiding this comment

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

"AR:=$(AR)" is especially nifty.

# For cross-compilation
configureFlags = [ "AR=${stdenv.cc.bintools.targetPrefix}ar" ];
postPatch = ''
substituteInPlace Makefile.in --replace "AR = ar" ""
Copy link
Member

Choose a reason for hiding this comment

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

Maybe "AR ?= ar" to be consistent with the above?

Copy link
Member

Choose a reason for hiding this comment

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

Also, since AR in the environment is already target-prefixed, are the configureFlags needed?

Copy link
Member

Choose a reason for hiding this comment

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

"AR:=$(AR)" per the above.

@@ -19,6 +19,8 @@ stdenv.mkDerivation {
sha256 = "0dd7xxikib201i99k2if066hh7gwf2i4ffckrjplq6lr206jn00r";
});

enableParallelBuilding = true;
Copy link
Member

Choose a reason for hiding this comment

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

Not that this hurts anything - but I'm kind of amazed this would fix cross compiling. Usually parallel building breaks stuff. This is the first time I've heard of it fixing anything.

Copy link
Member

Choose a reason for hiding this comment

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

It helps all the time when cross-compiling*!

  • not fixing errors but making the rebuild/rebuild/rebuild go a bit faster and reduces the toll on your sanity!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not fixing errors but making the rebuild/rebuild/rebuild go a bit faster and reduces the toll on your sanity!

Couldn't have said it better myself.

@@ -37,7 +39,10 @@ in stdenv.mkDerivation rec {
"--with-systemd=$(out)/etc/systemd/system"
"--enable-libmount-mount"
]
++ lib.optional (stdenv ? glibc) "--with-rpcgen=${stdenv.glibc.bin}/bin/rpcgen";
++ lib.optional (stdenv ? glibc) "--with-rpcgen=${stdenv.glibc.bin}/bin/rpcgen"
++ stdenv.lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll drop this patch.

@@ -20,6 +20,7 @@ in stdenv.mkDerivation rec {
prePatch = ''
tar -xaf $debian
patches="$(cat debian/patches/series | sed 's,^,debian/patches/,') $patches"
substituteInPlace Makefile --replace "AR = ar" "AR = ${stdenv.cc.targetPrefix}ar"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wow, I am slightly embarrassed to admit that I had no idea that make variables given on the command-line override definitions in the Makefile. Yes, overriding seems like a significantly better option.

echo cc > conf-ld
echo ${stdenv.cc.targetPrefix}cc > conf-cc
echo ${stdenv.cc.targetPrefix}cc > conf-ld
export AR=${stdenv.cc.targetPrefix}ar
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I suppose this also isn't needed anymore.

Copy link
Member

Choose a reason for hiding this comment

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

Oh good point

@dtzWill
Copy link
Member

dtzWill commented Apr 24, 2018

All good, I surely know what it's like to sit on a huge stack of patches and test them over and over while splitting them out. And always there's a detail or two I overlooked! That I swear wasn't like that or was needed a month ago or in a cross-env ... hehe.

Anyway, thanks for pushing these through and look forward to next iteration! :)

@bgamari
Copy link
Contributor Author

bgamari commented Apr 30, 2018

I've added two more low-risk fixes to this branch: glib and avahi.

@Ericson2314
Copy link
Member

@bgamari looks good except you actually added c0e0bc8 and 2400170?

@bgamari
Copy link
Contributor Author

bgamari commented May 3, 2018

Fixed.

@Ericson2314
Copy link
Member

Thanks @bgamari

{ kernel = parse.kernels.linux; abi = parse.abis.gnu; }
{ kernel = parse.kernels.linux; abi = parse.abis.gnueabi; }
{ kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; }
];
Copy link
Member

Choose a reason for hiding this comment

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

Just curious: why is this not just matching on ABI's? It seems unintuitive for "this package runs on GNU" to mean "gnu/linux" (and as a recent PR addressed seems to have been abused to mean "linux" in many packages).

But would it be "bad" to not require the kernel be linux?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A good question. I was looking to minimize the potential risk incurred by my patch, but I'll admit that this definition is rather fishy.

Copy link
Member

Choose a reason for hiding this comment

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

Haha, understood re:conservative changes. I do the same thing all the time. cc @Ericson2314 -- do you know the answer?

Not a big deal ... :)

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine either way. I made some changes upstream to GNU Config that are leading me to reconsider some of this stuff a bit. E.g. maybe ABI should be a per-kernel namespace.

@bgamari
Copy link
Contributor Author

bgamari commented May 3, 2018

Yay!

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.

These don't all seem to be needed--see comments.

If they're needed in your environment, I'd be curious to sort out why that is and for improving my own testing :).

@@ -10,6 +10,8 @@ stdenv.mkDerivation rec {
sha256 = "0hkdzc71pdnscbpdpgwljcchiyancarldjyd0w609sy18bky833x";
};

makeFlags = "CC=${stdenv.cc.targetPrefix}cc";
Copy link
Member

Choose a reason for hiding this comment

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

I don't believe this is needed, here's cross-building to aarch64-musl:

$ nix build -f channel:nixos-unstable --arg crossSystem '(import <nixpkgs/lib>).systems.examples.aarch64-multiplatform-musl' mmc-utils
$ ls -l result
lrwxrwxrwx 1 will users 91 May  3 16:34 result -> /nix/store/g5izr5yd8sydw6dizmnj8y2mlvwx28a5-mmc-utils-2015-11-18-aarch64-unknown-linux-musl

(where unstable is based on master, and doesn't have this commit yet)

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 same here.

@@ -15,6 +15,8 @@ stdenv.mkDerivation rec {
'';

makeFlags = [
"CC=${stdenv.cc.targetPrefix}cc"
"AR=${stdenv.cc.targetPrefix}ar"
Copy link
Member

Choose a reason for hiding this comment

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

These don't appear to be needed either. Same command as above, but try building nettools.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, I could have sworn I cherry-picked this one for a reason but indeed I haven't seen a failure yet after reverting it. Very odd.

CXX = "c++";
CXXCPP = "c++ -E";
CXX = "${stdenv.cc.targetPrefix}c++";
CXXCPP = "${stdenv.cc.targetPrefix}c++ -E";
Copy link
Member

Choose a reason for hiding this comment

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

This works as-is for me as well?

$ nix build -f channel:nixos-unstable --arg crossSystem '(import <nixpkgs/lib>).systems.examples.aarch64-multiplatform-musl' curl

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll admit I didn't test this one. I had assumed that c++ would either not exist or refer to the host compiler.

Copy link
Member

Choose a reason for hiding this comment

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

That assumption does make sense to me. That this would work is very odd. Does it actually run or just build? I'd think just the latter.

@@ -9,6 +9,9 @@ stdenv.mkDerivation rec {
sha256 = "13h7lc8wl9khhvkr0i3bl5j9bapf8anhqis1lcnwxg1vc2v058b0";
};

# For cross-compilation
makeFlags = [ "AR:=$(AR)" ];

Copy link
Member

Choose a reason for hiding this comment

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

Yes, this is needed! 😁

$ nix build -f channel:nixos-unstable --arg crossSystem '(import <nixpkgs/lib>).systems.examples.aarch64-multiplatform-musl' rng_tools                            16:40:32 on 18-05-03
error: build of '/nix/store/4sh7pnz0vwacxm7a784fyf6q6cbzjhaw-rng-tools-5-aarch64-unknown-linux-musl.drv' on 'ssh://wdietz2@presto' failed: builder for '/nix/store/4sh7pnz0vwacxm7a784fyf6q6cbzjhaw-rng-tools-5-aarch64-unknown-linux-musl.drv' failed with exit code 2
builder for '/nix/store/4sh7pnz0vwacxm7a784fyf6q6cbzjhaw-rng-tools-5-aarch64-unknown-linux-musl.drv' failed with exit code 1; last 10 log lines:
  aarch64-unknown-linux-musl-gcc -DHAVE_CONFIG_H -I.     -g -O2 -c fips.c
  rm -f librngd.a
  ar cru librngd.a fips.o
  /nix/store/xn5gv3lpfy91yvfy9b0i7klfcxh9xskz-bash-4.4-p19/bin/bash: ar: command not found
  make[2]: *** [Makefile:440: librngd.a] Error 127
  make[2]: Leaving directory '/build/rng-tools-5'
  make[1]: *** [Makefile:672: all-recursive] Error 1
  make[1]: Leaving directory '/build/rng-tools-5'
  make: *** [Makefile:377: all] Error 2
  builder for '/nix/store/4sh7pnz0vwacxm7a784fyf6q6cbzjhaw-rng-tools-5-aarch64-unknown-linux-musl.drv' failed with exit code 2
[0 built (1 failed), 0.0 MiB DL]
error: build of '/nix/store/4sh7pnz0vwacxm7a784fyf6q6cbzjhaw-rng-tools-5-aarch64-unknown-linux-musl.drv' failed

@Ericson2314
Copy link
Member

@dtzWill Thanks for investigating, and my bad on the eager merge. I guess just revert those bits before staging evals again?

@bgamari
Copy link
Contributor Author

bgamari commented May 4, 2018

Sorry for the confusion everyone! I could have sworn those two were needed.

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

5 participants