-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
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
Standardize all-packages.nix arguments and stdenv attributes #10874
Comments
Today, by coincidence, I tried cross-compiling things with mingw but
that failed because of libiconv, so it might not only be duplicated but
more importantly, it does not work. libiconv error was caused by assert
!stdenv.isLinux or something like that, which should be an assertion on
the target and not on the host. Thanks a lot for looking into this!
|
I personally believe the standard attributes (buildInputs, stdenv.system, etc.) should be for the target platform where the output is to be executed, as that seems to be the most common use case. (Note that I've never done any cross building, though :) |
I've recently been mulling this. We have all this |
We could have separate sets, but how would that go with passing dependencies into packages? Now we only put the attribute name in there, without specifying whether it's a native or cross package... |
@vcunat it would be a huge breaking change on the callPackage ideom, I'm afraid. I'd hope to stage it together when we overhaul the ideom to better expose flags like with the nixos module system. |
Well, then I think both ways could be done concurrently at the cost of even more complexity in the interim. |
Basically, I see why the current approach was chosen to minimize churn, but long term I'd like to do it what I see is the "right way". |
@Mathnerd314 Did the all-packages fix-point cleanup affect this at all? Notwithstanding what I wrote above, everything you proposed sounds like a good idea and I'd like to see it again. Just now I was yet again confronted with |
I don't think so. This is about meaning of |
@vcunat sure, not saying that PR actually changed semantics. But curious whether or not it made anything easier to implement. |
The difficulty here won't be in implementation, I think. We probably want to break backwards compatibility here (change meaning), which isn't an easy thing to do and some may oppose it. Also, we should design such changes carefully to avoid the need to change these soon again. |
@vcunat thanks for the clarification--sounds good to me. Time to get designing then!
Hmm, I thought |
|
Ah yes. Whereas I'd have thought |
Ok so thoughts so far:
|
To be clear,
Staring at the picture, the list of platforms must be at least one platform long--- For example:
Translated:
Note that because Now obviously this is way overkill for practical uses, but I believe supporting arbitrary lists of this sort will be a good way to battle-harden the cross-compiling infrastructure and ensure we implemented it correctly. |
Looking at https://github.com/NixOS/nixpkgs/blob/master/pkgs/top-level/default.nix#L8-L33, what is the relationship between |
This is similar to bjornfor's approach (#4855 (comment)). It sounds fine to me; I suggest discussing it there so it can get consensus. This issue is not about nativeDrv or crossDrv or anything like that (although stdenvCross is slightly relevant).
My idea is that bootstrapping and cross-compiling are very similar. There's no way to build "native" packages without a bootstrap compiler, and similarly there's no way to build cross-packages without a cross-compiler. With the right design, they can be passed around using the same code, so that "native" builds are cross-builds where the host/target are the same and the host tools are the bootstrap tools.
Target is a GCC-ism; clang always builds with all targets available. And GCC can be built and run twice (and actually is in the nixpkgs bootstrap); there is no need to support the "Canadian Cross", only one level of build/host or host/target distinction is needed. In my proposal it is bootSystem attribute / normal system attribute, I guess you could keep bikeshedding this.
This could be jury-rigged if needed by providing a "builtSystem" attribute in the package set such that it could be used for "bootSystem", so you would do
But nixpkgs would not need to support more than one level of cross-compilation at a time.
It's a parameter used in most of the stdenv's to build gcc and other base tools; the final stdenv consists of tools built with bootStdenv=stage4, and similarly stage4 was built with bootStdenv=stage3, down to the bootstrap tarball which has a null bootStdenv.
platform is an attribute set with a few gcc build options (fpu, cpu, etc.) and some kernel config.
I consider "backwards-compatibility" to mean that nixpkgs / nixos configurations don't need to change, and I think that is the case here. platform / system / crossSystem are internal to nixpkgs. |
Yeah I was inspired by that. A slight difference is I think the intended use of each package should only be a default---any package should be able to be used as a build or host dep with enough explicitness/verbosity.
Definitely! Right now "stdenv" is a nebulous/overloaded concept---a set of default packages for mkDerivation and a mini-package set for bootstrapping purposes. Now that
I'm definitely sympathetic---I've always been shocked and appalled not everyone does it the LLVM way, building for all targets. But that said, while software exists that can't do multi-target, we're kind of bound to support the concept. And LLVM-based tool chains in practice seem to still use binutils not lld, so nobody is completely avoiding this in practice.
Thanks for explaining it---reminds me a lot of https://github.com/rust-lang/rfcs/blob/master/text/0131-target-specification.md. It seems really we ought to derive system from platform, and the system string really ought to be a LLVM's target triple if it exists from all) but meaningful changes here might depend on changing nix/hydra?
Hmm not sure what you mean? Certainly bootstrapping involves building multiple GCCs no doubt about it.
So I guess with a |
I think of stdenv as something similar to Debian's "build-essential", containing all packages necessary for building simple C programs.
IMO all packages should be able to bootstrap themselves, we are pretty close to that (fetchurl is now built-in to Nix)
bootSystem could have a pkgs attribute. I'm not sure how that would work exactly.
What I meant was that, for GCC, using only compilers with host==target (native compiler) or build==host (cross compiler) is sufficient. If you wanted to do something with build != host != target, then you would build a native compiler for the host and a cross-compiler for the target (on that host). It's an extra GCC build but pretty small in the grand scheme of things. And regardless of Nixpkgs support, using a build!=host!=target setup in Nix would require a build-farm so that it could build on multiple platforms.
I think platform should contain the system attribute (and remove it from all-packages arguments), the rest is academic. |
Still trying to clarify my thoughts on the other stuff, but let me start here. This should be nested the other way around — the concept of a boot system makes no sense without packages for the boot system. Nix can only run code on a given platform if pacakges (or "imaginary" impure packages) exist for that platform. |
I think it would be a mistake to try to fix this issue perfectly in a single iteration. (holds more generally) Let's make a substantial improving step, e.g. excluding support for the canadian cross etc for now. We'll see after some time how it works out and we might reiterate. (Or not, if the issue won't be pressing enough anymore, but both are positive cases.) |
@vcunat Well I didn't say one big PR. I think I've been here long enough to know how that will go :). But I'd like to have some sort of long term plan, just because its all pretty non-trivial.
I want it to just be that, but while we bootstrap stdenvs specifically its something more.
I mean stdenv as a package set is bootstrapped, i.e. all the
I thought about this for a long, long time, and now agree, though perhaps for different reasons. Instead every "native round" we need to fix the package set so that it's build dep is itself. Unlike our fix-extend ideom here, the idea is that if a package is "already" defined, we don't override it. this ensures bootstrapped packages aren't infinitely bootstrapped. The three forms are roughly let
stage0 = ... bootstrapTools ...;
fixedStageSuccN = mkPkgs { bootPkgs = fixedStageSuccN ; ... } // StageN; # "final native stages"
overridingStageSuccN = mkPkgs { bootPkgs = StageN; ... }; # today's stdenv stages or cross stages. Now I feel that perhaps (buildPkgs.targetPlatform == hostPlatform) # Basic sanity
&& (buildPkgs.buildPkgs.hostPlatform == buildPkgs.hostPlatform ) # Inductively ensures closure property, I hope
&& (buildPkgs.hostPlatform == hostPlatform) || (targetPlatform == hostPlatform) # No Canadian cross just because anything that cares about |
Ok, to actually get to specifics, here is what I think the first step should be. Currently |
A Few notes:
|
See closely related issue #14965 |
NB I've just started prototyping these things in https://github.com/Ericson2314/nixpkgs/tree/cross |
Today I started prototyping stuff around #14965, but it seems we won't clash due to focus on different aspects of cross-compilation. |
@vcunat do you have branch / want to collaborate on this? |
Ok, actually have some meaningful work there now. Calling it a night after getting seemingly-undebuggable stack overflow when evaluating :/. |
@Ericson2314 is this still an issue? |
We're getting close! But yeah there's bits of this that are still not done. if somebody wants to edit the OP to add a giant checklist of other issues for each of @Mathnerd314's excellent points, that would be great. |
This will be very useful for bootstrapping, eventually.
Thank you for your contributions. This has been automatically marked as stale because it has had no activity for 180 days. If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity. Here are suggestions that might help resolve this more quickly:
|
@Ericson2314 what's the status of this issue? |
As author of this issue, this looks like it's under control now. There's a single set of platform-specific attributes defined via https://github.com/NixOS/nixpkgs/tree/master/lib/systems and mostly everything uses those. Furthermore the arguments |
Wow, I looked over everything in this thread, and a few of the linked issues and I think it's all done!* This is the issue that started it all for me more than any other, so It's a nice moment. *I'm still peeved that |
There's a lot of duplication between the cross-building stuff for gcc and the Linux stdenv bootstrap.
Similarly, in libiconv's setup, the same logic is repeated twice, once for cross-building and once for stdenv.
Also, consider the dropbox package, which checks
stdenv.system
to see which binary to download. Supposing that one was cross-compiling a NixOS system from OS X, this is incorrect;stdenv.system
would bex86_64-darwin
, while the desired valuex86_64-linux
would not even be available in the currentcrossSystem
attributes. (The closest isconfig
, which would be "x86_64-unknown-linux-gnu"). On the other hand, the url contains the arch, which is present incrossSystem
, but not instdenv
.In other words, it's unclear what attributes are supposed to be checked for platform-dependent behavior, and the set of attributes available is inconsistent between cross-builds and normal builds. This should be decided upon and the results documented somewhere (e.g. nixpkgs manual).
Also see #4855 for a related discussion on cross-building dependencies, #1928 for requested stdenv attributes and cross-building TODO's that never happened, #6221 and #7334 for more stdenv attributes, #8081 for bootstrap tools scope creep, #3574 and #7384 mentioning dedicated Hydra job for bootstrap tools, #6952 for a possible alternative to our current bootstrapping approach, #5944 for why cross-compiling only works with gcc, #4963 for ideas on NixOS (as opposed to nixpkgs) cross-compiling, #2817 for odd stdenv overrides behavior, and #4998 for the likely end state of this issue.
I propose setting
system
to be the crossSystem-style attribute set for the targeted system, and combiningbootStdenv
andcrossSystem
intobootSystem
, representing the host system on which the builders are run.The text was updated successfully, but these errors were encountered: