Skip to content

Commit

Permalink
FreeBSD: Rework scope + building libc
Browse files Browse the repository at this point in the history
  • Loading branch information
rhelmot authored and Ericson2314 committed Apr 1, 2024
1 parent 036ac55 commit 6462532
Show file tree
Hide file tree
Showing 40 changed files with 613 additions and 325 deletions.
2 changes: 2 additions & 0 deletions lib/systems/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ let
&& final.parsed.kernel == platform.parsed.kernel;
isCompatible = _: throw "2022-05-23: isCompatible has been removed in favor of canExecute, refer to the 22.11 changelog for details";
# Derived meta-data
useLLVM = final.isFreeBSD;

libc =
/**/ if final.isDarwin then "libSystem"
else if final.isMinGW then "msvcrt"
Expand Down
142 changes: 69 additions & 73 deletions pkgs/os-specific/bsd/freebsd/default.nix
Original file line number Diff line number Diff line change
@@ -1,77 +1,73 @@
{ stdenv, lib, stdenvNoCC
, makeScopeWithSplicing', generateSplicesForMkScope
, buildPackages
, fetchgit, fetchzip
}:

{ stdenv, lib, config, newScope, buildPackages, pkgsHostHost, makeSetupHook, substituteAll, runtimeShell, ... }:
let
inherit (buildPackages.buildPackages) rsync;

versions = builtins.fromJSON (builtins.readFile ./versions.json);

version = "13.1.0";
branch = "release/${version}";

in makeScopeWithSplicing' {
otherSplices = generateSplicesForMkScope "freebsd";
f = (self: lib.packagesFromDirectoryRecursive {
in lib.makeScope newScope (self:
let
byName = lib.packagesFromDirectoryRecursive {
callPackage = self.callPackage;
directory = ./pkgs;
} // {
sourceData = versions.${branch};

ports = fetchzip {
url = "https://cgit.freebsd.org/ports/snapshot/ports-dde3b2b456c3a4bdd217d0bf3684231cc3724a0a.tar.gz";
sha256 = "BpHqJfnGOeTE7tkFJBx0Wk8ryalmf4KNTit/Coh026E=";
};

# Why do we have splicing and yet do `nativeBuildInputs = with self; ...`?
# See note in ../netbsd/default.nix.

compatIfNeeded = lib.optional (!stdenvNoCC.hostPlatform.isFreeBSD) self.compat;

freebsd-lib = import ./lib { inherit version; };

# Overridden arguments avoid cross package-set splicing issues,
# otherwise would just use implicit
# `lib.packagesFromDirectoryRecursive` auto-call.

compat = self.callPackage ./pkgs/compat/package.nix {
inherit stdenv;
inherit (buildPackages.freebsd) makeMinimal boot-install;
};

csu = self.callPackage ./pkgs/csu.nix {
inherit (buildPackages.freebsd) makeMinimal install gencat;
inherit (self) include;
};

include = self.callPackage ./pkgs/include/package.nix {
inherit (buildPackages.freebsd) makeMinimal install rpcgen;
};

install = self.callPackage ./pkgs/install.nix {
inherit (buildPackages.freebsd) makeMinimal;
inherit (self) mtree libnetbsd;
};

libc = self.callPackage ./pkgs/libc/package.nix {
inherit (buildPackages.freebsd) makeMinimal install gencat rpcgen;
inherit (self) csu include;
};

libnetbsd = self.callPackage ./pkgs/libnetbsd/package.nix {
inherit (buildPackages.freebsd) makeMinimal;
};

mkDerivation = self.callPackage ./pkgs/mkDerivation.nix {
inherit stdenv;
inherit (buildPackages.freebsd) makeMinimal install tsort;
};

makeMinimal = self.callPackage ./pkgs/makeMinimal.nix {
inherit (self) make;
};

});
}
};
mkTerminate = terminate: target: if terminate <= 0 then throw "Cannot recurse deeper than three levels into FreeBSD scopes" else target;
in byName // (with self; { inherit stdenv;
compatIsNeeded = !self.stdenv.hostPlatform.isFreeBSD;

# build a self which is parameterized with whatever the targeted version is
# so e.g. pkgsCross.x86_64-freebsd.freebsd.branches."releng/14.0".buildFreebsd will get you
# freebsd.branches."releng/14.0"
buildFreebsd = mkTerminate terminate buildPackages.freebsd.overrideScope (_: _: ({ inherit hostBranch; terminate = terminate - 1; } // lib.optionalAttrs (stdenv.hostPlatform == buildPackages.stdenv.hostPlatform && stdenv.targetPlatform == buildPackages.stdenv.targetPlatform) { inherit buildFreebsd; }));
branches = mkTerminate terminate lib.flip lib.mapAttrs versions (branch: _: self.overrideScope (_: _: { hostBranch = branch; terminate = terminate - 1; }));

packages13 = mkTerminate terminate self.overrideScope (_: _: { hostBranch = "release/13.2.0"; terminate = terminate - 1; });
packages14 = mkTerminate terminate self.overrideScope (_: _: { hostBranch = "release/14.0.0"; terminate = terminate - 1; });
packagesGit = mkTerminate terminate self.overrideScope (_: _: { hostBranch = "main"; terminate = terminate - 1; });
terminate = 3;

hostBranch = let
supportedBranches = builtins.attrNames (lib.filterAttrs (k: v: v.supported) versions);
fallbackBranch = let
branchRegex = "releng/.*";
candidateBranches = builtins.filter (name: builtins.match branchRegex name != null) supportedBranches;
in
lib.last (lib.naturalSort candidateBranches);
envBranch = builtins.getEnv "NIXPKGS_FREEBSD_BRANCH";
selectedBranch =
if config.freebsdBranch != null then
config.freebsdBranch
else if envBranch != "" then
envBranch
else null;
chosenBranch = if selectedBranch != null then selectedBranch else fallbackBranch;
in
if versions ? ${chosenBranch} then chosenBranch else throw ''
Unknown FreeBSD branch ${chosenBranch}!
FreeBSD branches normally look like one of:
* `release/<major>.<minor>.0` for tagged releases without security updates
* `releng/<major>.<minor>` for release update branches with security updates
* `stable/<major>` for stable versions working towards the next minor release
* `main` for the latest development version
Set one with the NIXPKGS_FREEBSD_BRANCH environment variable or by setting `nixpkgs.config.freebsdBranch`.
'';

sourceData = versions.${hostBranch};
versionData = sourceData.version;
hostVersion = versionData.revision;

hostArchBsd = {
x86_64 = "amd64";
aarch64 = "arm64";
i486 = "i386";
i586 = "i386";
i686 = "i386";
}.${self.stdenv.hostPlatform.parsed.cpu.name} or self.stdenv.hostPlatform.parsed.cpu.name;

patchesRoot = ./patches/${hostVersion};

compatIfNeeded = lib.optional compatIsNeeded compat;

# for cross-compiling or bootstrapping
install-wrapper = builtins.readFile ./install-wrapper.sh;
boot-install = buildPackages.writeShellScriptBin "boot-install" (install-wrapper + ''
${xinstallBootstrap}/bin/xinstall "''${args[@]}"
'');
}))
30 changes: 30 additions & 0 deletions pkgs/os-specific/bsd/freebsd/install-wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
set -eu

args=()
declare -i path_args=0

while (( $# )); do
if (( $# == 1 )); then
if (( path_args > 1)) || [[ "$1" = */ ]]; then
mkdir -p "$1"
else
mkdir -p "$(dirname "$1")"
fi
fi
case $1 in
-C) ;;
-o | -g) shift ;;
-s) ;;
-m | -l)
# handle next arg so not counted as path arg
args+=("$1" "$2")
shift
;;
-*) args+=("$1") ;;
*)
path_args+=1
args+=("$1")
;;
esac
shift
done
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- a/share/mk/src.libnames.mk 2023-12-21 23:56:50.767042385 -0800
+++ b/share/mk/src.libnames.mk 2023-12-21 23:56:39.671089506 -0800
@@ -392,7 +392,7 @@
_DP_ztest= geom m nvpair umem zpool pthread avl zfs_core spl zutil zfs uutil icp
# The libc dependencies are not strictly needed but are defined to make the
# assert happy.
-_DP_c= compiler_rt
+_DP_c=
# Use libssp_nonshared only on i386 and power*. Other archs emit direct calls
# to __stack_chk_fail, not __stack_chk_fail_local provided by libssp_nonshared.
.if ${MK_SSP} != "no" && \
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ diff --git a/tools/build/Makefile b/tools/build/Makefile
index 948a5f9dfdb..592af84eeae 100644
--- a/tools/build/Makefile
+++ b/tools/build/Makefile
@@ -327,15 +327,15 @@ host-symlinks:
@@ -327,14 +327,14 @@ host-symlinks:
# and cross-tools stages. We do this here using mkdir since mtree may not exist
# yet (this happens if we are crossbuilding from Linux/Mac).
INSTALLDIR_LIST= \
- bin \
- lib/casper \
- lib/geom \
- usr/include/casper \
- usr/include/private/ucl \
Expand All @@ -16,7 +15,6 @@ index 948a5f9dfdb..592af84eeae 100644
- usr/libdata/pkgconfig \
- usr/libexec
+ ${BINDIR} \
+ ${LIBDIR}/casper \
+ ${LIBDIR}/geom \
+ ${INCLUDEDIR}/casper \
+ ${INCLUDEDIR}/private/ucl \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- a/usr.bin/xinstall/Makefile 2023-09-23 19:18:49.165192183 -0700
+++ b/usr.bin/xinstall/Makefile 2023-12-06 17:06:57.836888028 -0700
@@ -14,7 +14,7 @@
CFLAGS+= -I${SRCTOP}/lib/libnetbsd

LIBADD= md
-CFLAGS+= -DWITH_MD5 -DWITH_RIPEMD160
+CFLAGS= -I${BSDSRCDIR}/contrib/libc-vis -I${BSDSRCDIR}/lib/libnetbsd

.ifdef BOOTSTRAPPING
# For the bootstrap we disable copy_file_range()
13 changes: 13 additions & 0 deletions pkgs/os-specific/bsd/freebsd/patches/14.0/mtree-Makefile.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--- a/contrib/mtree/Makefile 2023-12-04 23:02:13.919144141 -0700
+++ b/contrib/mtree/Makefile 2023-12-04 23:02:58.371810109 -0700
@@ -10,8 +10,8 @@
SRCS= compare.c crc.c create.c excludes.c misc.c mtree.c spec.c specspec.c \
verify.c getid.c pack_dev.c only.c
.if (${HOSTPROG:U} == "")
-DPADD+= ${LIBUTIL}
-LDADD+= -lutil
+LIBADD+= ${LIBUTIL}
+#LIBADD+= -lutil
.endif

CPPFLAGS+= -I${NETBSDSRCDIR}/sbin/mknod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--- a/libexec/rtld-elf/Makefile
+++ b/libexec/rtld-elf/Makefile
@@ -86,7 +86,6 @@

# Some of the required math functions (div & mod) are implemented in
# libcompiler_rt on some architectures.
-LIBADD+= compiler_rt

.include <bsd.prog.mk>
${PROG_FULL}: ${VERSION_MAP}
69 changes: 69 additions & 0 deletions pkgs/os-specific/bsd/freebsd/pkgs/bmakeMinimal.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{ lib, stdenv, mkDerivation, bsdSetupHook, freebsdSetupHook, patchesRoot, hostVersion }:
mkDerivation {
path = "contrib/bmake";
extraPaths = [ "share/mk" ]
++ lib.optional (!stdenv.hostPlatform.isFreeBSD) "tools/build/mk";

buildInputs = [];
nativeBuildInputs = [ bsdSetupHook freebsdSetupHook ];

skipIncludesPhase = true;

makeFlags = [];

patches = [
/${patchesRoot}/bmake-no-compiler-rt.patch
];

postPatch = ''
patchShebangs configure
# make needs this to pick up our sys make files
export NIX_CFLAGS_COMPILE+=" -D_PATH_DEFSYSPATH=\"$out/share/mk\""
'' + lib.optionalString stdenv.isDarwin ''
substituteInPlace $BSDSRCDIR/share/mk/bsd.sys.mk \
--replace '-Wl,--fatal-warnings' "" \
--replace '-Wl,--warn-shared-textrel' ""
'' + lib.optionalString (stdenv.targetPlatform.isFreeBSD && hostVersion != "13.2") ''
substituteInPlace $BSDSRCDIR/share/mk/local.sys.dirdeps.env.mk \
--replace 'MK_host_egacy= yes' 'MK_host_egacy= no'
'';

configureFlags = ["--with-filemon=no"];

buildPhase = ''
runHook preBuild
sh ./make-bootstrap.sh
runHook postBuild
'';

installPhase = ''
runHook preInstall
install -D bmake "$out/bin/bmake"
ln -s "$out/bin/bmake" "$out/bin/make"
mkdir -p "$out/share"
cp -r "$BSDSRCDIR/share/mk" "$out/share/mk"
find "$out/share/mk" -type f -print0 |
while IFS= read -r -d "" f; do
substituteInPlace "$f" --replace 'usr/' ""
done
substituteInPlace "$out/share/mk/bsd.symver.mk" \
--replace '/share/mk' "$out/share/mk"
runHook postInstall
'';

postInstall = lib.optionalString (!stdenv.targetPlatform.isFreeBSD) ''
boot_mk="$BSDSRCDIR/tools/build/mk"
cp "$boot_mk"/Makefile.boot* "$out/share/mk"
replaced_mk="$out/share/mk.orig"
mkdir "$replaced_mk"
mv "$out"/share/mk/bsd.{lib,prog}.mk "$replaced_mk"
for m in bsd.{lib,prog}.mk; do
cp "$boot_mk/$m" "$out/share/mk"
substituteInPlace "$out/share/mk/$m" --replace '../../../share/mk' '../mk.orig'
done
'';
}
Loading

0 comments on commit 6462532

Please sign in to comment.