about summary refs log tree commit diff
path: root/nixpkgs/pkgs/development/compilers/dotnet/vmr.nix
blob: 962c0c0844a5b2fa50efa94b283ee33c59890649 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
{ clangStdenv
, stdenvNoCC
, lib
, fetchurl
, fetchFromGitHub
, dotnetCorePackages
, jq
, curl
, git
, cmake
, pkg-config
, llvm
, zlib
, icu
, lttng-ust_2_12
, libkrb5
, glibcLocales
, ensureNewerSourcesForZipFilesHook
, darwin
, xcbuild
, swiftPackages
, openssl
, getconf
, makeWrapper
, python3
, xmlstarlet
, callPackage

, dotnetSdk
, releaseManifestFile
, tarballHash
}:

let
  stdenv = if clangStdenv.isDarwin
    then swiftPackages.stdenv
    else clangStdenv;

  inherit (stdenv)
    isLinux
    isDarwin
    buildPlatform
    targetPlatform;
  inherit (darwin) cctools;
  inherit (swiftPackages) apple_sdk swift;

  releaseManifest = lib.importJSON releaseManifestFile;
  inherit (releaseManifest) release sourceRepository tag;

  buildRid = dotnetCorePackages.systemToDotnetRid buildPlatform.system;
  targetRid = dotnetCorePackages.systemToDotnetRid targetPlatform.system;
  targetArch = lib.elemAt (lib.splitString "-" targetRid) 1;

  sigtool = callPackage ./sigtool.nix {};

  # we need dwarfdump from cctools, but can't have e.g. 'ar' overriding stdenv
  dwarfdump = stdenvNoCC.mkDerivation {
    name = "dwarfdump-wrapper";
    dontUnpack = true;
    installPhase = ''
      mkdir -p "$out/bin"
      ln -s "${cctools}/bin/dwarfdump" "$out/bin"
    '';
  };

  _icu = if isDarwin then darwin.ICU else icu;

in stdenv.mkDerivation rec {
  pname = "dotnet-vmr";
  version = release;

  # TODO: fix this in the binary sdk packages
  preHook = lib.optionalString stdenv.isDarwin ''
    addToSearchPath DYLD_LIBRARY_PATH "${_icu}/lib"
    export DYLD_LIBRARY_PATH
  '';

  src = fetchurl {
    url = "${sourceRepository}/archive/refs/tags/${tag}.tar.gz";
    hash = tarballHash;
  };

  nativeBuildInputs = [
    ensureNewerSourcesForZipFilesHook
    jq
    curl.bin
    git
    cmake
    pkg-config
    python3
    xmlstarlet
  ]
  ++ lib.optionals isDarwin [
    getconf
  ];

  buildInputs = [
    # this gets copied into the tree, but we still want the hooks to run
    dotnetSdk
    # the propagated build inputs in llvm.dev break swift compilation
    llvm.out
    zlib
    _icu
    openssl
  ]
  ++ lib.optionals isLinux [
    libkrb5
    lttng-ust_2_12
  ]
  ++ lib.optionals isDarwin (with apple_sdk.frameworks; [
    xcbuild.xcrun
    swift
    (libkrb5.overrideAttrs (old: {
      # the propagated build inputs break swift compilation
      buildInputs = old.buildInputs ++ old.propagatedBuildInputs;
      propagatedBuildInputs = [];
    }))
    dwarfdump
    sigtool
    Foundation
    CoreFoundation
    CryptoKit
    System
  ]);

  # This is required to fix the error:
  # > CSSM_ModuleLoad(): One or more parameters passed to a function were not valid.
  # The error occurs during
  # AppleCryptoNative_X509ImportCollection -> ReadX509 -> SecItemImport
  # while importing trustedroots/codesignctl.pem. This happens during any dotnet
  # restore operation.
  # Enabling com.apple.system.opendirectoryd.membership causes swiftc to use
  # /var/folders for its default cache path, so the swiftc -module-cache-path
  # patch below is required.
  sandboxProfile = ''
    (allow file-read* (subpath "/private/var/db/mds/system"))
    (allow mach-lookup (global-name "com.apple.SecurityServer")
                       (global-name "com.apple.system.opendirectoryd.membership"))
  '';

  patches = [
    ./fix-aspnetcore-portable-build.patch
    ./fix-tmp-path.patch
  ]
  ++ lib.optionals isDarwin [
    ./stop-passing-bare-sdk-arg-to-swiftc.patch
  ];

  postPatch = ''
    # set the sdk version in global.json to match the bootstrap sdk
    jq '(.tools.dotnet=$dotnet)' global.json --arg dotnet "$(${dotnetSdk}/bin/dotnet --version)" > global.json~
    mv global.json{~,}

    patchShebangs $(find -name \*.sh -type f -executable)

    # I'm not sure why this is required, but these files seem to use the wrong
    # property name.
    # TODO: not needed in 9.0?
    [[ ! -f src/xliff-tasks/eng/Versions.props ]] || \
      sed -i 's:\bVersionBase\b:VersionPrefix:g' \
        src/xliff-tasks/eng/Versions.props

    # at least in 9.0 preview 1, this package depends on a specific beta build
    # of System.CommandLine
    xmlstarlet ed \
      --inplace \
      -s //Project -t elem -n PropertyGroup \
      -s \$prev -t elem -n NoWarn -v '$(NoWarn);NU1603' \
      src/nuget-client/src/NuGet.Core/NuGet.CommandLine.XPlat/NuGet.CommandLine.XPlat.csproj

    # AD0001 crashes intermittently in source-build-reference-packages with
    # 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.'.
    # possibly related to https://github.com/dotnet/runtime/issues/90356
    xmlstarlet ed \
      --inplace \
      -s //Project -t elem -n PropertyGroup \
      -s \$prev -t elem -n NoWarn -v '$(NoWarn);AD0001' \
      src/source-build-reference-packages/src/referencePackages/Directory.Build.props

    # https://github.com/microsoft/ApplicationInsights-dotnet/issues/2848
    xmlstarlet ed \
      --inplace \
      -u //_:Project/_:PropertyGroup/_:BuildNumber -v 0 \
      src/source-build-externals/src/application-insights/.props/_GlobalStaticVersion.props

    # this fixes compile errors with clang 15 (e.g. darwin)
    substituteInPlace \
      src/runtime/src/native/libs/CMakeLists.txt \
      --replace-fail 'add_compile_options(-Weverything)' 'add_compile_options(-Wall)'

    # strip native symbols in runtime
    # see: https://github.com/dotnet/source-build/issues/2543
    xmlstarlet ed \
      --inplace \
      -s //Project -t elem -n PropertyGroup \
      -s \$prev -t elem -n KeepNativeSymbols -v false \
      src/runtime/Directory.Build.props
  ''
  + lib.optionalString isLinux ''
    substituteInPlace \
      src/runtime/src/native/libs/System.Security.Cryptography.Native/opensslshim.c \
      --replace-fail '"libssl.so"' '"${openssl.out}/lib/libssl.so"'

    substituteInPlace \
      src/runtime/src/native/libs/System.Net.Security.Native/pal_gssapi.c \
      --replace-fail '"libgssapi_krb5.so.2"' '"${libkrb5}/lib/libgssapi_krb5.so.2"'

    substituteInPlace \
      src/runtime/src/native/libs/System.Globalization.Native/pal_icushim.c \
      --replace-fail '"libicui18n.so"' '"${icu}/lib/libicui18n.so"' \
      --replace-fail '"libicuuc.so"' '"${icu}/lib/libicuuc.so"'

    # TODO: we should really make sure the first one (9.0) or the rest (8.0)
    # works, but --replace-fail results in an empty file
    substituteInPlace \
      src/runtime/src/native/libs/System.Globalization.Native/pal_icushim.c \
      --replace-warn '#define VERSIONED_LIB_NAME_LEN 64' '#define VERSIONED_LIB_NAME_LEN 256' \
      --replace-warn 'libicuucName[64]' 'libicuucName[256]' \
      --replace-warn 'libicui18nName[64]' 'libicui18nName[256]'
  ''
  + lib.optionalString isDarwin ''
    substituteInPlace \
      src/runtime/src/mono/CMakeLists.txt \
      src/runtime/src/native/libs/System.Globalization.Native/CMakeLists.txt \
      --replace-fail '/usr/lib/libicucore.dylib' '${darwin.ICU}/lib/libicucore.dylib'

    substituteInPlace \
      src/runtime/src/installer/managed/Microsoft.NET.HostModel/HostModelUtils.cs \
      src/sdk/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets \
      --replace-fail '/usr/bin/codesign' '${sigtool}/bin/codesign'

    # [...]/build.proj(123,5): error : Did not find PDBs for the following SDK files:
    # [...]/build.proj(123,5): error : sdk/8.0.102/System.Resources.Extensions.dll
    # [...]/build.proj(123,5): error : sdk/8.0.102/System.CodeDom.dll
    # [...]/build.proj(123,5): error : sdk/8.0.102/FSharp/System.Resources.Extensions.dll
    # [...]/build.proj(123,5): error : sdk/8.0.102/FSharp/System.CodeDom.dll
    substituteInPlace \
      build.proj \
      --replace-warn 'FailOnMissingPDBs="true"' 'FailOnMissingPDBs="false"'

    # [...]/installer.singlerid.targets(434,5): error MSB3073: The command "pkgbuild [...]" exited with code 127
    xmlstarlet ed \
      --inplace \
      -s //Project -t elem -n PropertyGroup \
      -s \$prev -t elem -n InnerBuildArgs -v '$(InnerBuildArgs) /p:SkipInstallerBuild=true' \
      src/runtime/eng/SourceBuild.props

    # fixes swift errors, see sandboxProfile
    # <unknown>:0: error: unable to open output file '/var/folders/[...]/C/clang/ModuleCache/[...]/SwiftShims-[...].pcm': 'Operation not permitted'
    # <unknown>:0: error: could not build Objective-C module 'SwiftShims'
    substituteInPlace \
      src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/CMakeLists.txt \
      --replace-fail 'xcrun swiftc' 'xcrun swiftc -module-cache-path "$ENV{HOME}/.cache/module-cache"'
  '';

  prepFlags = [
    "--no-artifacts"
    "--no-prebuilts"
  ];

  configurePhase = ''
    runHook preConfigure

    # The build process tries to overwrite some things in the sdk (e.g.
    # SourceBuild.MSBuildSdkResolver.dll), so it needs to be mutable.
    cp -Tr ${dotnetSdk} .dotnet
    chmod -R +w .dotnet

    ./prep.sh $prepFlags

    runHook postConfigure
  '';

  dontUseCmakeConfigure = true;

  # https://github.com/NixOS/nixpkgs/issues/38991
  # bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
  LOCALE_ARCHIVE = lib.optionalString isLinux
    "${glibcLocales}/lib/locale/locale-archive";

  buildFlags = [
    "--with-packages" dotnetSdk.artifacts
    "--clean-while-building"
    "--release-manifest" releaseManifestFile
    "--"
    "-p:PortableBuild=true"
  ] ++ lib.optional (targetRid != buildRid) "-p:TargetRid=${targetRid}";

  buildPhase = ''
    runHook preBuild

    # on darwin, in a sandbox, this causes:
    # CSSM_ModuleLoad(): One or more parameters passed to a function were not valid.
    export DOTNET_GENERATE_ASPNET_CERTIFICATE=0

    # CLR_CC/CXX need to be set to stop the build system from using clang-11,
    # which is unwrapped
    version= \
    CLR_CC=$(command -v clang) \
    CLR_CXX=$(command -v clang++) \
      ./build.sh $buildFlags

    runHook postBuild
  '';

  installPhase = ''
    runHook preInstall

    mkdir "$out"

    pushd "artifacts/${targetArch}/Release"
    for archive in *.tar.gz; do
      target=$out/''${archive%.tar.gz}
      mkdir "$target"
      tar -C "$target" -xzf "$PWD/$archive"
    done
    popd

    runHook postInstall
  '';

  # dotnet cli is in the root, so we need to strip from there
  # TODO: should we install in $out/share/dotnet?
  stripDebugList = [ "." ];
  # stripping dlls results in:
  # Failed to load System.Private.CoreLib.dll (error code 0x8007000B)
  stripExclude = [ "*.dll" ];

  passthru = {
    inherit releaseManifest buildRid targetRid;
    icu = _icu;
  };

  meta = with lib; {
    description = "Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI";
    homepage = "https://dotnet.github.io/";
    license = licenses.mit;
    maintainers = with maintainers; [ corngood ];
    mainProgram = "dotnet";
    platforms = [
      "x86_64-linux"
      "aarch64-linux"
      "x86_64-darwin"
      "aarch64-darwin"
    ];
  };
}