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

Revamp cross-compilation docs #127115

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

siraben
Copy link
Member

@siraben siraben commented Jun 16, 2021

Motivation for this change

I want this to be an interactive process with the community. Cross-compilation is one of Nixpkgs' greatest strengths, but the docs do not do it justice. In particular:

WIP for now

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • 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 nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • 21.11 Release Notes
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@Mindavi Mindavi added the 6.topic: cross-compilation Building packages on a different sort platform than than they will be run on label Jun 16, 2021
@domenkozar
Copy link
Member

Also see https://nix.dev/tutorials/cross-compilation

@siraben
Copy link
Member Author

siraben commented Jun 18, 2021

@domenkozar wow, I didn't know nix.dev covered cross-compilation, thanks! Recently heard the podcast as well :)

@domenkozar
Copy link
Member

@domenkozar wow, I didn't know nix.dev covered cross-compilation, thanks! Recently heard the podcast as well :)

It's quite recent, added yesterday :)

Great work with these changes! Looks good to me.

@siraben
Copy link
Member Author

siraben commented Jul 4, 2021

@ianthehenry I saw you mentioned the cross-compilation section of Nixpkgs in your blog post, I agree the way the section is currently structured is confusing as well and I only managed to make heads or tails of it from various sources online by @matthewbauer, discussions with @Ericson2314 and diving head-first into adding cross-compilation support for a few new targets. Would appreciate any suggestions and/or feedback in this WIP PR. You also may want to check out the nix.dev tutorial on cross-compilation.

This section is poignant:

And I think that, if cross-compilation should work by default for as many packages as possible, it is important to communicate to users how they can make that work, in simple language that can be understood by someone (like me) who has not given a lot of thought to cross-compilation before. I feel like the current state of the documentation is probably illegible to people who don’t already know how it works, and I would venture a guess that this means the “average” Nix user (like me) doesn’t know what they should be doing in order to support it. So I’m just not going to think about it, and hope that it works.

@siraben
Copy link
Member Author

siraben commented Jul 4, 2021

@ianthehenry I also highly recommend you join our Matrix channels so you can see what the community is up to and ask questions when they arise.

@ianthehenry
Copy link

@siraben You may have seen this post already, but just in case: the first and most confusing explanation of cross-compilation in the manual is actually in Chapter 6. Trying to read that section was the primary source of my frustration in the summary (ctrl-F "offset").

The actual cross-compilation chapter made better reading, for the most part, although the section on bootstrapping completely lost me. That said, I admire any effort to clarify it, and I think the changes you've made so far certainly do increase the legibility a bit.

For me I think that a concrete example would be very helpful -- I tried to cross-compile a trivial package and was unable to. I don't know if I was doing something completely wrong, if I just got unlucky, if Linux is not a reasonable target platform, or what. (I expect that cross-compilation mostly exists for microcontrollers, but that's harder for someone like me (who just wants to see how it works) to experiment with.)

@ghost
Copy link

ghost commented Apr 3, 2022

I expect that cross-compilation mostly exists for microcontrollers

There are tons of use cases for cross-compilation. Here are two that you might not have noticed:

  1. Cross-compilation allows Hydra to produce trusted bootstrap-files archives for platforms that it lacks physical hardware for. The hashes of these trusted archives get embedded into nixpkgs here. mips64el will be added to this list as soon as libtool: fix /usr/bin/file impurity #166879 merges, and I plan to work on mips32 and powerpc64 after that.

  2. Cross-compilation lets you use machines that are readily-accessible with large amounts of memory and CPU (like x86_64) to do builds for architectures that are popular in routers and switches (like mips32/mips64). This makes a big difference in development turnaround time.

There is a proposal (#21471) to make all compiles be cross-compiles, in order to avoid having two separate codepaths for every package. Even if you don't use cross-compilation, planning for it helps clarify build-time/run-time distinctions quite a bit.

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Oct 1, 2022
@stale stale bot removed the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jun 26, 2023
@siraben
Copy link
Member Author

siraben commented Jun 26, 2023

Still think it's valuable to update cross-compilation updates, but might not have time this summer to get around to the whole thing...

@siraben siraben marked this pull request as ready for review June 26, 2023 12:13
@siraben
Copy link
Member Author

siraben commented Jun 26, 2023

Maybe we can merge it as-is and incrementally do some of the suggestions at a later PR?

| Type of compilation | Condition |
|----------------------------|-------------------------|
| native compilation | build == host == target |
| cross-compilation | build /= host == target |
Copy link

Choose a reason for hiding this comment

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

This is wrong; "cross compilation" is ambiguous: it can mean either

build /= host == target

or

build == host /= target

Indeed, this is exactly the reason why nixpkgs doesn't have a stdenv.isCross. It's an ambiguous term.

Comment on lines +13 to +20
Nixpkgs follows the [conventions of GNU autoconf](https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html). We distinguish between 3 types of platforms when building a derivation: _build_, _host_, and _target_. In summary, _build_ is the platform on which a package is being built, _host_ is the platform on which it will run. The third attribute, _target_, is relevant only for certain specific compilers and build tools. Using this terminology, we can summarize the different types of compilation as follows:

| Type of compilation | Condition |
|----------------------------|-------------------------|
| native compilation | build == host == target |
| cross-compilation | build /= host == target |
| Canadian cross-compilation | build /= host /= target |

Copy link

Choose a reason for hiding this comment

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

Suggested change
Nixpkgs follows the [conventions of GNU autoconf](https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html). We distinguish between 3 types of platforms when building a derivation: _build_, _host_, and _target_. In summary, _build_ is the platform on which a package is being built, _host_ is the platform on which it will run. The third attribute, _target_, is relevant only for certain specific compilers and build tools. Using this terminology, we can summarize the different types of compilation as follows:
| Type of compilation | Condition |
|----------------------------|-------------------------|
| native compilation | build == host == target |
| cross-compilation | build /= host == target |
| Canadian cross-compilation | build /= host /= target |
Nixpkgs follows the [conventions of GNU autoconf](https://gcc.gnu.org/onlinedocs/gccint/Configure-Terms.html). We distinguish between 3 types of platforms when building a derivation: _build_, _host_, and _target_. In summary, _build_ is the platform on which a package is being built, _host_ is the platform on which it will run. The third attribute, _target_, is relevant only for certain specific compilers and build tools.

@@ -62,15 +69,17 @@ The exact schema these fields follow is a bit ill-defined due to a long and conv

: This is, quite frankly, a dumping ground of ad-hoc settings (it's an attribute set). See `lib.systems.platforms` for examples—there's hopefully one in there that will work verbatim for each platform that is working. Please help us triage these flags and give them better homes!

Using these attributes, the build process of a package can change depending on the situation, for instance, when cross-compiling, one may want to apply specific patches or disable tests.
Copy link

Choose a reason for hiding this comment

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

Suggested change
Using these attributes, the build process of a package can change depending on the situation, for instance, when cross-compiling, one may want to apply specific patches or disable tests.
Using these attributes, the build process of a package can change depending on the situation.
  1. Tests are already disabled when !buildPlatform.canExecute hostPlatform
  2. We generally try really hard to avoid conditionally applying patches, because conditionally-applied patches tend to get broken by version bumps and never noticed.

@@ -123,6 +132,9 @@ software floating point emulation. `libgcc` would be a "target→ *" dependency

Some frequently encountered problems when packaging for cross-compilation should be answered here. Ideally, the information above is exhaustive, so this section cannot provide any new information, but it is ludicrous and cruel to expect everyone to spend effort working through the interaction of many features just to figure out the same answer to the same common problem. Feel free to add to this list!

#### How do I test cross-compilation using emulation? {#cross-qa-emulation}
Compile the package and run `nix-shell -p qemu`, then run `qemu-system-<arch>` where `<arch>` is the architecture of interest. Alternatively, Nixpkgs has some logic to dispatch to the right emulator, see [\#106375](https://github.com/NixOS/nixpkgs/issues/106375)
Copy link

Choose a reason for hiding this comment

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

Probably better to actually document lib.systems.emulatorFor than to point to a github issue...

@wegank wegank added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Mar 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: cross-compilation Building packages on a different sort platform than than they will be run on 8.has: documentation 10.rebuild-darwin: 0 10.rebuild-linux: 0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants