summary refs log tree commit diff
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2014-01-05 06:55:47 -0500
committerShea Levy <shea@shealevy.com>2014-01-05 06:55:47 -0500
commitac2035287fbec30d92165fd3839d1bf71b8edd47 (patch)
treef2f4adff7366a35686a61bf02cc438870fe146a8
parenta589bfae17b66af41794dc3eca1245aa514d6cac (diff)
downloadnixlib-ac2035287fbec30d92165fd3839d1bf71b8edd47.tar
nixlib-ac2035287fbec30d92165fd3839d1bf71b8edd47.tar.gz
nixlib-ac2035287fbec30d92165fd3839d1bf71b8edd47.tar.bz2
nixlib-ac2035287fbec30d92165fd3839d1bf71b8edd47.tar.lz
nixlib-ac2035287fbec30d92165fd3839d1bf71b8edd47.tar.xz
nixlib-ac2035287fbec30d92165fd3839d1bf71b8edd47.tar.zst
nixlib-ac2035287fbec30d92165fd3839d1bf71b8edd47.zip
Greatly reduce kernel closure size
Based on access analysis with strace, I determined an essentially
minimal required set of files from the kernel source that was needed to
build all current kernel packages on 3.10, which ultimately resulted in
keeping 30M of source. Generalizing from that minimal set, which
required ad-hoc specifications of which headers outside of include/ and
arch/*/include and which files in the scripts/ directory should be kept,
to a policy of keeping all non-arch-specific headers that aren't part of
the drivers/ directory and the entire scripts/ directory added an
additional 17M, but there was nothing in the analysis that indicated
that that ad-hoc specification was at all complete so I think the extra
hit is worth the likely greater compatibility.

For reference, we now keep:

* All headers that are NOT in arch/${notTargetArch}/include or drivers/
* The scripts/ directory
* Makefile
* arch/${targetArch}/Makefile

IMO the most likely cause of future problems are the headers in
drivers/, but hopefully they won't actually be needed as they add 50M
Ideally kernel packages would only use include and
arch/${targetArch}/include, but alas this is observably not the case.

master:
  * $out
    * size: 234M
    * references-closure: linux-headers, glibc, attr, acl, zlib, gcc,
      coreutils, perl, bash
merge-kernel-builds:
  * $out
    * size: 152M
    * references-closure: none
  * $dev
    * size: 57M
    * references-closure: linux-headers, glibc, zlib, gcc

So even with the non-minimal set we still beat out master. Keeping the
drivers headers would make us only slightly bigger.

Signed-off-by: Shea Levy <shea@shealevy.com>
-rw-r--r--pkgs/os-specific/linux/kernel/generic.nix10
-rw-r--r--pkgs/os-specific/linux/kernel/manual-config.nix43
2 files changed, 41 insertions, 12 deletions
diff --git a/pkgs/os-specific/linux/kernel/generic.nix b/pkgs/os-specific/linux/kernel/generic.nix
index 5cb6745da122..42ec3de93691 100644
--- a/pkgs/os-specific/linux/kernel/generic.nix
+++ b/pkgs/os-specific/linux/kernel/generic.nix
@@ -70,10 +70,16 @@ let
 
         kernelConfig = kernelConfigFun configCross;
 
-        inherit (kernel.crossDrv) src patches prePatch preUnpack;
+        inherit (kernel.crossDrv) src patches preUnpack;
       };
 
-    inherit (kernel) src patches prePatch preUnpack;
+    prePatch = kernel.prePatch + ''
+      # Patch kconfig to print "###" after every question so that
+      # generate-config.pl from the generic builder can answer them.
+      sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
+    '';
+
+    inherit (kernel) src patches preUnpack;
 
     buildPhase = ''
       cd $buildRoot
diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix
index 67e8f0655393..206f95661e8e 100644
--- a/pkgs/os-specific/linux/kernel/manual-config.nix
+++ b/pkgs/os-specific/linux/kernel/manual-config.nix
@@ -49,6 +49,7 @@ let
 
   commonMakeFlags = [
     "O=$(buildRoot)"
+    "DEPMOD=${kmod}/bin/depmod"
   ];
 
   drvAttrs = config_: platform: kernelPatches: configfile:
@@ -94,13 +95,6 @@ let
             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 = ''
@@ -142,15 +136,44 @@ let
         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
+        # If/when kernel builds fail due to missing files, you can add
+        # them here. Note that we may see packages requiring headers
+        # from drivers/ in the future; it adds 50M to keep all of its
+        # headers on 3.10 though.
+
+        chmod +w -R ../source
+        arch=`cd $dev/lib/modules/${modDirVersion}/build/arch; ls`
+
+        # Remove unusued arches
+        mv arch/$arch .
+        rm -fR arch
+        mkdir arch
+        mv $arch arch
+
+        # Remove all driver-specific code (50M of which is headers)
+        rm -fR drivers
+
+        # Keep all headers
+        find .  -type f -name '*.h' -print0 | xargs -0 chmod -w
+
+        # Keep root and arch-specific Makefiles
+        chmod -w Makefile
+        chmod -w arch/$arch/Makefile
+
+        # Keep whole scripts dir
+        chmod -w -R scripts
+
+        # Delete everything not kept
+        find . -type f -perm -u=w -print0 | xargs -0 rm
+
+        # Delete empty directories
         find -empty -type d -delete
       '' else optionalString installsFirmware ''
         make firmware_install $makeFlags "''${makeFlagsArray[@]}" \
           $installFlags "''${installFlagsArray[@]}"
       '');
 
-      # !!! This leaves references to gcc and kmod in $dev
+      # !!! This leaves references to gcc in $dev
       # that we might be able to avoid
       postFixup = if isModular then ''
         if [ -z "$dontStrip" ]; then