Merge pull request #328582 from rhelmot/freebsd-stdenv

FreeBSD stdenv: re-init
This commit is contained in:
Jörg Thalheim 2024-07-24 06:43:35 +02:00 committed by GitHub
commit afe8fbf038
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 4688 additions and 404 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

@ -6,9 +6,9 @@ binaries (without the reliance on external inputs):
- `bootstrap-tools`: an archive with the compiler toolchain and other
helper tools enough to build the rest of the `nixpkgs`.
- initial binaries needed to unpack `bootstrap-tools.*`. On `linux`
it's just `busybox`, on `darwin` it is unpack.nar.xz which contains
the binaries and script needed to unpack the tools. These binaries
can be executed directly from the store.
it's just `busybox`, on `darwin` and `freebsd` it is unpack.nar.xz
which contains the binaries and script needed to unpack the tools.
These binaries can be executed directly from the store.
These are called "bootstrap files".

View File

@ -95,6 +95,7 @@ CROSS_TARGETS=(
powerpc64-unknown-linux-gnuabielfv2
powerpc64le-unknown-linux-gnu
riscv64-unknown-linux-gnu
x86_64-unknown-freebsd
)
is_cross() {
@ -163,6 +164,7 @@ for target in "${targets[@]}"; do
case "$target" in
*linux*) nixpkgs_prefix="pkgs/stdenv/linux" ;;
*darwin*) nixpkgs_prefix="pkgs/stdenv/darwin" ;;
*freebsd*) nixpkgs_prefix="pkgs/stdenv/freebsd" ;;
*) die "don't know where to put '$target'" ;;
esac

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
}

View File

@ -0,0 +1,13 @@
{
unpack = import <nix/fetchurl.nix> {
url = "http://192.168.122.1:8000/result/on-server/unpack.nar.xz";
hash = "sha256-y6quCU9JKnKBdHDcUkdkM0ypWDT2cdSiqR1WqA+8ozE=";
name = "boostrapUnpacked";
unpack = true;
};
bootstrapTools = import <nix/fetchurl.nix> {
url = "http://192.168.122.1:8000/result/on-server/bootstrap-tools.tar.xz";
hash = "sha256-ypIOxsB8a/RPupki0ZTjb+vuE+ibtmS8e3DazeolHj8=";
name = "bootstrapTools.tar.xz";
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,276 +1,520 @@
{ 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 ? [ ],
bootstrapFiles ?
let table = {
x86_64-freebsd = import ./bootstrap-files/x86_64-unknown-freebsd.nix;
};
files = table.${localSystem.system} or (throw "unsupported platform ${localSystem.system} for the pure FreeBSD stdenv");
in files
}:
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;
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 = "${bootstrapFiles.unpack}/libexec/ld-elf.so.1";
args = [ "${bootstrapFiles.unpack}/bin/bash" ./unpack-bootstrap-files.sh ];
LD_LIBRARY_PATH = "${bootstrapFiles.unpack}/lib";
src = bootstrapFiles.unpack;
inherit (bootstrapFiles) bootstrapTools;
}
);
linkBootstrap = (
attrs:
derivation (
attrs
// {
inherit system;
name = attrs.name or (builtins.baseNameOf (builtins.elemAt attrs.paths 0));
src = bootstrapArchive;
builder = "${bootstrapArchive}/bin/bash";
args = [ ./linkBootstrap.sh ];
PATH = "${bootstrapArchive}/bin";
paths = attrs.paths;
}
)
);
# commented linkBootstrap entries are provided but unused
bootstrapTools = {
expand-response-params = "";
bsdcp = linkBootstrap { paths = [ "bin/bsdcp" ]; };
patchelf = linkBootstrap { paths = [ "bin/patchelf" ]; };
bash = linkBootstrap {
paths = [
"bin/bash"
"bin/sh"
];
shell = "bin/bash";
shellPath = "/bin/bash";
};
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"
];
curl = linkBootstrap {
paths = [
"bin/curl"
];
};
coreutils = trivialBuilder rec {
inherit (localSystem) system;
llvmPackages = {
clang-unwrapped = linkBootstrap {
paths = [
"bin/clang"
"bin/clang++"
"bin/cpp"
];
version = "16";
};
libunwind = linkBootstrap {
name = "libunwind";
paths = [
"lib/libunwind.a"
"lib/libunwind.so"
"lib/libunwind.so.1"
"lib/libunwind.so.1.0"
"lib/libunwind_shared.so"
];
};
};
coreutils = linkBootstrap {
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 = linkBootstrap {
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 = linkBootstrap {
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 = linkBootstrap { paths = [ "bin/iconv" ]; };
patch = linkBootstrap { paths = [ "bin/patch" ]; };
gnutar = linkBootstrap { paths = [ "bin/tar" ]; };
gawk = linkBootstrap {
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 = linkBootstrap { paths = [ "bin/make" ]; };
gnugrep = linkBootstrap {
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 = linkBootstrap { paths = [ "bin/sed" ]; };
gzip = linkBootstrap {
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 = linkBootstrap { paths = [ "bin/bzip2" ]; };
xz = linkBootstrap {
paths = [
"bin/xz"
"bin/unxz"
];
};
cacert = fetchURL rec {
url = "https://curl.haxx.se/ca/cacert-2020-01-01.pem";
sha256 = "07q808n307gzaga93abpf6an7c3rd35p18psdc1dd83lspgp1xxd";
executable = false;
binutils-unwrapped = linkBootstrap {
name = "binutils";
paths = map (str: "bin/" + str) [
"ld"
#"as"
#"addr2line"
"ar"
#"c++filt"
#"elfedit"
#"gprof"
#"objdump"
"nm"
"objcopy"
"ranlib"
"readelf"
"size"
"strings"
"strip"
];
};
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}"
];
freebsd = {
locales = linkBootstrap { paths = [ "share/locale" ]; };
libc = linkBootstrap {
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
;
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;
inherit (prevStage)
fetchurl
python3
bison
perl
cmake
ninja
;
fetchurlReal = super.fetchurl;
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;
fetchurl = prevStage.fetchurlReal;
freebsd = super.freebsd.overrideScope (
self': super': { localesPrev = prevStage.freebsd.localesReal; }
);
};
})
]

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

@ -0,0 +1,22 @@
{system ? builtins.currentSystem}:
let
inherit (releaseLib) lib;
releaseLib = import ../../top-level/release-lib.nix {
# We're not using any functions from release-lib.nix that look at
# supportedSystems.
supportedSystems = [];
};
make = crossSystem: import ./make-bootstrap-tools.nix {
pkgs = releaseLib.pkgsForCross crossSystem system;
};
in lib.mapAttrs (n: make) (with lib.systems.examples; {
# NOTE: Only add platforms for which there are files in `./bootstrap-files`
# or for which you plan to request the tarball upload soon. See the
# maintainers/scripts/bootstrap-files/README.md
# on how to request an upload.
# Sort following the sorting in `./default.nix` `bootstrapFiles` argument.
x86_64-unknown-freebsd = x86_64-freebsd;
})

View File

@ -0,0 +1,102 @@
{ pkgs ? import ../../.. {} }:
let
inherit (pkgs) runCommand lib;
# splicing doesn't seem to work right here
inherit (pkgs.buildPackages) nix rsync;
pack-all =
packCmd: name: pkgs: fixups:
(runCommand name {
requiredSystemFeatures = [ "recursive-nix" ];
nativeBuildInputs = [ nix 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 -e -T $NIX_BUILD_CORES >$out";
tar-all = pack-all "XZ_OPT=\"-9 -e -T $NIX_BUILD_CORES\" tar cJf $out --hard-dereference --sort=name --numeric-owner --owner=0 --group=0 --mtime=@1 .";
coreutils-big = pkgs.coreutils.override { singleBinary = false; };
mkdir = runCommand "mkdir" { coreutils = coreutils-big; } ''
mkdir -p $out/bin
cp $coreutils/bin/mkdir $out/bin
'';
in rec {
unpack = nar-all "unpack.nar.xz" (with pkgs; [bash mkdir xz gnutar]) ''
rm -rf include lib/*.a lib/i18n lib/bash share
'';
bootstrap-tools = tar-all "bootstrap-tools.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 bin/strings from the list, since it will be used only during bootstrap
# - manually remove all files under include and lib/clang/*/include from the list in order to improve forward compatibility (and since they are very small)
# - plop it here
) "xargs rm -f <${./bootstrap-tools-spurious.txt}";
build = runCommand "build" { } ''
mkdir -p $out/on-server
ln -s ${unpack} $out/on-server/unpack.nar.xz
ln -s ${bootstrap-tools} $out/on-server/bootstrap-tools.tar.xz
'';
}

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,57 @@
$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 $bootstrapTools
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
# meticulously replace every nix store path with the right one
# to work with binaries, make sure the path remains the same length by prefixing pathsep chars
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
}

View File

@ -3347,6 +3347,8 @@ with pkgs;
}
else if stdenv.hostPlatform.isLinux then
callPackage ../stdenv/linux/make-bootstrap-tools.nix {}
else if stdenv.hostPlatform.isFreeBSD then
callPackage ../stdenv/freebsd/make-bootstrap-tools.nix {}
else throw "freshBootstrapTools: unknown hostPlatform ${stdenv.hostPlatform.config}";
boxes = callPackage ../tools/text/boxes { };

View File

@ -266,14 +266,18 @@ in
/* Cross-built bootstrap tools for every supported platform */
bootstrapTools = let
tools = import ../stdenv/linux/make-bootstrap-tools-cross.nix { system = "x86_64-linux"; };
meta = {
linuxTools = import ../stdenv/linux/make-bootstrap-tools-cross.nix { system = "x86_64-linux"; };
freebsdTools = import ../stdenv/freebsd/make-bootstrap-tools-cross.nix { system = "x86_64-linux"; };
linuxMeta = {
maintainers = [ maintainers.dezgeg ];
};
mkBootstrapToolsJob = drv:
freebsdMeta = {
maintainers = [ maintainers.rhelmot ];
};
mkBootstrapToolsJob = meta: drv:
assert elem drv.system supportedSystems;
hydraJob' (addMetaAttrs meta drv);
in mapAttrsRecursiveCond (as: !isDerivation as) (name: mkBootstrapToolsJob)
linux = mapAttrsRecursiveCond (as: !isDerivation as) (name: mkBootstrapToolsJob linuxMeta)
# The `bootstrapTools.${platform}.bootstrapTools` derivation
# *unpacks* the bootstrap-files using their own `busybox` binary,
# so it will fail unless buildPlatform.canExecute hostPlatform.
@ -281,7 +285,10 @@ in
# attribute, so there is no way to detect this -- we must add it
# as a special case. We filter the "test" attribute (only from
# *cross*-built bootstrapTools) for the same reason.
(mapAttrs (_: v: removeAttrs v ["bootstrapTools" "test"]) tools);
(mapAttrs (_: v: removeAttrs v ["bootstrapTools" "test"]) linuxTools);
freebsd = mapAttrsRecursiveCond (as: !isDerivation as) (name: mkBootstrapToolsJob freebsdMeta)
freebsdTools;
in linux // freebsd;
# Cross-built nixStatic for platforms for enabled-but-unsupported platforms
mips64el-nixCrossStatic = mapTestOnCross systems.examples.mips64el-linux-gnuabi64 nixCrossStatic;

View File

@ -22,6 +22,7 @@
"x86_64-apple-darwin"
"x86_64-unknown-linux-gnu"
"x86_64-unknown-linux-musl"
"x86_64-unknown-freebsd"
]
# Strip most of attributes when evaluating to spare memory usage
, scrubJobs ? true
@ -249,6 +250,16 @@ let
# TODO: Re-enable once the new bootstrap-tools are in place.
#inherit (bootstrap.test-pkgs) stdenv;
}
else if hasSuffix "-freebsd" config then
let
bootstrap = import ../stdenv/freebsd/make-bootstrap-tools.nix {
pkgs = import ../.. {
localSystem = { inherit config; };
};
};
in {
inherit (bootstrap) build; # test does't exist yet
}
else
abort "No bootstrap implementation for system: ${config}"
);