lol
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 18.09-beta 117 lines 4.8 kB view raw
1# This file defines a single function for booting a package set from a list of 2# stages. The exact mechanics of that function are defined below; here I 3# (@Ericson2314) wish to describe the purpose of the abstraction. 4# 5# The first goal is consistency across stdenvs. Regardless of what this function 6# does, by making every stdenv use it for bootstrapping we ensure that they all 7# work in a similar way. [Before this abstraction, each stdenv was its own 8# special snowflake due to different authors writing in different times.] 9# 10# The second goal is consistency across each stdenv's stage functions. By 11# writing each stage it terms of the previous stage, commonalities between them 12# are more easily observable. [Before, there usually was a big attribute set 13# with each stage, and stages would access the previous stage by name.] 14# 15# The third goal is composition. Because each stage is written in terms of the 16# previous, the list can be reordered or, more practically, extended with new 17# stages. The latter is used for cross compiling and custom 18# stdenvs. Additionally, certain options should by default apply only to the 19# last stage, whatever it may be. By delaying the creation of stage package sets 20# until the final fold, we prevent these options from inhibiting composition. 21# 22# The fourth and final goal is debugging. Normal packages should only source 23# their dependencies from the current stage. But for the sake of debugging, it 24# is nice that all packages still remain accessible. We make sure previous 25# stages are kept around with a `stdenv.__bootPackges` attribute referring the 26# previous stage. It is idiomatic that attributes prefixed with `__` come with 27# special restrictions and should not be used under normal circumstances. 28{ lib, allPackages }: 29 30# Type: 31# [ pkgset -> (args to stage/default.nix) or ({ __raw = true; } // pkgs) ] 32# -> pkgset 33# 34# In english: This takes a list of function from the previous stage pkgset and 35# returns the final pkgset. Each of those functions returns, if `__raw` is 36# undefined or false, args for this stage's pkgset (the most complex and 37# important arg is the stdenv), or, if `__raw = true`, simply this stage's 38# pkgset itself. 39# 40# The list takes stages in order, so the final stage is last in the list. In 41# other words, this does a foldr not foldl. 42stageFuns: let 43 44 /* "dfold" a ternary function `op' between successive elements of `list' as if 45 it was a doubly-linked list with `lnul' and `rnul` base cases at either 46 end. In precise terms, `fold op lnul rnul [x_0 x_1 x_2 ... x_n-1]` is the 47 same as 48 49 let 50 f_-1 = lnul f_0; 51 f_0 = op f_-1 x_0 f_1; 52 f_1 = op f_0 x_1 f_2; 53 f_2 = op f_1 x_2 f_3; 54 ... 55 f_n = op f_n-1 x_n f_n+1; 56 f_n+1 = rnul f_n; 57 in 58 f_0 59 */ 60 dfold = op: lnul: rnul: list: 61 let 62 len = builtins.length list; 63 go = pred: n: 64 if n == len 65 then rnul pred 66 else let 67 # Note the cycle -- call-by-need ensures finite fold. 68 cur = op pred (builtins.elemAt list n) succ; 69 succ = go cur (n + 1); 70 in cur; 71 lapp = lnul cur; 72 cur = go lapp 0; 73 in cur; 74 75 # Take the list and disallow custom overrides in all but the final stage, 76 # and allow it in the final flag. Only defaults this boolean field if it 77 # isn't already set. 78 withAllowCustomOverrides = lib.lists.imap1 79 (index: stageFun: prevStage: 80 # So true by default for only the first element because one 81 # 1-indexing. Since we reverse the list, this means this is true 82 # for the final stage. 83 { allowCustomOverrides = index == 1; } 84 // (stageFun prevStage)) 85 (lib.lists.reverseList stageFuns); 86 87 # Adds the stdenv to the arguments, and sticks in it the previous stage for 88 # debugging purposes. 89 folder = nextStage: stageFun: prevStage: let 90 args = stageFun prevStage; 91 args' = args // { 92 stdenv = args.stdenv // { 93 # For debugging 94 __bootPackages = prevStage; 95 __hatPackages = nextStage; 96 }; 97 }; 98 in 99 if args.__raw or false 100 then args' 101 else allPackages ((builtins.removeAttrs args' ["selfBuild"]) // { 102 buildPackages = if args.selfBuild or true then null else prevStage; 103 targetPackages = if args.selfBuild or true then null else nextStage; 104 }); 105 106 # This is a hack for resolving cross-compiled compilers' run-time 107 # deps. (That is, compilers that are themselves cross-compiled, as 108 # opposed to used to cross-compile packages.) 109 postStage = buildPackages: { 110 __raw = true; 111 stdenv.cc = 112 if buildPackages.stdenv.cc.isClang or false 113 then buildPackages.clang 114 else buildPackages.gcc; 115 }; 116 117in dfold folder postStage (_: {}) withAllowCustomOverrides