{ version, lib, writeText, }: { inherit version; mkBsdArch = stdenv': { x86_64 = "amd64"; aarch64 = "aarch64"; i486 = "i386"; i586 = "i386"; i686 = "i386"; armv6l = "armv6"; armv7l = "armv7"; powerpc = "powerpc"; powerpc64 = "powerpc64"; powerpc64le = "powerpc64le"; riscv64 = "riscv64"; } .${stdenv'.hostPlatform.parsed.cpu.name} or stdenv'.hostPlatform.parsed.cpu.name; mkBsdCpuArch = stdenv': { x86_64 = "amd64"; aarch64 = "aarch64"; i486 = "i386"; i586 = "i386"; i686 = "i386"; armv6l = "arm"; armv7l = "arm"; powerpc = "powerpc"; powerpc64 = "powerpc"; powerpc64le = "powerpc"; riscv64 = "riscv"; } .${stdenv'.hostPlatform.parsed.cpu.name} or stdenv'.hostPlatform.parsed.cpu.name; mkBsdMachine = stdenv': { x86_64 = "amd64"; aarch64 = "arm64"; i486 = "i386"; i586 = "i386"; i686 = "i386"; armv6l = "arm"; armv7l = "arm"; powerpc = "powerpc"; powerpc64 = "powerpc"; powerpc64le = "powerpc"; riscv64 = "riscv"; } .${stdenv'.hostPlatform.parsed.cpu.name} or stdenv'.hostPlatform.parsed.cpu.name; install-wrapper = builtins.readFile ../../lib/install-wrapper.sh; # this function takes a list of patches and a list of paths and returns a list of derivations, # one per file that is patched, containing the actual patch contents. This allows us to have # extract only the patches that are relevant for a given subset of the source tree. # note: the "list of patches" input can be a directory containing patch files, a path or a list of valid inputs to this argument, recursively. filterPatches = patches: paths: let isDir = file: let base = baseNameOf file; type = (builtins.readDir (dirOf file)).${base} or null; in file == /. || type == "directory"; consolidatePatches = patches: if (lib.isDerivation patches) then [ patches ] else if (builtins.isPath patches) then (if (isDir patches) then (lib.filesystem.listFilesRecursive patches) else [ patches ]) else if (builtins.isList patches) then (lib.flatten (builtins.map consolidatePatches patches)) else throw "Bad patches - must be path or derivation or list thereof"; consolidated = consolidatePatches patches; splitPatch = patchFile: let allLines' = lib.strings.splitString "\n" (builtins.readFile patchFile); allLines = builtins.filter ( line: !((lib.strings.hasPrefix "diff --git" line) || (lib.strings.hasPrefix "index " line)) ) allLines'; foldFunc = a: b: if ((lib.strings.hasPrefix "--- " b) || (lib.strings.hasPrefix "diff --git " b)) then (a ++ [ [ b ] ]) else ((lib.lists.init a) ++ (lib.lists.singleton ((lib.lists.last a) ++ [ b ]))); partitionedPatches' = lib.lists.foldl foldFunc [ [ ] ] allLines; partitionedPatches = if (builtins.length partitionedPatches' > 1) then (lib.lists.drop 1 partitionedPatches') else (throw "${patchFile} does not seem to be a unified patch (diff -u). this is required for FreeBSD."); filterFunc = patchLines: let prefixedPath = builtins.elemAt (builtins.split " |\t" (builtins.elemAt patchLines 1)) 2; unfixedPath = lib.path.subpath.join (lib.lists.drop 1 (lib.path.subpath.components prefixedPath)); in lib.lists.any (included: lib.path.hasPrefix (/. + ("/" + included)) (/. + ("/" + unfixedPath))) ( paths ); filteredLines = builtins.filter filterFunc partitionedPatches; derive = patchLines: writeText "freebsd-patch" (lib.concatLines patchLines); derivedPatches = builtins.map derive filteredLines; in derivedPatches; in lib.lists.concatMap splitPatch consolidated; }