1{
2 clangStdenv,
3 lib,
4 fetchurl,
5 dotnetCorePackages,
6 jq,
7 curl,
8 git,
9 cmake,
10 pkg-config,
11 llvm,
12 zlib,
13 icu,
14 lttng-ust_2_12,
15 krb5,
16 glibcLocales,
17 ensureNewerSourcesForZipFilesHook,
18 darwin,
19 xcbuild,
20 swiftPackages,
21 apple-sdk_13,
22 openssl,
23 getconf,
24 python3,
25 xmlstarlet,
26 nodejs,
27 cpio,
28 callPackage,
29 unzip,
30 yq,
31 installShellFiles,
32
33 baseName ? "dotnet",
34 bootstrapSdk,
35 releaseManifestFile,
36 tarballHash,
37}:
38
39let
40 stdenv = if clangStdenv.hostPlatform.isDarwin then swiftPackages.stdenv else clangStdenv;
41
42 inherit (stdenv)
43 isLinux
44 isDarwin
45 buildPlatform
46 targetPlatform
47 ;
48 inherit (swiftPackages) swift;
49
50 releaseManifest = lib.importJSON releaseManifestFile;
51 inherit (releaseManifest) release sourceRepository tag;
52
53 buildRid = dotnetCorePackages.systemToDotnetRid buildPlatform.system;
54 targetRid = dotnetCorePackages.systemToDotnetRid targetPlatform.system;
55 targetArch = lib.elemAt (lib.splitString "-" targetRid) 1;
56
57 sigtool = callPackage ./sigtool.nix { };
58
59 _icu = if isDarwin then darwin.ICU else icu;
60
61in
62stdenv.mkDerivation rec {
63 pname = "${baseName}-vmr";
64 version = release;
65
66 # TODO: fix this in the binary sdk packages
67 preHook = lib.optionalString stdenv.hostPlatform.isDarwin ''
68 addToSearchPath DYLD_LIBRARY_PATH "${_icu}/lib"
69 export DYLD_LIBRARY_PATH
70 '';
71
72 src = fetchurl {
73 url = "${sourceRepository}/archive/refs/tags/${tag}.tar.gz";
74 hash = tarballHash;
75 };
76
77 nativeBuildInputs = [
78 ensureNewerSourcesForZipFilesHook
79 jq
80 curl.bin
81 git
82 cmake
83 pkg-config
84 python3
85 xmlstarlet
86 unzip
87 yq
88 installShellFiles
89 ]
90 ++ lib.optionals (lib.versionAtLeast version "9") [
91 nodejs
92 ]
93 ++ lib.optionals (lib.versionAtLeast version "10") [
94 cpio
95 ]
96 ++ lib.optionals isDarwin [
97 getconf
98 ];
99
100 buildInputs = [
101 # this gets copied into the tree, but we still need the sandbox profile
102 bootstrapSdk
103 # the propagated build inputs in llvm.dev break swift compilation
104 llvm.out
105 zlib
106 _icu
107 openssl
108 ]
109 ++ lib.optionals isLinux [
110 krb5
111 lttng-ust_2_12
112 ]
113 ++ lib.optionals isDarwin (
114 [
115 xcbuild
116 swift
117 krb5
118 sigtool
119 ]
120 ++ lib.optional (lib.versionAtLeast version "10") apple-sdk_13
121 );
122
123 # This is required to fix the error:
124 # > CSSM_ModuleLoad(): One or more parameters passed to a function were not valid.
125 # The error occurs during
126 # AppleCryptoNative_X509ImportCollection -> ReadX509 -> SecItemImport
127 # while importing trustedroots/codesignctl.pem. This happens during any dotnet
128 # restore operation.
129 # Enabling com.apple.system.opendirectoryd.membership causes swiftc to use
130 # /var/folders for its default cache path, so the swiftc -module-cache-path
131 # patch below is required.
132 sandboxProfile = ''
133 (allow file-read* (subpath "/private/var/db/mds/system"))
134 (allow mach-lookup (global-name "com.apple.SecurityServer")
135 (global-name "com.apple.system.opendirectoryd.membership"))
136 '';
137
138 patches =
139 lib.optionals (lib.versionAtLeast version "9" && lib.versionOlder version "10") [
140 ./UpdateNuGetConfigPackageSourcesMappings-don-t-add-em.patch
141 ./vmr-compiler-opt-v9.patch
142 ]
143 ++ lib.optionals (lib.versionOlder version "9") [
144 ./fix-aspnetcore-portable-build.patch
145 ./vmr-compiler-opt-v8.patch
146 ]
147 ++ lib.optionals (lib.versionAtLeast version "10") [
148 ./bundler-fix-file-size-estimation-when-bundling-symli.patch
149 ];
150
151 postPatch = ''
152 # set the sdk version in global.json to match the bootstrap sdk
153 sdk_version=$(HOME=$(mktemp -d) ${bootstrapSdk}/bin/dotnet --version)
154 jq '(.tools.dotnet=$dotnet)' global.json --arg dotnet "$sdk_version" > global.json~
155 mv global.json{~,}
156
157 patchShebangs $(find -name \*.sh -type f -executable)
158
159 # I'm not sure why this is required, but these files seem to use the wrong
160 # property name.
161 # TODO: not needed in 9.0?
162 [[ ! -f src/xliff-tasks/eng/Versions.props ]] || \
163 sed -i 's:\bVersionBase\b:VersionPrefix:g' \
164 src/xliff-tasks/eng/Versions.props
165
166 # at least in 9.0 preview 1, this package depends on a specific beta build
167 # of System.CommandLine
168 xmlstarlet ed \
169 --inplace \
170 -s //Project -t elem -n PropertyGroup \
171 -s \$prev -t elem -n NoWarn -v '$(NoWarn);NU1603' \
172 src/nuget-client/src/NuGet.Core/NuGet.CommandLine.XPlat/NuGet.CommandLine.XPlat.csproj
173
174 # AD0001 crashes intermittently in source-build-reference-packages with
175 # CSC : error AD0001: Analyzer 'Microsoft.NetCore.CSharp.Analyzers.Runtime.CSharpDetectPreviewFeatureAnalyzer' threw an exception of type 'System.NullReferenceException' with message 'Object reference not set to an instance of an object.'.
176 # possibly related to https://github.com/dotnet/runtime/issues/90356
177 xmlstarlet ed \
178 --inplace \
179 -s //Project -t elem -n PropertyGroup \
180 -s \$prev -t elem -n NoWarn -v '$(NoWarn);AD0001' \
181 src/source-build-reference-packages/src/referencePackages/Directory.Build.props
182
183 ''
184 + lib.optionalString (lib.versionOlder version "10") ''
185 # https://github.com/microsoft/ApplicationInsights-dotnet/issues/2848
186 xmlstarlet ed \
187 --inplace \
188 -u //_:Project/_:PropertyGroup/_:BuildNumber -v 0 \
189 src/source-build-externals/src/application-insights/.props/_GlobalStaticVersion.props
190 ''
191 + ''
192
193 # this fixes compile errors with clang 15 (e.g. darwin)
194 substituteInPlace \
195 src/runtime/src/native/libs/CMakeLists.txt \
196 --replace-fail 'add_compile_options(-Weverything)' 'add_compile_options(-Wall)'
197 ''
198 + lib.optionalString (lib.versionAtLeast version "9") (
199 ''
200 # repro.csproj fails to restore due to missing freebsd packages
201 xmlstarlet ed \
202 --inplace \
203 -s //Project -t elem -n PropertyGroup \
204 -s \$prev -t elem -n RuntimeIdentifiers -v ${targetRid} \
205 src/runtime/src/coreclr/tools/aot/ILCompiler/repro/repro.csproj
206
207 # https://github.com/dotnet/runtime/pull/98559#issuecomment-1965338627
208 xmlstarlet ed \
209 --inplace \
210 -s //Project -t elem -n PropertyGroup \
211 -s \$prev -t elem -n NoWarn -v '$(NoWarn);CS9216' \
212 src/runtime/Directory.Build.props
213
214 # https://github.com/dotnet/source-build/issues/3131#issuecomment-2030215805
215 substituteInPlace \
216 src/aspnetcore/eng/Dependencies.props \
217 --replace-fail \
218 "'\$(DotNetBuildSourceOnly)' == 'true'" \
219 "'\$(DotNetBuildSourceOnly)' == 'true' and \$(PortableBuild) == 'false'"
220
221 # https://github.com/dotnet/source-build/issues/4325
222 xmlstarlet ed \
223 --inplace \
224 -r '//Target[@Name="UnpackTarballs"]/Move' -v Copy \
225 eng/init-source-only.proj
226
227 # error: _FORTIFY_SOURCE requires compiling with optimization (-O) [-Werror,-W#warnings]
228 substituteInPlace \
229 src/runtime/src/coreclr/ilasm/CMakeLists.txt \
230 --replace-fail 'set_source_files_properties( prebuilt/asmparse.cpp PROPERTIES COMPILE_FLAGS "-O0" )' ""
231 ''
232 + lib.optionalString (lib.versionOlder version "10") ''
233
234 # https://github.com/dotnet/source-build/issues/4444
235 xmlstarlet ed \
236 --inplace \
237 -s '//Project/Target/MSBuild[@Targets="Restore"]' \
238 -t attr -n Properties -v "NUGET_PACKAGES='\$(CurrentRepoSourceBuildPackageCache)'" \
239 src/aspnetcore/eng/Tools.props
240 # patch packages installed from npm cache
241 xmlstarlet ed \
242 --inplace \
243 -s //Project -t elem -n Import \
244 -i \$prev -t attr -n Project -v "${./patch-npm-packages.proj}" \
245 src/aspnetcore/eng/DotNetBuild.props
246 ''
247 )
248 + lib.optionalString isLinux (
249 ''
250 substituteInPlace \
251 src/runtime/src/native/libs/System.Security.Cryptography.Native/opensslshim.c \
252 --replace-fail '"libssl.so"' '"${openssl.out}/lib/libssl.so"'
253
254 substituteInPlace \
255 src/runtime/src/native/libs/System.Net.Security.Native/pal_gssapi.c \
256 --replace-fail '"libgssapi_krb5.so.2"' '"${lib.getLib krb5}/lib/libgssapi_krb5.so.2"'
257
258 substituteInPlace \
259 src/runtime/src/native/libs/System.Globalization.Native/pal_icushim.c \
260 --replace-fail '"libicui18n.so"' '"${icu}/lib/libicui18n.so"' \
261 --replace-fail '"libicuuc.so"' '"${icu}/lib/libicuuc.so"'
262 ''
263 + lib.optionalString (lib.versionAtLeast version "9") ''
264 substituteInPlace \
265 src/runtime/src/native/libs/System.Globalization.Native/pal_icushim.c \
266 --replace-fail '#define VERSIONED_LIB_NAME_LEN 64' '#define VERSIONED_LIB_NAME_LEN 256'
267 ''
268 + lib.optionalString (lib.versionOlder version "9") ''
269 substituteInPlace \
270 src/runtime/src/native/libs/System.Globalization.Native/pal_icushim.c \
271 --replace-warn 'libicuucName[64]' 'libicuucName[256]' \
272 --replace-warn 'libicui18nName[64]' 'libicui18nName[256]'
273 ''
274 )
275 + lib.optionalString isDarwin (
276 ''
277 substituteInPlace \
278 src/runtime/src/native/libs/System.Globalization.Native/CMakeLists.txt \
279 --replace-fail '/usr/lib/libicucore.dylib' '${darwin.ICU}/lib/libicucore.dylib'
280
281 substituteInPlace \
282 src/runtime/src/installer/managed/Microsoft.NET.HostModel/HostModelUtils.cs \
283 ''
284 + lib.optionalString (lib.versionOlder version "10") " src/sdk/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets \\\n"
285 + ''
286 --replace-fail '/usr/bin/codesign' '${sigtool}/bin/codesign'
287
288 # fix: strip: error: unknown argument '-n'
289 substituteInPlace \
290 src/runtime/eng/native/functions.cmake \
291 --replace-fail ' -no_code_signature_warning' ""
292
293 # [...]/installer.singlerid.targets(434,5): error MSB3073: The command "pkgbuild [...]" exited with code 127
294 xmlstarlet ed \
295 --inplace \
296 -s //Project -t elem -n PropertyGroup \
297 -s \$prev -t elem -n SkipInstallerBuild -v true \
298 src/runtime/Directory.Build.props
299 ''
300 + lib.optionalString (lib.versionAtLeast version "10") ''
301 xmlstarlet ed \
302 --inplace \
303 -s //Project -t elem -n PropertyGroup \
304 -s \$prev -t elem -n SkipInstallerBuild -v true \
305 src/aspnetcore/Directory.Build.props
306 ''
307 + ''
308 # stop passing -sdk without a path
309 # stop using xcrun
310 # add -module-cache-path to fix swift errors, see sandboxProfile
311 # <unknown>:0: error: unable to open output file '/var/folders/[...]/C/clang/ModuleCache/[...]/SwiftShims-[...].pcm': 'Operation not permitted'
312 # <unknown>:0: error: could not build Objective-C module 'SwiftShims'
313 substituteInPlace \
314 src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/CMakeLists.txt \
315 --replace-fail ' -sdk ''${CMAKE_OSX_SYSROOT}' "" \
316 --replace-fail 'xcrun swiftc' 'swiftc -module-cache-path "$ENV{HOME}/.cache/module-cache"'
317
318 # fix: strip: error: unknown argument '-n'
319 substituteInPlace \
320 src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets \
321 ''
322 + lib.optionalString (lib.versionAtLeast version "9") " src/runtime/src/native/managed/native-library.targets \\\n"
323 + ''
324 --replace-fail ' -no_code_signature_warning' ""
325
326 # ld: library not found for -ld_classic
327 substituteInPlace \
328 src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets \
329 ''
330 + lib.optionalString (lib.versionOlder version "10") " src/runtime/src/coreclr/tools/aot/ILCompiler/ILCompiler.csproj \\\n"
331 + " --replace-fail 'Include=\"-ld_classic\"' \"\"\n"
332 + lib.optionalString (lib.versionOlder version "9") ''
333 # [...]/build.proj(123,5): error : Did not find PDBs for the following SDK files:
334 # [...]/build.proj(123,5): error : sdk/8.0.102/System.Resources.Extensions.dll
335 # [...]/build.proj(123,5): error : sdk/8.0.102/System.CodeDom.dll
336 # [...]/build.proj(123,5): error : sdk/8.0.102/FSharp/System.Resources.Extensions.dll
337 # [...]/build.proj(123,5): error : sdk/8.0.102/FSharp/System.CodeDom.dll
338 substituteInPlace \
339 build.proj \
340 --replace-fail 'FailOnMissingPDBs="true"' 'FailOnMissingPDBs="false"'
341
342 substituteInPlace \
343 src/runtime/src/mono/CMakeLists.txt \
344 --replace-fail '/usr/lib/libicucore.dylib' '${darwin.ICU}/lib/libicucore.dylib'
345 ''
346 );
347
348 prepFlags = [
349 "--no-artifacts"
350 "--no-prebuilts"
351 "--with-packages"
352 bootstrapSdk.artifacts
353
354 ]
355 # https://github.com/dotnet/source-build/issues/5286#issuecomment-3097872768
356 ++ lib.optional (lib.versionAtLeast version "10") "-p:SkipArcadeSdkImport=true";
357
358 configurePhase =
359 let
360 prepScript = if (lib.versionAtLeast version "9") then "./prep-source-build.sh" else "./prep.sh";
361 in
362 ''
363 runHook preConfigure
364
365 # The build process tries to overwrite some things in the sdk (e.g.
366 # SourceBuild.MSBuildSdkResolver.dll), so it needs to be mutable.
367 cp -Tr ${bootstrapSdk}/share/dotnet .dotnet
368 chmod -R +w .dotnet
369
370 export HOME=$(mktemp -d)
371 ''
372 + lib.optionalString (lib.versionAtLeast version "10") ''
373 dotnet nuget add source "${bootstrapSdk.artifacts}"
374 ''
375 + ''
376 ${prepScript} $prepFlags
377
378 runHook postConfigure
379 '';
380
381 postConfigure = lib.optionalString (lib.versionAtLeast version "9") ''
382 # see patch-npm-packages.proj
383 typeset -f isScript patchShebangs > src/aspnetcore/patch-shebangs.sh
384 '';
385
386 dontConfigureNuget = true; # NUGET_PACKAGES breaks the build
387 dontUseCmakeConfigure = true;
388
389 # https://github.com/NixOS/nixpkgs/issues/38991
390 # bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
391 LOCALE_ARCHIVE = lib.optionalString isLinux "${glibcLocales}/lib/locale/locale-archive";
392
393 # clang: error: argument unused during compilation: '-Wa,--compress-debug-sections' [-Werror,-Wunused-command-line-argument]
394 # caused by separateDebugInfo
395 NIX_CFLAGS_COMPILE = "-Wno-unused-command-line-argument";
396
397 buildFlags = [
398 "--with-packages"
399 bootstrapSdk.artifacts
400 "--clean-while-building"
401 "--release-manifest"
402 releaseManifestFile
403 ]
404 ++ lib.optionals (lib.versionAtLeast version "9") [
405 "--source-build"
406 ]
407 ++ lib.optionals (lib.versionAtLeast version "10") [
408 "--branding default"
409 ]
410 ++ [
411 "--"
412 "-p:PortableBuild=true"
413 ]
414 ++ lib.optional (targetRid != buildRid) "-p:TargetRid=${targetRid}";
415
416 buildPhase = ''
417 runHook preBuild
418
419 # on darwin, in a sandbox, this causes:
420 # CSSM_ModuleLoad(): One or more parameters passed to a function were not valid.
421 export DOTNET_GENERATE_ASPNET_CERTIFICATE=0
422
423 # CLR_CC/CXX need to be set to stop the build system from using clang-11,
424 # which is unwrapped
425 # dotnet needs to be in PATH to fix:
426 # src/sdk/eng/restore-toolset.sh: line 114: /nix/store/[...]-dotnet-sdk-9.0.100-preview.2.24157.14//.version: Read-only file system
427 version= \
428 CLR_CC=$(command -v clang) \
429 CLR_CXX=$(command -v clang++) \
430 PATH=$PWD/.dotnet:$PATH \
431 ./build.sh $buildFlags
432
433 runHook postBuild
434 '';
435
436 outputs = [
437 "out"
438 "man"
439 ];
440
441 installPhase =
442 let
443 assets = if (lib.versionAtLeast version "9") then "assets" else targetArch;
444 # 10.0.0-preview.6 ends up creating duplicate files in .nupkgs, for example in
445 # Microsoft.Internal.Runtime.AspNetCore.Transport.10.0.0-preview.6.25358.103.nupkg
446 #
447 # lib/net10.0//System.Diagnostics.EventLog.pdb
448 # lib/net10.0/System.Diagnostics.EventLog.pdb
449 unzipFlags = "-q" + lib.optionalString (lib.versionAtLeast version "10") "o" + "d";
450 in
451 ''
452 runHook preInstall
453
454 mkdir -p "$out"/lib
455
456 pushd "artifacts/${assets}/Release"
457 find . -name \*.tar.gz | while read archive; do
458 target=$out/lib/$(basename "$archive" .tar.gz)
459 # dotnet 9 currently has two copies of the sdk tarball
460 [[ ! -e "$target" ]] || continue
461 mkdir "$target"
462 tar -C "$target" -xzf "$PWD/$archive"
463 done
464 popd
465
466 local -r unpacked="$PWD/.unpacked"
467 for nupkg in $out/lib/Private.SourceBuilt.Artifacts.*.${targetRid}/{,SourceBuildReferencePackages/}*.nupkg; do
468 rm -rf "$unpacked"
469 unzip ${unzipFlags} "$unpacked" "$nupkg"
470 chmod -R +rw "$unpacked"
471 rm "$nupkg"
472 mv "$unpacked" "$nupkg"
473 # TODO: should we fix executable flags here? see dotnetInstallHook
474 done
475
476 installManPage src/sdk/documentation/manpages/sdk/*
477
478 runHook postInstall
479 '';
480
481 ${if stdenv.isDarwin && lib.versionAtLeast version "10" then "postInstall" else null} = ''
482 mkdir -p "$out"/nix-support
483 echo ${sigtool} > "$out"/nix-support/manual-sdk-deps
484 '';
485
486 # stripping dlls results in:
487 # Failed to load System.Private.CoreLib.dll (error code 0x8007000B)
488 # stripped crossgen2 results in:
489 # Failure processing application bundle; possible file corruption.
490 # this needs to be a bash array
491 preFixup = ''
492 stripExclude=(\*.dll crossgen2)
493 '';
494
495 separateDebugInfo = true;
496
497 passthru = {
498 inherit releaseManifest buildRid targetRid;
499 icu = _icu;
500 # ilcompiler is currently broken: https://github.com/dotnet/source-build/issues/1215
501 hasILCompiler = lib.versionAtLeast version "9";
502 };
503
504 meta = with lib; {
505 description = "Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI";
506 homepage = "https://dotnet.github.io/";
507 license = licenses.mit;
508 maintainers = with maintainers; [ corngood ];
509 mainProgram = "dotnet";
510 platforms = [
511 "x86_64-linux"
512 "aarch64-linux"
513 "x86_64-darwin"
514 "aarch64-darwin"
515 ];
516 # build deadlocks intermittently on rosetta
517 # https://github.com/dotnet/runtime/issues/111628
518 broken = stdenv.hostPlatform.system == "x86_64-darwin";
519 };
520}