about summary refs log tree commit diff
path: root/pkgs/os-specific
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2014-01-01 23:56:24 -0500
committerShea Levy <shea@shealevy.com>2014-01-01 23:56:24 -0500
commit2c38df1c5bd2f79b9c6f28118ae0520fdd95974b (patch)
tree1df800ef1dbbc0fd6581bead5a8158aef0102e25 /pkgs/os-specific
parentf95d214cfdf115b9444acc5ce8060a5b1b23ed77 (diff)
downloadnixlib-2c38df1c5bd2f79b9c6f28118ae0520fdd95974b.tar
nixlib-2c38df1c5bd2f79b9c6f28118ae0520fdd95974b.tar.gz
nixlib-2c38df1c5bd2f79b9c6f28118ae0520fdd95974b.tar.bz2
nixlib-2c38df1c5bd2f79b9c6f28118ae0520fdd95974b.tar.lz
nixlib-2c38df1c5bd2f79b9c6f28118ae0520fdd95974b.tar.xz
nixlib-2c38df1c5bd2f79b9c6f28118ae0520fdd95974b.tar.zst
nixlib-2c38df1c5bd2f79b9c6f28118ae0520fdd95974b.zip
kernel build: limit dev output footprint
This makes the disk usage footprint of building the kernel smaller in 3
ways:

1) There is no separate kernel source derivation
2) Rather than using the entire build tree, only the output of make
modules_prepare is kept in the $dev output (plus the module symbol
versioning file generated during the build)
3) Only the subset of the source tree known to be needed for external
builds is kept in $dev

Note that while 2) is supported by official kernel documentation, I
couldn't find any source describing what we need to keep for 3). I've
started with the bare minimum (the main Makefile is called by the
Makefile generated by make modules_prepare) and we can/should add more
as needed for kernelPackages.

Signed-off-by: Shea Levy <shea@shealevy.com>
Diffstat (limited to 'pkgs/os-specific')
-rw-r--r--pkgs/os-specific/linux/kernel/generic.nix16
-rw-r--r--pkgs/os-specific/linux/kernel/manual-config.nix83
2 files changed, 55 insertions, 44 deletions
diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix
index 888dcf1e9a51..5cb6745da122 100644
--- a/pkgs/os-specific/linux/kernel/generic.nix
+++ b/pkgs/os-specific/linux/kernel/generic.nix
@@ -69,18 +69,26 @@ let
         ignoreConfigErrors = true;
 
         kernelConfig = kernelConfigFun configCross;
+
+        inherit (kernel.crossDrv) src patches prePatch preUnpack;
       };
-    buildCommand = ''
+
+    inherit (kernel) src patches prePatch preUnpack;
+
+    buildPhase = ''
+      cd $buildRoot
+
       # Get a basic config file for later refinement with $generateConfig.
-      make -C ${kernel.sourceRoot} O=$PWD $kernelBaseConfig ARCH=$arch
+      make -C ../$sourceRoot O=$PWD $kernelBaseConfig ARCH=$arch
 
       # Create the config file.
       echo "generating kernel configuration..."
       echo "$kernelConfig" > kernel-config
       DEBUG=1 ARCH=$arch KERNEL_CONFIG=kernel-config AUTO_MODULES=$autoModules \
-           SRC=${kernel.sourceRoot} perl -w $generateConfig
-      mv .config $out
+           SRC=../$sourceRoot perl -w $generateConfig
     '';
+
+    installPhase = "mv .config $out";
   };
 
   kernel = linuxManualConfig {
diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix
index 408c79c781af..c8910f8ed06e 100644
--- a/pkgs/os-specific/linux/kernel/manual-config.nix
+++ b/pkgs/os-specific/linux/kernel/manual-config.nix
@@ -48,7 +48,7 @@ let
   ''; };
 
   commonMakeFlags = [
-    "O=$(buildRoot)" "KBUILD_BUILD_VERSION=1-NixOS"
+    "O=$(buildRoot)"
   ];
 
   drvAttrs = config_: platform: kernelPatches: configfile:
@@ -73,48 +73,34 @@ let
 
       installsFirmware = (config.isEnabled "FW_LOADER") &&
         (isModular || (config.isDisabled "FIRMWARE_IN_KERNEL"));
-
-      sourceRoot = stdenv.mkDerivation {
-        name = "linux-source-${version}";
-
-        inherit src;
-
-        patches = map (p: p.patch) kernelPatches;
-
-        phases = [ "unpackPhase" "patchPhase" "installPhase" ];
-
-        prePatch = ''
-          for mf in $(find -name Makefile -o -name Makefile.include -o -name install.sh); do
-              echo "stripping FHS paths in \`$mf'..."
-              sed -i "$mf" -e 's|/usr/bin/||g ; s|/bin/||g ; s|/sbin/||g'
-          done
-
-          sed -i Makefile -e 's|= depmod|= ${kmod}/sbin/depmod|'
-
-          # Patch kconfig to print "###" after every question so that
-          # generate-config.pl from the generic builder can answer them.
-          # This only affects oldaskconfig.
-          sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
-        '';
-
-        installPhase = ''
-          cd ..
-          mv $sourceRoot $out
-        '';
-      };
     in {
       outputs = if isModular then [ "out" "dev" ] else null;
 
       passthru = {
-        inherit version modDirVersion config kernelPatches src;
+        inherit version modDirVersion config kernelPatches;
       };
 
-      inherit sourceRoot;
+      inherit src;
 
-      unpackPhase = ''
+      preUnpack = ''
         mkdir build
         export buildRoot="$(pwd)/build"
-        cd ${sourceRoot}
+      '';
+
+      patches = map (p: p.patch) kernelPatches;
+
+      prePatch = ''
+        for mf in $(find -name Makefile -o -name Makefile.include -o -name install.sh); do
+            echo "stripping FHS paths in \`$mf'..."
+            sed -i "$mf" -e 's|/usr/bin/||g ; s|/bin/||g ; s|/sbin/||g'
+        done
+
+        sed -i Makefile -e 's|= depmod|= ${kmod}/sbin/depmod|'
+
+        # Patch kconfig to print "###" after every question so that
+        # generate-config.pl from the generic builder can answer them.
+        # This only affects oldaskconfig.
+        sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
       '';
 
       configurePhase = ''
@@ -124,7 +110,7 @@ let
         runHook postConfigure
       '';
 
-      buildFlags = [ platform.kernelTarget ] ++ optional isModular "modules";
+      buildFlags = [ "KBUILD_BUILD_VERSION=1-NixOS" platform.kernelTarget ] ++ optional isModular "modules";
 
       installFlags = [
         "INSTALLKERNEL=${installkernel}"
@@ -141,22 +127,39 @@ let
         make modules_install $makeFlags "''${makeFlagsArray[@]}" \
           $installFlags "''${installFlagsArray[@]}"
         unlink $out/lib/modules/${modDirVersion}/build
+        unlink $out/lib/modules/${modDirVersion}/source
+
         mkdir -p $dev/lib/modules/${modDirVersion}
-        mv $out/lib/modules/${modDirVersion}/source $dev/lib/modules/${modDirVersion}/source
+        cd ..
+        mv $sourceRoot $dev/lib/modules/${modDirVersion}/source
+        cd $dev/lib/modules/${modDirVersion}/source
+
+        mv $buildRoot/.config $buildRoot/Module.symvers $TMPDIR
+        rm -fR $buildRoot
+        mkdir $buildRoot
+        mv $TMPDIR/.config $TMPDIR/Module.symvers $buildRoot
+        make modules_prepare $makeFlags "''${makeFlagsArray[@]}"
         mv $buildRoot $dev/lib/modules/${modDirVersion}/build
+
+        # !!! No documentation on how much of the source tree must be kept
+        # If/when kernel builds fail due to missing files, you can undelete
+        # them here
+        ls -A | grep -v Makefile | xargs rm -fR
       '' else optionalString installsFirmware ''
         make firmware_install $makeFlags "''${makeFlagsArray[@]}" \
           $installFlags "''${installFlagsArray[@]}"
       '');
 
+      # !!! This leaves references to gcc and kmod in $dev
+      # that we might be able to avoid
       postFixup = if isModular then ''
         if [ -z "$dontStrip" ]; then
             find $out -name "*.ko" -print0 | xargs -0 -r ''${crossConfig+$crossConfig-}strip -S
-            # Remove all references to the source directory to avoid unneeded
-            # runtime dependencies
-            find $out -name "*.ko" -print0 | xargs -0 -r sed -i \
-              "s|${sourceRoot}|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${sourceRoot.name}|g"
         fi
+        # !!! Should this be part of stdenv? Also patchELF should take an argument...
+        prefix=$dev
+        patchELF
+        prefix=$out
       '' else null;
 
       meta = {