dotnet: combine binary and source expressions

This commit is contained in:
David McFarland
2026-03-28 20:38:35 -03:00
parent 8e2546f16c
commit 928e583edf
30 changed files with 316 additions and 264 deletions
@@ -1,11 +0,0 @@
{
callPackage,
dotnetCorePackages,
}:
callPackage ../dotnet.nix {
releaseManifestFile = ./release.json;
releaseInfoFile = ./release-info.json;
bootstrapSdk = dotnetCorePackages.dotnet_10.sdk;
depsFile = ./deps.json;
fallbackTargetPackages = dotnetCorePackages.sdk_10_0_2xx-bin.targetPackages;
}
@@ -1,11 +0,0 @@
{
callPackage,
dotnetCorePackages,
}:
callPackage ../dotnet.nix {
releaseManifestFile = ./release.json;
releaseInfoFile = ./release-info.json;
bootstrapSdkFile = ./bootstrap-sdk.nix;
depsFile = ./deps.json;
fallbackTargetPackages = dotnetCorePackages.sdk_10_0-bin.targetPackages;
}
@@ -1,12 +0,0 @@
{
callPackage,
dotnetCorePackages,
}:
callPackage ../dotnet.nix {
releaseManifestFile = ./release.json;
releaseInfoFile = ./release-info.json;
bootstrapSdkFile = ./bootstrap-sdk.nix;
depsFile = ./deps.json;
fallbackTargetPackages = dotnetCorePackages.sdk_11_0-bin.targetPackages;
allowPrerelease = true;
}
@@ -1,11 +0,0 @@
{
callPackage,
dotnetCorePackages,
}:
callPackage ../dotnet.nix {
releaseManifestFile = ./release.json;
releaseInfoFile = ./release-info.json;
bootstrapSdkFile = ./bootstrap-sdk.nix;
depsFile = ./deps.json;
fallbackTargetPackages = dotnetCorePackages.sdk_8_0-bin.targetPackages;
}
@@ -1,11 +0,0 @@
{
callPackage,
dotnetCorePackages,
}:
callPackage ../dotnet.nix {
releaseManifestFile = ./release.json;
releaseInfoFile = ./release-info.json;
bootstrapSdkFile = ./bootstrap-sdk.nix;
depsFile = ./deps.json;
fallbackTargetPackages = dotnetCorePackages.sdk_9_0-bin.targetPackages;
}
@@ -63,12 +63,12 @@ let
sdk = ".NET SDK ${version}";
};
mkWrapper = callPackage ./wrapper.nix { };
mkWrapper = callPackage ../wrapper.nix { };
hostRid = systemToDotnetRid stdenv.hostPlatform.system;
targetRid = systemToDotnetRid stdenv.targetPlatform.system;
sigtool = callPackage ./sigtool.nix { };
sigtool = callPackage ../sigtool.nix { };
signAppHost = callPackage ./sign-apphost.nix { };
hasILCompiler = lib.versionAtLeast version (if hostRid == "osx-arm64" then "8" else "7");
@@ -3,7 +3,7 @@
callPackage,
}:
let
sigtool = callPackage ./sigtool.nix { };
sigtool = callPackage ../sigtool.nix { };
in
replaceVars ./sign-apphost.proj {
+58 -128
View File
@@ -14,7 +14,7 @@
}:
let
pkgs = makeScopeWithSplicing' {
scope = makeScopeWithSplicing' {
otherSplices = generateSplicesForMkScope "dotnetCorePackages";
f = (
self:
@@ -23,8 +23,10 @@ let
fetchNupkg = callPackage ../../../build-support/dotnet/fetch-nupkg { };
buildDotnet = attrs: callPackage (import ./build-dotnet.nix attrs) { };
buildDotnetSdk =
let
buildDotnet = attrs: callPackage (import ./binary/build-dotnet.nix attrs) { };
in
version:
import version {
inherit fetchNupkg;
@@ -33,17 +35,6 @@ let
buildNetSdk = attrs: buildDotnet (attrs // { type = "sdk"; });
};
dotnet-bin = lib.mergeAttrsList (
map buildDotnetSdk [
./6.0/releases.nix
./7.0/releases.nix
./8.0/releases.nix
./9.0/releases.nix
./10.0/releases.nix
./11.0/releases.nix
]
);
runtimeIdentifierMap = {
"x86_64-linux" = "linux-x64";
"aarch64-linux" = "linux-arm64";
@@ -54,24 +45,16 @@ let
};
in
lib.optionalAttrs config.allowAliases (
{
# EOL
sdk_2_1 = throw "Dotnet SDK 2.1 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_2_2 = throw "Dotnet SDK 2.2 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_3_0 = throw "Dotnet SDK 3.0 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_3_1 = throw "Dotnet SDK 3.1 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_5_0 = throw "Dotnet SDK 5.0 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
}
// dotnet-bin
)
// lib.mapAttrs' (k: v: lib.nameValuePair "${k}-bin" v) dotnet-bin
// {
inherit callPackage fetchNupkg buildDotnetSdk;
{
inherit
callPackage
fetchNupkg
buildDotnetSdk
;
generate-dotnet-sdk = writeScriptBin "generate-dotnet-sdk" (
# Don't include current nixpkgs in the exposed version. We want to make the script runnable without nixpkgs repo.
builtins.replaceStrings [ " -I nixpkgs=./." ] [ "" ] (builtins.readFile ./update.sh)
builtins.replaceStrings [ " -I nixpkgs=./." ] [ "" ] (builtins.readFile ./binary/update.sh)
);
# Convert a "stdenv.hostPlatform.system" to a dotnet RID
@@ -90,112 +73,59 @@ let
mkNugetSource = callPackage ../../../build-support/dotnet/make-nuget-source { };
mkNugetDeps = callPackage ../../../build-support/dotnet/make-nuget-deps { };
addNuGetDeps = callPackage ../../../build-support/dotnet/add-nuget-deps { };
dotnet_8 = lib.recurseIntoAttrs (callPackage ./8.0 { });
dotnet_9 = lib.recurseIntoAttrs (callPackage ./9.0 { });
dotnet_10 = lib.recurseIntoAttrs (callPackage ./10.0 { });
dotnet_10_0_2xx = lib.recurseIntoAttrs (callPackage ./10.0.2xx { });
dotnet_11 = lib.recurseIntoAttrs (callPackage ./11.0 { });
}
);
};
# combine an SDK with the runtime/packages from a base SDK
combineSdk =
base: fallback:
if (fallback.runtime.version != base.runtime.version) then
throw "combineSdk: unable to combine ${fallback.name} with ${base.name} because runtime versions don't match (${fallback.runtime.version} != ${base.runtime.version})"
else if base.meta.broken then
fallback
else
callPackage = scope.callPackage;
pkgs =
scope
// (
let
withBaseRuntimes =
if fallback.version == base.version then
base.unwrapped
else
(pkgs.combinePackages [
base.runtime
base.aspnetcore
fallback
]).unwrapped.overrideAttrs
(old: {
name = fallback.unwrapped.name;
# resolve symlinks so DOTNET_ROOT is self-contained
postBuild = ''
mv "$out"/share/dotnet{,~}
cp -Lr "$out"/share/dotnet{~,}
rm -r "$out"/share/dotnet~
''
+ old.postBuild;
passthru = old.passthru // {
inherit (base)
runtime
aspnetcore
;
inherit (fallback.unwrapped)
pname
version
;
};
});
dotnet_6 = callPackage ./dotnet.nix {
dir = ./6.0;
withVMR = false;
};
withFallbackPackages = withBaseRuntimes.overrideAttrs (old: {
passthru =
old.passthru
// (
let
hostRid = pkgs.systemToDotnetRid base.stdenv.hostPlatform.system;
hasILCompiler = base.hasILCompiler || fallback.hasILCompiler;
packageName = "runtime.${hostRid}.Microsoft.DotNet.ILCompiler";
mergePackages =
a: b:
let
names = lib.genAttrs' a (p: lib.nameValuePair p.pname null);
in
a ++ lib.filter (p: !lib.hasAttr p.pname names) b;
packages = mergePackages base.packages fallback.packages;
targetPackages = lib.mapAttrs (
name: value: mergePackages value fallback.targetPackages.${name}
) base.targetPackages;
in
{
inherit hasILCompiler packages targetPackages;
}
);
});
dotnet_7 = callPackage ./dotnet.nix {
dir = ./7.0;
withVMR = false;
};
dotnet_8 = callPackage ./dotnet.nix {
dir = ./8.0;
};
dotnet_9 = callPackage ./dotnet.nix {
dir = ./9.0;
};
dotnet_10 = callPackage ./dotnet.nix {
dir = ./10.0;
};
dotnet_11 = callPackage ./dotnet.nix {
dir = ./11.0;
allowPrerelease = true;
};
in
pkgs.callPackage ./wrapper.nix { } "sdk" withFallbackPackages;
lib.optionalAttrs config.allowAliases {
# EOL
sdk_2_1 = throw "Dotnet SDK 2.1 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_2_2 = throw "Dotnet SDK 2.2 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_3_0 = throw "Dotnet SDK 3.0 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_3_1 = throw "Dotnet SDK 3.1 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
sdk_5_0 = throw "Dotnet SDK 5.0 is EOL, please use 8.0 (LTS) or 9.0 (Current)";
}
// lib.mergeAttrsList [
dotnet_6
dotnet_7
dotnet_8
dotnet_9
dotnet_10
dotnet_11
]
);
in
pkgs
// rec {
# use binary SDK here to avoid downgrading feature band
# combining sdk_8 results in a broken ilcompiler
sdk_8_0_1xx = if !pkgs.dotnet_8.vmr.meta.broken then pkgs.dotnet_8.sdk else pkgs.sdk_8_0_1xx-bin;
sdk_9_0_1xx = combineSdk pkgs.dotnet_9.sdk pkgs.sdk_9_0_1xx-bin;
sdk_10_0_1xx = combineSdk pkgs.dotnet_10.sdk pkgs.sdk_10_0_1xx-bin;
sdk_10_0_2xx = combineSdk pkgs.dotnet_10_0_2xx.sdk pkgs.sdk_10_0_2xx-bin;
sdk_11_0_1xx = combineSdk pkgs.dotnet_11.sdk pkgs.sdk_11_0_1xx-bin;
# source-built SDK only exists for _1xx feature band
# https://github.com/dotnet/source-build/issues/3667
sdk_8_0_4xx = combineSdk sdk_8_0_1xx pkgs.sdk_8_0_4xx-bin;
sdk_9_0_3xx = combineSdk sdk_9_0_1xx pkgs.sdk_9_0_3xx-bin;
sdk_8_0 = sdk_8_0_4xx;
sdk_9_0 = sdk_9_0_3xx;
sdk_10_0 = sdk_10_0_2xx;
sdk_11_0 = sdk_11_0_1xx;
sdk_8_0-source = if !pkgs.dotnet_8.vmr.meta.broken then pkgs.dotnet_8.sdk else pkgs.sdk_8_0_1xx-bin;
sdk_9_0-source = if !pkgs.dotnet_9.vmr.meta.broken then pkgs.dotnet_9.sdk else pkgs.sdk_9_0_1xx-bin;
sdk_10_0-source =
if !pkgs.dotnet_10.vmr.meta.broken then pkgs.dotnet_10_0_2xx.sdk else pkgs.sdk_10_0_2xx-bin;
sdk_11_0-source =
if !pkgs.dotnet_11.vmr.meta.broken then pkgs.dotnet_11.sdk else pkgs.sdk_11_0_1xx-bin;
runtime_8_0 = sdk_8_0.runtime;
runtime_9_0 = sdk_9_0.runtime;
runtime_10_0 = sdk_10_0.runtime;
runtime_11_0 = sdk_11_0.runtime;
aspnetcore_8_0 = sdk_8_0.aspnetcore;
aspnetcore_9_0 = sdk_9_0.aspnetcore;
aspnetcore_10_0 = sdk_10_0.aspnetcore;
aspnetcore_11_0 = sdk_11_0.aspnetcore;
}
+12 -75
View File
@@ -1,85 +1,22 @@
{
stdenvNoCC,
config,
callPackage,
lib,
fetchurl,
releaseManifestFile,
releaseInfoFile,
bootstrapSdkFile ? null,
bootstrapSdk ? null,
allowPrerelease ? false,
depsFile,
fallbackTargetPackages,
pkgsBuildHost,
dir ? null,
releasesFile ? dir + "/releases.nix",
buildDotnetSdk,
}:
assert bootstrapSdkFile != null || bootstrapSdk != null;
withVMR ? true,
...
}@attrs:
let
inherit (lib.importJSON releaseInfoFile)
tarballHash
artifactsUrl
artifactsHash
;
binary = buildDotnetSdk releasesFile;
mkPackages = callPackage ./packages.nix;
vmr =
if bootstrapSdk != null then
callPackage ./vmr.nix {
inherit
releaseManifestFile
tarballHash
;
bootstrapSdk = bootstrapSdk.unwrapped;
hasRuntime = false;
}
else
callPackage ./stage1.nix {
inherit
releaseManifestFile
tarballHash
depsFile
;
bootstrapSdk = (buildDotnetSdk bootstrapSdkFile).sdk.unwrapped.overrideAttrs (old: {
passthru = old.passthru or { } // {
artifacts = stdenvNoCC.mkDerivation {
name = lib.nameFromURL artifactsUrl ".tar.gz";
src = fetchurl {
url = artifactsUrl;
hash = artifactsHash;
};
sourceRoot = ".";
installPhase = ''
mkdir -p $out
cp -r * $out/
'';
};
};
});
};
pkgs = mkPackages {
inherit vmr fallbackTargetPackages;
};
sourcePackages = lib.optionalAttrs withVMR (callPackage ./source (attrs // { inherit binary; }));
pkgs =
lib.optionalAttrs config.allowAliases binary
// lib.mapAttrs' (k: v: lib.nameValuePair "${k}-bin" v) binary
// sourcePackages;
in
pkgs
// {
vmr = pkgs.vmr.overrideAttrs (old: {
passthru = old.passthru // {
updateScript = pkgsBuildHost.callPackage ./update.nix {
inherit
releaseManifestFile
releaseInfoFile
bootstrapSdkFile
allowPrerelease
;
};
};
});
}
@@ -0,0 +1,241 @@
{
config,
stdenvNoCC,
callPackage,
lib,
fetchurl,
dir ? null,
releaseManifestFile ? dir + "/release.json",
releaseInfoFile ? dir + "/release-info.json",
bootstrapSdkFile ? dir + "/bootstrap-sdk.nix",
bootstrapSdk ? null,
allowPrerelease ? false,
depsFile ? dir + "/deps.json",
pkgsBuildHost,
buildDotnetSdk,
withBinary ? true,
combinePackages,
systemToDotnetRid,
binary,
}@attrs:
assert bootstrapSdk != null || bootstrapSdkFile != null;
let
inherit (lib.importJSON releaseManifestFile)
sdkVersion
;
suffix =
let
parts = lib.take 3 (lib.splitVersion sdkVersion);
patch = lib.elemAt parts 2;
band = lib.substring 0 (lib.stringLength patch - 2) patch;
major = lib.elemAt parts 0;
channel = lib.concatStringsSep "_" (lib.take 2 parts);
sdk = lib.concatStringsSep "_" (lib.replaceElemAt parts 2 "${band}xx");
in
{
source = if band == "1" then major else sdk;
inherit major channel sdk;
};
releaseInfo = (lib.importJSON releaseInfoFile);
inherit (releaseInfo)
tarballHash
artifactsUrl
artifactsHash
;
artifacts = stdenvNoCC.mkDerivation {
name = lib.nameFromURL artifactsUrl ".tar.gz";
src = fetchurl {
url = artifactsUrl;
hash = artifactsHash;
};
sourceRoot = ".";
installPhase = ''
mkdir -p $out
cp -r * $out/
'';
};
vmr =
if bootstrapSdk != null then
callPackage ./vmr.nix {
inherit
releaseManifestFile
tarballHash
;
bootstrapSdk = bootstrapSdk.unwrapped;
hasRuntime = false;
}
else
callPackage ./stage1.nix {
inherit
releaseManifestFile
tarballHash
depsFile
;
bootstrapSdk = (buildDotnetSdk bootstrapSdkFile).sdk.unwrapped.overrideAttrs (old: {
passthru = old.passthru or { } // {
inherit artifacts;
};
});
};
fallbackSdk = binary.${"sdk_${suffix.sdk}"};
fallbackTargetPackages = fallbackSdk.targetPackages;
vmrPackages =
let
pkgs = callPackage ./packages.nix {
inherit vmr fallbackTargetPackages;
};
in
lib.recurseIntoAttrs (
pkgs
// {
vmr = pkgs.vmr.overrideAttrs (old: {
passthru = old.passthru // {
updateScript = pkgsBuildHost.callPackage ./update.nix {
inherit
releaseManifestFile
releaseInfoFile
bootstrapSdkFile
allowPrerelease
;
};
};
});
}
);
source =
vmrPackages
// lib.optionalAttrs vmr.meta.broken rec {
sdk = fallbackSdk;
inherit (sdk) runtime aspnetcore;
};
# combine an SDK with the runtime/packages from a base SDK
combineSdk =
base: fallback:
if (fallback.runtime.version != base.runtime.version) then
throw "combineSdk: unable to combine ${fallback.name} with ${base.name} because runtime versions don't match (${fallback.runtime.version} != ${base.runtime.version})"
else if base.meta.broken then
fallback
else
let
withBaseRuntimes =
if fallback.version == base.version then
base.unwrapped
else
(combinePackages [
base.runtime
base.aspnetcore
fallback
]).unwrapped.overrideAttrs
(old: {
name = fallback.unwrapped.name;
# resolve symlinks so DOTNET_ROOT is self-contained
postBuild = ''
mv "$out"/share/dotnet{,~}
cp -Lr "$out"/share/dotnet{~,}
rm -r "$out"/share/dotnet~
''
+ old.postBuild;
passthru = old.passthru // {
inherit (base)
runtime
aspnetcore
;
inherit (fallback.unwrapped)
pname
version
hasILCompiler
;
};
});
withFallbackPackages = withBaseRuntimes.overrideAttrs (old: {
passthru =
old.passthru
// (
let
hostRid = systemToDotnetRid base.stdenv.hostPlatform.system;
hasILCompiler = base.hasILCompiler || withBaseRuntimes.hasILCompiler;
packageName = "runtime.${hostRid}.Microsoft.DotNet.ILCompiler";
mergePackages =
a: b:
let
names = lib.genAttrs' a (p: lib.nameValuePair p.pname null);
in
a ++ lib.filter (p: !lib.hasAttr p.pname names) b;
packages = mergePackages base.packages fallback.packages;
targetPackages = lib.mapAttrs (
name: value: mergePackages value fallback.targetPackages.${name}
) base.targetPackages;
in
{
inherit hasILCompiler packages targetPackages;
}
);
});
in
callPackage ../wrapper.nix { } "sdk" withFallbackPackages;
in
{
"dotnet_${suffix.source}" = vmrPackages;
}
// (
let
combined = lib.mapAttrs (s: v: combineSdk source.sdk v) (
if withBinary then
lib.filterAttrs (n: _: lib.substring 0 4 n == "sdk_") binary
else
{
"sdk_${suffix.sdk}" = binary.${"sdk_${suffix.sdk}"};
}
//
lib.optionalAttrs (lib.versionAtLeast source.sdk.version binary.${"sdk_${suffix.channel}"}.version)
{
"sdk_${suffix.channel}" = binary.${"sdk_${suffix.channel}"};
}
);
in
combined
// {
"sdk_${suffix.channel}-source" = source.sdk;
"runtime_${suffix.channel}" = source.runtime;
"aspnetcore_${suffix.channel}" = source.aspnetcore;
}
)
// lib.optionalAttrs withBinary (
lib.mergeAttrsList (
map
(
featureBand:
callPackage ./default.nix (
attrs
// {
dir = dir + "/${featureBand}";
withBinary = false;
bootstrapSdk = vmrPackages.sdk;
}
)
)
(
lib.filter (x: x != "1xx") (
map (x: lib.elemAt x 2) (
lib.filter (x: x != null && lib.versionAtLeast (lib.elemAt x 0) "10") (
map (lib.match "sdk_(.*)_(.*)_(.*)") (lib.attrNames binary)
)
)
)
)
)
)
@@ -12,7 +12,7 @@
}:
let
mkWrapper = callPackage ./wrapper.nix { };
mkWrapper = callPackage ../wrapper.nix { };
mkCommon =
type: args:
mkWrapper type (
@@ -58,7 +58,7 @@ let
targetRid = dotnetCorePackages.systemToDotnetRid targetPlatform.system;
targetArch = lib.elemAt (lib.splitString "-" targetRid) 1;
sigtool = callPackage ./sigtool.nix { };
sigtool = callPackage ../sigtool.nix { };
_icu = if isDarwin then darwin.ICU else icu;