2
0
Fork 0
genodepkgs/packages/genode/default.nix

280 lines
6.9 KiB
Nix

# SPDX-License-Identifier: CC0-1.0
{ nixpkgs, mkDhallManifest }:
let
src = nixpkgs.fetchgit {
url = "https://git.sr.ht/~ehmry/genode";
rev = "11ff9a1dc524dadd3252777d9be529910e375e66";
sha256 = "1238ashnx40fmc715w1mqiachdw7bkd04zy6d6l1hmn7f0ld535n";
};
inherit (nixpkgs) buildPackages llvmPackages;
sourceForgeToolchain = nixpkgs.buildPackages.callPackage ./toolchain.nix { };
stdenvLlvm = let inherit (nixpkgs) stdenv;
in assert stdenv.cc.isClang; stdenv;
stdenvGcc = let
env = nixpkgs.stdenvAdapters.overrideCC nixpkgs.stdenv sourceForgeToolchain;
in assert env.cc.isGNU; env;
inherit (stdenvLlvm) lib targetPlatform;
specs = with targetPlatform;
[ ]
++ lib.optional is32bit "32bit"
++ lib.optional is64bit "64bit"
++ lib.optional isAarch32 "arm"
++ lib.optional isAarch64 "arm_64"
++ lib.optional isRiscV "riscv"
++ lib.optional isx86 "x86"
++ lib.optional isx86_32 "x86_32"
++ lib.optional isx86_64 "x86_64";
toTupConfig = env: attrs:
let
tupArch = with env.targetPlatform;
if isAarch32 then
"arm"
else
if isAarch64 then
"arm64"
else
if isx86_32 then
"i386"
else
if isx86_64 then
"x86_64"
else
abort "unhandled targetPlatform";
attrs' = with env; { TUP_ARCH = tupArch; } // attrs;
in with builtins;
env.mkDerivation {
name = "tup.config";
nativeBuildInputs = with nixpkgs.buildPackages; [
binutils
pkgconfig
which
];
text = let
op = config: name: ''
${config}CONFIG_${name}=${getAttr name attrs}
'';
in foldl' op "" (attrNames attrs);
passAsFile = [ "text" ];
preferLocalBuild = true;
buildCommand = let
subst = let
vars = [ "AR" "NM" ];
f = other: var:
other + ''
echo CONFIG_${var}=`which ''$${var}` >> $out
'';
in foldl' f "" vars;
utils = let
vars = [ "pkg-config" "objcopy" ];
f = other: var:
other + ''
echo CONFIG_${var}=`which ${var}` >> $out
'';
in foldl' f "" vars;
in ''
cp $textPath $out
${subst}
${utils}
'';
};
tupConfigGcc = let
f = env:
let prefix = bin: env.cc.targetPrefix + bin;
in {
CC = prefix "gcc";
CXX = prefix "g++";
LD = prefix "ld";
OBJCOPY = prefix "objcopy";
RANLIB = prefix "ranlib";
READELF = prefix "readelf";
STRIP = prefix "strip";
PKGCONFIG = "${nixpkgs.buildPackages.pkgconfig}/bin/pkg-config";
IS_GCC = "";
LINUX_HEADERS = buildPackages.glibc.dev;
};
in toTupConfig stdenvGcc (f stdenvGcc);
tupConfigLlvm = let
f = env:
let prefix = bin: "${env.cc}/bin/${env.cc.targetPrefix}${bin}";
in {
CC = prefix "cc";
CXX = prefix "c++";
LD = prefix "ld";
OBJCOPY = "llvm-objcopy";
OBJDUMP = "llvm-objdump";
RANLIB = "llvm-ranlib";
READELF = "llvm-readelf";
STRIP = "llvm-strip";
PKGCONFIG = "${nixpkgs.buildPackages.pkgconfig}/bin/pkg-config";
IS_LLVM = "";
LIBCXXABI = llvmPackages.libcxxabi;
LIBCXX = llvmPackages.libcxx;
LIBUNWIND_BAREMETAL =
llvmPackages.libunwind.override { isBaremetal = true; };
LIBUNWIND = llvmPackages.libunwind;
LINUX_HEADERS = buildPackages.glibc.dev;
};
in toTupConfig stdenvLlvm (f stdenvLlvm);
buildRepo = { env, repo, repoInputs }:
env.mkDerivation {
pname = repo;
version = "19.11";
inherit repo specs src;
nativeBuildInputs = repoInputs;
# This is wrong, why does pkg-config not collect buildInputs?
propagatedNativeBuildInputs = repoInputs;
depsBuildBuild = with buildPackages; [ llvm pkgconfig tup ];
tupConfig = if env.cc.isGNU then
tupConfigGcc
else if env.cc.isClang then
tupConfigLlvm
else
throw "no Tup config for this stdenv";
configurePhase = ''
# Configure Tup
set -v
install -m666 $tupConfig tup.config
echo CONFIG_NIX_OUTPUTS_OUT=$out >> tup.config
echo CONFIG_NIX_OUTPUTS_DEV=$out >> tup.config
# Disable other repos
for R in repos/*; do
[ "$R" != "repos/$repo" ] && find $R -name Tupfile -delete
done
# Scan repository and generate script
tup init
tup generate buildPhase.sh
# Redirect artifacts to Nix store
mkdir -p $out/lib $out/include
ln -s $out out
ln -s $out dev
'';
buildPhase = ''
test -d repos/$repo/src/ld && cp -rv repos/$repo/src/ld $out/
pushd .
set -v
source buildPhase.sh
set +v
popd
'';
installPhase = ''
# Populate the "dev" headers
if [ -d "repos/$repo/include" ]; then
for DIR in repos/$repo/include; do
for SPEC in $specs; do
if [ -d $DIR/spec/$SPEC ]; then
cp -r $DIR/spec/$SPEC/* $out/include
rm -r $DIR/spec/$SPEC
fi
done
rm -rf $DIR/spec
cp -r $DIR $out/
done
fi
touch $out/.genode
for pc in $out/lib/pkgconfig/*.pc; do
sed -e "s|^Libs: |Libs: -L$out/lib |" -i $pc
done
'';
meta = with env.lib; {
description =
"The Genode operation system framework (${repo} repository).";
homepage = "https://genode.org/";
license = licenses.agpl3;
maintainers = [ maintainers.ehmry ];
};
};
buildRepoGcc' = { ... }@args:
let drv = buildRepo ({ env = stdenvGcc; } // args);
in { manifest = mkDhallManifest drv; } // drv;
buildRepoLlvm' = { ... }@args:
let drv = buildRepo ({ env = stdenvLlvm; } // args);
in { manifest = mkDhallManifest drv; } // drv;
drvs = rec {
base = buildRepoGcc' {
repo = "base";
repoInputs = [ ];
};
base-linux = buildRepoGcc' {
repo = "base-linux";
repoInputs = [ base ];
};
base-nova = buildRepoGcc' {
repo = "base-nova";
repoInputs = [ base ];
};
os = buildRepoLlvm' {
repo = "os";
repoInputs = [ base ];
};
gems = buildRepoLlvm' {
repo = "gems";
repoInputs = [ base os ];
};
inherit stdenvGcc stdenvLlvm tupConfigGcc tupConfigLlvm;
};
manifest = with builtins;
let
repoDrvs = filter (drv: typeOf drv == "set" && hasAttr "repo" drv && hasAttr "manifest" drv)
(attrValues drvs);
records = map (drv: "${drv.repo}=${drv.manifest}") repoDrvs;
text = "{" + builtins.concatStringsSep "," records + "}";
in nixpkgs.writeTextFile {
name = "genode.manifest.dhall";
inherit text;
};
in drvs // manifest // { pname = "genode"; inherit manifest; }