nixpkgs/lib/systems/inspect.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

482 lines
8.4 KiB
Nix
Raw Permalink Normal View History

Convert libs to a fixed-point This does break the API of being able to import any lib file and get its libs, however I'm not sure people did this. I made this while exploring being able to swap out docFn with a stub in #2305, to avoid functor performance problems. I don't know if that is going to move forward (or if it is a problem or not,) but after doing all this work figured I'd put it up anyway :) Two notable advantages to this approach: 1. when a lib inherits another lib's functions, it doesn't automatically get put in to the scope of lib 2. when a lib implements a new obscure functions, it doesn't automatically get put in to the scope of lib Using the test script (later in this commit) I got the following diff on the API: + diff master fixed-lib 11764a11765,11766 > .types.defaultFunctor > .types.defaultTypeMerge 11774a11777,11778 > .types.isOptionType > .types.isType 11781a11786 > .types.mkOptionType 11788a11794 > .types.setType 11795a11802 > .types.types This means that this commit _adds_ to the API, however I can't find a way to fix these last remaining discrepancies. At least none are _removed_. Test script (run with nix-repl in the PATH): #!/bin/sh set -eux repl() { suff=${1:-} echo "(import ./lib)$suff" \ | nix-repl 2>&1 } attrs_to_check() { repl "${1:-}" \ | tr ';' $'\n' \ | grep "\.\.\." \ | cut -d' ' -f2 \ | sed -e "s/^/${1:-}./" \ | sort } summ() { repl "${1:-}" \ | tr ' ' $'\n' \ | sort \ | uniq } deep_summ() { suff="${1:-}" depth="${2:-4}" depth=$((depth - 1)) summ "$suff" for attr in $(attrs_to_check "$suff" | grep -v "types.types"); do if [ $depth -eq 0 ]; then summ "$attr" | sed -e "s/^/$attr./" else deep_summ "$attr" "$depth" | sed -e "s/^/$attr./" fi done } ( cd nixpkgs #git add . #git commit -m "Auto-commit, sorry" || true git checkout fixed-lib deep_summ > ../fixed-lib git checkout master deep_summ > ../master ) if diff master fixed-lib; then echo "SHALLOW MATCH!" fi ( cd nixpkgs git checkout fixed-lib repl .types )
2017-07-28 20:05:35 -04:00
{ lib }:
let
inherit (lib)
any
attrValues
concatMap
filter
hasPrefix
isList
mapAttrs
matchAttrs
recursiveUpdateUntil
toList
;
inherit (lib.strings) toJSON;
inherit (lib.systems.parse)
kernels
kernelFamilies
significantBytes
cpuTypes
execFormats
;
abis = mapAttrs (_: abi: removeAttrs abi [ "assertions" ]) lib.systems.parse.abis;
in
rec {
# these patterns are to be matched against {host,build,target}Platform.parsed
patterns = rec {
# The patterns below are lists in sum-of-products form.
#
# Each attribute is list of product conditions; non-list values are treated
# as a singleton list. If *any* product condition in the list matches then
# the predicate matches. Each product condition is tested by
# `lib.attrsets.matchAttrs`, which requires a match on *all* attributes of
# the product.
isi686 = {
cpu = cpuTypes.i686;
};
isx86_32 = {
cpu = {
family = "x86";
bits = 32;
};
};
isx86_64 = {
cpu = {
family = "x86";
bits = 64;
};
};
2019-09-02 01:55:38 -04:00
isPower = {
cpu = {
family = "power";
};
};
isPower64 = {
cpu = {
family = "power";
bits = 64;
};
};
# This ABI is the default in NixOS PowerPC64 BE, but not on mainline GCC,
# so it sometimes causes issues in certain packages that makes the wrong
# assumption on the used ABI.
isAbiElfv2 = [
{
abi = {
abi = "elfv2";
};
}
{
abi = {
name = "musl";
};
cpu = {
family = "power";
bits = 64;
};
}
];
isx86 = {
cpu = {
family = "x86";
};
};
isAarch32 = {
cpu = {
family = "arm";
bits = 32;
};
};
2023-01-19 16:39:30 +00:00
isArmv7 = map (
{ arch, ... }:
{
cpu = { inherit arch; };
}
) (filter (cpu: hasPrefix "armv7" cpu.arch or "") (attrValues cpuTypes));
isAarch64 = {
cpu = {
family = "arm";
bits = 64;
};
};
2022-07-28 13:43:30 +02:00
isAarch = {
cpu = {
family = "arm";
};
};
isMicroBlaze = {
cpu = {
family = "microblaze";
};
};
isMips = {
cpu = {
family = "mips";
};
};
isMips32 = {
cpu = {
family = "mips";
bits = 32;
};
};
isMips64 = {
cpu = {
family = "mips";
bits = 64;
};
};
isMips64n32 = {
cpu = {
family = "mips";
bits = 64;
};
abi = {
abi = "n32";
};
};
isMips64n64 = {
cpu = {
family = "mips";
bits = 64;
};
abi = {
abi = "64";
};
};
isMmix = {
cpu = {
family = "mmix";
};
};
isRiscV = {
cpu = {
family = "riscv";
};
};
isRiscV32 = {
cpu = {
family = "riscv";
bits = 32;
};
};
isRiscV64 = {
cpu = {
family = "riscv";
bits = 64;
};
};
isRx = {
cpu = {
family = "rx";
};
};
isSparc = {
cpu = {
family = "sparc";
};
};
isSparc64 = {
cpu = {
family = "sparc";
2023-01-19 16:40:01 +00:00
bits = 64;
};
};
isWasm = {
cpu = {
family = "wasm";
};
};
isMsp430 = {
cpu = {
family = "msp430";
};
};
isVc4 = {
cpu = {
family = "vc4";
};
};
isAvr = {
cpu = {
family = "avr";
};
};
isAlpha = {
cpu = {
family = "alpha";
};
};
isOr1k = {
cpu = {
family = "or1k";
};
};
isM68k = {
cpu = {
family = "m68k";
};
};
isS390 = {
2023-01-19 16:40:01 +00:00
cpu = {
family = "s390";
};
};
isS390x = {
2023-04-27 20:04:17 +03:00
cpu = {
family = "s390";
bits = 64;
};
};
isLoongArch64 = {
cpu = {
2023-04-27 20:04:17 +03:00
family = "loongarch";
2023-01-19 16:40:01 +00:00
bits = 64;
};
};
isJavaScript = {
cpu = cpuTypes.javascript;
};
is32bit = {
cpu = {
bits = 32;
};
};
is64bit = {
cpu = {
bits = 64;
};
};
isILP32 =
[
{
cpu = {
family = "wasm";
bits = 32;
};
}
]
++ map
(a: {
abi = {
abi = a;
};
})
[
"n32"
"ilp32"
"x32"
];
isBigEndian = {
cpu = {
significantByte = significantBytes.bigEndian;
};
};
isLittleEndian = {
cpu = {
significantByte = significantBytes.littleEndian;
};
};
isBSD = {
kernel = {
families = { inherit (kernelFamilies) bsd; };
};
};
isDarwin = {
kernel = {
families = { inherit (kernelFamilies) darwin; };
2020-07-21 13:11:36 -07:00
};
};
2020-07-21 13:11:36 -07:00
isUnix = [
isBSD
isDarwin
isLinux
isSunOS
isCygwin
isRedox
];
isMacOS = {
kernel = kernels.macos;
};
isiOS = {
kernel = kernels.ios;
};
isLinux = {
kernel = kernels.linux;
};
isSunOS = {
kernel = kernels.solaris;
};
isFreeBSD = {
kernel = {
name = "freebsd";
};
};
isNetBSD = {
kernel = kernels.netbsd;
};
isOpenBSD = {
kernel = kernels.openbsd;
};
isWindows = {
kernel = kernels.windows;
};
isCygwin = {
kernel = kernels.windows;
abi = abis.cygnus;
};
isMinGW = {
kernel = kernels.windows;
abi = abis.gnu;
};
isWasi = {
kernel = kernels.wasi;
2020-07-21 13:11:36 -07:00
};
isRedox = {
kernel = kernels.redox;
2019-09-02 01:55:38 -04:00
};
isGhcjs = {
kernel = kernels.ghcjs;
};
isGenode = {
kernel = kernels.genode;
};
isNone = {
kernel = kernels.none;
};
isAndroid = [
{ abi = abis.android; }
{ abi = abis.androideabi; }
];
isGnu =
with abis;
map (a: { abi = a; }) [
gnuabi64
gnuabin32
gnu
gnueabi
gnueabihf
gnuabielfv1
gnuabielfv2
];
isMusl =
with abis;
map (a: { abi = a; }) [
musl
musleabi
musleabihf
muslabin32
muslabi64
2018-05-09 23:33:31 -04:00
];
isUClibc =
with abis;
map (a: { abi = a; }) [
uclibc
uclibceabi
uclibceabihf
];
isEfi = [
{
cpu = {
family = "arm";
version = "6";
};
}
{
cpu = {
family = "arm";
version = "7";
};
}
{
cpu = {
family = "arm";
version = "8";
};
}
{
cpu = {
family = "riscv";
};
}
{
cpu = {
family = "x86";
};
}
{
cpu = {
family = "loongarch";
};
}
];
isElf = {
kernel.execFormat = execFormats.elf;
};
isMacho = {
kernel.execFormat = execFormats.macho;
};
};
# given two patterns, return a pattern which is their logical AND.
# Since a pattern is a list-of-disjuncts, this needs to
patternLogicalAnd =
pat1_: pat2_:
let
# patterns can be either a list or a (bare) singleton; turn
# them into singletons for uniform handling
pat1 = toList pat1_;
pat2 = toList pat2_;
in
concatMap (
attr1:
map (
attr2:
recursiveUpdateUntil (
path: subattr1: subattr2:
if (builtins.intersectAttrs subattr1 subattr2) == { } || subattr1 == subattr2 then
true
else
throw ''
pattern conflict at path ${toString path}:
${toJSON subattr1}
${toJSON subattr2}
''
) attr1 attr2
) pat2
) pat1;
matchAnyAttrs =
patterns:
if isList patterns then
attrs: any (pattern: matchAttrs pattern attrs) patterns
else
matchAttrs patterns;
predicates = mapAttrs (_: matchAnyAttrs) patterns;
# these patterns are to be matched against the entire
# {host,build,target}Platform structure; they include a `parsed={}` marker so
# that `lib.meta.availableOn` can distinguish them from the patterns which
# apply only to the `parsed` field.
platformPatterns = mapAttrs (_: p: { parsed = { }; } // p) {
isStatic = {
isStatic = true;
};
};
}