stdenv/freebsd: reinit

The old stdenv didn't work, and was also impure. The new one works, and
is pure. Presently, the bootstrap tools are cross compiled into one small
nar and one large tar, which is then unpacked, patched, and split into
smaller derivations. Efforts were made to make the boot process as short
as possible - there are only two clangs built, and as many packages are
propagated between stages as possible while leaving the bootstrap tools
out of the final stdenv's closure.
This commit is contained in:
Audrey Dutcher 2024-05-27 12:08:14 -07:00
parent 82cbb284d3
commit 1e2071847d
12 changed files with 5975 additions and 396 deletions

View File

@ -24,6 +24,5 @@
# "armv5tel-linux" is excluded because it is not bootstrapped
"powerpc64le-linux"
"riscv64-linux"
# "x86_64-freebsd" is excluded because it is mostly broken
"x86_64-freebsd"
]

View File

@ -5,6 +5,7 @@
stdenvNoLibs,
overrideCC,
buildPackages,
stdenvNoLibcxx ? overrideCC stdenv buildPackages.llvmPackages.clangNoLibcxx,
versionData,
patches,
compatIfNeeded,
@ -29,7 +30,7 @@ lib.makeOverridable (
else if attrs.noLibc or false then
stdenvNoLibs
else if attrs.noLibcxx or false then
overrideCC stdenv buildPackages.llvmPackages.clangNoLibcxx
stdenvNoLibcxx
else
stdenv;
in

View File

@ -0,0 +1,5 @@
fixupOutputHooks+=(_FreeBSDPatchelfShrink)
_FreeBSDPatchelfShrink() {
find $prefix -type f | xargs -n1 patchelf --shrink-rpath &>/dev/null || true
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,105 @@
{ system }:
((import <nixpkgs> { }).callPackage (
{
stdenv,
pkgsCross,
runCommand,
lib,
buildPackages,
}:
let
pkgs = pkgsCross.${system};
pack-all =
packCmd: name: pkgs: fixups:
(runCommand name {
requiredSystemFeatures = [ "recursive-nix" ];
} ''
nix_store=${lib.getBin buildPackages.nix}/bin/nix-store
rsync=${lib.getExe buildPackages.rsync}
base=$PWD
requisites="$($nix_store --query --requisites ${lib.concatStringsSep " " pkgs} | tac)"
rm -f $base/nix-support/propagated-build-inputs
for f in $requisites; do
cd $f
$rsync --chmod="+w" -av . $base
done
cd $base
rm -rf nix nix-support
mkdir nix-support
for dir in $requisites; do
cd "$dir/nix-support" 2>/dev/null || continue
for f in $(find . -type f); do
mkdir -p "$base/nix-support/$(dirname $f)"
cat $f >>"$base/nix-support/$f"
done
done
cd $base
${fixups}
rm .nix-socket
${packCmd}
'');
nar-all = pack-all "$nix_store --dump . | xz -9 -T $NIX_BUILD_CORES >$out";
tar-all = pack-all "XZ_OPT=\"-9 -T $NIX_BUILD_CORES\" tar cJf $out .";
coreutils-big = pkgs.coreutils.override { singleBinary = false; };
mkdir = runCommand "mkdir" { coreutils = coreutils-big; } ''
mkdir -p $out/bin
cp $coreutils/bin/mkdir $out/bin
'';
in {
bootstrap-files0 = nar-all "${system}-bootstrap-files0.nar.xz" (with pkgs; [bash mkdir xz gnutar]) ''
rm -rf include lib/*.a lib/i18n lib/bash share
'';
bootstrap-files1 = tar-all "${system}-bootstrap-files1.tar.xz" (
with pkgs;
[
(runCommand "bsdcp" { } "mkdir -p $out/bin; cp ${freebsd.cp}/bin/cp $out/bin/bsdcp")
coreutils
gnutar
findutils
gnumake
gnused
patchelf
gnugrep
gawk
diffutils
patch
bash
xz
xz.dev
gzip
bzip2
bzip2.dev
curl
expand-response-params
binutils-unwrapped
freebsd.libc
llvmPackages.libcxx
llvmPackages.libcxx.dev
llvmPackages.compiler-rt
llvmPackages.compiler-rt.dev
llvmPackages.clang-unwrapped
(freebsd.locales.override { locales = [ "C.UTF-8" ]; })
]
# INSTRUCTIONS FOR GENERATING THE SPURIOUS LIST
# - empty this list
# - rebuild bootstrap files and update their urls and hashes
# - turn on atime on your FreeBSD nix store filesystem
# - run nix-collect-garbage on FreeBSD to make it so we rebuild FODs
# - build the nixpkgs __bootstrapArchive attribute on FreeBSD
# - reboot your FreeBSD system. Otherwise the atimes will simply be wrong because of kernel caching
# - run a full build of stdenv on FreeBSD. with -j3, this takes 1h40 on my 20 cpu VM (AMD host)
# - use the following to generate a list with access times and filenames
# find /nix/store/###-bootstrap-archive -type f | xargs stat | grep -E 'Access: 2|File:' | paste -d ' ' - - | awk '{ print $4 " " $5 " " $6 " " $2 }' | sort -n > atimes
# - manually identify the point where files have no longer been accessed after the patching phase
# - use your favorite text editor to snip out the time column, the /nix/store/###-bootstrap-archive/ prefix, and the files that have not been used during bootstrap
# - turn off atime if it was off before since it will degrade performance
# - manually remove from the list the following; they are not marked as atime'd even though they are used
# - bin/strings # used only during bootstrap
# - plop it here
) "xargs rm -f <${./bootstrap-files-spurious.txt}";
}
) { })

View File

@ -1,276 +1,550 @@
{ lib
, localSystem, crossSystem, config, overlays, crossOverlays ? []
# afaik the longest dependency chain is stdenv -> stdenv-1#coreutils -> stdenv-1#gmp -> stdenv-0#libcxx -> stdenv-0#libc
# this is only possible through aggressive hacking to make libcxx build with stdenv-0#libc instead of bootstrapTools.libc.
{
lib,
localSystem,
crossSystem,
config,
overlays,
crossOverlays ? [ ],
}:
assert crossSystem == localSystem;
let inherit (localSystem) system;
fetchURL = import <nix/fetchurl.nix>;
trivialBuilder = (import ./trivial-builder.nix);
make = trivialBuilder rec {
inherit (localSystem) system;
name = "make";
ver = "4.3";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.gz";
sha256 = "06cfqzpqsvdnsxbysl5p2fgdgxgl9y4p7scpnrfa8z2zgkjdspz0";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
let
inherit (localSystem) system;
bootstrap-urls-table = {
x86_64-freebsd = {
stage0 = {
url = "http://192.168.122.1:8000/stage0.nar.xz";
hash = "sha256-iGPBcwzDLJFroXwE/ADW+aUevywZCOher4mg9Ysx2j4=";
name = "bootstrap-files0";
unpack = true;
};
stage1 = {
url = "http://192.168.122.1:8000/stage1.tar.xz";
hash = "sha256-i0VBzbMPnSSmPjh5CYOQXTYCbSBbfa5omA0xZ2fjDlU=";
name = "bootstrap-files1.tar.xz";
};
};
bash = trivialBuilder rec {
inherit (localSystem) system;
name = "bash";
ver = "4.4.18";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.gz";
sha256 = "08vz660768mnnax7n8d4d85jxafwdmsxsi7fh0hzvmafbvn9wkb0";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
};
fetchurlBoot = import <nix/fetchurl.nix>;
bootstrap-files = builtins.mapAttrs (k: fetchurlBoot) bootstrap-urls-table.${localSystem.system};
mkExtraBuildCommands0 = cc: ''
rsrc="$out/resource-root"
mkdir "$rsrc"
ln -s "${lib.getLib cc}/lib/clang/16/include" "$rsrc"
echo "-resource-dir=$rsrc" >> $out/nix-support/cc-cflags
'';
mkExtraBuildCommands =
cc: compiler-rt:
mkExtraBuildCommands0 cc
+ ''
ln -s "${compiler-rt.out}/lib" "$rsrc/lib"
ln -s "${compiler-rt.out}/share" "$rsrc/share"
'';
bootstrapArchive = (
derivation {
inherit system;
name = "bootstrap-archive";
pname = "bootstrap-archive";
version = "9.9.9";
builder = "${bootstrap-files.stage0}/libexec/ld-elf.so.1";
args = [ "${bootstrap-files.stage0}/bin/bash" ./unpack-bootstrap-files.sh ];
LD_LIBRARY_PATH = "${bootstrap-files.stage0}/lib";
src = bootstrap-files.stage0;
inherit (bootstrap-files) stage1;
}
);
linkBS = (
attrs:
derivation (
attrs
// {
inherit system;
name = attrs.name or (builtins.baseNameOf (builtins.elemAt attrs.paths 0));
src = bootstrapArchive;
builder = "${bootstrapArchive}/bin/bash";
args = [ ./linkBS.sh ];
PATH = "${bootstrapArchive}/bin";
paths = attrs.paths;
}
)
);
# commented linkBS entries are provided but unused
bootstrapTools = {
expand-response-params = "";
bsdcp = linkBS { paths = [ "bin/bsdcp" ]; };
patchelf = linkBS { paths = [ "bin/patchelf" ]; };
bash = linkBS {
paths = [
"bin/bash"
"bin/sh"
];
shell = "bin/bash";
shellPath = "/bin/bash";
};
coreutils = trivialBuilder rec {
inherit (localSystem) system;
curl = linkBS {
paths = [
"bin/curl"
];
};
llvmPackages = {
clang-unwrapped = linkBS {
paths = [
"bin/clang"
"bin/clang++"
"bin/cpp"
];
version = "16";
};
libunwind = linkBS {
name = "libunwind";
paths = [
"lib/libunwind.a"
"lib/libunwind.so"
"lib/libunwind.so.1"
"lib/libunwind.so.1.0"
"lib/libunwind_shared.so"
];
};
};
coreutils = linkBS {
name = "coreutils";
ver = "8.31";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "1zg9m79x1i2nifj4kb0waf9x3i5h6ydkypkjnbsb9rnwis8rqypz";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-gmp"
"--without-libpth-prefix"
];
paths = map (str: "bin/" + str) [
"base64"
"basename"
"cat"
"chcon"
"chgrp"
"chmod"
"chown"
"chroot"
"cksum"
"comm"
"cp"
"csplit"
"cut"
"date"
"dd"
"df"
"dir"
"dircolors"
"dirname"
"du"
"echo"
"env"
"expand"
"expr"
"factor"
"false"
"fmt"
"fold"
"groups"
"head"
"hostid"
"id"
"install"
"join"
"kill"
"link"
"ln"
"logname"
"ls"
"md5sum"
"mkdir"
"mkfifo"
"mknod"
"mktemp"
"mv"
"nice"
"nl"
"nohup"
"nproc"
"numfmt"
"od"
"paste"
"pathchk"
"pinky"
"pr"
"printenv"
"printf"
"ptx"
"pwd"
"readlink"
"realpath"
"rm"
"rmdir"
"runcon"
"seq"
"shred"
"shuf"
"sleep"
"sort"
"split"
"stat"
"stdbuf"
"stty"
"sum"
"tac"
"tail"
"tee"
"test"
"timeout"
"touch"
"tr"
"true"
"truncate"
"tsort"
"tty"
"uname"
"unexpand"
"uniq"
"unlink"
"users"
"vdir"
"wc"
"who"
"whoami"
"yes"
"["
];
};
findutils = trivialBuilder rec {
inherit (localSystem) system;
name = "findutils";
ver = "4.7.0";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "16kqz9yz98dasmj70jwf5py7jk558w96w0vgp3zf9xsqk3gzpzn5";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-gmp"
"--without-libpth-prefix"
];
};
diffutils = trivialBuilder rec {
inherit (localSystem) system;
diffutils = linkBS {
name = "diffutils";
ver = "3.7";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "09isrg0isjinv8c535nxsi1s86wfdfzml80dbw41dj9x3hiad9xk";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-libsigsegv-prefix"
];
paths = map (str: "bin/" + str) [
"diff"
"cmp"
#"diff3"
#"sdiff"
];
};
grep = trivialBuilder rec {
inherit (localSystem) system;
name = "grep";
ver = "3.4";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "1yy33kiwrxrwj2nxa4fg15bvmwyghqbs8qwkdvy5phm784f7brjq";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--disable-perl-regexp"
"--without-libsegsegv-prefix"
];
findutils = linkBS {
name = "findutils";
paths = [
"bin/find"
"bin/xargs"
];
};
patch = trivialBuilder rec {
inherit (localSystem) system;
name = "patch";
ver = "2.7.6";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "1zfqy4rdcy279vwn2z1kbv19dcfw25d2aqy9nzvdkq5bjzd0nqdc";
iconv = linkBS { paths = [ "bin/iconv" ]; };
patch = linkBS { paths = [ "bin/patch" ]; };
gnutar = linkBS { paths = [ "bin/tar" ]; };
gawk = linkBS {
paths = [
"bin/awk"
"bin/gawk"
];
};
gawk = trivialBuilder rec {
inherit (localSystem) system;
name = "gawk";
ver = "5.0.1";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "15570p7g2x54asvr2fsc56sxzmm08fbk4mzpcs5n92fp9vq8cklf";
configureArgs = [ "--disable-nls"
"--disable-mpfr"
"--without-libintl-prefix"
"--without-libiconv-prefix"
"--without-libsegsegv-prefix"
];
gnumake = linkBS { paths = [ "bin/make" ]; };
gnugrep = linkBS {
paths = [
"bin/grep"
"bin/egrep"
"bin/fgrep"
];
};
cpio = trivialBuilder rec {
inherit (localSystem) system;
name = "cpio";
ver = "2.13";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.gz";
sha256 = "126vyg4a8wcdwh6npgvxy6gq433bzgz3ph37hmjpycc4r7cp0x78";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
gnused = linkBS { paths = [ "bin/sed" ]; };
gzip = linkBS {
paths = [
"bin/gzip"
#"bin/gunzip"
];
};
sed = trivialBuilder rec {
inherit (localSystem) system;
name = "sed";
ver = "4.8";
url = "https://ftp.gnu.org/gnu/${name}/${name}-${ver}.tar.xz";
sha256 = "0cznxw73fzv1n3nj2zsq6nf73rvsbxndp444xkpahdqvlzz0r6zp";
configureArgs = [ "--disable-nls"
"--without-libintl-prefix"
"--without-libiconv-prefix"
];
bzip2 = linkBS { paths = [ "bin/bzip2" ]; };
xz = linkBS {
paths = [
"bin/xz"
"bin/unxz"
];
};
cacert = fetchURL rec {
url = "https://curl.haxx.se/ca/cacert-2020-01-01.pem";
sha256 = "07q808n307gzaga93abpf6an7c3rd35p18psdc1dd83lspgp1xxd";
executable = false;
cacert = linkBS {
paths = [
"etc/ssl/certs"
"nix-support/setup-hook"
];
};
curl = trivialBuilder rec {
inherit (localSystem) system;
name = "curl";
ver = "7.68.0";
url = "https://curl.haxx.se/download/${name}-${ver}.tar.xz";
sha256 = "0nh3j90w6b97wqcgxjfq55qhkz9s38955fbhwzv2fsi7483j895p";
configureArgs = [ "--disable-nls"
"--disable-ares"
"--disable-debug"
"--disable-ldap"
"--disable-ldaps"
"--disable-rtsp"
"--disable-dict"
"--disable-telnet"
"--disable-tftp"
"--disable-pop3"
"--disable-imap"
"--disable-smb"
"--disable-smtp"
"--disable-gopher"
"--disable-manual"
"--disable-verbose"
"--disable-sspi"
"--disable-tls-srp"
"--disable-unix-sockets"
"--without-brotli"
"--without-gnutls"
"--without-mbedtls"
"--without-wolfssl"
"--without-bearssl"
"--without-libidn2"
"--without-librtmp"
"--without-nghttp2"
"--with-ssl=/usr"
"--with-ca-bundle=${cacert}"
];
binutils-unwrapped = linkBS {
name = "binutils";
paths = map (str: "bin/" + str) [
"ld"
#"as"
#"addr2line"
"ar"
#"c++filt"
#"elfedit"
#"gprof"
#"objdump"
"nm"
"objcopy"
"ranlib"
"readelf"
"size"
"strings"
"strip"
];
};
freebsd = {
locales = linkBS { paths = [ "share/locale" ]; };
libc = linkBS {
name = "bootstrapLibs";
paths = [
"lib"
"include"
"share"
"libexec"
];
pname = "libs";
version = "bootstrap";
};
};
};
mkStdenv =
{
name ? "freebsd",
overrides ?
prevStage: super: self:
{ },
hascxx ? true,
}:
prevStage:
let
bsdcp =
prevStage.bsdcp or (prevStage.runCommand "bsdcp" { }
"mkdir -p $out/bin; cp ${prevStage.freebsd.cp}/bin/cp $out/bin/bsdcp"
);
initialPath = with prevStage; [
coreutils
gnutar
findutils
gnumake
gnused
patchelf
gnugrep
gawk
diffutils
patch
bash
xz
gzip
bzip2
bsdcp
];
shell = "${prevStage.bash}/bin/bash";
stdenvNoCC = import ../generic {
inherit
config
initialPath
shell
fetchurlBoot
;
name = "stdenvNoCC-${name}";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
cc = null;
};
fetchurlBoot = import ../../build-support/fetchurl {
inherit lib stdenvNoCC;
inherit (prevStage) curl;
};
stdenv = import ../generic {
inherit
config
initialPath
shell
fetchurlBoot
;
name = "stdenv-${name}";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
extraNativeBuildInputs = [
./unpack-source.sh
./always-patchelf.sh
];
cc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
inherit lib stdenvNoCC;
name = "${name}-cc";
inherit (prevStage.freebsd) libc;
inherit (prevStage) gnugrep coreutils expand-response-params;
libcxx = prevStage.llvmPackages.libcxx or null;
runtimeShell = shell;
propagateDoc = false;
nativeTools = false;
nativeLibc = false;
cc = prevStage.llvmPackages.clang-unwrapped;
isClang = true;
extraPackages = lib.optionals hascxx [
prevStage.llvmPackages.compiler-rt
];
nixSupport = {
libcxx-cxxflags = lib.optionals (!hascxx) [ "-isystem ${prevStage.freebsd.libc}/include/c++/v1" ];
};
extraBuildCommands = lib.optionalString hascxx (
mkExtraBuildCommands prevStage.llvmPackages.clang-unwrapped prevStage.llvmPackages.compiler-rt
);
bintools = lib.makeOverridable (import ../../build-support/bintools-wrapper) {
inherit lib stdenvNoCC;
name = "${name}-bintools";
inherit (prevStage.freebsd) libc;
inherit (prevStage) gnugrep coreutils expand-response-params;
runtimeShell = shell;
bintools = prevStage.binutils-unwrapped;
propagateDoc = false;
nativeTools = false;
nativeLibc = false;
};
};
overrides = overrides prevStage;
preHook = ''
export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
export PATH_LOCALE=${prevStage.freebsd.localesReal or prevStage.freebsd.locales}/share/locale
'';
};
in
{
inherit config overlays stdenv;
};
bashExe = "${bash}/bin/bash";
in
[
({}: {
__raw = true;
bootstrapTools = derivation ({
inherit system;
inherit make bash coreutils findutils
diffutils grep patch gawk cpio sed
curl;
name = "trivial-bootstrap-tools";
builder = bashExe;
args = [ ./trivial-bootstrap.sh ];
buildInputs = [ make ];
mkdir = "/bin/mkdir";
ln = "/bin/ln";
} // lib.optionalAttrs config.contentAddressedByDefault {
__contentAddressed = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
});
})
({ bootstrapTools, ... }: rec {
__raw = true;
inherit bootstrapTools;
fetchurl = import ../../build-support/fetchurl {
inherit lib;
stdenvNoCC = stdenv;
curl = bootstrapTools;
};
stdenv = import ../generic {
name = "stdenv-freebsd-boot-1";
buildPlatform = localSystem;
hostPlatform = localSystem;
targetPlatform = localSystem;
inherit config;
initialPath = [ "/" "/usr" ];
shell = "${bootstrapTools}/bin/bash";
fetchurlBoot = null;
cc = null;
overrides = self: super: {
};
};
})
(prevStage: {
__raw = true;
inherit (prevStage) bootstrapTools;
stdenv = import ../generic {
name = "stdenv-freebsd-boot-0";
inherit config;
initialPath = [ prevStage.bootstrapTools ];
inherit (prevStage.stdenv)
buildPlatform hostPlatform targetPlatform
shell;
fetchurlBoot = prevStage.fetchurl;
cc = null;
};
})
(prevStage: {
inherit config overlays;
stdenv = import ../generic rec {
name = "stdenv-freebsd-boot-3";
inherit config;
inherit (prevStage.stdenv)
buildPlatform hostPlatform targetPlatform
initialPath shell fetchurlBoot;
cc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
inherit lib;
nativeTools = true;
nativePrefix = "/usr";
nativeLibc = true;
stdenvNoCC = prevStage.stdenv;
buildPackages = {
inherit (prevStage) stdenv;
};
cc = {
name = "clang-9.9.9";
cc = "/usr";
outPath = prevStage.bootstrapTools;
};
isClang = true;
bintools = import ../../build-support/bintools-wrapper {
(
{ }:
mkStdenv {
name = "freebsd-boot-0";
hascxx = false;
overrides = prevStage: self: super: {
# this one's goal is to build foundational libs like libc and libcxx. we want to override literally every possible bin package we can with bootstrap tools
# we CAN'T import LLVM because the compiler built here is used to build the final compiler and the final compiler must not be built by the bootstrap compiler
inherit (bootstrapTools)
patchelf
bash
curl
coreutils
diffutils
findutils
iconv
patch
gnutar
gawk
gnumake
gnugrep
gnused
gzip
bzip2
xz
cacert
;
binutils-unwrapped = builtins.removeAttrs bootstrapTools.binutils-unwrapped [ "src" ];
fetchurl = import ../../build-support/fetchurl {
inherit lib;
stdenvNoCC = prevStage.stdenv;
nativeTools = true;
nativeLibc = true;
propagateDoc = false;
nativePrefix = "/usr";
bintools = { name = "${name}-binutils";
outPath = prevStage.bootstrapTools; };
inherit (self) stdenvNoCC;
inherit (prevStage) curl;
};
gettext = super.gettext.overrideAttrs {
NIX_CFLAGS_COMPILE = "-DHAVE_ICONV=1"; # we clearly have iconv. what do you want?
};
curlReal = super.curl;
tzdata = super.tzdata.overrideAttrs { NIX_CFLAGS_COMPILE = "-DHAVE_GETTEXT=0"; };
# make it so libcxx/libunwind are built in this stdenv and not the next
freebsd = super.freebsd.overrideScope (self': super': {
inherit (prevStage.freebsd) locales;
stdenvNoLibcxx =
self.overrideCC (self.stdenv // { name = "stdenv-freebsd-boot-0.4"; })
(
self.stdenv.cc.override {
name = "freebsd-boot-0.4-cc";
libc = self.freebsd.libc;
bintools = self.stdenv.cc.bintools.override {
name = "freebsd-boot-0.4-bintools";
libc = self.freebsd.libc;
};
}
);
});
llvmPackages = super.llvmPackages // {
libcxx =
(super.llvmPackages.libcxx.override {
stdenv = self.overrideCC (self.stdenv // { name = "stdenv-freebsd-boot-0.5"; }) (
self.stdenv.cc.override {
name = "freebsd-boot-0.5-cc";
libc = self.freebsd.libc;
bintools = self.stdenv.cc.bintools.override {
name = "freebsd-boot-0.5-bintools";
libc = self.freebsd.libc;
};
extraPackages = [
self.llvmPackages.compiler-rt
];
extraBuildCommands = mkExtraBuildCommands self.llvmPackages.clang-unwrapped self.llvmPackages.compiler-rt;
}
);
}).overrideAttrs
(
self': super': {
NIX_CFLAGS_COMPILE = "-nostdlib++";
NIX_LDFLAGS = "--allow-shlib-undefined";
cmakeFlags = builtins.filter (x: x != "-DCMAKE_SHARED_LINKER_FLAGS=-nostdlib") super'.cmakeFlags;
}
);
};
};
preHook = "export NIX_NO_SELF_RPATH=1";
} bootstrapTools
)
(mkStdenv {
name = "freebsd-boot-1";
overrides = prevStage: self: super: {
# this one's goal is to build all the tools that get imported into the final stdenv.
# we can import the foundational libs from boot-0
# we can import bins and libs that DON'T get imported OR LINKED into the final stdenv from boot-0
curl = prevStage.curlReal;
curlReal = super.curl;
cacert = prevStage.cacert;
inherit (prevStage)
fetchurl
python3
bison
perl
cmake
ninja
;
freebsd = super.freebsd.overrideScope (
self': super': {
locales = prevStage.freebsd.locales;
localesReal = super'.locales;
libc = prevStage.freebsd.libc;
}
);
llvmPackages = super.llvmPackages // {
libcxx = prevStage.llvmPackages.libcxx;
};
};
})
(mkStdenv {
name = "freebsd";
overrides = prevStage: self: super: {
__bootstrapArchive = bootstrapArchive;
curl = prevStage.curlReal;
cacert = prevStage.cacert;
inherit (prevStage) fetchurl;
freebsd = super.freebsd.overrideScope (
self': super': { localesPrev = prevStage.freebsd.localesReal; }
);
haskellPackages = super.haskellPackages.override {
overrides = (
self: super: {
digest = super.digest.overrideAttrs {
postPatch = ''
sed -E -i -e 's/ && !os\(freebsd\)//' digest.cabal
'';
};
}
);
};
};
})
]

View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
for path in $paths; do
if ! [ -e "$src/$path" ]; then
echo "Error: $path does not exist"
exit 1
fi
mkdir -p $out/$(dirname $path)
ln -s $src/$path $out/$path
done

View File

@ -1,118 +0,0 @@
set -e
set -o nounset
set -o pipefail
echo Building the trivial bootstrap environment...
#echo
#echo Needed FreeBSD packages:
#echo findutils gcpio gawk gnugrep coreutils bash gsed gtar gmake xar binutils gpatch lbzip2 diffutils
$mkdir -p $out/bin
ln () {
if [ ! -z "${2:-}" ]; then
if [ -f "$out/bin/$2" ]; then
echo "$2 exists"
exit 1
fi
fi
if test ! -f "$1"; then
echo Target "$2" does not exist
exit 1
fi
# TODO: check that destination directory exists
if [ ! -z "${2:-}" ]; then
$ln -s "$1" "$out/bin/$2"
else
$ln -s "$1" "$out/bin/"
fi
}
ln $bash/bin/bash
ln $make/bin/make
ln /bin/sh
for i in b2sum base32 base64 basename basenc cat chcon chgrp chmod \
chown chroot cksum comm cp csplit cut date dd df dir dircolors \
dirname du echo env expand expr factor false fmt fold install \
groups head hostid id join kill link ln logname ls md5sum mkdir \
mkfifo mknod mktemp mv nice nl nohup nproc numfmt od paste pathchk \
pinky pr printenv printf ptx pwd readlink realpath rm rmdir runcon \
seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf \
sleep sort split stat stdbuf stty sum sync tac tee test timeout \
touch tr true truncate tsort tty uname unexpand uniq unlink uptime \
users vdir wc who whoami yes
do
ln "$coreutils/bin/$i" "$i"
done
for i in find xargs; do
ln "$findutils/bin/$i" "$i"
done
for i in diff diff3 sdiff; do
ln "$diffutils/bin/$i" "$i"
done
for i in grep egrep fgrep; do
ln "$grep/bin/$i" "$i"
done
ln /usr/bin/locale
ln /usr/bin/more
ln /usr/bin/hexdump # for bitcoin
ln /usr/bin/bzip2
ln /usr/bin/bunzip2
ln /usr/bin/bzip2recover
ln /usr/bin/xz
ln /usr/bin/unxz
ln /usr/bin/lzma
ln /usr/bin/unlzma
ln /bin/ps
ln /bin/hostname
ln /usr/bin/cmp
ln $sed/bin/sed
ln /usr/bin/tar tar
ln $gawk/bin/gawk
ln $gawk/bin/gawk awk
ln $cpio/bin/cpio
ln $curl/bin/curl curl
ln /usr/bin/gzip
ln /usr/bin/gunzip
ln /usr/bin/tail tail # note that we are not using gtail!!!
ln /usr/bin/less less
ln $patch/bin/patch patch
ln /usr/bin/which which
## binutils
# pkg info -l binutils | grep usr/local/bin
ln /usr/bin/addr2line
ln /usr/bin/ar
ln /usr/bin/as
ln /usr/bin/c++filt
#ln /usr/bin/dwp
#ln /usr/bin/elfedit
ln /usr/bin/gprof
ln /usr/bin/ld
#ln /usr/bin/ld.bfd
#ln /usr/bin/ld.gold
ln /usr/bin/nm
ln /usr/bin/objcopy
ln /usr/bin/objdump
ln /usr/bin/ranlib
ln /usr/bin/readelf
ln /usr/bin/size
ln /usr/bin/strings
ln /usr/bin/strip
ln /usr/bin/cc
ln /usr/bin/cpp
ln /usr/bin/c++
#pkg info -l llvm37 | grep usr/local/bin

View File

@ -1,13 +0,0 @@
{ system, name, ver, url, sha256, configureArgs ? [], executable ? false } :
let fetchURL = import <nix/fetchurl.nix>;
in derivation {
inherit system configureArgs;
name = "trivial-bootstrap-${name}-${ver}";
dname = "${name}-${ver}";
src = fetchURL {
inherit url sha256 executable;
};
builder = ./trivial-builder.sh;
}

View File

@ -1,10 +0,0 @@
#!/bin/sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
tar -zxvf $src
cd $dname
mkdir -p $out/bin
./configure --prefix=$out $configureArgs
make
make install

View File

@ -0,0 +1,56 @@
$src/libexec/ld-elf.so.1 $src/bin/mkdir $out
$src/libexec/ld-elf.so.1 $src/bin/tar -I "$src/libexec/ld-elf.so.1 $src/bin/xz" -C $out -xf $stage1
export LD_LIBRARY_PATH=$out/lib
BADLIST=ld-elf.so.1
oobpatch() {
$out/libexec/ld-elf.so.1 $src/bin/cp $1 ./tmp
$out/libexec/ld-elf.so.1 $out/bin/patchelf --set-rpath $out/lib --set-interpreter $out/libexec/ld-elf.so.1 ./tmp
$out/libexec/ld-elf.so.1 $src/bin/mv ./tmp $1
BADLIST="$BADLIST|${1##*/}"
}
oobpatch $out/bin/patchelf
oobpatch $out/lib/libthr.so.3
oobpatch $out/lib/libc.so.7
for f in $($out/libexec/ld-elf.so.1 $out/bin/find $out/lib -type f); do
$out/libexec/ld-elf.so.1 $out/bin/grep -E "$BADLIST" <<<"$f" && continue
$out/libexec/ld-elf.so.1 $out/bin/patchelf --set-rpath $out/lib $f
done
for f in $out/bin/* $out/bin/.*; do
$out/libexec/ld-elf.so.1 $out/bin/grep -E "$BADLIST" <<<"$f" &>/dev/null && continue
$out/libexec/ld-elf.so.1 $out/bin/patchelf --set-rpath $out/lib --set-interpreter $out/libexec/ld-elf.so.1 $f
done
unset LD_LIBRARY_PATH
export PATH=$out/bin
# sanity check
$out/bin/true || exit 1
# scorched earth
for f in $(find $out -type f); do
while true; do
BADMAN="$(strings $f | grep -o '/nix/store/.*' | grep -v "$out" | head -n1)"
if [ -z "$BADMAN" ]; then
break
fi
echo scorch $f
BADMAN="$(echo "$BADMAN" | cut -d/ -f-4)"
GOODMAN="$out"
if [ ${#GOODMAN} -gt ${#BADMAN} ]; then
echo "Can't patch $f: $BADMAN too short"
break
fi
while ! [ ${#GOODMAN} -eq ${#BADMAN} ]; do
GOODMAN="/$GOODMAN"
done
if ! sed -E -i -e "s@$BADMAN@$GOODMAN@g" $f; then
echo "Can't patch $f: sed failed"
break
fi
done
done
echo $out

View File

@ -0,0 +1,41 @@
unpackCmdHooks+=(_FreeBSDUnpackSource)
_FreeBSDUnpackSource() {
local fn="$1"
local destination
if [ -d "$fn" ]; then
destination="$(stripHash "$fn")"
if [ -e "$destination" ]; then
echo "Cannot copy $fn to $destination: destination already exists!"
echo "Did you specify two \"srcs\" with the same \"name\"?"
return 1
fi
# We can't preserve hardlinks because they may have been
# introduced by store optimization, which might break things
# in the build.
bsdcp -a -- "$fn" "$destination"
chmod -R +w "$destination"
else
case "$fn" in
*.tar.xz | *.tar.lzma | *.txz)
# Don't rely on tar knowing about .xz.
xz -d < "$fn" | tar xf - --warning=no-timestamp
;;
*.tar | *.tar.* | *.tgz | *.tbz2 | *.tbz)
# GNU tar can automatically select the decompression method
# (info "(tar) gzip").
tar xf "$fn" --warning=no-timestamp
;;
*)
return 1
;;
esac
fi
}