about summary refs log tree commit diff
path: root/pkgs/os-specific/bsd/freebsd/lib/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/os-specific/bsd/freebsd/lib/default.nix')
-rw-r--r--pkgs/os-specific/bsd/freebsd/lib/default.nix107
1 files changed, 106 insertions, 1 deletions
diff --git a/pkgs/os-specific/bsd/freebsd/lib/default.nix b/pkgs/os-specific/bsd/freebsd/lib/default.nix
index d022f7cfa14c6..d8d975ef71ad7 100644
--- a/pkgs/os-specific/bsd/freebsd/lib/default.nix
+++ b/pkgs/os-specific/bsd/freebsd/lib/default.nix
@@ -1,4 +1,8 @@
-{ version }:
+{
+  version,
+  lib,
+  writeText,
+}:
 
 {
   inherit version;
@@ -7,12 +11,113 @@
     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;
 }