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

Make cross-compiling with the crossSystem argument work #18386

Conversation

DavidEGrayson
Copy link
Contributor

@DavidEGrayson DavidEGrayson commented Sep 7, 2016

Motivation for this change

I would like to be able to compile software for systems that do not have Nix. It looks like nixpkgs has a crossSystem argument that should allow this, but when I tried to use it, I encountered a bunch of problems.

The main problem was that the crossSystem argument affected a bunch of native derivations, such as gcc5, so when I tried to cross-compile, Nix would needlessly try to rebuild the stdenv, and encounter some error.

Another issue was that the cross compilers were built using the bootstrap tools instead of the normal stdenv, and they were built using gcc.cc.override which seems invalid to me. Fixing this issue was the final thing that allowed me to successfully cross-compile for the Raspberry Pi.

See my detailed commit messages for more info. (I actually redid the commit history before submitting this pull request to make it easy for reviewers to follow.) Thanks!

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
    • OS X
    • Linux
  • Tried to run nix-shell -p nox --run "nox-review wip --against d4eac027" but its error message did not make much sense to me. It looks like it tried to evaluate libcCross1 without specifying a crossSystem argument, which is invalid (just like it would also be invalid to evaluate libcCross).
  • Tested execution of all binary files (usually in ./result/bin/)
  • Fits CONTRIBUTING.md.

The main way I tested this PR was by applying nix-build to this Nix expression. That Nix expression does several things: it ensures that the gcc5 in my pull request does not get affected by the crossSystem argument. It also ensures that my pull request does not affect any native GCC derivations, so we will not need a mass rebuild. It also compiles the "hello" package for the Raspberry Pi.


Future work
  • I am only touching the GCC 5 recipe in this pull request, but we should apply my fixes to GCC 6 after they are accepted.
  • The test I added in the new directory test should be automatically run by Hydra. I do not know how to set that up.
  • Note that this pull request only makes cross-compiling work if the build system is Linux. A bit more work would be needed to make cross-compiling work on Darwin.

No more mutual importing between top-level/default.nix and
top-level/stdenv.nix.  Instead of having stdenv.nix import
default.nix, we will have default.nix construct the allPackages
function and pass it as an argument to stdenv.nix.

No more use of misleading names "self" and "super" in stdenv.nix.
Those names have a specific meaning given to them by lib.extend, which
did not apply.

Incorporate all topLevelArguments into allPackages.  Previously,
allPackages used default values for bootStdenv, noSysDirs,
crossSystem, and platform, ignoring the values passed by the user to
default.nix.  That behavior seemed surprising and likely to cause
bugs, so I changed it.

In stdenv.nix, use better indentation to make it clear that there are
four basic ways to choose a stdenv.
native derivations (e.g. gcc) to change when crossSystem is specified.

A common sense principle of the crossSystem argument is that its value
should not affect the native derivations.

Instead of using that hack, we use a smarter stdenvOverrides system
that allows us to just change the nativeDrvs while leaving the
crossDrvs alone.

NOTE: Someone should do the same thing for the Darwin stdenv if
they want to cross-compile things on Darwin.
gcc5:
- Make it so crossSystem and libcCross do not affect the native compiler.
- NOTE: We should do this for the other gcc versions too.

gccCrossStageStatic, gccCrossStageFinal:
- Use the real stdenv instead of using bootstrap tools.
  Bootstrap tools are a threat to the purity of the Nix system, so we
  should only use them to build the stdenv and nothing else.  Also,
  this seemed to fix a configure error I was getting with cross glibc
  for the Raspberry Pi.
- Explicitly disable langObjC and langObjCpp.

glibcCross:
- Use the real stdenv instead of using bootstrap tools.

libcCross1:
- Move the logic for picking this so it is closer to libcCrossChooser.

libiconv:
- Choose the nativeDrv and crossDrv independently so that the crossSystem
  does not affect the nativeDrv.

At this point, cross-compiling seems to work fine.  I tested it by
applying nix-build to this expression:

rec {
  myNixpkgsFunc = import ./nixpkgs;
  myNixpkgs = myNixpkgsFunc {};

  baseNixpkgsFunc = import ((import <nixpkgs> { }).fetchFromGitHub {
    owner = "NixOS";
    repo = "nixpkgs";
    rev = "d4eac0278ca188aa236b6a7f0fbb15f8ee4273d0";
    sha256 = "0mpx6bjvix7dfmgn6a2chmmicamz9v941fki0lgzfk2gw90fqg6w";
  });
  baseNixpkgs = baseNixpkgsFunc {};

  myTestsPass = (import ./nixpkgs/test/cross_system.nix).testsPass;

  gcc6Same = myNixpkgs.gcc6 == baseNixpkgs.gcc6;
  gcc5Same = myNixpkgs.gcc5 == baseNixpkgs.gcc5;
  gcc49Same = myNixpkgs.gcc49 == baseNixpkgs.gcc49;
  gcc48Same = myNixpkgs.gcc48 == baseNixpkgs.gcc48;
  gcc45Same = myNixpkgs.gcc45 == baseNixpkgs.gcc45;
  gccSame = gcc6Same && gcc5Same && gcc49Same && gcc45Same;

  testsPass = myTestsPass && gccSame;

  derivations = rec {
    recurseForDerivations = assert testsPass; true;

    rpiCrossSystem = {
      config = "armv6l-unknown-linux-gnueabi";
      bigEndian = false;
      arch = "arm";
      float = "hard";
      fpu = "vfp";
      withTLS = true;
      libc = "glibc";
      platform = myNixpkgs.platforms.raspberrypi;
      openssl.system = "linux-generic32";
      gcc = {
        arch = "armv6";
        fpu = "vfp";
        float = "softfp";
        abi = "aapcs-linux";
      };
    };
    rpiPkgs = myNixpkgsFunc { crossSystem = rpiCrossSystem; };
    rpiHello = rpiPkgs.hello.crossDrv;
  };
}
argument does not affect native derivations.
@mention-bot
Copy link

@DavidEGrayson, thanks for your PR! By analyzing the annotation information on this pull request, we identified @nbp, @shlevy and @errge to be potential reviewers

@DavidEGrayson
Copy link
Contributor Author

I'll also ping @viric because it sounds like he was doing cross-compiling.

@bjornfor
Copy link
Contributor

bjornfor commented Sep 7, 2016

Also @dezgeg, @Ericson2314, @rasendubi

@Ericson2314
Copy link
Member

I will take a look at this tomorrow but you may be interested in #15043 and Ericson2314@ee2a484

# want to avoid a meaningless mass rebuild. These variables get
# overridden via crossAttrs in an actual cross-build.
// { crossMingw = false; crossStageStatic = true; }

Copy link
Contributor

Choose a reason for hiding this comment

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

So this is only required one time for the transition? If yes I think we should remove and deal with one mass-rebuild 😉

Copy link
Contributor Author

@DavidEGrayson DavidEGrayson Sep 7, 2016

Choose a reason for hiding this comment

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

I thought that adding this would make it simpler and easier for my pull request to be merged, and it also helped me ensure that I did not accidentally screw something up. I used Nix assertions to assert that the native GCC 5 in my pull request and in the upstream commit it is based on are the same 😉.

This is kind of a subjective decision, so I would mainly be concerned with what the people in charge of nixpkgs think. @groxxda, do you have the authority to merge my pull request?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not in the position to merge but nixpkgs is a community project and I consider myself part of the community just like any other contributor 😉
This is my subjective view:
Avoiding a single mass rebuild does not weight out the cons of "dead code" (whereas during testing it is very valid), and one mass rebuild is not a blocker for pull requests to get merged.
Since we only need this code to make the test work, it should be moved into the test file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are there instances in the past where we chose to do a mass rebuild so we could remove one line of dead code?

Also, does your subjective opinion change if I point out that the recipe for GCC 5 will be deleted some day when nothing depends on it any more?

Copy link
Contributor

Choose a reason for hiding this comment

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

This can be merged with an update that requires a mass-rebuild on it's own so the extra cost could be minimal.
This line needs to be duplicated into every gcc expression that should be asserted inside the tests, right? Imo that's an even stronger argument for moving it inside the tests file and make it generic.
For me it's as simple as: If you only need it for the tests, put it inside the tests file.

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's only needed to make my outside-of-tree tests pass and to avoid a mass rebuild. The tests in the tree would not be able to detect that a mass rebuild is happening because they only look at the current commit of nixpkgs. The tests in the tree just make sure that a few native derivations don't get changed when crossSystem is specified.

Copy link
Member

@rasendubi rasendubi Sep 7, 2016

Choose a reason for hiding this comment

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

I'm also in favor of mass rebuild here. Mass-rebuild patches are merged into staging, so they don't disturb normal flow much.

Also if we consider the fact that we'll remove that dead code in the future, that will cause mass rebuild anyway. Don't see any reason to wait.

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 7, 2016

@Ericson2314 I haven't looked in detail at your pull request but it's good to see that some other people care about getting cross-compiling to work.

In my pull request, I wanted to avoid the circular importing between top-level/default.nix and top-level/stdenv.nix, because I found that confusing and unnecessary. I was able to get rid of that just by changing a few lines, and moving the definition of allPackages to top-level/default.nix. We can think of allPackages as a function that calls top-level/default.nix with all of its original arguments, but lets you override some of those arguments (e.g. to provide a bootStdenv).

I can see my pull request touches only 7 files compared to the 16 files touched in #15043 , and my pull request actually does make cross-compiling work, so I hope we can get it merged in faster. 🙏

@groxxda
Copy link
Contributor

groxxda commented Sep 7, 2016

Please don't get me wrong, I'm really 👍 to see this merged, since as far as I can tell cross compilation is broken and most of the other work got stale before it was ready to merge.
Since this PR looks minimal and get's things working, I 🙏 this finally makes it into master.

@shlevy
Copy link
Member

shlevy commented Sep 7, 2016

@DavidEGrayson Do you know if anyone who has had cross-compilation working in the past now sees it failing? Note that it's definitely worked before, even if it doesn't currently, so it may just be something documented wrong.

@Ericson2314
Copy link
Member

Ericson2314 commented Sep 7, 2016

@DavidEGrayson did you take into account the bootstrap phases? the stdenvs themselves still call all packages, so as far as I can tell the importing in both directions occurs. I'd agree that let's just get something merged at this point, but I believe insofar that you do attack the circular imports stuff, we fix it in opposite ways. I believe mine patch does fix cross-compiling, full stop, but I haven't tested this in a while.

There is also no mass rebuild risk with mine I believe, but perhaps I haven't done enough work on cross compiling itself?

@Ericson2314
Copy link
Member

@shlevy In my experience it does work, but there is pointless rebuilding currently.

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 7, 2016

@shlevy: No I don't, but I'll try to look. Maybe I'll try to figure out how to build pkgs/top-level/release-cross.nix and see if that works in the current master. I do know that my attempts to cross-build all failed with various errors before I made the changes in this pull request, which allowed me to finally build "hello" for the Raspberry Pi.

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 7, 2016

@Ericson2314: Yes, the allPackages function is used by stdenv to bootstrap itself, but from the perspective of the stdenv expressions, that is now just a simple function call instead of an actual import, so I think it's easier to think about even though it has a similar effect. I think it's good that top-level/stdenv.nix doesn't really know how to build packages, it just knows that it has this function that can take a stdenv and return package expressions. If you pass the bootStdenv argument to allPackages during the process of making a stdenv, there should be no risk of circular dependencies as allPackages evaluates.

What do you mean when you say there is no mass-rebuild risk? You're talking about your own pull request?

@Ericson2314
Copy link
Member

@DavidEGrayson on the second part, yeah, talking about my own.

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 7, 2016

@rasendubi: This pull request moves nixpkgs closer to the point that you would want it to be, right? So would you support merging the pull request as is? (After this gets merged, you could make a small pull request where you argue for the mass-rebuild.)

@Ericson2314
Copy link
Member

Ericson2314 commented Sep 7, 2016

CC @vcunat and @Mathnerd314, who were interested in these sort of things.

@Ericson2314
Copy link
Member

I'm looking at the commits in detail now.

@Ericson2314
Copy link
Member

@DavidEGrayson I like the first two commits and the tests, for sure. I think the 3rd commit may be better addressed in by adding a stage to the cross stdenv like in my PR, and using overrideNativeDeps, but I'm still thinking about it. That part of my PR should be relatively orthogonal to the rest and able to be cherry picked.

@rasendubi
Copy link
Member

rasendubi commented Sep 7, 2016

@DavidEGrayson I'm no way blocking the pull request. Though, I don't support it (yet), as I would like to test/review it first. (Hope to do that at weekend.)

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 7, 2016

My TODO list:

  • Don't use a long list of strings in pkgs/stdenv/linux/default.nix to define stdenvOverrides.
  • Restore the comment about allowedRequisites in pkgs/stdenv/linux/default.nix even though it looks junky.
  • Look for more concrete evidence of problems with the current master branch for @shlevy, and post specific error messages. Try building release-cross.nix on master and on my branch and see how it goes.
  • Try to cross-build a native GCC 5 compiler for the Raspberry Pi to make sure that works. Some of my changes might have broken that, because I want to ignore libcCross in certain places if cross is null.

Thank you to everyone who has contributed to the discussion so far!

about allowedRequisites that I did not write.
using a set instead of a list of strings.  This is more flexible and
looks nicer.
@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 8, 2016

Thanks to some info from @shlevy, I have looked at pkgs/top-level/release-cross.nix, and I have learned that it can generally be used to successfully cross-compile some things, and Hydra does that regularly with the cross-trunk job set.

But here is a concrete example of some cross-compiling issues on nixpkgs master. Suppose I check out a recent commit on master, d4eac02, and add this file in the pkgs/top-level/ directory:

(import ./. {
  system = builtins.currentSystem;
  crossSystem = {
    config = "foobar";
    arch = "arm";
    libc = "uclibc";
    platform = (import ../.. {}).platforms.raspberrypi;
  };
}).git

This file is not supposed to be valid, but it sort of emulates what I was trying to do when I first looked into cross-compiling with Nix. I was trying to compile for a new system that does not use glibc, and I needed to fetch some sources from git to support building the compiler for this system. If I run nix-build on this new file, the abridged result is:

these derivations will be built:
  /nix/store/1bnm7156fx4vz60fs5kf2yz1wv5127jp-linux-pam-1.2.1.drv
  /nix/store/1xrc64k02gb6qgqaf84684209w1ybmg6-w3m-0.5.3-2015-12-20.drv
  /nix/store/wfgdz7qnjxaqbdair7n93rv4wm537s5m-libxml2-2.9.4.drv
  /nix/store/308l502f4w12ag7rvwqr6zgnkb7m338j-libxslt-1.1.28.drv
  /nix/store/qrc61rxalpir6wdifd01gqn7207ck2vh-xmlto-0.0.28.drv
  /nix/store/97f1q4d408adiirr87cpp3hqvhc6prrk-opensp-1.5.2.drv
  /nix/store/adsgyqf7wsvyhflfkpwf31kr5vh29wd5-libiconv-1.14.drv
  /nix/store/5ynq4i4fm56hyicq86683djjxvi1jjkb-docbook2X-0.8.8.drv
  /nix/store/v0wd59xn219zyhvqr5ysgjmvvgv9is4g-pcre-8.38.drv
  /nix/store/76rcb8zdn89wl7d5n3skmzspqxvyvm36-gnugrep-2.25.drv
  /nix/store/h6jmab5xlgdz4g6cdnqflllnymg74r8l-texinfo-5.2.drv
  /nix/store/v88l8qvzcpxgchrplqqkqdbyszskpji3-openssh-7.3p1.drv
  /nix/store/kly3x044yckwi19d3v68c3r20mkrawa9-git-2.10.0.drv
building path(s) ‘/nix/store/191sag71p88pgv4widn2zrzv838lblsr-libiconv-1.14’
unpacking sources
unpacking source archive /nix/store/mgvhamvs92cvhzkq3qwg2slz9sj2vcd7-libiconv-1.14.tar.gz
........
make[3]: Leaving directory '/tmp/nix-build-libiconv-1.14.drv-0/libiconv-1.14'
gcc -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I.. -I../lib  -I../intl -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1   -g -O2 -c allocator.c
gcc -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I.. -I../lib  -I../intl -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1   -g -O2 -c areadlink.c
gcc -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I.. -I../lib  -I../intl -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1   -g -O2 -c careadlinkat.c
gcc -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I.. -I../lib  -I../intl -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1   -g -O2 -c malloca.c
gcc -DHAVE_CONFIG_H -DEXEEXT=\"\" -I. -I.. -I../lib  -I../intl -DDEPENDS_ON_LIBICONV=1 -DDEPENDS_ON_LIBINTL=1   -g -O2 -c progname.c
In file included from progname.c:26:0:
./stdio.h:1010:1: error: 'gets' undeclared here (not in a function)
 _GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
 ^
make[2]: *** [Makefile:914: progname.o] Error 1
make[2]: Leaving directory '/tmp/nix-build-libiconv-1.14.drv-0/libiconv-1.14/srclib'
make[1]: *** [Makefile:865: all] Error 2
make[1]: Leaving directory '/tmp/nix-build-libiconv-1.14.drv-0/libiconv-1.14/srclib'
make: *** [Makefile:35: all] Error 2
builder for ‘/nix/store/adsgyqf7wsvyhflfkpwf31kr5vh29wd5-libiconv-1.14.drv’ failed with exit code 2
cannot build derivation ‘/nix/store/kly3x044yckwi19d3v68c3r20mkrawa9-git-2.10.0.drv’: 1 dependencies couldn't be built
error: build of ‘/nix/store/kly3x044yckwi19d3v68c3r20mkrawa9-git-2.10.0.drv’ failed

So we can see that because of some values I chose for the crossSystem, nixpkgs thinks it needs to build a native libiconv for its native git package (when in fact it should use the libiconv features of the glibc), and it fails to build the native libiconv. When that happened, I decided that even though my crossSystem values were not completely valid, nixpkgs was behaving badly and I needed to debug nixpkgs itself to make progress.

I hope you can now understand my motivation for this pull request.

@shlevy
Copy link
Member

shlevy commented Sep 8, 2016

@DavidEGrayson To be clear, technically nixpkgs is not buggy but is poorly documented and has a bad interface, right? So you're improving the interface? (have not yet had time to fully review)

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 8, 2016

@shlevy I am improving the internal interface between pkgs/top-level/default.nix and pkgs/top-level/stdenv.nix, but that isn't the most important part of the pull request. That is the first commit of the pull request. The other commits fix behavior I would consider to be buggy, such as the native GCC and libiconv derivations depending on crossSystem, and other things like that.

However, saying "nixpkgs is buggy" would be a somewhat subjective: it depends on what list of features you think nixpkgs should have. If you say that the only supported cross-compilation scenarios are the currently-passing jobs in the nixpkgs:cross-trunk jobset, then by that measure nixpkgs is not buggy, and this pull request is just adding new features.

The GCC 5 documentation says that --with-headers is obsolete and
deprecated in favor of --with-sysroot.  Also, this seems to fix a
problem I was having where the configure script could not find glibc's
limit.h, so it did not add the administrivia at the top and bottom of
include-fixed/limits.h which tell it to #include_next the real
limits.h, which resulted in limits.h defining the wrong value for
MB_LEN_MAX, which caused an error while cross-building coreutils.
@rasendubi rasendubi added the 6.topic: cross-compilation Building packages on a different platform than they will be used on label Sep 15, 2016
@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 24, 2016

So actually the crossMingw and crossStageStatic attributes outside of crossAttrs in the GCC 5 expression are not dead code: they are needed when you are building a cross-compiler, and when you are building a cross-compiler, you not actually cross-compiling yet, in the sense that crossAttrs and crossDrv are not in play.

I am still working on fixing up this pull request as described above in my TODO list.

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Sep 24, 2016

Hey, the --with-headers argument to GCC's configure script, which we are using for cross-compilation is deprecated according to the in-tree documentation of GCC 5.4.0 and 6.2.0:

https://github.com/gcc-mirror/gcc/blob/gcc-5_4_0-release/gcc/doc/install.texi#L2020-L2022
https://github.com/gcc-mirror/gcc/blob/gcc-6_2_0-release/gcc/doc/install.texi#L2069-L2071

The documentation says you are supposed to use --with-sysroot instead. Assuming that --with-sysroot works, are there any objections to changing the GCC recipe to use it in this pull request, even if it is not strictly necessary? This would only affect cross-compilation. Besides switching away from a deprecated option, one of the benefits is that the headers of the cross libc would not get copied into the GCC output, so we would save some space.

@shlevy
Copy link
Member

shlevy commented Sep 25, 2016

@DavidEGrayson 👍 on switching configure option

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Oct 2, 2016

My Raspberry Pi bootstrap tools (compiled from DavidEGrayson@9cedf1b ) are compiling for "armv5t" instead of "arm" for some reason, even though the compiler is named armv6l-unknown-linux-gnueabi-gcc. Debugging the cross GCC is harder than it needs to be because of this issue which I just reported: #19151

I will keep debugging it though; I am not stuck. I suppose my next step would be to see if this is just a GCC issue or also a binutils issue.

@bjornfor
Copy link
Contributor

Any news?

@DavidEGrayson
Copy link
Contributor Author

Not much. But I started building a drvdiff utility to help me figure out why my Raspberry Pi cross-compiler would behave so differently than the upstream nixpkgs one (producing output for the wrong ARM architecture).

@zsmithnyc
Copy link

@DavidEGrayson @bjornfor My company is offering sponsored on-demand ARM64 hardware if you're interested in testing your build on AARCH64. WE can support standard CI tools to deploy the hosts automatically, etc, so DM me if you're in need of access for NIX.

@shlevy
Copy link
Member

shlevy commented Dec 1, 2016

Status on this? Please ping me when you think this is ready

@DavidEGrayson
Copy link
Contributor Author

The status of this pull request is still the same as last time: I am (slowly) working on this drvdiff utility so I can efficient debug why my cross toolchain would compile for the wrong ARM architecture when I try to compile "hello" for the Raspberry Pi. Pull request #19940 has been merged recently, so this pull request will need some work to avoid conflicts when we finally get it working.

I think the right order to do things is to get drvdiff working, figure out why this pull request did not work, fix it, and then work on rebasing the whole thing onto the latest nixpkgs master and resolving conflicts.

I did some more work for this pull request back in September but I had not pushed those commits to the pull request branch because I was intending to clean them up. Well, to make it easier for other people who want to help out, I have now pushed those commits to the pull request branch (updating that branch from 873da5a to 9cedf1b).

@DavidEGrayson
Copy link
Contributor Author

DavidEGrayson commented Dec 8, 2016

Here are my rough notes and test NIX expression for the GCC ARM architecture problem in case anyone wants to investigate, but I am not stuck and can probably figure it out given enough time.

@dezgeg
Copy link
Contributor

dezgeg commented Dec 8, 2016

In pkgs/development/compilers/gcc/5/default.nix:

130     crossConfigureFlags = let
131         gccArch = stdenv.cross.gcc.arch or null;
132         gccCpu = stdenv.cross.gcc.cpu or null;
133         gccAbi = stdenv.cross.gcc.abi or null;
134         gccFpu = stdenv.cross.gcc.fpu or null;
135         gccFloat = stdenv.cross.gcc.float or null;
136         gccMode = stdenv.cross.gcc.mode or null;
137         withArch = if gccArch != null then " --with-arch=${gccArch}" else "";
138         withCpu = if gccCpu != null then " --with-cpu=${gccCpu}" else "";
139         withAbi = if gccAbi != null then " --with-abi=${gccAbi}" else "";
140         withFpu = if gccFpu != null then " --with-fpu=${gccFpu}" else "";
141         withFloat = if gccFloat != null then " --with-float=${gccFloat}" else "";
142         withMode = if gccMode != null then " --with-mode=${gccMode}" else "";
143       in
144         "--target=${cross.config}" +
145         withArch +
146         withCpu +
147         withAbi +
148         withFpu +
149         withFloat +
150         withMode +

After your changes stdenv.cross is null here (in the case of gcc-5.4.0-armv6l-unknown-linux-gnueabi-stage-final.drv) so all the withFoo flags are empty. The cross variable seems to contain the correct things though. So that needs either s/stdenv.cross/cross/ or figuring out why stdenv.cross is not set if the difference was unintentional.

@DavidEGrayson DavidEGrayson force-pushed the pr_make_cross_compiling_great_again branch from 7a5dade to 7bed7fb Compare December 11, 2016 06:20
because stdenv.cross is nullwhen we build the cross compiler.
@DavidEGrayson DavidEGrayson force-pushed the pr_make_cross_compiling_great_again branch from 7bed7fb to 9fde656 Compare December 11, 2016 06:26
@DavidEGrayson
Copy link
Contributor Author

Thanks for figuring that out, @dezgeg! After I fixed that (commit 9fde656 of this PR), I was able to successfully cross-compile a "Hello world" program for the Raspberry Pi and run it.

I fixed it by changing stdenv.cross to cross in the definition of crossConfigureFlags for GCC 5. The reason stdenv.cross is null is because this PR removes some tricky circular references from nixpkgs: we use a normal stdenv without any cross-compilation (stdenv.cross is null) to build our cross compiler. So when we are building the cross-compiler, stdenv.cross will be null. Once the cross-compiler is built, then we create a stdenv with a cross attribute, as before.

@Ericson2314
Copy link
Member

Ericson2314 commented Dec 18, 2016

I rebased this (untested though) as https://github.com/Ericson2314/nixpkgs/tree/deg-cross

@shlevy shlevy requested review from shlevy and removed request for shlevy December 18, 2016 22:39
@DavidEGrayson
Copy link
Contributor Author

My rebase of this pull request onto a modern nixpkgs master commit is almost finished. But while testing it, I noticed that six days ago there was a change that broke 31 of the cross-compilation jobs:

https://hydra.nixos.org/eval/1314290

@DavidEGrayson
Copy link
Contributor Author

I'm closing this because it's stale. Anyone interested in the changes from this pull request should discuss them in the new version of the pull request (v2) here: #21388

@dezgeg
Copy link
Contributor

dezgeg commented Dec 24, 2016

This should fix the coreutils cross building breakage: 30074dd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: cross-compilation Building packages on a different platform than they will be used on
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants