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