From ac2035287fbec30d92165fd3839d1bf71b8edd47 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sun, 5 Jan 2014 06:55:47 -0500 Subject: 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 --- pkgs/os-specific/linux/kernel/generic.nix | 10 ++++-- pkgs/os-specific/linux/kernel/manual-config.nix | 43 +++++++++++++++++++------ 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 -- cgit 1.4.1