From 2c38df1c5bd2f79b9c6f28118ae0520fdd95974b Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Wed, 1 Jan 2014 23:56:24 -0500 Subject: 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 --- pkgs/os-specific/linux/kernel/generic.nix | 16 +++-- pkgs/os-specific/linux/kernel/manual-config.nix | 83 +++++++++++++------------ 2 files changed, 55 insertions(+), 44 deletions(-) (limited to 'pkgs/os-specific') 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 = { -- cgit 1.4.1