@ -4,6 +4,16 @@
# http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html especially
# Triple::normalize. Parsing should essentially act as a more conservative
# version of that last function.
#
# Most of the types below come in "open" and "closed" pairs. The open ones
# specify what information we need to know about systems in general, and the
# closed ones are sub-types representing the whitelist of systems we support in
# practice.
#
# Code in the remainder of nixpkgs shouldn't rely on the closed ones in
# e.g. exhaustive cases. Its more a sanity check to make sure nobody defines
# systems that overlap with existing ones and won't notice something amiss.
#
{ lib }:
with lib . lists ;
with lib . types ;
@ -11,29 +21,52 @@ with lib.attrsets;
with ( import ./inspect.nix { inherit lib ; } ) . predicates ;
let
setTypesAssert = type : pred :
inherit ( lib . options ) mergeOneOption ;
setTypes = type :
mapAttrs ( name : value :
assert pred value ;
setType type ( { inherit name ; } // value ) ) ;
setTypes = type : setTypesAssert type ( _ : true ) ;
assert type . check value ;
setType type . name ( { inherit name ; } // value ) ) ;
in
rec {
isSignificantByte = isType " s i g n i f i c a n t - b y t e " ;
significantBytes = setTypes " s i g n i f i c a n t - b y t e " {
################################################################################
types . openSignifiantByte = mkOptionType {
name = " s i g n i f i c a n t - b y t e " ;
description = " E n d i a n n e s s " ;
merge = mergeOneOption ;
} ;
types . significantByte = enum ( attrValues significantBytes ) ;
significantBytes = setTypes types . openSignifiantByte {
bigEndian = { } ;
littleEndian = { } ;
} ;
isCpuType = isType " c p u - t y p e " ;
cpuTypes = with significantBytes ; setTypesAssert " c p u - t y p e "
( x : elem x . bits [ 8 16 32 64 128 ]
&& ( if 8 < x . bits
then isSignificantByte x . significantByte
else ! ( x ? significantByte ) ) )
{
################################################################################
# Reasonable power of 2
types . bitWidth = enum [ 8 16 32 64 128 ] ;
################################################################################
types . openCpuType = mkOptionType {
name = " c p u - t y p e " ;
description = " i n s t r u c t i o n s e t a r c h i t e c t u r e n a m e a n d i n f o r m a t i o n " ;
merge = mergeOneOption ;
check = x : types . bitWidth . check x . bits
&& ( if 8 < x . bits
then types . significantByte . check x . significantByte
else ! ( x ? significantByte ) ) ;
} ;
types . cpuType = enum ( attrValues cpuTypes ) ;
cpuTypes = with significantBytes ; setTypes types . openCpuType {
arm = { bits = 32 ; significantByte = littleEndian ; family = " a r m " ; } ;
armv5tel = { bits = 32 ; significantByte = littleEndian ; family = " a r m " ; } ;
armv6l = { bits = 32 ; significantByte = littleEndian ; family = " a r m " ; } ;
@ -50,16 +83,34 @@ rec {
wasm64 = { bits = 64 ; significantByte = littleEndian ; family = " w a s m " ; } ;
} ;
isVendor = isType " v e n d o r " ;
vendors = setTypes " v e n d o r " {
################################################################################
types . openVendor = mkOptionType {
name = " v e n d o r " ;
description = " v e n d o r f o r t h e p l a t f o r m " ;
merge = mergeOneOption ;
} ;
types . vendor = enum ( attrValues vendors ) ;
vendors = setTypes types . openVendor {
apple = { } ;
pc = { } ;
unknown = { } ;
} ;
isExecFormat = isType " e x e c - f o r m a t " ;
execFormats = setTypes " e x e c - f o r m a t " {
################################################################################
types . openExecFormat = mkOptionType {
name = " e x e c - f o r m a t " ;
description = " e x e c u t a b l e c o n t a i n e r u s e d b y t h e k e r n e l " ;
merge = mergeOneOption ;
} ;
types . execFormat = enum ( attrValues execFormats ) ;
execFormats = setTypes types . openExecFormat {
aout = { } ; # a.out
elf = { } ;
macho = { } ;
@ -68,15 +119,33 @@ rec {
unknown = { } ;
} ;
isKernelFamily = isType " k e r n e l - f a m i l y " ;
kernelFamilies = setTypes " k e r n e l - f a m i l y " {
################################################################################
types . openKernelFamily = mkOptionType {
name = " e x e c - f o r m a t " ;
description = " e x e c u t a b l e c o n t a i n e r u s e d b y t h e k e r n e l " ;
merge = mergeOneOption ;
} ;
types . kernelFamily = enum ( attrValues kernelFamilies ) ;
kernelFamilies = setTypes types . openKernelFamily {
bsd = { } ;
} ;
isKernel = x : isType " k e r n e l " x ;
kernels = with execFormats ; with kernelFamilies ; setTypesAssert " k e r n e l "
( x : isExecFormat x . execFormat && all isKernelFamily ( attrValues x . families ) )
{
################################################################################
types . openKernel = mkOptionType {
name = " k e r n e l " ;
description = " k e r n e l n a m e a n d i n f o r m a t i o n " ;
merge = mergeOneOption ;
check = x : types . execFormat . check x . execFormat
&& all types . kernelFamily . check ( attrValues x . families ) ;
} ;
types . kernel = enum ( attrValues kernels ) ;
kernels = with execFormats ; with kernelFamilies ; setTypes types . openKernel {
darwin = { execFormat = macho ; families = { } ; } ;
freebsd = { execFormat = elf ; families = { inherit bsd ; } ; } ;
hurd = { execFormat = elf ; families = { } ; } ;
@ -93,8 +162,17 @@ rec {
win32 = kernels . windows ;
} ;
isAbi = isType " a b i " ;
abis = setTypes " a b i " {
################################################################################
types . openAbi = mkOptionType {
name = " a b i " ;
description = " b i n a r y i n t e r f a c e f o r c o m p i l e d c o d e a n d s y s c a l l s " ;
merge = mergeOneOption ;
} ;
types . abi = enum ( attrValues abis ) ;
abis = setTypes types . openAbi {
cygnus = { } ;
gnu = { } ;
msvc = { } ;
@ -106,12 +184,24 @@ rec {
unknown = { } ;
} ;
################################################################################
types . system = mkOptionType {
name = " s y s t e m " ;
description = " f u l l y p a r s e d r e p r e s e n t a t i o n o f l l v m - o r n i x - s t y l e p l a t f o r m t u p l e " ;
merge = mergeOneOption ;
check = { cpu , vendor , kernel , abi }:
types . cpuType . check cpu
&& types . vendor . check vendor
&& types . kernel . check kernel
&& types . abi . check abi ;
} ;
isSystem = isType " s y s t e m " ;
mkSystem = { cpu , vendor , kernel , abi }:
assert isCpuType cpu && isVendor vendor && isKernel kernel && isAbi abi ;
setType " s y s t e m " {
inherit cpu vendor kernel abi ;
} ;
mkSystem = components :
assert types . system . check components ;
setType " s y s t e m " components ;
mkSkeletonFromList = l : {
" 2 " = # We only do 2-part hacks for things Nix already supports
@ -174,4 +264,6 @@ rec {
optAbi = lib . optionalString ( abi != abis . unknown ) " - ${ abi . name } " ;
in " ${ cpu . name } - ${ vendor . name } - ${ kernel . name } ${ optAbi } " ;
################################################################################
}