nixpkgs/pkgs/os-specific/linux/kernel/manual-config.nix

178 lines
4.9 KiB
Nix

{ stdenv, runCommand, nettools, perl, kmod, writeTextFile, coffeescript }:
with stdenv.lib;
let
# Function to parse the config file to get the features supported
readFeatures = config:
let
configParser = writeTextFile { name = "config-parser"; executable=true; text = ''
#!${coffeescript}/bin/coffee
fs = require "fs"
events = require "events"
lineEmitter = new events.EventEmitter()
buffer = new Buffer 0
input = fs.createReadStream process.argv[2]
input.on 'data', (data) ->
nextBuffer = new Buffer buffer.length + data.length
buffer.copy(nextBuffer)
data.copy(nextBuffer, buffer.length)
start = 0
offset = buffer.length
buffer = nextBuffer
for i in [1..data.length]
if data[i] == '\n'.charCodeAt 0
end = i+offset+1
line = buffer.slice start, end - 1
start = end
lineEmitter.emit "line", line.toString()
buffer = buffer.slice start
input.once 'end', ->
input.destroy()
if safeToWrite
output.end "}"
output.destroySoon()
else
output.once 'drain', ->
output.end "}"
output.destroySoon()
output = fs.createWriteStream process.env["out"]
output.setMaxListeners 0
safeToWrite = output.write "{\n"
unless safeToWrite
output.once 'drain', ->
safeToWrite = true
escapeNixString = (str) ->
str.replace("'''", "''''").replace("''${", "'''''${")
lineEmitter.on 'line', (line) ->
unless line.length is 0 or line.charAt(0) is '#'
split = line.split '='
name = split[0].substring "CONFIG_".length
value = escapeNixString split.slice(1).join ""
lineToWrite = "\"#{name}\" = '''#{value}''';\n"
if safeToWrite
safeToWrite = output.write lineToWrite
else
input.pause()
output.once 'drain', ->
safeToWrite = output.write lineToWrite
input.resume()
'';};
configAttrs = import "${runCommand "attrList.nix" {} "${configParser} ${config}"}";
getValue = option:
if hasAttr option configAttrs then getAttr option configAttrs else null;
isYes = option: (getValue option) == "y";
in
{
modular = isYes "MODULES";
};
in
{
# The kernel version
version,
# The version of the kernel module directory
modDirVersion ? version,
# The kernel source (tarball, git checkout, etc.)
src,
# Any patches
patches ? [],
# The kernel .config file
config,
# Manually specified features the kernel supports
# If unspecified, this will be autodetected from the .config
features ? optionalAttrs allowImportFromDerivation (readFeatures config),
# Whether to utilize the controversial import-from-derivation feature to parse the config
allowImportFromDerivation ? false
}:
let
commonMakeFlags = [
"O=../build"
"INSTALL_PATH=$(out)"
"INSTALLKERNEL=${installkernel}"
];
installkernel = writeTextFile { name = "installkernel"; executable=true; text = ''
#!/bin/sh
mkdir $4
mv -v $2 $4
mv -v $3 $4
'';};
in
stdenv.mkDerivation ({
name = "linux-${version}";
enableParallelBuilding = true;
passthru = {
inherit version modDirVersion features;
};
inherit patches src;
prePatch = ''
for mf in $(find -name Makefile -o -name Makefile.include); do
echo "stripping FHS paths in \`$mf'..."
sed -i "$mf" -e 's|/usr/bin/||g ; s|/bin/||g ; s|/sbin/||g'
done
'';
configurePhase = ''
runHook preConfigure
mkdir ../build
make $makeFlags "''${makeFlagsArray[@]}" mrproper
ln -sv ${config} ../build/.config
make $makeFlags "''${makeFlagsArray[@]}" oldconfig
rm ../build/.config.old
runHook postConfigure
'';
buildNativeInputs = [ perl nettools kmod ];
makeFlags = commonMakeFlags;
meta = {
description = "The Linux kernel";
license = "GPLv2";
homepage = http://www.kernel.org/;
maintainers = [
maintainers.shlevy
];
platforms = lib.platforms.linux;
};
} // optionalAttrs (features ? modular && features.modular) {
makeFlags = commonMakeFlags ++ [
"MODLIB=\"$(out)/lib/modules/${modDirVersion}\""
];
postInstall = ''
make modules_install $makeFlags "''${makeFlagsArray[@]}" \
$installFlags "''${installFlagsArray[@]}"
rm -f $out/lib/modules/${modDirVersion}/{build,source}
cd ..
mv $sourceRoot $out/lib/modules/${modDirVersion}/source
mv build $out/lib/modules/${modDirVersion}/build
unlink $out/lib/modules/${modDirVersion}/build/source
ln -sv $out/lib/modules/${modDirVersion}/{,build/}source
'';
postFixup = ''
if [ -z "$dontStrip" ]; then
find $out -name "*.ko" -print0 | xargs -0 strip -S
fi
'';
})