add a devshell for NixOS

Bazel on NixOS is problematic -- it's packaged, but not patched to
actually _work_ outside of FHS environments.

Vere build system presents an additional accidental hurdle: it expects
the musl-cross-make toolchain to be under /usr/local/<target> and uses
sudo to install it there, as one does.  Unfortunately NixOS nerfs sudo
in user namespaces (which are used to implement FHS environments) for
security reasons, making it impossible to install the toolchain the
normal way.

So in order to restore the ability to build Vere under NixOS without
resorting to containers (which is unsporting), this commit adds a
flake, which defines a devshell, which provides the toolchain and all
the other needed tools.  So one can "nix develop", go get
coffee (first invocation may take 15 minutes or so, subsequent ones
will be instant until next nix store GC), and then "bazel build
:urbit" etc.
This commit is contained in:
Midlyx Hatrys 2023-02-17 19:04:51 +02:00
parent 3e3746d601
commit 45b28a49ed
2 changed files with 171 additions and 0 deletions

48
flake.lock Normal file
View File

@ -0,0 +1,48 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1677383253,
"narHash": "sha256-UfpzWfSxkfXHnb4boXZNaKsAcUrZT9Hw+tao1oZxd08=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "9952d6bc395f5841262b006fbace8dd7e143b634",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"parts": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1675933616,
"narHash": "sha256-/rczJkJHtx16IFxMmAWu5nNYcSXNg1YYXTHoGjLrLUA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "47478a4a003e745402acf63be7f9a092d51b83d7",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"parts": "parts"
}
}
},
"root": "root",
"version": 7
}

123
flake.nix Normal file
View File

@ -0,0 +1,123 @@
{
description = "Vere build devshell";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
parts = {
url = "github:hercules-ci/flake-parts";
inputs.nixpkgs-lib.follows = "nixpkgs";
};
};
outputs = inputs@{ self, nixpkgs, parts }: parts.lib.mkFlake { inherit inputs; } (let
# map systems to the musl-cross-make target names; only
# x86_64-linux is tested though
toolchainTargets = {
"x86_64-linux" = "x86_64-linux-musl";
"aarch64-linux" = "aarch64-linux-musl";
};
# map dep urls to hashes
toolchainDeps = {
"https://ftpmirror.gnu.org/gnu/gcc/gcc-9.4.0/gcc-9.4.0.tar.xz" = "13l3p6g2krilaawbapmn9zmmrh3zdwc36mfr3msxfy038hps6pf9";
"https://ftpmirror.gnu.org/gnu/binutils/binutils-2.33.1.tar.xz" = "1grcf8jaw3i0bk6f9xfzxw3qfgmn6fgkr108isdkbh1y3hnzqrmb";
"https://musl.libc.org/releases/musl-1.2.3.tar.gz" = "196lrzw0qy5axiz9p5ay50q2mls8hbfckr4rw0klc7jjc9h0nnvx";
"https://ftpmirror.gnu.org/gnu/gmp/gmp-6.1.2.tar.bz2" = "1clg7pbpk6qwxj5b2mw0pghzawp2qlm3jf9gdd8i6fl6yh2bnxaj";
"https://ftpmirror.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz" = "0biwnhjm3rx3hc0rfpvyniky4lpzsvdcwhmcn7f0h4iw2hwcb1b9";
"https://ftpmirror.gnu.org/gnu/mpfr/mpfr-4.0.2.tar.bz2" = "1k1s4p56272bggvyrxfn3zdycr4wy7h5ipac70cr03lys013ypn0";
"http://ftp.barfooze.de/pub/sabotage/tarballs//linux-headers-4.19.88-1.tar.xz" = "04r8k4ckqbklx9sfm07cr7vfw5ra4cic0rzanm9dfh0crxncfnwr";
"http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=3d5db9ebe860" = "75d5d255a2a273b6e651f82eecfabf6cbcd8eaeae70e86b417384c8f4a58d8d3";
};
in {
systems = builtins.attrNames toolchainTargets;
flake = {};
perSystem = { pkgs, system, ... }: let
target = toolchainTargets.${system};
# in order to make the toolchain derivation pure, spoof `wget`
# to use FODs for the dependencies that would otherwise be
# downloaded
pseudoWget = let
c = pkgs.coreutils;
in pkgs.writeScriptBin "wget" ''
#!${pkgs.stdenv.shell}
declare -A targets
${builtins.concatStringsSep "\n"
(builtins.map (url:
"targets[${nixpkgs.lib.escapeShellArg url}]=" + (nixpkgs.lib.escapeShellArg (pkgs.fetchurl {
inherit url;
sha256 = builtins.getAttr url toolchainDeps;
})))
(builtins.attrNames toolchainDeps))}
# -c -O target url
target="$3"
url="$4"
preFetched=${"$" + "{targets[$url]}"}
if [[ -z "$preFetched" ]]; then
${c}/bin/echo 1>&2 "$target ($url) is new or changed, nix-prefetch-url it and add or update the url and hash in toolchainDeps in flake.nix"
exit 1
fi
${c}/bin/cp --reflink=auto "$preFetched" "$target"
'';
toolchain = let
# keep in sync with `_musl_cross_make_version` in
# bazel/toolchain/BUILD.bazel
version = "fe915821b652a7fa37b34a596f47d8e20bc72338";
# `-g -O2` are the defaults (there's no way to add cflags via
# config.mak), `-Wno-format-security` is the interesting
# addition (without which gcc build fails in several places
# due to `-Werror=format-security` being on for some reason)
commonCFLAGS = "-g -O2 -Wno-format-security";
in pkgs.stdenv.mkDerivation {
name = "musl-cross-make";
inherit system version;
src = pkgs.fetchFromGitHub {
owner = "richfelker";
repo = "musl-cross-make";
rev = version;
sha256 = "sha256-FthfhZ+qGf2nWLICvjaO8fiP5+PYU7PqFCbPwXmJFes=";
};
nativeBuildInputs = [
pseudoWget
];
enableParallelBuilding = true;
configurePhase = ''
cat > config.mak <<EOF
TARGET = ${target}
OUTPUT = $out
COMMON_CONFIG += CFLAGS="${commonCFLAGS}" CXXFLAGS="${commonCFLAGS}"
EOF
'';
};
in {
devShells.default = (pkgs.buildFHSUserEnvBubblewrap {
name = "vere-devenv";
targetPkgs = pkgs: [
toolchain
]
++ (with pkgs; [
autoconf
automake
bazel_5
binutils # for `nm`
jdk11_headless
libtool
m4
]);
extraBuildCommands = ''
chmod +w usr
mkdir -p usr/local
# symlinking breaks Bazel inclusion checks, so have to copy
cp -a --reflink=auto ${toolchain} usr/local/${target}
'';
}).env;
};
});
}