Implement generic kernel build via manual-config
This has three major benefits: 1. We no longer have two kernel build processes to maintain 2. The build process is (IMO) cleaner and cleaves more closely to upstream. In partuclar, we use make install to install the kernel and development source/build trees, eliminating the guesswork about which files to copy. 3. The derivation has multiple outputs: the kernel and modules are in the default `out' output, while the build and source trees are in a `dev' output. This makes it possible for the full source and build tree to be kept (which is expected by out-of-tree modules) without bloating the closure of the system derivation. In addition, if a solution for how to handle queries in the presence of imports from derivations ever makes it into nix, a framework for querying the full configuration of the kernel in nix expressions is already in place. Signed-off-by: Shea Levy <shea@shealevy.com>
This commit is contained in:
parent
a87b1f36e0
commit
f95d214cfd
@ -1,149 +0,0 @@
|
||||
source $stdenv/setup
|
||||
|
||||
|
||||
makeFlags="ARCH=$arch SHELL=/bin/sh KBUILD_BUILD_VERSION=1-NixOS $makeFlags"
|
||||
if [ -n "$crossConfig" ]; then
|
||||
makeFlags="$makeFlags CROSS_COMPILE=$crossConfig-"
|
||||
fi
|
||||
|
||||
postPatch() {
|
||||
# Makefiles are full of /bin/pwd, /bin/false, /bin/bash, etc.
|
||||
# Patch these away, assuming the tools are in $PATH.
|
||||
for mf in $(find -name Makefile); do
|
||||
echo "stripping FHS paths in \`$mf'..."
|
||||
sed -i "$mf" -e 's|/usr/bin/||g ; s|/bin/||g'
|
||||
done
|
||||
}
|
||||
|
||||
configurePhase() {
|
||||
if test -n "$preConfigure"; then
|
||||
eval "$preConfigure"
|
||||
fi
|
||||
|
||||
export INSTALL_PATH=$out
|
||||
export INSTALL_MOD_PATH=$out
|
||||
|
||||
# Set our own localversion, if specified.
|
||||
rm -f localversion*
|
||||
if test -n "$localVersion"; then
|
||||
echo "$localVersion" > localversion-nix
|
||||
fi
|
||||
|
||||
# Patch kconfig to print "###" after every question so that
|
||||
# generate-config.pl can answer them.
|
||||
sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
|
||||
|
||||
# Get a basic config file for later refinement with $generateConfig.
|
||||
make $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 \
|
||||
perl -w $generateConfig
|
||||
}
|
||||
|
||||
|
||||
installPhase() {
|
||||
|
||||
mkdir -p $out
|
||||
|
||||
# New kernel versions have a combined tree for i386 and x86_64.
|
||||
archDir=$arch
|
||||
if test -e arch/x86 -a \( "$arch" = i386 -o "$arch" = x86_64 \); then
|
||||
archDir=x86
|
||||
fi
|
||||
|
||||
|
||||
# Copy the bzImage and System.map.
|
||||
cp System.map $out
|
||||
if test "$arch" = um; then
|
||||
mkdir -p $out/bin
|
||||
cp linux $out/bin
|
||||
elif test "$kernelTarget" != "vmlinux"; then
|
||||
# In any case we copy the 'vmlinux' ELF in the next lines
|
||||
cp arch/$archDir/boot/$kernelTarget $out
|
||||
fi
|
||||
|
||||
cp vmlinux $out
|
||||
|
||||
if grep -q "CONFIG_MODULES=y" .config; then
|
||||
# Install the modules in $out/lib/modules.
|
||||
make modules_install \
|
||||
DEPMOD=$kmod/sbin/depmod \
|
||||
$makeFlags "${makeFlagsArray[@]}" \
|
||||
$installFlags "${installFlagsArray[@]}"
|
||||
|
||||
if test -z "$dontStrip"; then
|
||||
# Strip the kernel modules.
|
||||
echo "Stripping kernel modules..."
|
||||
if [ -z "$crossConfig" ]; then
|
||||
find $out -name "*.ko" -print0 | xargs -0 strip -S
|
||||
else
|
||||
find $out -name "*.ko" -print0 | xargs -0 $crossConfig-strip -S
|
||||
fi
|
||||
fi
|
||||
|
||||
# move this to install later on
|
||||
# largely copied from early FC3 kernel spec files
|
||||
version=$(cd $out/lib/modules && ls -d *)
|
||||
|
||||
# remove symlinks and create directories
|
||||
rm -f $out/lib/modules/$version/build
|
||||
rm -f $out/lib/modules/$version/source
|
||||
mkdir $out/lib/modules/$version/build
|
||||
|
||||
# copy config
|
||||
cp .config $out/lib/modules/$version/build/.config
|
||||
ln -s $out/lib/modules/$version/build/.config $out/config
|
||||
|
||||
if test "$arch" != um; then
|
||||
# copy all Makefiles and Kconfig files
|
||||
ln -s $out/lib/modules/$version/build $out/lib/modules/$version/source
|
||||
cp --parents `find -type f -name Makefile -o -name "Kconfig*"` $out/lib/modules/$version/build
|
||||
cp Module.symvers $out/lib/modules/$version/build
|
||||
|
||||
if test "$dontStrip" = "1"; then
|
||||
# copy any debugging info that can be found
|
||||
cp --parents -rv `find -name \*.debug -o -name debug.a` \
|
||||
"$out/lib/modules/$version/build"
|
||||
fi
|
||||
|
||||
# weed out unneeded stuff
|
||||
rm -rf $out/lib/modules/$version/build/Documentation
|
||||
rm -rf $out/lib/modules/$version/build/scripts
|
||||
rm -rf $out/lib/modules/$version/build/include
|
||||
|
||||
# copy architecture dependent files
|
||||
cp -a arch/$archDir/scripts $out/lib/modules/$version/build/ || true
|
||||
cp -a arch/$archDir/*lds $out/lib/modules/$version/build/ || true
|
||||
cp -a arch/$archDir/Makefile*.cpu $out/lib/modules/$version/build/arch/$archDir/ || true
|
||||
cp -a --parents arch/$archDir/kernel/asm-offsets.s $out/lib/modules/$version/build/arch/$archDir/kernel/ || true
|
||||
|
||||
# copy scripts
|
||||
rm -f scripts/*.o
|
||||
rm -f scripts/*/*.o
|
||||
cp -a scripts $out/lib/modules/$version/build
|
||||
|
||||
# copy include files
|
||||
includeDir=$out/lib/modules/$version/build/include
|
||||
mkdir -p $includeDir
|
||||
(cd include && cp -a * $includeDir)
|
||||
(cd arch/$archDir/include && cp -a * $includeDir || true)
|
||||
(cd arch/$archDir/include && cp -a asm/* $includeDir/asm/ || true)
|
||||
(cd arch/$archDir/include && cp -a generated/asm/* $includeDir/asm/ || true)
|
||||
(cd arch/$archDir/include/asm/mach-generic && cp -a * $includeDir/ || true)
|
||||
# include files for special arm architectures
|
||||
if [ "$archDir" == "arm" ]; then
|
||||
cp -a --parents arch/arm/mach-*/include $out/lib/modules/$version/build
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$postInstall"; then
|
||||
eval "$postInstall";
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
genericBuild
|
@ -11,6 +11,9 @@
|
||||
|
||||
use strict;
|
||||
use IPC::Open2;
|
||||
use Cwd;
|
||||
|
||||
my $wd = getcwd;
|
||||
|
||||
my $debug = $ENV{'DEBUG'};
|
||||
my $autoModules = $ENV{'AUTO_MODULES'};
|
||||
@ -36,7 +39,7 @@ close ANSWERS;
|
||||
sub runConfig {
|
||||
|
||||
# Run `make config'.
|
||||
my $pid = open2(\*IN, \*OUT, "make config SHELL=bash ARCH=$ENV{ARCH}");
|
||||
my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$wd config SHELL=bash ARCH=$ENV{ARCH}");
|
||||
|
||||
# Parse the output, look for questions and then send an
|
||||
# appropriate answer.
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ stdenv, fetchurl, perl, mktemp, kmod, bc
|
||||
{ stdenv, perl, linuxManualConfig
|
||||
|
||||
, # The kernel source tarball.
|
||||
src
|
||||
@ -23,20 +23,7 @@
|
||||
# symbolic name and `patch' is the actual patch. The patch may
|
||||
# optionally be compressed with gzip or bzip2.
|
||||
kernelPatches ? []
|
||||
|
||||
, # Allows you to set your own kernel version suffix (e.g.,
|
||||
# "-my-kernel").
|
||||
localVersion ? ""
|
||||
|
||||
, preConfigure ? ""
|
||||
, extraMeta ? {}
|
||||
, ubootChooser ? null
|
||||
, postInstall ? ""
|
||||
|
||||
, # After the builder did a 'make all' (kernel + modules)
|
||||
# we force building the target asked: bzImage/zImage/uImage/...
|
||||
postBuild ? "make $makeFlags $kernelTarget; make $makeFlags -C scripts unifdef"
|
||||
|
||||
, ...
|
||||
}:
|
||||
|
||||
@ -52,93 +39,76 @@ let
|
||||
map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
|
||||
in lib.concatStringsSep "\n" ([baseConfig] ++ configFromPatches);
|
||||
|
||||
configfile = stdenv.mkDerivation {
|
||||
name = "linux-config-${version}";
|
||||
|
||||
generateConfig = ./generate-config.pl;
|
||||
|
||||
kernelConfig = kernelConfigFun config;
|
||||
|
||||
ignoreConfigErrors = stdenv.platform.name != "pc";
|
||||
|
||||
nativeBuildInputs = [ perl ];
|
||||
|
||||
platformName = stdenv.platform.name;
|
||||
kernelBaseConfig = stdenv.platform.kernelBaseConfig;
|
||||
kernelTarget = stdenv.platform.kernelTarget;
|
||||
autoModules = stdenv.platform.kernelAutoModules;
|
||||
arch = stdenv.platform.kernelArch;
|
||||
|
||||
crossAttrs = let
|
||||
cp = stdenv.cross.platform;
|
||||
in {
|
||||
arch = cp.kernelArch;
|
||||
platformName = cp.name;
|
||||
kernelBaseConfig = cp.kernelBaseConfig;
|
||||
kernelTarget = cp.kernelTarget;
|
||||
autoModules = cp.kernelAutoModules;
|
||||
|
||||
# Just ignore all options that don't apply (We are lazy).
|
||||
ignoreConfigErrors = true;
|
||||
|
||||
kernelConfig = kernelConfigFun configCross;
|
||||
};
|
||||
buildCommand = ''
|
||||
# Get a basic config file for later refinement with $generateConfig.
|
||||
make -C ${kernel.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
|
||||
'';
|
||||
};
|
||||
|
||||
kernel = linuxManualConfig {
|
||||
inherit version modDirVersion src kernelPatches;
|
||||
|
||||
configfile = configfile.nativeDrv or configfile;
|
||||
|
||||
crossConfigfile = configfile.crossDrv or configfile;
|
||||
|
||||
config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
|
||||
|
||||
crossConfig = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
|
||||
};
|
||||
|
||||
configWithPlatform = kernelPlatform:
|
||||
import ./common-config.nix { inherit stdenv version kernelPlatform extraConfig; };
|
||||
|
||||
config = configWithPlatform stdenv.platform;
|
||||
configCross = configWithPlatform stdenv.cross.platform;
|
||||
|
||||
in
|
||||
|
||||
stdenv.mkDerivation {
|
||||
name = "linux-${version}";
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
passthru = {
|
||||
inherit version modDirVersion kernelPatches;
|
||||
# Combine the `features' attribute sets of all the kernel patches.
|
||||
features = lib.fold (x: y: (x.features or {}) // y) features kernelPatches;
|
||||
|
||||
meta = kernel.meta // extraMeta;
|
||||
};
|
||||
|
||||
builder = ./builder.sh;
|
||||
|
||||
generateConfig = ./generate-config.pl;
|
||||
|
||||
inherit preConfigure src kmod localVersion postInstall postBuild;
|
||||
|
||||
patches = map (p: p.patch) kernelPatches;
|
||||
|
||||
kernelConfig = kernelConfigFun config;
|
||||
|
||||
# For UML and non-PC, just ignore all options that don't apply (We are lazy).
|
||||
ignoreConfigErrors = stdenv.platform.name != "pc";
|
||||
|
||||
nativeBuildInputs = [ perl mktemp bc ];
|
||||
|
||||
buildInputs = lib.optional (stdenv.platform.uboot != null)
|
||||
(ubootChooser stdenv.platform.uboot);
|
||||
|
||||
platformName = stdenv.platform.name;
|
||||
kernelBaseConfig = stdenv.platform.kernelBaseConfig;
|
||||
kernelTarget = stdenv.platform.kernelTarget;
|
||||
autoModules = stdenv.platform.kernelAutoModules;
|
||||
|
||||
# Should we trust platform.kernelArch? We can only do
|
||||
# that once we differentiate i686/x86_64 in platforms.
|
||||
arch =
|
||||
if stdenv.system == "i686-linux" then "i386" else
|
||||
if stdenv.system == "x86_64-linux" then "x86_64" else
|
||||
if stdenv.isArm then "arm" else
|
||||
if stdenv.system == "mips64el-linux" then "mips" else
|
||||
abort "Platform ${stdenv.system} is not supported.";
|
||||
|
||||
crossAttrs = let
|
||||
cp = stdenv.cross.platform;
|
||||
in
|
||||
assert cp.name == "sheevaplug" -> cp.uboot != null;
|
||||
{
|
||||
arch = cp.kernelArch;
|
||||
platformName = cp.name;
|
||||
kernelBaseConfig = cp.kernelBaseConfig;
|
||||
kernelTarget = cp.kernelTarget;
|
||||
autoModules = cp.kernelAutoModules;
|
||||
|
||||
# Just ignore all options that don't apply (We are lazy).
|
||||
ignoreConfigErrors = true;
|
||||
|
||||
kernelConfig = kernelConfigFun configCross;
|
||||
|
||||
# The substitution of crossAttrs happens *after* the stdenv cross adapter sets
|
||||
# the parameters for the usual stdenv. Thus, we need to specify
|
||||
# the ".crossDrv" in the buildInputs here.
|
||||
buildInputs = lib.optional (cp.uboot != null) (ubootChooser cp.uboot).crossDrv;
|
||||
};
|
||||
|
||||
meta = {
|
||||
description =
|
||||
"The Linux kernel" +
|
||||
(if kernelPatches == [] then "" else
|
||||
" (with patches: "
|
||||
+ lib.concatStrings (lib.intersperse ", " (map (x: x.name) kernelPatches))
|
||||
+ ")");
|
||||
license = "GPLv2";
|
||||
homepage = http://www.kernel.org/;
|
||||
maintainers = [
|
||||
lib.maintainers.eelco
|
||||
lib.maintainers.chaoflow
|
||||
];
|
||||
platforms = lib.platforms.linux;
|
||||
} // extraMeta;
|
||||
}
|
||||
nativeDrv = lib.addPassthru kernel.nativeDrv passthru;
|
||||
|
||||
crossDrv = lib.addPassthru kernel.crossDrv passthru;
|
||||
in if kernel ? crossDrv then nativeDrv // { inherit nativeDrv crossDrv; } else lib.addPassthru kernel passthru
|
||||
|
@ -48,7 +48,7 @@ let
|
||||
''; };
|
||||
|
||||
commonMakeFlags = [
|
||||
"O=$(buildRoot)"
|
||||
"O=$(buildRoot)" "KBUILD_BUILD_VERSION=1-NixOS"
|
||||
];
|
||||
|
||||
drvAttrs = config_: platform: kernelPatches: configfile:
|
||||
@ -124,7 +124,7 @@ let
|
||||
runHook postConfigure
|
||||
'';
|
||||
|
||||
buildFlags = [ stdenv.platform.kernelTarget ] ++ optional isModular "modules";
|
||||
buildFlags = [ platform.kernelTarget ] ++ optional isModular "modules";
|
||||
|
||||
installFlags = [
|
||||
"INSTALLKERNEL=${installkernel}"
|
||||
@ -158,6 +158,21 @@ let
|
||||
"s|${sourceRoot}|$NIX_STORE/eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-${sourceRoot.name}|g"
|
||||
fi
|
||||
'' else null;
|
||||
|
||||
meta = {
|
||||
description =
|
||||
"The Linux kernel" +
|
||||
(if kernelPatches == [] then "" else
|
||||
" (with patches: "
|
||||
+ stdenv.lib.concatStrings (stdenv.lib.intersperse ", " (map (x: x.name) kernelPatches))
|
||||
+ ")");
|
||||
license = "GPLv2";
|
||||
homepage = http://www.kernel.org/;
|
||||
maintainers = [
|
||||
maintainers.shlevy
|
||||
];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
@ -173,7 +188,7 @@ stdenv.mkDerivation ((drvAttrs config stdenv.platform (kernelPatches ++ nativeKe
|
||||
"ARCH=${stdenv.platform.kernelArch}"
|
||||
];
|
||||
|
||||
crossAttrs = let cp = stdenv.cross.platform; in {
|
||||
crossAttrs = let cp = stdenv.cross.platform; in
|
||||
(drvAttrs crossConfig cp (kernelPatches ++ crossKernelPatches) crossConfigfile) // {
|
||||
makeFlags = commonMakeFlags ++ [
|
||||
"ARCH=${cp.kernelArch}"
|
||||
@ -186,14 +201,4 @@ stdenv.mkDerivation ((drvAttrs config stdenv.platform (kernelPatches ++ nativeKe
|
||||
# may be different from stdenv.platform.uboot)
|
||||
buildInputs = optional (cp.uboot != null) (ubootChooser cp.uboot).crossDrv;
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "The Linux kernel";
|
||||
license = "GPLv2";
|
||||
homepage = http://www.kernel.org/;
|
||||
maintainers = [
|
||||
maintainers.shlevy
|
||||
];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
})
|
||||
|
@ -6704,7 +6704,7 @@ let
|
||||
kernelPatches = callPackage ../os-specific/linux/kernel/patches.nix { };
|
||||
|
||||
linux_3_2 = makeOverridable (import ../os-specific/linux/kernel/linux-3.2.nix) {
|
||||
inherit fetchurl stdenv perl mktemp bc kmod ubootChooser;
|
||||
inherit fetchurl stdenv perl linuxManualConfig;
|
||||
kernelPatches =
|
||||
[ kernelPatches.sec_perm_2_6_24
|
||||
# kernelPatches.aufs3_2
|
||||
@ -6754,7 +6754,7 @@ let
|
||||
});
|
||||
|
||||
linux_3_4 = makeOverridable (import ../os-specific/linux/kernel/linux-3.4.nix) {
|
||||
inherit fetchurl stdenv perl mktemp bc kmod ubootChooser;
|
||||
inherit fetchurl stdenv perl linuxManualConfig;
|
||||
kernelPatches =
|
||||
[ kernelPatches.sec_perm_2_6_24
|
||||
# kernelPatches.aufs3_4
|
||||
@ -6773,11 +6773,11 @@ let
|
||||
});
|
||||
|
||||
linux_3_6_rpi = makeOverridable (import ../os-specific/linux/kernel/linux-rpi-3.6.nix) {
|
||||
inherit fetchurl stdenv perl mktemp bc kmod ubootChooser;
|
||||
inherit fetchurl stdenv perl linuxManualConfig;
|
||||
};
|
||||
|
||||
linux_3_10 = makeOverridable (import ../os-specific/linux/kernel/linux-3.10.nix) {
|
||||
inherit fetchurl stdenv perl mktemp bc kmod ubootChooser;
|
||||
inherit fetchurl stdenv perl linuxManualConfig;
|
||||
kernelPatches =
|
||||
[
|
||||
kernelPatches.sec_perm_2_6_24
|
||||
@ -6798,7 +6798,7 @@ let
|
||||
});
|
||||
|
||||
linux_3_11 = makeOverridable (import ../os-specific/linux/kernel/linux-3.11.nix) {
|
||||
inherit fetchurl stdenv perl mktemp bc kmod ubootChooser;
|
||||
inherit fetchurl stdenv perl linuxManualConfig;
|
||||
kernelPatches =
|
||||
[
|
||||
kernelPatches.sec_perm_2_6_24
|
||||
@ -6810,7 +6810,7 @@ let
|
||||
};
|
||||
|
||||
linux_3_12 = makeOverridable (import ../os-specific/linux/kernel/linux-3.12.nix) {
|
||||
inherit fetchurl stdenv perl mktemp bc kmod ubootChooser;
|
||||
inherit fetchurl stdenv perl linuxManualConfig;
|
||||
kernelPatches =
|
||||
[
|
||||
kernelPatches.sec_perm_2_6_24
|
||||
|
Loading…
Reference in New Issue
Block a user