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