mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
Merge pull request #12503 from roberth/overriding
Overriding the componentized build
This commit is contained in:
commit
e672243bed
3 changed files with 328 additions and 148 deletions
26
flake.nix
26
flake.nix
|
@ -155,6 +155,8 @@
|
|||
f = import ./packaging/components.nix {
|
||||
inherit (final) lib;
|
||||
inherit officialRelease;
|
||||
inherit stdenv;
|
||||
pkgs = final;
|
||||
src = self;
|
||||
};
|
||||
};
|
||||
|
@ -224,6 +226,30 @@
|
|||
LANG=C.UTF-8 ${pkgs.changelog-d}/bin/changelog-d ${./doc/manual/rl-next} >$out
|
||||
'';
|
||||
repl-completion = nixpkgsFor.${system}.native.callPackage ./tests/repl-completion.nix { };
|
||||
|
||||
/**
|
||||
Checks for our packaging expressions.
|
||||
This shouldn't build anything significant; just check that things
|
||||
(including derivations) are _set up_ correctly.
|
||||
*/
|
||||
packaging-overriding =
|
||||
let
|
||||
pkgs = nixpkgsFor.${system}.native;
|
||||
nix = self.packages.${system}.nix;
|
||||
in
|
||||
assert (nix.appendPatches [ pkgs.emptyFile ]).libs.nix-util.src.patches == [ pkgs.emptyFile ];
|
||||
if pkgs.stdenv.buildPlatform.isDarwin then
|
||||
lib.warn "packaging-overriding check currently disabled because of a permissions issue on macOS" pkgs.emptyFile
|
||||
else
|
||||
# If this fails, something might be wrong with how we've wired the scope,
|
||||
# or something could be broken in Nixpkgs.
|
||||
pkgs.testers.testEqualContents {
|
||||
assertion = "trivial patch does not change source contents";
|
||||
expected = "${./.}";
|
||||
actual =
|
||||
# Same for all components; nix-util is an arbitrary pick
|
||||
(nix.appendPatches [ pkgs.emptyFile ]).libs.nix-util.src;
|
||||
};
|
||||
}
|
||||
// (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
|
||||
dockerImage = self.hydraJobs.dockerImage.${system};
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
src,
|
||||
stdenv,
|
||||
officialRelease,
|
||||
}:
|
||||
|
||||
scope:
|
||||
|
||||
let
|
||||
inherit (scope) callPackage;
|
||||
inherit (scope)
|
||||
callPackage
|
||||
;
|
||||
inherit (pkgs.buildPackages)
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
;
|
||||
|
||||
baseVersion = lib.fileContents ../.version;
|
||||
|
||||
|
@ -20,6 +29,165 @@ let
|
|||
}_${src.shortRev or "dirty"}";
|
||||
|
||||
fineVersion = baseVersion + fineVersionSuffix;
|
||||
|
||||
root = ../.;
|
||||
|
||||
# Indirection for Nixpkgs to override when package.nix files are vendored
|
||||
filesetToSource = lib.fileset.toSource;
|
||||
|
||||
/**
|
||||
Given a set of layers, create a mkDerivation-like function
|
||||
*/
|
||||
mkPackageBuilder =
|
||||
exts: userFn: stdenv.mkDerivation (lib.extends (lib.composeManyExtensions exts) userFn);
|
||||
|
||||
setVersionLayer = finalAttrs: prevAttrs: {
|
||||
preConfigure =
|
||||
prevAttrs.prevAttrs or ""
|
||||
+
|
||||
# Update the repo-global .version file.
|
||||
# Symlink ./.version points there, but by default only workDir is writable.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
};
|
||||
|
||||
localSourceLayer =
|
||||
finalAttrs: prevAttrs:
|
||||
let
|
||||
workDirPath =
|
||||
# Ideally we'd pick finalAttrs.workDir, but for now `mkDerivation` has
|
||||
# the requirement that everything except passthru and meta must be
|
||||
# serialized by mkDerivation, which doesn't work for this.
|
||||
prevAttrs.workDir;
|
||||
|
||||
workDirSubpath = lib.path.removePrefix root workDirPath;
|
||||
sources =
|
||||
assert prevAttrs.fileset._type == "fileset";
|
||||
prevAttrs.fileset;
|
||||
src = lib.fileset.toSource {
|
||||
fileset = sources;
|
||||
inherit root;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
sourceRoot = "${src.name}/" + workDirSubpath;
|
||||
inherit src;
|
||||
|
||||
# Clear what `derivation` can't/shouldn't serialize; see prevAttrs.workDir.
|
||||
fileset = null;
|
||||
workDir = null;
|
||||
};
|
||||
|
||||
resolveRelPath = p: lib.path.removePrefix root p;
|
||||
|
||||
makeFetchedSourceLayer =
|
||||
finalScope: finalAttrs: prevAttrs:
|
||||
let
|
||||
workDirPath =
|
||||
# Ideally we'd pick finalAttrs.workDir, but for now `mkDerivation` has
|
||||
# the requirement that everything except passthru and meta must be
|
||||
# serialized by mkDerivation, which doesn't work for this.
|
||||
prevAttrs.workDir;
|
||||
|
||||
workDirSubpath = resolveRelPath workDirPath;
|
||||
|
||||
in
|
||||
{
|
||||
sourceRoot = "${finalScope.patchedSrc.name}/" + workDirSubpath;
|
||||
src = finalScope.patchedSrc;
|
||||
version =
|
||||
let
|
||||
n = lib.length finalScope.patches;
|
||||
in
|
||||
if n == 0 then finalAttrs.version else finalAttrs.version + "+${toString n}";
|
||||
|
||||
# Clear what `derivation` can't/shouldn't serialize; see prevAttrs.workDir.
|
||||
fileset = null;
|
||||
workDir = null;
|
||||
};
|
||||
|
||||
mesonLayer = finalAttrs: prevAttrs: {
|
||||
# NOTE:
|
||||
# As of https://github.com/NixOS/nixpkgs/blob/8baf8241cea0c7b30e0b8ae73474cb3de83c1a30/pkgs/by-name/me/meson/setup-hook.sh#L26,
|
||||
# `mesonBuildType` defaults to `plain` if not specified. We want our Nix-built binaries to be optimized by default.
|
||||
# More on build types here: https://mesonbuild.com/Builtin-options.html#details-for-buildtype.
|
||||
mesonBuildType = "release";
|
||||
# NOTE:
|
||||
# Users who are debugging Nix builds are expected to set the environment variable `mesonBuildType`, per the
|
||||
# guidance in https://github.com/NixOS/nix/blob/8a3fc27f1b63a08ac983ee46435a56cf49ebaf4a/doc/manual/source/development/debugging.md?plain=1#L10.
|
||||
# For this reason, we don't want to refer to `finalAttrs.mesonBuildType` here, but rather use the environment variable.
|
||||
preConfigure =
|
||||
prevAttrs.preConfigure or ""
|
||||
+
|
||||
lib.optionalString
|
||||
(
|
||||
!stdenv.hostPlatform.isWindows
|
||||
# build failure
|
||||
&& !stdenv.hostPlatform.isStatic
|
||||
# LTO breaks exception handling on x86-64-darwin.
|
||||
&& stdenv.system != "x86_64-darwin"
|
||||
)
|
||||
''
|
||||
case "$mesonBuildType" in
|
||||
release|minsize) appendToVar mesonFlags "-Db_lto=true" ;;
|
||||
*) appendToVar mesonFlags "-Db_lto=false" ;;
|
||||
esac
|
||||
'';
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
] ++ prevAttrs.nativeBuildInputs or [ ];
|
||||
mesonCheckFlags = prevAttrs.mesonCheckFlags or [ ] ++ [
|
||||
"--print-errorlogs"
|
||||
];
|
||||
};
|
||||
|
||||
mesonBuildLayer = finalAttrs: prevAttrs: {
|
||||
nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [
|
||||
pkg-config
|
||||
];
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
env =
|
||||
prevAttrs.env or { }
|
||||
// lib.optionalAttrs (
|
||||
stdenv.isLinux
|
||||
&& !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")
|
||||
&& !(stdenv.hostPlatform.useLLVM or false)
|
||||
) { LDFLAGS = "-fuse-ld=gold"; };
|
||||
};
|
||||
|
||||
mesonLibraryLayer = finalAttrs: prevAttrs: {
|
||||
outputs = prevAttrs.outputs or [ "out" ] ++ [ "dev" ];
|
||||
};
|
||||
|
||||
# Work around weird `--as-needed` linker behavior with BSD, see
|
||||
# https://github.com/mesonbuild/meson/issues/3593
|
||||
bsdNoLinkAsNeeded =
|
||||
finalAttrs: prevAttrs:
|
||||
lib.optionalAttrs stdenv.hostPlatform.isBSD {
|
||||
mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or [ ];
|
||||
};
|
||||
|
||||
miscGoodPractice = finalAttrs: prevAttrs: {
|
||||
strictDeps = prevAttrs.strictDeps or true;
|
||||
enableParallelBuilding = true;
|
||||
};
|
||||
|
||||
/**
|
||||
Append patches to the source layer.
|
||||
*/
|
||||
appendPatches =
|
||||
scope: patches:
|
||||
scope.overrideScope (
|
||||
finalScope: prevScope: {
|
||||
patches = prevScope.patches ++ patches;
|
||||
}
|
||||
);
|
||||
|
||||
in
|
||||
|
||||
# This becomes the pkgs.nixComponents attribute set
|
||||
|
@ -27,6 +195,110 @@ in
|
|||
version = baseVersion + versionSuffix;
|
||||
inherit versionSuffix;
|
||||
|
||||
inherit filesetToSource;
|
||||
|
||||
/**
|
||||
A user-provided extension function to apply to each component derivation.
|
||||
*/
|
||||
mesonComponentOverrides = finalAttrs: prevAttrs: { };
|
||||
|
||||
/**
|
||||
An overridable derivation layer for handling the sources.
|
||||
*/
|
||||
sourceLayer = localSourceLayer;
|
||||
|
||||
/**
|
||||
Resolve a path value to either itself or a path in the `src`, depending
|
||||
whether `overrideSource` was called.
|
||||
*/
|
||||
resolvePath = p: p;
|
||||
|
||||
/**
|
||||
Apply an extension function (i.e. overlay-shaped) to all component derivations.
|
||||
*/
|
||||
overrideAllMesonComponents =
|
||||
f:
|
||||
scope.overrideScope (
|
||||
finalScope: prevScope: {
|
||||
mesonComponentOverrides = lib.composeExtensions scope.mesonComponentOverrides f;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
Provide an alternate source. This allows the expressions to be vendored without copying the sources,
|
||||
but it does make the build non-granular; all components will use a complete source.
|
||||
|
||||
Packaging expressions will be ignored.
|
||||
*/
|
||||
overrideSource =
|
||||
src:
|
||||
scope.overrideScope (
|
||||
finalScope: prevScope: {
|
||||
sourceLayer = makeFetchedSourceLayer finalScope;
|
||||
/**
|
||||
Unpatched source for the build of Nix. Packaging expressions will be ignored.
|
||||
*/
|
||||
src = src;
|
||||
/**
|
||||
Patches for the whole Nix source. Changes to packaging expressions will be ignored.
|
||||
*/
|
||||
patches = [ ];
|
||||
/**
|
||||
Fetched and patched source to be used in component derivations.
|
||||
*/
|
||||
patchedSrc =
|
||||
if finalScope.patches == [ ] then
|
||||
src
|
||||
else
|
||||
pkgs.buildPackages.srcOnly (
|
||||
pkgs.buildPackages.stdenvNoCC.mkDerivation {
|
||||
name = "${finalScope.src.name or "nix-source"}-patched";
|
||||
inherit (finalScope) src patches;
|
||||
}
|
||||
);
|
||||
resolvePath = p: finalScope.patchedSrc + "/${resolveRelPath p}";
|
||||
appendPatches = appendPatches finalScope;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
Append patches to be applied to the whole Nix source.
|
||||
This affects all components.
|
||||
|
||||
Changes to the packaging expressions will be ignored.
|
||||
*/
|
||||
appendPatches =
|
||||
patches:
|
||||
# switch to "fetched" source first, so that patches apply to the whole tree.
|
||||
(scope.overrideSource "${./..}").appendPatches patches;
|
||||
|
||||
mkMesonDerivation = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
scope.sourceLayer
|
||||
setVersionLayer
|
||||
mesonLayer
|
||||
scope.mesonComponentOverrides
|
||||
];
|
||||
mkMesonExecutable = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
scope.sourceLayer
|
||||
setVersionLayer
|
||||
mesonLayer
|
||||
mesonBuildLayer
|
||||
scope.mesonComponentOverrides
|
||||
];
|
||||
mkMesonLibrary = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
scope.sourceLayer
|
||||
mesonLayer
|
||||
setVersionLayer
|
||||
mesonBuildLayer
|
||||
mesonLibraryLayer
|
||||
scope.mesonComponentOverrides
|
||||
];
|
||||
|
||||
nix-util = callPackage ../src/libutil/package.nix { };
|
||||
nix-util-c = callPackage ../src/libutil-c/package.nix { };
|
||||
nix-util-test-support = callPackage ../src/libutil-test-support/package.nix { };
|
||||
|
@ -66,5 +338,33 @@ in
|
|||
|
||||
nix-perl-bindings = callPackage ../src/perl/package.nix { };
|
||||
|
||||
nix-everything = callPackage ../packaging/everything.nix { };
|
||||
nix-everything = callPackage ../packaging/everything.nix { } // {
|
||||
# Note: no `passthru.overrideAllMesonComponents`
|
||||
# This would propagate into `nix.overrideAttrs f`, but then discard
|
||||
# `f` when `.overrideAllMesonComponents` is used.
|
||||
# Both "methods" should be views on the same fixpoint overriding mechanism
|
||||
# for that to work. For now, we intentionally don't support the broken
|
||||
# two-fixpoint solution.
|
||||
/**
|
||||
Apply an extension function (i.e. overlay-shaped) to all component derivations, and return the nix package.
|
||||
*/
|
||||
overrideAllMesonComponents = f: (scope.overrideAllMesonComponents f).nix-everything;
|
||||
|
||||
/**
|
||||
Append patches to be applied to the whole Nix source.
|
||||
This affects all components.
|
||||
|
||||
Changes to the packaging expressions will be ignored.
|
||||
*/
|
||||
appendPatches = ps: (scope.appendPatches ps).nix-everything;
|
||||
|
||||
/**
|
||||
Provide an alternate source. This allows the expressions to be vendored without copying the sources,
|
||||
but it does make the build non-granular; all components will use a complete source.
|
||||
|
||||
Packaging expressions will be ignored.
|
||||
*/
|
||||
overrideSource = src: (scope.overrideSource src).nix-everything;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@ in
|
|||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
root = ../.;
|
||||
|
||||
stdenv = if prevStdenv.isDarwin && prevStdenv.isx86_64 then darwinStdenv else prevStdenv;
|
||||
|
||||
# Fix the following error with the default x86_64-darwin SDK:
|
||||
|
@ -30,125 +28,6 @@ let
|
|||
# all the way back to 10.6.
|
||||
darwinStdenv = pkgs.overrideSDK prevStdenv { darwinMinVersion = "10.13"; };
|
||||
|
||||
# Nixpkgs implements this by returning a subpath into the fetched Nix sources.
|
||||
resolvePath = p: p;
|
||||
|
||||
# Indirection for Nixpkgs to override when package.nix files are vendored
|
||||
filesetToSource = lib.fileset.toSource;
|
||||
|
||||
/**
|
||||
Given a set of layers, create a mkDerivation-like function
|
||||
*/
|
||||
mkPackageBuilder =
|
||||
exts: userFn: stdenv.mkDerivation (lib.extends (lib.composeManyExtensions exts) userFn);
|
||||
|
||||
setVersionLayer = finalAttrs: prevAttrs: {
|
||||
preConfigure =
|
||||
prevAttrs.prevAttrs or ""
|
||||
+
|
||||
# Update the repo-global .version file.
|
||||
# Symlink ./.version points there, but by default only workDir is writable.
|
||||
''
|
||||
chmod u+w ./.version
|
||||
echo ${finalAttrs.version} > ./.version
|
||||
'';
|
||||
};
|
||||
|
||||
localSourceLayer =
|
||||
finalAttrs: prevAttrs:
|
||||
let
|
||||
workDirPath =
|
||||
# Ideally we'd pick finalAttrs.workDir, but for now `mkDerivation` has
|
||||
# the requirement that everything except passthru and meta must be
|
||||
# serialized by mkDerivation, which doesn't work for this.
|
||||
prevAttrs.workDir;
|
||||
|
||||
workDirSubpath = lib.path.removePrefix root workDirPath;
|
||||
sources =
|
||||
assert prevAttrs.fileset._type == "fileset";
|
||||
prevAttrs.fileset;
|
||||
src = lib.fileset.toSource {
|
||||
fileset = sources;
|
||||
inherit root;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
sourceRoot = "${src.name}/" + workDirSubpath;
|
||||
inherit src;
|
||||
|
||||
# Clear what `derivation` can't/shouldn't serialize; see prevAttrs.workDir.
|
||||
fileset = null;
|
||||
workDir = null;
|
||||
};
|
||||
|
||||
mesonLayer = finalAttrs: prevAttrs: {
|
||||
# NOTE:
|
||||
# As of https://github.com/NixOS/nixpkgs/blob/8baf8241cea0c7b30e0b8ae73474cb3de83c1a30/pkgs/by-name/me/meson/setup-hook.sh#L26,
|
||||
# `mesonBuildType` defaults to `plain` if not specified. We want our Nix-built binaries to be optimized by default.
|
||||
# More on build types here: https://mesonbuild.com/Builtin-options.html#details-for-buildtype.
|
||||
mesonBuildType = "release";
|
||||
# NOTE:
|
||||
# Users who are debugging Nix builds are expected to set the environment variable `mesonBuildType`, per the
|
||||
# guidance in https://github.com/NixOS/nix/blob/8a3fc27f1b63a08ac983ee46435a56cf49ebaf4a/doc/manual/source/development/debugging.md?plain=1#L10.
|
||||
# For this reason, we don't want to refer to `finalAttrs.mesonBuildType` here, but rather use the environment variable.
|
||||
preConfigure =
|
||||
prevAttrs.preConfigure or ""
|
||||
+
|
||||
lib.optionalString
|
||||
(
|
||||
!stdenv.hostPlatform.isWindows
|
||||
# build failure
|
||||
&& !stdenv.hostPlatform.isStatic
|
||||
# LTO breaks exception handling on x86-64-darwin.
|
||||
&& stdenv.system != "x86_64-darwin"
|
||||
)
|
||||
''
|
||||
case "$mesonBuildType" in
|
||||
release|minsize) appendToVar mesonFlags "-Db_lto=true" ;;
|
||||
*) appendToVar mesonFlags "-Db_lto=false" ;;
|
||||
esac
|
||||
'';
|
||||
nativeBuildInputs = [
|
||||
pkgs.buildPackages.meson
|
||||
pkgs.buildPackages.ninja
|
||||
] ++ prevAttrs.nativeBuildInputs or [ ];
|
||||
mesonCheckFlags = prevAttrs.mesonCheckFlags or [ ] ++ [
|
||||
"--print-errorlogs"
|
||||
];
|
||||
};
|
||||
|
||||
mesonBuildLayer = finalAttrs: prevAttrs: {
|
||||
nativeBuildInputs = prevAttrs.nativeBuildInputs or [ ] ++ [
|
||||
pkgs.buildPackages.pkg-config
|
||||
];
|
||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||
env =
|
||||
prevAttrs.env or { }
|
||||
// lib.optionalAttrs (
|
||||
stdenv.isLinux
|
||||
&& !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")
|
||||
&& !(stdenv.hostPlatform.useLLVM or false)
|
||||
) { LDFLAGS = "-fuse-ld=gold"; };
|
||||
};
|
||||
|
||||
mesonLibraryLayer = finalAttrs: prevAttrs: {
|
||||
outputs = prevAttrs.outputs or [ "out" ] ++ [ "dev" ];
|
||||
};
|
||||
|
||||
# Work around weird `--as-needed` linker behavior with BSD, see
|
||||
# https://github.com/mesonbuild/meson/issues/3593
|
||||
bsdNoLinkAsNeeded =
|
||||
finalAttrs: prevAttrs:
|
||||
lib.optionalAttrs stdenv.hostPlatform.isBSD {
|
||||
mesonFlags = [ (lib.mesonBool "b_asneeded" false) ] ++ prevAttrs.mesonFlags or [ ];
|
||||
};
|
||||
|
||||
miscGoodPractice = finalAttrs: prevAttrs: {
|
||||
strictDeps = prevAttrs.strictDeps or true;
|
||||
enableParallelBuilding = true;
|
||||
};
|
||||
in
|
||||
scope:
|
||||
{
|
||||
|
@ -187,31 +66,6 @@ scope:
|
|||
installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase;
|
||||
});
|
||||
|
||||
inherit resolvePath filesetToSource;
|
||||
|
||||
mkMesonDerivation = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
localSourceLayer
|
||||
setVersionLayer
|
||||
mesonLayer
|
||||
];
|
||||
mkMesonExecutable = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
localSourceLayer
|
||||
setVersionLayer
|
||||
mesonLayer
|
||||
mesonBuildLayer
|
||||
];
|
||||
mkMesonLibrary = mkPackageBuilder [
|
||||
miscGoodPractice
|
||||
bsdNoLinkAsNeeded
|
||||
localSourceLayer
|
||||
mesonLayer
|
||||
setVersionLayer
|
||||
mesonBuildLayer
|
||||
mesonLibraryLayer
|
||||
];
|
||||
}
|
||||
# libgit2: Nixpkgs 24.11 has < 1.9.0
|
||||
// lib.optionalAttrs (!lib.versionAtLeast pkgs.libgit2.version "1.9.0") {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue