-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
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
Platform normalization #24610
Platform normalization #24610
Conversation
@Ericson2314, thanks for your PR! By analyzing the history of the files in this pull request, we identified @viric, @dezgeg and @nbp to be potential reviewers. |
pkgs/top-level/release-lib.nix
Outdated
assertTrue = bool: | ||
if bool | ||
then pkgs.runCommand "evaluated-to-true" {} "true" | ||
then pkgs.runCommand "evaluated-to-false" {} "false"; |
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 looks like an syntax error.
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.
ok this was fixed later.
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.
Well, I want each commit to stand on its own so that should be correct from the start!
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.
Fixed from the start!
lib/tests/systems.nix
Outdated
{ | ||
all = assertTrue (mseteq all (linux ++ darwin ++ cygwin ++ freebsd ++ openbsd ++ netbsd ++ illumos)); | ||
|
||
arm = assertTrue (mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv7l-linux" "aarch64-linux" ]); |
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 there was a commit, which removed explicitly aarch64 from arm, because the cpu architecture is different.
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 was a241abf
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.
Just as I include x86_64
in the x86
family, so I still include aarch64
in the arm
one. But the arm
list there also constrains the word width to 32 bits---that should do the trick.
Just quickly glanced through this, why are we using the module system type system here? This seems like a really complex change and it's not clear to me why we're doing it this way. |
3ab0ad4
to
ff55591
Compare
ff55591
to
09139e3
Compare
Ok fixed the module tests (mistake in 2nd commit). Removing the "WIP" as this thing is no longer obviously broken, but it needs more review for style / objectives before merging. |
09139e3
to
9f44340
Compare
9f44340
to
d52ccd4
Compare
@nbp You have time to review this? Besides use of the module system, it would be good to figure out some plan for all the crazy edge cases when converting between LLVM triples and Nix "doubles" (e.g. stuff like |
assertTrue = bool: | ||
if bool | ||
then pkgs.runCommand "evaluated-to-true" {} "touch $out" | ||
else pkgs.runCommand "evaluated-to-false" {} "false"; |
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.
Why is this? Why not just use assert
?
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.
Basically a workaround around hydra not tracking evaluation errors per revisions. I'd like this to count towards the "test failed vs test pass" numbers like everything else.
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.
IMHO such tests are better done at build time (i.e. by having a single job that does nix-instantiate --eval tests.nix
, probably by adding it to lib/tests/release.nix
). I don't want to clutter Nixpkgs/NixOS jobsets with lots of tiny Nixpkgs lib tests...
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 is basically what the module tests are doing, they basically spawn multiple Nix expressions tests within one job which contains all module tests.
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 feel like recursive nix is a very heavy-handled solution here. If we don't want sub jobs so flattened, hydra should change the way it treats sub jobs.
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.
Note that this is not what I would call recursive nix, as the module system does not evaluate any derivation, it only use the interpreter with nix-instanciate
command, and check for the output of the command.
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.
@Ericson2314 so what is easier, an extra job to test these, or changing Hydra so it tracks evaluation errors by revision?
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.
Hmm? In a later PR I rewrote the tests the semi-recursive-Nix way.
lib/systems/parse.nix
Outdated
, abi ? assert false; null # ditto | ||
} @ args: let | ||
getCpu = name: | ||
attrByPath [name] (throw "Unknow cpuType `${name}'.") |
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.
Unknow
-> Unknown
. Also don't use backticks as quote characters please.
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.
Thanks, fixed.
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.
@edolstra the backtick-quote used to be the way names were reported by Nix tools.
lib/trivial.nix
Outdated
@@ -108,6 +108,9 @@ rec { | |||
# Flip the order of the arguments of a binary function. | |||
flip = f: a: b: f b a; | |||
|
|||
# Apply function if argument is non-null | |||
mapNullable = f: a: if isNull a then a else f a; |
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.
Functions used in only one place shouldn't be added to lib
.
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 can do that, but I've wanted this many times. I bet I could grep for == null|isNull
and probably find many more uses. I'd be happy to do so after this PR to prove its utility :).
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.
#24974 other uses :D.
To be honest I've never understood what If the goal is to provide a handful of properties of platforms, it would be simpler to just enumerate them, given that we only support something like 6 platforms. E.g.
Though some properties seem questionable. For example, why do we care whether a platform is 64 bit or big endian? (What do we even mean with 64 bit? LP64, LLP64, ...?) The other thing I've never understood is why |
My end goal here is to eventually replace all the
While we only support a few build platforms, people can and do specify all sorts of obscure stuff for the host platform. I want to be more general so the same predicates can be used for all of build, host, and target.
What CPU attributes we track is less important than a mechanism to do so. If this specific needs to be given more detailed or removed, I'd be happy to do so.
Yeah I agree that file / the |
@@ -424,11 +424,11 @@ rec { | |||
matchAttrs { cpu = { bits = 64; }; } sys | |||
=> true | |||
*/ | |||
matchAttrs = pattern: attrs: | |||
fold or false (attrValues (zipAttrsWithNames (attrNames pattern) (n: values: | |||
matchAttrs = pattern: attrs: assert isAttrs pattern; |
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.
Can we remove the FIXME from the comment now?
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.
Done
lib/systems/parse.nix
Outdated
}; | ||
isKernel = x: isType "kernel" x | ||
&& isExecFormat x.execFormat | ||
&& all isKernelFamily (attrValues x.families); |
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.
These conditions should be assertions at the creation of anything with _type = "kernel"
, otherwise this assertion would be checked every time these sets are accessed instead of the only time these sets are created. Thus the type "kernel"
would imply that these assertions are valid as well, without recursively going down in the set.
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.
Inductive enforcement makes sense. Likewise for isCpuType
which you wrote I'd think :D?
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.
yes, please.
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.
Done
lib/systems/parse.nix
Outdated
inherit name cpu arch kernel; | ||
&& isVendor x.vendor | ||
&& isKernel x.kernel | ||
&& isAbi x.abi; |
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.
Same here for isSystem
.
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.
Done
lib/systems/parse.nix
Outdated
l = lib.splitString "-" s; | ||
|
||
mkSystemFromSkeleton = { cpu | ||
, vendor ? assert false; null # optional, but fallback too complex for here |
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.
nit: These are actually inferred below, update the comment to say 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.
Done
elaborate = args: let | ||
final = { | ||
# Prefer to parse `config` as it is strictly more informative. | ||
parsed = parse.mkSystemFromString (if args ? config then args.config else args.system); |
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.
What is this config
attribute and from where does it come from?
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's an LLVM target triple. The name is unfortunate but not my choice. See the code block in https://nixos.org/wiki/CrossCompiling#Cross-compiling_in_practice for example.
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.
Sadly that wiki page is gone now - Can we not rename this attribute to llvmTargetConfig
?
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.
https://web.archive.org/web/20160322211219/https://nixos.org/wiki/CrossCompiling
I'm all for improving the name but we must be careful as this is a public interface to how Nixpkgs is instantiated.
Also, while I follow LLVM most closely, other tools use these 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.
ah right. In that case, maybe rename args
to compileConfig
?
lib/systems/parse.nix
Outdated
, abi ? assert false; null # ditto | ||
} @ args: let | ||
getCpu = name: | ||
attrByPath [name] (throw "Unknow cpuType `${name}'.") |
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.
@edolstra the backtick-quote used to be the way names were reported by Nix tools.
db0a3e2
to
3ccd13a
Compare
3ccd13a
to
6f1d655
Compare
This is a semantic change, but probably a safe one. In any event, this is very old hardware that probably no one uses anymore anyways.
Previously, platforms was a random thing in top-level
The old hard-coded lists are now used to test system parsing. In the process, make an `assertTrue` in release lib for eval tests; also use it in release-cross
Warning, this changes the compatibility claims of existing packages!
6f1d655
to
3efc661
Compare
} @ args: let | ||
getCpu = name: | ||
attrByPath [name] (throw "Unknown CPU type: ${name}") | ||
cpuTypes; |
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.
@Ericson2314 This might have been pointed out, but... I believe you can also do this to the same effect:
cpuTypes.${name} or (throw "Unknown CPU type: ${name}")
At least, if I'm not mistaken. Which is better is a matter of opinion, I suppose (though I guess it's also possible that one performs better than the other).
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.
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.
Feel free to make another PR---in general I expect this file to get a lot attention and grow in complexity as this stuff gets used---I've got more to stuff to upstream so not sure whether I have time!
@Ericson2314 Yes please, it would be nice to have one Hydra job for Nixpkgs lib tests. |
Worthwhile to do now that NixOS#24610 makes it less abysmal.
Motivation for this change
Finally deal with the awkward friction between
{build,host,target}Platform.system
and{build,host,target}Platform.config
. This is a followup to #22575 and fixes #24170 .@nbp this uses your old system code and tests. I think I've used the module type system idiomatically, but I am unsure about the "CPU families" bit. In lieu of real sets, I used a map [why do we say attribute set"...], but perhaps
matchAttrs
should be mutually recursive with amatchLists
that treats the list as a set (or looks for sublists].@nbp Also, I broke the existing module system test infra with some mysterious call package exception. Not sure what's up with that, but want to get this up for review.Fixed.This can be reviewed or even merged commit-by-commit, but watch out: github is putting the commits out or order again (argh!).
CC @wizeman
Things done
(nix.useSandbox on NixOS,
or option
build-use-sandbox
innix.conf
on non-NixOS)
nix-shell -p nox --run "nox-review wip"
./result/bin/
)