178 lines
4.9 KiB
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
|
|
'';
|
|
})
|