Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] kernel: attempt to rerun unpackPhase if sthg fishy (e.g. buildRoot unset) #31463

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pkgs/os-specific/linux/kernel/builder.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# TODO testing if that's better
source $stdenv/setup

# that s how cmake replaces
# if [ -z "$dontUseCmakeConfigure" -a -z "$configurePhase" ]; then
# setOutputFlags=
# configurePhase=cmakeConfigurePhase
# fi
155 changes: 155 additions & 0 deletions pkgs/os-specific/linux/kernel/config.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
stdenv
, lib
# , config
# , buildRoot
# , srcRoot
, ignoreConfigErrors, version
# , kernelConfig
, config, configCross ?null
, kernelPatches
, runCommand
, kernel
, perl, hostPlatform
, ...
}:

# with import lib.nix;
/*

# TODO we should be able to generate standalone config and config on the go
# => we need functions with module etc
# espcially we need a bash builder
# TODO have a standalone
# etait defini dans generic.nix

There variables are exported to be used by the generate-config.pl script, see the buildPhase
debug
autoModules
preferBuiltin
ignoreConfigErrors
kernel_config

kernel-config is a file

TODO doesn t need to be a derviation ?
can 't we justr override the source or split into two derivations:
- standalone
- embedded
*/
let

readConfig = configfile: import (runCommand "config.nix" {} ''
echo "{" > "$out"
while IFS='=' read key val; do
[ "x''${key#CONFIG_}" != "x$key" ] || continue
no_firstquote="''${val#\"}";
echo ' "'"$key"'" = "'"''${no_firstquote%\"}"'";' >> "$out"
done < "${configfile}"
echo "}" >> $out
'').outPath;

# RENAME to 'load'
convertKernelConfigToJson = readConfig;

patchKconfig = ''
# 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
'';

# generates functor
#
kernelConfigFun = baseConfig: kernelPatches:
let
configFromPatches =
map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
in lib.concatStringsSep "\n" ([baseConfig] ++ configFromPatches);
in
stdenv.mkDerivation rec {
inherit ignoreConfigErrors;
name = "linux-config-${version}";


# Runs generate-config
# my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$wd config SHELL=bash ARCH=$ENV{ARCH}");
generateConfig = ./generate-config.pl;

# string that will be echoed to kernel-config file
# writeFile
# echo "$kernelConfig" > kernel-config
kernelConfig = kernelConfigFun config kernelPatches;

nativeBuildInputs = [ perl ];

platformName = stdenv.platform.name;

# sthg like "defconfig"
kernelBaseConfig = stdenv.platform.kernelBaseConfig;

# e.g. "bzImage"
kernelTarget = stdenv.platform.kernelTarget;
# HHHAAAACCKKK
autoModules = false; # stdenv.platform.kernelAutoModules;
preferBuiltin = stdenv.platform.kernelPreferBuiltin or false;
# kernel ARCH
arch = stdenv.platform.kernelArch;

crossAttrs = let
cp = hostPlatform.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;

inherit (kernel.crossDrv) src patches preUnpack;
};

patchKconfig = ''
# Patch kconfig to print "###" after every question so that
# generate-config.pl from the generic builder can answer them.
echo "Patching Kconfig"
sed -e '/fflush(stdout);/i\printf("###");' -i scripts/kconfig/conf.c
'';

prePatch = kernel.prePatch + patchKconfig;
# inherit (kernel) src patches preUnpack;
inherit (kernel) src patches preUnpack;

# TODO replace with config.nix buildPhase
# add a cd ?
buildPhase = buildConfigCommands;

# need to be in srcRoot before launching this !
buildConfigCommands = ''
set -x
echo $PWD
cd $buildRoot

# Get a basic config file for later refinement with $ generateConfig.
# make O=$buildRoot $kernelBaseConfig ARCH=$arch
# /$sourceRoot
make -C .. O=$buildRoot $kernelBaseConfig ARCH=$arch

# Create the config file.
echo "generating kernel configuration..."
echo "${kernelConfig}" > $buildRoot/kernel-config
echo "Printing kernel config"
# TODO SRC ?
DEBUG=1 ARCH=$arch KERNEL_CONFIG=$buildRoot/kernel-config \
AUTO_MODULES=${builtins.toString autoModules} \
ignoreConfigErrors=${builtins.toString ignoreConfigErrors} \
PREFER_BUILTIN=$preferBuiltin SRC=. BUILD_FOLDER=$buildRoot perl -w ${generateConfig}
'';

installPhase = "mv $buildRoot/.config $out";

enableParallelBuilding = true;
}
16 changes: 10 additions & 6 deletions pkgs/os-specific/linux/kernel/generate-config.pl
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@
use IPC::Open2;
use Cwd;

my $wd = getcwd;
# my $wd = getcwd;

# exported via nix
my $debug = $ENV{'DEBUG'};
my $autoModules = $ENV{'AUTO_MODULES'};
my $preferBuiltin = $ENV{'PREFER_BUILTIN'};

my $ignoreConfigErrors = $ENV{'ignoreConfigErrors'};
my $buildFolder=$ENV{'BUILD_FOLDER'};
my $finalConfig="$buildFolder/.config";

$SIG{PIPE} = 'IGNORE';

# Read the answers.
my %answers;
my %requiredAnswers;
open ANSWERS, "<$ENV{KERNEL_CONFIG}" or die;
open ANSWERS, "<$ENV{KERNEL_CONFIG}" or die "Could not open answer file";
while (<ANSWERS>) {
chomp;
s/#.*//;
Expand All @@ -40,7 +44,7 @@
sub runConfig {

# Run `make config'.
my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$wd config SHELL=bash ARCH=$ENV{ARCH}");
my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$buildFolder config SHELL=bash ARCH=$ENV{ARCH}");

# Parse the output, look for questions and then send an
# appropriate answer.
Expand Down Expand Up @@ -122,7 +126,7 @@ sub runConfig {
# there. `make config' often overrides answers if later questions
# cause options to be selected.
my %config;
open CONFIG, "<.config" or die;
open CONFIG, "<$finalConfig" or die "Could not read .config";
while (<CONFIG>) {
chomp;
if (/^CONFIG_([A-Za-z0-9_]+)="(.*)"$/) {
Expand All @@ -137,7 +141,7 @@ sub runConfig {
close CONFIG;

foreach my $name (sort (keys %answers)) {
my $f = $requiredAnswers{$name} && $ENV{'ignoreConfigErrors'} ne "1"
my $f = $requiredAnswers{$name} && $ignoreConfigErrors ne "1"
? sub { die "error: " . $_[0]; } : sub { warn "warning: " . $_[0]; };
&$f("unused option: $name\n") unless defined $config{$name};
&$f("option not set correctly: $name (wanted '$answers{$name}', got '$config{$name}')\n")
Expand Down
97 changes: 31 additions & 66 deletions pkgs/os-specific/linux/kernel/generic.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
, # The kernel version.
version

, # Overrides to the kernel config.
, # path to a .config file (or its content ?)
# if it s null we generate it
configfilename ? null

, # Appended verbatim to kernel .config
extraConfig ? ""

, # The version number used for the module directory
Expand All @@ -26,8 +30,10 @@
, ignoreConfigErrors ? stdenv.platform.name != "pc"
, extraMeta ? {}
, hostPlatform
, callPackage
# , pkgs
, ...
}:
} @ args:

assert stdenv.isLinux;

Expand All @@ -51,79 +57,38 @@ let
config = configWithPlatform stdenv.platform;
configCross = configWithPlatform hostPlatform.platform;

kernelConfigFun = baseConfig:
let
configFromPatches =
map ({extraConfig ? "", ...}: extraConfig) kernelPatches;
in lib.concatStringsSep "\n" ([baseConfig] ++ configFromPatches);

configfile = stdenv.mkDerivation {
configDrv = callPackage ./config.nix {
inherit ignoreConfigErrors;
name = "linux-config-${version}";

generateConfig = ./generate-config.pl;

kernelConfig = kernelConfigFun config;

nativeBuildInputs = [ perl ];

platformName = stdenv.platform.name;
kernelBaseConfig = stdenv.platform.kernelBaseConfig;
kernelTarget = stdenv.platform.kernelTarget;
autoModules = stdenv.platform.kernelAutoModules;
preferBuiltin = stdenv.platform.kernelPreferBuiltin or false;
arch = stdenv.platform.kernelArch;

crossAttrs = let
cp = hostPlatform.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;

inherit (kernel.crossDrv) src patches preUnpack;
};
inherit version src kernelPatches stdenv config;
# modDirVersion
inherit kernel;
};

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

# Get a basic config file for later refinement with $generateConfig.
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 \
PREFER_BUILTIN=$preferBuiltin SRC=../$sourceRoot perl -w $generateConfig
'';

installPhase = "mv .config $out";

enableParallelBuilding = true;
};
# TODO moved it
# callPackage ./config.nix {};
# configfile = stdenv.mkDerivation {
# configfile = (import ./config.nix);

# TODO le transformer plutot en
kernel = buildLinux {
# TODO args
inherit version modDirVersion src kernelPatches stdenv;
# inherit ignoreConfigErrors;
inherit configDrv;

# configfile = configfile.nativeDrv or configfile;
# configfile = configfile.nativeDrv or configfile;

# this is really configfilename
# configfile = if configfilename then configfilename else (callPackage ./config.nix {});
configfile = null;

configfile = configfile.nativeDrv or configfile;

crossConfigfile = configfile.crossDrv or configfile;
# TODO fix later
# crossConfigfile = configfile.crossDrv or configfile;

# erase parent config ???!
config = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };

crossConfig = { CONFIG_MODULES = "y"; CONFIG_FW_LOADER = "m"; };
Expand Down
Loading