diff --git a/arcade-no-apphost.patch b/arcade-no-apphost.patch
new file mode 100644
index 0000000..cec03a1
--- /dev/null
+++ b/arcade-no-apphost.patch
@@ -0,0 +1,36 @@
+Index: a/src/Microsoft.DotNet.GitSync.CommitManager/Microsoft.DotNet.GitSync.CommitManager.csproj
+===================================================================
+--- a/src/Microsoft.DotNet.GitSync.CommitManager/Microsoft.DotNet.GitSync.CommitManager.csproj
++++ b/src/Microsoft.DotNet.GitSync.CommitManager/Microsoft.DotNet.GitSync.CommitManager.csproj
+@@ -5,6 +5,7 @@
+ netcoreapp3.1
+ latest
+ true
++ false
+
+
+
+Index: a/src/Microsoft.DotNet.SwaggerGenerator/Microsoft.DotNet.SwaggerGenerator.CmdLine/Microsoft.DotNet.SwaggerGenerator.CmdLine.csproj
+===================================================================
+--- a/src/Microsoft.DotNet.SwaggerGenerator/Microsoft.DotNet.SwaggerGenerator.CmdLine/Microsoft.DotNet.SwaggerGenerator.CmdLine.csproj
++++ b/src/Microsoft.DotNet.SwaggerGenerator/Microsoft.DotNet.SwaggerGenerator.CmdLine/Microsoft.DotNet.SwaggerGenerator.CmdLine.csproj
+@@ -9,6 +9,7 @@
+ dotnet-swaggergen
+ false
+ true
++ false
+
+
+
+Index: a/src/Microsoft.DotNet.XUnitConsoleRunner/src/Microsoft.DotNet.XUnitConsoleRunner.csproj
+===================================================================
+--- a/src/Microsoft.DotNet.XUnitConsoleRunner/src/Microsoft.DotNet.XUnitConsoleRunner.csproj
++++ b/src/Microsoft.DotNet.XUnitConsoleRunner/src/Microsoft.DotNet.XUnitConsoleRunner.csproj
+@@ -11,6 +11,7 @@
+ 2.5.1
+ true
+ Major
++ false
+
+
+
diff --git a/build-arm64-bootstrap-tarball b/build-arm64-bootstrap-tarball
new file mode 100755
index 0000000..9f1cc7d
--- /dev/null
+++ b/build-arm64-bootstrap-tarball
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+set -euo pipefail
+
+set -x
+
+bootstrap_dir=$(readlink -f "$1")
+
+version=$(jq -r '.tools.dotnet' "$bootstrap_dir"/global.json)
+
+date=$(date +%F)
+
+mkdir -p "dotnet-arm64-prebuilts-$date"
+
+pushd "dotnet-arm64-prebuilts-$date"
+
+# Getting the exact matching rc2 version gets us an arm64 build without this
+# fix https://github.com/dotnet/runtime/pull/58959. That causes a segfault on
+# startup.
+# wget "https://dotnetcli.azureedge.net/dotnet/Sdk/$version/dotnet-sdk-$version-linux-arm64.tar.gz"
+
+wget https://aka.ms/dotnet/6.0.1XX-rc2/daily/dotnet-sdk-linux-arm64.tar.gz
+
+mapfile -t linux_x64_packages < <(tar tf "$bootstrap_dir"/packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz | grep linux-x64)
+
+for package in "${linux_x64_packages[@]}"; do
+ if [[ "$package" = *'.Intermediate.'* ]]; then
+ continue;
+ fi
+
+ filename=${package##*/}
+ name=${filename%.6.0*}
+ arm_name=${name/linux-x64/linux-arm64}
+ version="6.0${filename##*6.0}"
+ version=${version%.*}
+
+ nappo download --verbose "$arm_name" "$version"
+
+done
+
+popd
+
+tar czf "dotnet-arm64-prebuilts-$date.tar.gz" "dotnet-arm64-prebuilts-$date"
diff --git a/build-dotnet-tarball b/build-dotnet-tarball
index 826752b..8f15c6f 100755
--- a/build-dotnet-tarball
+++ b/build-dotnet-tarball
@@ -1,11 +1,11 @@
#!/bin/bash
# Usage:
-# build-dotnet-tarball [--bootstrap]
+# build-dotnet-tarball [--bootstrap]
#
-# Creates a source archive from a tag (or commit) at github.com/dotnet/source-build
+# Creates a source archive from a tag (or commit) at github.com/dotnet/installer
-# Source-build is a little strange, we need to clone it, check out the
+# installer is a little strange, we need to clone it, check out the
# tag, build it and then create a tarball from the archive directory
# it creates. Also, it is likely that the source archive is only
# buildable on the OS it was initially created in.
@@ -15,9 +15,9 @@ IFS=$'\n\t'
function print_usage {
echo "Usage:"
- echo "$0 [--bootstrap] "
+ echo "$0 [--bootstrap] "
echo
- echo "Creates a source archive from a tag at https://github.com/dotnet/source-build"
+ echo "Creates a source archive from a tag at https://github.com/dotnet/installer"
echo ""
echo " --bootstrap build a source tarball usable for bootstrapping .NET"
}
@@ -102,14 +102,16 @@ set -x
dir_name="dotnet-${tag}"
unmodified_tarball_name="${dir_name}-original"
tarball_name="${dir_name}"
+tarball_suffix=.tar.gz
if [[ ${build_bootstrap} == true ]]; then
unmodified_tarball_name="${unmodified_tarball_name}-${arch}-bootstrap"
tarball_name="${tarball_name}-${arch}-bootstrap"
+ tarball_suffix=.tar.xz
fi
-if [ -f "${tarball_name}.tar.gz" ]; then
- echo "error: ${tarball_name}.tar.gz already exists"
+if [ -f "${tarball_name}${tarball_suffix}" ]; then
+ echo "error: ${tarball_name}${tarball_suffix} already exists"
exit 1
fi
@@ -125,15 +127,9 @@ if [ ! -f "${unmodified_tarball_name}.tar.gz" ]; then
./build.sh /p:ArcadeBuildTarball=true /p:TarballDir="$(readlink -f ../"${unmodified_tarball_name}")"
popd
- if [[ ${build_bootstrap} == true ]]; then
- pushd "${unmodified_tarball_name}"
- ./prep.sh
- popd
- fi
-
popd
- tar czf "${unmodified_tarball_name}.tar.gz" -C "${temp_dir}" "${unmodified_tarball_name}"
+ tar cf "${unmodified_tarball_name}.tar.gz" -C "${temp_dir}" "${unmodified_tarball_name}"
rm -rf "${temp_dir}"
fi
@@ -145,15 +141,36 @@ mv "${unmodified_tarball_name}" "${tarball_name}"
pushd "${tarball_name}"
if [[ ${build_bootstrap} == true ]]; then
+ if [[ "$(wc -l < packages/archive/archiveArtifacts.txt)" != 1 ]]; then
+ echo "error: this is not going to work! update $0 to fix this issue."
+ exit 1
+ fi
+
+ pushd packages/archive/
+ curl -O $(cat archiveArtifacts.txt)
+ popd
+
+ mkdir foo
+ pushd foo
+
+ tar xf ../packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz
+ sed -i -E 's|6.0.0-rtm.21521.1|6.0.0-rtm.21521.4|' PackageVersions.props
+ sed -i -E 's|6.0.0-rtm.21521.1|6.0.0-rtm.21521.4|' PackageVersions.props
+ cat PackageVersions.props
+
+ tar czf ../packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz *
+
+ popd
+ rm -rf foo
+
+ ./prep.sh --bootstrap
+
mkdir -p fixup-previously-source-built-artifacts
pushd fixup-previously-source-built-artifacts
tar xf ../packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz
find . -iname '*fedora*nupkg' -delete
- rm runtime.linux-x64.Microsoft.NETCore.IL*sm.*.nupkg
- wget https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/825db618-e3eb-4426-ba54-b1d6e6c944d8/nuget/v3/flat2//runtime.linux-x64.Microsoft.NETCore.ILAsm/6.0.0-rc.2.21459.6/runtime.linux-x64.microsoft.netcore.ilasm.6.0.0-rc.2.21459.6.nupkg
- wget https://pkgs.dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_packaging/825db618-e3eb-4426-ba54-b1d6e6c944d8/nuget/v3/flat2//runtime.linux-x64.Microsoft.NETCore.ILDAsm/6.0.0-rc.2.21459.6/runtime.linux-x64.microsoft.netcore.ildasm.6.0.0-rc.2.21459.6.nupkg
# We must keep the original file names in the archive, even prepending a ./ leads to issues
- tar -I 'gzip -9' -cf ../packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz *
+ tar -I 'gzip -1' -cf ../packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz *
popd
rm -rf fixup-previously-source-built-artifacts
@@ -164,12 +181,26 @@ fi
# Remove files with funny licenses, crypto implementations and other
# not-very-useful artifacts to reduce tarball size
-# FIXME
-#rm -r src/aspnetcore.*/src/SignalR/clients/java/signalr/gradle*
-#find src/aspnetcore.*/src -type d -name samples -print0 | xargs -0 rm -r
-#rm -r src/nuget-client.*/test/EndToEnd
-#rm -r src/source-build.*/src/humanizer/samples/
+
+# Binaries for gradle
+rm -r src/aspnetcore.*/src/SignalR/clients/java/signalr/gradle*
+
+# Unnecessary crypto implementation: IDEA
+rm -r src/runtime.*/src/tests/JIT/Performance/CodeQuality/Bytemark/
+
+# https://github.com/dotnet/aspnetcore/issues/34785
+find src/aspnetcore.*/src -type d -name samples -print0 | xargs -0 rm -r
+
+# https://github.com/NuGet/Home/issues/11094
+rm -r src/nuget-client.*/test/EndToEnd
+
+# https://github.com/Humanizr/sample-aspnetmvc/issues/1
+rm -r src/source-build.*/src/humanizer/samples/
popd
-tar -I 'gzip -9' -cf "${tarball_name}.tar.gz" "${tarball_name}"
+if [[ ${build_bootstrap} == true ]]; then
+ tar -I 'xz -T 0' -cf "${tarball_name}${tarball_suffix}" "${tarball_name}"
+else
+ tar -czf "${tarball_name}${tarball_suffix}" "${tarball_name}"
+fi
diff --git a/check-debug-symbols.py b/check-debug-symbols.py
index be26d87..b873c77 100755
--- a/check-debug-symbols.py
+++ b/check-debug-symbols.py
@@ -65,7 +65,7 @@ def scan_file(file):
def is_elf(file):
result = subprocess.run(['file', file], stdout=subprocess.PIPE, encoding='utf-8', check=True)
- return re.search('ELF 64-bit LSB (?:executable|shared object)', result.stdout)
+ return re.search('ELF 64-bit LSB (?:pie )(?:executable|shared object)', result.stdout)
def scan_file_if_sensible(file):
if is_elf(file):
diff --git a/dotnet6.0.spec b/dotnet6.0.spec
index 6f523a3..d222adf 100644
--- a/dotnet6.0.spec
+++ b/dotnet6.0.spec
@@ -20,21 +20,21 @@
# until that's done, disable LTO. This has to happen before setting the flags below.
%define _lto_cflags %{nil}
-%global host_version 6.0.0-rc.2.21470.23
-%global runtime_version 6.0.0-rc.2.21470.23
-%global aspnetcore_runtime_version 6.0.0-rc.2.21470.37
-%global sdk_version 6.0.100-rc.2.21474.1
-%global templates_version 6.0.0-rc.2.21470.37
+%global host_version 6.0.0
+%global runtime_version 6.0.0
+%global aspnetcore_runtime_version 6.0.0
+%global sdk_version 6.0.100
+%global templates_version 6.0.0
#%%global templates_version %%(echo %%{runtime_version} | awk 'BEGIN { FS="."; OFS="." } {print $1, $2, $3+1 }')
-%global host_rpm_version 6.0.0
-%global runtime_rpm_version 6.0.0
-%global aspnetcore_runtime_rpm_version %{runtime_rpm_version}
-%global sdk_rpm_version 6.0.0
+%global host_rpm_version %{host_version}
+%global runtime_rpm_version %{runtime_version}
+%global aspnetcore_runtime_rpm_version %{aspnetcore_runtime_version}
+%global sdk_rpm_version %{sdk_version}
# upstream can update releases without revving the SDK version so these don't always match
#%%global upstream_tag v%%{sdk_version}-SDK
-%global upstream_tag 28be3e9a006d90d8c6e87d4353b77882829df718
+%global upstream_tag 9e8b04bbff820c93c142f99a507a46b976f5c14c
%if 0%{?fedora} || 0%{?rhel} < 8
%global use_bundled_libunwind 0
@@ -42,7 +42,7 @@
%global use_bundled_libunwind 1
%endif
-%ifarch aarch64
+%ifarch aarch64 s390x
%global use_bundled_libunwind 1
%endif
@@ -52,49 +52,94 @@
%ifarch aarch64
%global runtime_arch arm64
%endif
+%ifarch s390x
+%global runtime_arch s390x
+%endif
%{!?runtime_id:%global runtime_id %(. /etc/os-release ; echo "${ID}.${VERSION_ID%%.*}")-%{runtime_arch}}
Name: dotnet6.0
Version: %{sdk_rpm_version}
-Release: 0.3.%{upstream_tag}%{?dist}
+Release: 1%{?dist}
Summary: .NET Runtime and SDK
License: MIT and ASL 2.0 and BSD and LGPLv2+ and CC-BY and CC0 and MS-PL and EPL-1.0 and GPL+ and GPLv2 and ISC and OFL and zlib
URL: https://github.com/dotnet/
+%if %{with bootstrap}
# The source is generated on a Fedora box via:
# ./build-dotnet-tarball --bootstrap %%{upstream_tag}
-Source0: dotnet-%{upstream_tag}-x64-bootstrap.tar.gz
+Source0: dotnet-%{upstream_tag}-x64-bootstrap.tar.xz
+# Generated via ./build-arm64-bootstrap-tarball
+Source1: dotnet-arm64-prebuilts-2021-10-29.tar.gz
+# Generated manually, same pattern as the arm64 tarball
+Source2: dotnet-s390x-prebuilts-2021-10-29.tar.gz
+%else
+# The source is generated on a Fedora box via:
+# ./build-dotnet-tarball %%{upstream_tag}
+Source0: dotnet-%{upstream_tag}.tar.gz
+%endif
Source10: check-debug-symbols.py
Source11: dotnet.sh.in
-# https://github.com/NuGet/NuGet.Client/pull/4254
-Patch200: nuget-client-use-work-tree-with-git-apply.patch
+# Fix using lld on Fedora
+Patch100: runtime-arm64-lld-fix.patch
+# Mono still has a dependency on (now unbuildable) ILStrip which was removed from CoreCLR: https://github.com/dotnet/runtime/pull/60315
+Patch101: runtime-mono-remove-ilstrip.patch
+
# https://github.com/dotnet/command-line-api/pull/1401
Patch300: command-line-api-use-work-tree-with-git-apply.patch
+
# https://github.com/microsoft/vstest/pull/3046
Patch400: vstest-use-work-tree-with-git-apply.patch
+# This is the suggestion from https://github.com/dotnet/source-build/pull/2450, applied
Patch500: fsharp-use-work-tree-with-git-apply.patch
+# Disable apphost, needed for s390x
+Patch501: fsharp-no-apphost.patch
+# This is the suggestion from https://github.com/dotnet/source-build/pull/2450, applied
Patch600: xliff-tasks-use-work-tree-with-git-apply.patch
+# Disable apphost, needed for s390x
+Patch700: arcade-no-apphost.patch
+
+# Named mutex fix for mono, needed for s390x. https://github.com/dotnet/roslyn/pull/57003
+Patch800: roslyn-57003-mono-named-mutex.patch
+# Disable apphost, needed for s390x
+Patch801: roslyn-no-apphost.patch
+
+# Disable apphost, needed for s390x
+Patch900: roslyn-analyzers-no-apphost.patch
+
+# Fix mono-specific runtime crashes running msbuild. CoreCLR does not
+# load types that are not actually used/invoked at runtime, while mono
+# does. System.Configuration and System.Security are missing in
+# source-build builds, which breaks msbuild.
+Patch1000: msbuild-no-systemsecurity.patch
+Patch1001: msbuild-no-systemconfiguration.patch
+
# Disable telemetry by default; make it opt-in
-Patch1500: sdk-telemetry-optout.patch
+Patch1500: sdk-telemetry-optout.patch
+# https://github.com/dotnet/sdk/pull/22373
+Patch1501: sdk-22373-portablerid.patch
+
+# https://github.com/dotnet/installer/pull/12516
+Patch1600: installer-12516-portablerid.patch
+# https://github.com/dotnet/installer/pull/12622
+Patch1601: installer-12622-fix-runtime-symbols.patch
-#%%if 0%%{?fedora} > 32 || 0%%{?rhel} > 8
-#ExclusiveArch: aarch64 x86_64
-#%%else
+%if 0%{?fedora} || 0%{?rhel} >= 8
+ExclusiveArch: aarch64 x86_64 s390x
+%else
ExclusiveArch: x86_64
-#%%endif
+%endif
BuildRequires: clang
BuildRequires: cmake
BuildRequires: coreutils
%if %{without bootstrap}
-BuildRequires: dotnet-sdk-6.0-build-reference-packages
BuildRequires: dotnet-sdk-6.0
BuildRequires: dotnet-sdk-6.0-source-built-artifacts
%endif
@@ -105,18 +150,20 @@ BuildRequires: glibc-langpack-en
%endif
BuildRequires: hostname
BuildRequires: krb5-devel
-BuildRequires: libcurl-devel
BuildRequires: libicu-devel
%if ! %{use_bundled_libunwind}
BuildRequires: libunwind-devel
%endif
-BuildRequires: lldb-devel
+%ifarch aarch64
+BuildRequires: lld
+%endif
BuildRequires: llvm
BuildRequires: lttng-ust-devel
BuildRequires: make
BuildRequires: openssl-devel
BuildRequires: python3
BuildRequires: tar
+BuildRequires: util-linux
BuildRequires: zlib-devel
%description
@@ -319,12 +366,25 @@ These are not meant for general use.
%if %{without bootstrap}
%setup -q -n dotnet-%{upstream_tag}
%else
-%ifarch x86_64
-%setup -q -T -b 0 -n dotnet-%{upstream_tag}-%{runtime_arch}-bootstrap
-%endif
+
+%setup -q -T -b 0 -n dotnet-%{upstream_tag}-x64-bootstrap
+
+%ifnarch x86_64
+
+rm -rf .dotnet
%ifarch aarch64
-%setup -q -T -b 0 -n dotnet-%{upstream_tag}-%{runtime_arch}-bootstrap
+tar -x --strip-components=1 -f %{SOURCE1} -C packages/prebuilt
%endif
+%ifarch s390x
+tar -x --strip-components=1 -f %{SOURCE2} -C packages/prebuilt
+%endif
+mkdir -p .dotnet
+tar xf packages/prebuilt/dotnet-sdk*.tar.gz -C .dotnet/
+rm packages/prebuilt/dotnet-sdk*.tar.gz
+boot_sdk_version=$(ls -1 .dotnet/sdk/)
+sed -i -E 's|"dotnet": "[^"]+"|"dotnet" : "'$boot_sdk_version'"|' global.json
+%endif
+
%endif
%if %{without bootstrap}
@@ -336,9 +396,7 @@ find -iname '*.nupkg' -type f -delete
find -iname '*.zip' -type f -delete
rm -rf .dotnet/
rm -rf packages/source-built
-%endif
-%if %{without bootstrap}
mkdir -p packages/archive
ln -s %{_libdir}/dotnet/source-built-artifacts/Private.SourceBuilt.Artifacts.*.tar.gz packages/archive/
ln -s %{_libdir}/dotnet/reference-packages/Private.SourceBuild.ReferencePackages*.tar.gz packages/archive/
@@ -351,10 +409,8 @@ sed -i 's|/usr/share/dotnet|%{_libdir}/dotnet|' src/runtime.*/src/native/corehos
# sed -i 's|skiptests|skiptests ignorewarnings|' repos/runtime.common.props
pushd src/runtime.*
-popd
-
-pushd src/nuget-client.*
-%patch200 -p1
+%patch100 -p1
+%patch101 -p1
popd
pushd src/command-line-api.*
@@ -367,26 +423,53 @@ popd
pushd src/fsharp.*
%patch500 -p1
+%patch501 -p1
popd
pushd src/xliff-tasks.*
%patch600 -p1
popd
-pushd src/sdk.*
-%patch1500 -p1
+pushd src/arcade.*
+%patch700 -p1
popd
-%if %{without bootstrap}
-%ifnarch x86_64
-mkdir -p artifacts/obj/%{runtime_arch}/Release
-cp artifacts/obj/x64/Release/PackageVersions.props artifacts/obj/%{runtime_arch}/Release/PackageVersions.props
-%endif
+pushd src/roslyn.*
+%patch800 -p3
+%patch801 -p1
+popd
+
+pushd src/roslyn-analyzers.*
+%patch900 -p1
+popd
+
+pushd src/msbuild.*
+
+# These are mono-specific fixes. Mono is only used on s390x. Restrict
+# patch to s390x to avoid potential risk in other architectures.
+%ifarch s390x
+%patch1000 -p1
+%patch1001 -p1
%endif
-# Disable package validation which breaks our build, even though we
-# are injecting "blessed" nuget packages produced by Microsoft.
+popd
+
+pushd src/sdk.*
+%patch1500 -p1
+%patch1501 -p1
+popd
+
+pushd src/installer.*
+%patch1600 -p1
+popd
+
+# We need to apply the patch to the already-built tarball's
+# repos/runtime.common.targets, not to the installer's "source" copy.
+%patch1601 -p5
+
+# Disable package validation which breaks our build.
# There's no need to run validation in RPM packages anyway.
+# See https://github.com/dotnet/runtime/pull/60881
sed -i -E 's|( /p:BuildDebPackage=false)|\1 /p:EnablePackageValidation=false|' src/runtime.*/eng/SourceBuild.props
%if ! %{use_bundled_libunwind}
@@ -455,10 +538,13 @@ install -dm 0755 %{buildroot}%{_libdir}/dotnet
ls artifacts/%{runtime_arch}/Release
tar xf artifacts/%{runtime_arch}/Release/dotnet-sdk-%{sdk_version}-%{runtime_id}.tar.gz -C %{buildroot}%{_libdir}/dotnet/
-# FIXME: no managed symbols in 6.0?
+# See https://github.com/dotnet/source-build/issues/2579
+find %{buildroot}%{_libdir}/dotnet/ -type f -name 'testhost.x86' -delete
+find %{buildroot}%{_libdir}/dotnet/ -type f -name 'vstest.console' -delete
+
# Install managed symbols
-#tar xf artifacts/%%{runtime_arch}/Release/runtime/dotnet-runtime-symbols-%%{runtime_version}-%%{runtime_id}.tar.gz \
-# -C %%{buildroot}/%%{_libdir}/dotnet/shared/Microsoft.NETCore.App/%%{runtime_version}/
+tar xf artifacts/%{runtime_arch}/Release/runtime/dotnet-runtime-symbols-%{runtime_id}-%{runtime_version}.tar.gz \
+ -C %{buildroot}/%{_libdir}/dotnet/shared/Microsoft.NETCore.App/%{runtime_version}/
# Fix executable permissions on files
find %{buildroot}%{_libdir}/dotnet/ -type f -name 'apphost' -exec chmod +x {} \;
@@ -505,9 +591,8 @@ install -m 0644 artifacts/%{runtime_arch}/Release/Private.SourceBuilt.Artifacts.
# Check debug symbols in all elf objects. This is not in %%check
# because native binaries are stripped by rpm-build after %%install.
# So we need to do this check earlier.
-# FIXME
-#echo "Testing build results for debug symbols..."
-#%%{SOURCE10} -v %%{buildroot}%%{_libdir}/dotnet/
+echo "Testing build results for debug symbols..."
+%{SOURCE10} -v %{buildroot}%{_libdir}/dotnet/
@@ -566,6 +651,24 @@ install -m 0644 artifacts/%{runtime_arch}/Release/Private.SourceBuilt.Artifacts.
%changelog
+* Wed Nov 10 2021 Omair Majid - 6.0.100-1
+- Update to .NET 6
+
+* Fri Oct 22 2021 Omair Majid - 6.0.0-0.7.rc2
+- Update to .NET 6 RC2
+
+* Fri Oct 08 2021 Omair Majid - 6.0.0-0.6.28be3e9a006d90d8c6e87d4353b77882829df718
+- Enable building on arm64
+- Related: RHBZ#1986017
+
+* Sun Oct 03 2021 Omair Majid - 6.0.0-0.5.28be3e9a006d90d8c6e87d4353b77882829df718
+- Enable building on s390x
+- Related: RHBZ#1986017
+
+* Sun Oct 03 2021 Omair Majid - 6.0.0-0.4.28be3e9a006d90d8c6e87d4353b77882829df718
+- Clean up tarball and add initial support for s390x
+- Related: RHBZ#1986017
+
* Sun Sep 26 2021 Omair Majid - 6.0.0-0.3.28be3e9a006d90d8c6e87d4353b77882829df718
- Update to work-in-progress RC2 release
diff --git a/fsharp-no-apphost.patch b/fsharp-no-apphost.patch
new file mode 100644
index 0000000..1534888
--- /dev/null
+++ b/fsharp-no-apphost.patch
@@ -0,0 +1,21 @@
+--- a/tests/benchmarks/MicroPerf/MicroPerf.fsproj
++++ b/tests/benchmarks/MicroPerf/MicroPerf.fsproj
+@@ -9,6 +9,7 @@
+ $(OtherFlags) --nowarn:57
+ $(OtherFlags) --langversion:preview
+ $(OtherFlags) --define:PREVIEW
++ false
+
+
+
+ $(OtherFlags) --nowarn:1204
+
+
diff --git a/installer-12516-portablerid.patch b/installer-12516-portablerid.patch
new file mode 100644
index 0000000..4cb4ab6
--- /dev/null
+++ b/installer-12516-portablerid.patch
@@ -0,0 +1,23 @@
+From 892222071f73062f969f4f6ed1df8f759b9327b7 Mon Sep 17 00:00:00 2001
+From: Tom Deseyn
+Date: Wed, 3 Nov 2021 15:12:59 +0100
+Subject: [PATCH] GetRuntimeInformation.targets: determine
+ PortableProductMonikerRid based on HostOSName and Architecture.
+
+---
+ src/redist/targets/GetRuntimeInformation.targets | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/redist/targets/GetRuntimeInformation.targets b/src/redist/targets/GetRuntimeInformation.targets
+index 5133c3a3841..01f704c7d8e 100644
+--- a/src/redist/targets/GetRuntimeInformation.targets
++++ b/src/redist/targets/GetRuntimeInformation.targets
+@@ -28,6 +28,8 @@
+ '$(Rid)' == 'linux-musl-x64' ">$(Rid)
+ $(OSName)-$(Architecture)
+
++ $(HostOSName)-$(Architecture)
++
+ dotnet-sdk-internal$(PgoTerm)
+ dotnet-sdk$(PgoTerm)
+
diff --git a/installer-12622-fix-runtime-symbols.patch b/installer-12622-fix-runtime-symbols.patch
new file mode 100644
index 0000000..fa2d46f
--- /dev/null
+++ b/installer-12622-fix-runtime-symbols.patch
@@ -0,0 +1,48 @@
+From 7365824ddc6ed66152cfc50f4c8508368953099c Mon Sep 17 00:00:00 2001
+From: Omair Majid
+Date: Tue, 9 Nov 2021 08:39:27 -0500
+Subject: [PATCH] Also publish non-portable RID runtime symbols tarball
+
+This fixes a regression in .NET 6 source-build compared to the .NET
+5 source-build.
+
+source-build wants to publish runtime symbols tarball for portable (eg,
+linux-x64) and non-portable (eg, fedora.33-x64) RIDs here after a build.
+Following .NET 5 conventions, I expected to see:
+
+ ./artifacts/x64/Release/runtime/dotnet-runtime-symbols-fedora.34-x64-6.0.0.tar.gz
+ ./artifacts/x64/Release/runtime/dotnet-runtime-symbols-linux-x64-6.0.0.tar.gz
+
+Unfortunately, only the portable RID (linux-x64) tarball is present
+after a full source-build in .NET 6.
+
+It turns out this is a bug in our build scripts. We try and copy
+binaries - including the symbol tarballs - after building each of
+runtime-portable and runtime. However, the target dependency is wrong:
+after `Build`, the intermediate package doesn't exist from the
+just-built repo.
+
+What ends up happening is that nothing is copied after building
+runtime-portable. However, after building runtime, the runtime-portable
+intermediate artifacts are found and copied over. So the end
+build has portable RID symbos, but not the non-portable ones.
+
+Fix that by changing the dependency of this target so it runs after
+intermediate packages are available.
+---
+ src/SourceBuild/tarball/content/repos/runtime.common.targets | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/SourceBuild/tarball/content/repos/runtime.common.targets b/src/SourceBuild/tarball/content/repos/runtime.common.targets
+index ca606b23d21..862b70dc832 100644
+--- a/src/SourceBuild/tarball/content/repos/runtime.common.targets
++++ b/src/SourceBuild/tarball/content/repos/runtime.common.targets
+@@ -23,7 +23,7 @@
+
+
+
+
diff --git a/msbuild-no-systemconfiguration.patch b/msbuild-no-systemconfiguration.patch
new file mode 100644
index 0000000..537470d
--- /dev/null
+++ b/msbuild-no-systemconfiguration.patch
@@ -0,0 +1,46 @@
+--- a/src/Build/Definition/ProjectCollection.cs
++++ b/src/Build/Definition/ProjectCollection.cs
+@@ -1754,7 +1754,11 @@ namespace Microsoft.Build.Evaluation
+ #if FEATURE_WIN32_REGISTRY
+ ToolsetRegistryReader registryReader = null,
+ #endif
++#if FEATURE_SYSTEM_CONFIGURATION
+ ToolsetConfigurationReader configReader = null
++#else
++ object configReader = null
++#endif
+ )
+ {
+ _toolsets = new Dictionary(StringComparer.OrdinalIgnoreCase);
+--- a/src/Build/Definition/ToolsetReader.cs
++++ b/src/Build/Definition/ToolsetReader.cs
+@@ -101,7 +101,11 @@ namespace Microsoft.Build.Evaluation
+ #if FEATURE_WIN32_REGISTRY
+ ToolsetRegistryReader registryReader,
+ #endif
++#if FEATURE_SYSTEM_CONFIGURATION
+ ToolsetConfigurationReader configurationReader,
++#else
++ object _configurationReader,
++#endif
+ PropertyDictionary environmentProperties,
+ PropertyDictionary globalProperties,
+ ToolsetDefinitionLocations locations
+@@ -120,6 +124,7 @@ namespace Microsoft.Build.Evaluation
+
+ if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
+ {
++#if FEATURE_SYSTEM_CONFIGURATION
+ if (configurationReader == null)
+ {
+ configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties);
+@@ -129,6 +134,9 @@ namespace Microsoft.Build.Evaluation
+ defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties,
+ initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration,
+ out defaultOverrideToolsVersionFromConfiguration);
++#else
++ throw new InvalidOperationException("ToolsetDefinitionLocations.ConfigurationFile not supported");
++#endif
+ }
+
+ string defaultToolsVersionFromRegistry = null;
diff --git a/msbuild-no-systemsecurity.patch b/msbuild-no-systemsecurity.patch
new file mode 100644
index 0000000..dcf6809
--- /dev/null
+++ b/msbuild-no-systemsecurity.patch
@@ -0,0 +1,12 @@
+--- a/src/Shared/ExceptionHandling.cs
++++ b/src/Shared/ExceptionHandling.cs
+@@ -153,7 +153,9 @@ namespace Microsoft.Build.Shared
+ internal static bool IsXmlException(Exception e)
+ {
+ return e is XmlException
++#if FEATURE_SECURITY_PERMISSIONS
+ || e is XmlSyntaxException
++#endif
+ || e is XmlSchemaException
+ || e is UriFormatException; // XmlTextReader for example uses this under the covers
+ }
diff --git a/nuget-client-use-work-tree-with-git-apply.patch b/nuget-client-use-work-tree-with-git-apply.patch
deleted file mode 100644
index e1785ae..0000000
--- a/nuget-client-use-work-tree-with-git-apply.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 691babb1c8316e2f829fbcf9f2aa14f4b7711960 Mon Sep 17 00:00:00 2001
-From: Omair Majid
-Date: Thu, 9 Sep 2021 10:03:36 -0400
-Subject: [PATCH] [ArPow] Use --work-tree with git apply
-
-This makes things work bettern in a source-tarball build (where there
-may not be a .git directory), or there might be a .git directory but
-it's for a different repo than the one we are building.
----
- eng/source-build/source-build.proj | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/eng/source-build/source-build.proj b/eng/source-build/source-build.proj
-index 6f90f9793..72058ac88 100644
---- a/eng/source-build/source-build.proj
-+++ b/eng/source-build/source-build.proj
-@@ -55,7 +55,7 @@
-
-
-
-
---
-2.31.1
-
diff --git a/roslyn-57003-mono-named-mutex.patch b/roslyn-57003-mono-named-mutex.patch
new file mode 100644
index 0000000..c264bff
--- /dev/null
+++ b/roslyn-57003-mono-named-mutex.patch
@@ -0,0 +1,453 @@
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs
+@@ -31,5 +31,24 @@ namespace Roslyn.Utilities
+ }
+ }
+ }
++ ///
++ /// Are we running on .NET 5 or later using the Mono runtime?
++ /// Will also return true when running on Mono itself; if necessary
++ /// we can use IsRunningOnMono to distinguish.
++ ///
++ public static bool IsUsingMonoRuntime
++ {
++ get
++ {
++ try
++ {
++ return !(Type.GetType("Mono.RuntimeStructs", throwOnError: false) is null);
++ }
++ catch
++ {
++ return false;
++ }
++ }
++ }
+ }
+ }
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs
+@@ -79,7 +79,7 @@ namespace Microsoft.CodeAnalysis.Compile
+ // to connect. When it fails it should fall back to in-proc
+ // compilation.
+ bool holdsMutex;
+- using (var serverMutex = new Mutex(initiallyOwned: true,
++ using (var serverMutex = BuildServerConnection.OpenOrCreateMutex(
+ name: BuildServerConnection.GetServerMutexName(_pipeName),
+ createdNew: out holdsMutex))
+ {
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs
+@@ -103,7 +103,7 @@ class Hello
+ var mutexName = BuildServerConnection.GetServerMutexName(pipeName);
+
+ bool holdsMutex;
+- using (var mutex = new Mutex(initiallyOwned: true,
++ using (var mutex = BuildServerConnection.OpenOrCreateMutex(
+ name: mutexName,
+ createdNew: out holdsMutex))
+ {
+@@ -119,7 +119,7 @@ class Hello
+ }
+ finally
+ {
+- mutex.ReleaseMutex();
++ mutex.Dispose();
+ }
+ }
+ }
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs
+@@ -304,7 +304,7 @@ End Module")
+ var newTempDir = _tempDirectory.CreateDirectory(new string('a', 100 - _tempDirectory.Path.Length));
+ await ApplyEnvironmentVariables(
+ new[] { new KeyValuePair("TMPDIR", newTempDir.Path) },
+- async () =>
++ async () => await Task.Run(async () =>
+ {
+ using var serverData = await ServerUtil.CreateServer(_logger);
+ var result = RunCommandLineCompiler(
+@@ -317,7 +317,7 @@ End Module")
+
+ var listener = await serverData.Complete();
+ Assert.Equal(CompletionData.RequestCompleted, listener.CompletionDataList.Single());
+- });
++ }));
+ }
+
+ [Fact]
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs
+@@ -101,7 +101,7 @@ namespace Microsoft.CodeAnalysis.Compile
+
+ var thread = new Thread(() =>
+ {
+- using (var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created))
++ using (var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created))
+ using (var stream = NamedPipeUtil.CreateServer(pipeName))
+ {
+ readyMre.Set();
+@@ -112,7 +112,7 @@ namespace Microsoft.CodeAnalysis.Compile
+ stream.Close();
+
+ doneMre.WaitOne();
+- mutex.ReleaseMutex();
++ mutex.Dispose();
+ }
+ });
+
+@@ -153,7 +153,7 @@ namespace Microsoft.CodeAnalysis.Compile
+ {
+ using (var stream = NamedPipeUtil.CreateServer(pipeName))
+ {
+- var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created);
++ var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created);
+ readyMre.Set();
+
+ stream.WaitForConnection();
+@@ -161,7 +161,6 @@ namespace Microsoft.CodeAnalysis.Compile
+
+ // Client is waiting for a response. Close the mutex now. Then close the connection
+ // so the client gets an error.
+- mutex.ReleaseMutex();
+ mutex.Dispose();
+ stream.Close();
+
+Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs
+===================================================================
+--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs
++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs
+@@ -543,19 +543,10 @@ namespace Microsoft.CodeAnalysis.Command
+ {
+ try
+ {
+- if (PlatformInformation.IsRunningOnMono)
++ if (PlatformInformation.IsUsingMonoRuntime)
+ {
+- IServerMutex? mutex = null;
+- bool createdNew = false;
+- try
+- {
+- mutex = new ServerFileMutexPair(mutexName, false, out createdNew);
+- return !createdNew;
+- }
+- finally
+- {
+- mutex?.Dispose();
+- }
++ using var mutex = new ServerFileMutex(mutexName);
++ return !mutex.CouldLock();
+ }
+ else
+ {
+@@ -572,9 +563,11 @@ namespace Microsoft.CodeAnalysis.Command
+
+ internal static IServerMutex OpenOrCreateMutex(string name, out bool createdNew)
+ {
+- if (PlatformInformation.IsRunningOnMono)
++ if (PlatformInformation.IsUsingMonoRuntime)
+ {
+- return new ServerFileMutexPair(name, initiallyOwned: true, out createdNew);
++ var mutex = new ServerFileMutex(name);
++ createdNew = mutex.TryLock(0);
++ return mutex;
+ }
+ else
+ {
+@@ -648,19 +641,22 @@ namespace Microsoft.CodeAnalysis.Command
+ }
+
+ ///
+- /// An interprocess mutex abstraction based on OS advisory locking (FileStream.Lock/Unlock).
++ /// An interprocess mutex abstraction based on file sharing permission (FileShare.None).
+ /// If multiple processes running as the same user create FileMutex instances with the same name,
+ /// those instances will all point to the same file somewhere in a selected temporary directory.
+- /// The TryLock method can be used to attempt to acquire the mutex, with Unlock or Dispose used to release.
++ /// The TryLock method can be used to attempt to acquire the mutex, with Dispose used to release.
++ /// The CouldLock method can be used to check whether an attempt to acquire the mutex would have
++ /// succeeded at the current time, without actually acquiring it.
+ /// Unlike Win32 named mutexes, there is no mechanism for detecting an abandoned mutex. The file
+ /// will simply revert to being unlocked but remain where it is.
+ ///
+- internal sealed class FileMutex : IDisposable
++ internal sealed class ServerFileMutex : IServerMutex
+ {
+- public readonly FileStream Stream;
++ public FileStream? Stream;
+ public readonly string FilePath;
++ public readonly string GuardPath;
+
+- public bool IsLocked { get; private set; }
++ public bool IsDisposed { get; private set; }
+
+ internal static string GetMutexDirectory()
+ {
+@@ -670,61 +666,176 @@ namespace Microsoft.CodeAnalysis.Command
+ return result;
+ }
+
+- public FileMutex(string name)
++ public ServerFileMutex(string name)
+ {
+- FilePath = Path.Combine(GetMutexDirectory(), name);
+- Stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
++ var mutexDirectory = GetMutexDirectory();
++ FilePath = Path.Combine(mutexDirectory, name);
++ GuardPath = Path.Combine(mutexDirectory, ".guard");
+ }
+
+- public bool TryLock(int timeoutMs)
++ ///
++ /// Acquire the guard by opening the guard file with FileShare.None. The guard must only ever
++ /// be held for very brief amounts of time, so we can simply spin until it is acquired. The
++ /// guard must be released by disposing the FileStream returned from this routine. Note the
++ /// guard file is never deleted; this is a leak, but only of a single file.
++ ///
++ internal FileStream LockGuard()
+ {
+- if (IsLocked)
+- throw new InvalidOperationException("Lock already held");
+-
+- var sw = Stopwatch.StartNew();
+- do
++ // We should be able to acquire the guard quickly. Limit the number of retries anyway
++ // by some arbitrary bound to avoid getting hung up in a possibly infinite loop.
++ for (var i = 0; i < 100; i++)
+ {
+ try
+ {
+- Stream.Lock(0, 0);
+- IsLocked = true;
+- return true;
++ return new FileStream(GuardPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
+ }
+ catch (IOException)
+ {
+- // Lock currently held by someone else.
++ // Guard currently held by someone else.
+ // We want to sleep for a short period of time to ensure that other processes
+ // have an opportunity to finish their work and relinquish the lock.
+ // Spinning here (via Yield) would work but risks creating a priority
+ // inversion if the lock is held by a lower-priority process.
+ Thread.Sleep(1);
+ }
++ }
++ // Handle unexpected failure to acquire guard as error.
++ throw new InvalidOperationException("Unable to acquire guard");
++ }
++
++ ///
++ /// Attempt to acquire the lock by opening the lock file with FileShare.None. Sets "Stream"
++ /// and returns true if successful, returns false if the lock is already held by another
++ /// thread or process. Guard must be held when calling this routine.
++ ///
++ internal bool TryLockFile()
++ {
++ Debug.Assert(Stream is null);
++ FileStream? stream = null;
++ try
++ {
++ stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
++ // On some targets, the file locking used to implement FileShare.None may not be
++ // atomic with opening/creating the file. This creates a race window when another
++ // thread holds the lock and is just about to unlock: we may be able to open the
++ // file here, then the other thread unlocks and deletes the file, and then we
++ // acquire the lock on our file handle - but the actual file is already deleted.
++ // To close this race, we verify that the file does in fact still exist now that
++ // we have successfull acquired the locked FileStream. (Note that this check is
++ // safe because we cannot race with an other attempt to create the file since we
++ // hold the guard, and after the FileStream constructor returned we can no race
++ // with file deletion because we hold the lock.)
++ if (!File.Exists(FilePath))
++ {
++ // To simplify the logic, we treat this case as "unable to acquire the lock"
++ // because it we caught another process while it owned the lock and was just
++ // giving it up. If the caller retries, we'll likely acquire the lock then.
++ stream.Dispose();
++ return false;
++ }
++ }
++ catch (Exception)
++ {
++ stream?.Dispose();
++ return false;
++ }
++ Stream = stream;
++ return true;
++ }
++
++ ///
++ /// Release the lock by deleting the lock file and disposing "Stream".
++ ///
++ internal void UnlockFile()
++ {
++ Debug.Assert(Stream is not null);
++ try
++ {
++ // Delete the lock file while the stream is not yet disposed
++ // and we therefore still hold the FileShare.None exclusion.
++ // There may still be a race with another thread attempting a
++ // TryLockFile in parallel, but that is safely handled there.
++ File.Delete(FilePath);
++ }
++ finally
++ {
++ Stream.Dispose();
++ Stream = null;
++ }
++ }
++
++ public bool TryLock(int timeoutMs)
++ {
++ if (IsDisposed)
++ throw new ObjectDisposedException("Mutex");
++ if (Stream is not null)
++ throw new InvalidOperationException("Lock already held");
++
++ var sw = Stopwatch.StartNew();
++ do
++ {
++ try
++ {
++ // Attempt to acquire lock while holding guard.
++ using var guard = LockGuard();
++ if (TryLockFile())
++ return true;
++ }
+ catch (Exception)
+ {
+- // Something else went wrong.
+ return false;
+ }
++
++ // See comment in LockGuard.
++ Thread.Sleep(1);
+ } while (sw.ElapsedMilliseconds < timeoutMs);
+
+ return false;
+ }
+
+- public void Unlock()
++ public bool CouldLock()
+ {
+- if (!IsLocked)
+- return;
+- Stream.Unlock(0, 0);
+- IsLocked = false;
++ if (IsDisposed)
++ return false;
++ if (Stream is not null)
++ return false;
++
++ try
++ {
++ // Attempt to acquire lock while holding guard, and if successful
++ // immediately unlock again while still holding guard. This ensures
++ // no other thread will spuriously observe the lock as held due to
++ // the lock attempt here.
++ using var guard = LockGuard();
++ if (TryLockFile())
++ {
++ UnlockFile();
++ return true;
++ }
++ }
++ catch (Exception)
++ {
++ return false;
++ }
++
++ return false;
+ }
+
+ public void Dispose()
+ {
+- var wasLocked = IsLocked;
+- if (wasLocked)
+- Unlock();
+- Stream.Dispose();
+- // We do not delete the lock file here because there is no reliable way to perform a
+- // 'delete if no one has the file open' operation atomically on *nix. This is a leak.
++ if (IsDisposed)
++ return;
++ IsDisposed = true;
++ if (Stream is not null)
++ {
++ try
++ {
++ UnlockFile();
++ }
++ catch (Exception)
++ {
++ }
++ }
+ }
+ }
+
+@@ -792,56 +903,4 @@ namespace Microsoft.CodeAnalysis.Command
+ }
+ }
+ }
+-
+- ///
+- /// Approximates a named mutex with 'locked', 'unlocked' and 'abandoned' states.
+- /// There is no reliable way to detect whether a mutex has been abandoned on some target platforms,
+- /// so we use the AliveMutex to manually track whether the creator of a mutex is still running,
+- /// while the HeldMutex represents the actual lock state of the mutex.
+- ///
+- internal sealed class ServerFileMutexPair : IServerMutex
+- {
+- public readonly FileMutex AliveMutex;
+- public readonly FileMutex HeldMutex;
+-
+- public bool IsDisposed { get; private set; }
+-
+- public ServerFileMutexPair(string mutexName, bool initiallyOwned, out bool createdNew)
+- {
+- AliveMutex = new FileMutex(mutexName + "-alive");
+- HeldMutex = new FileMutex(mutexName + "-held");
+- createdNew = AliveMutex.TryLock(0);
+- if (initiallyOwned && createdNew)
+- {
+- if (!TryLock(0))
+- throw new Exception("Failed to lock mutex after creating it");
+- }
+- }
+-
+- public bool TryLock(int timeoutMs)
+- {
+- if (IsDisposed)
+- throw new ObjectDisposedException("Mutex");
+- return HeldMutex.TryLock(timeoutMs);
+- }
+-
+- public void Dispose()
+- {
+- if (IsDisposed)
+- return;
+- IsDisposed = true;
+-
+- try
+- {
+- HeldMutex.Unlock();
+- AliveMutex.Unlock();
+- }
+- finally
+- {
+- AliveMutex.Dispose();
+- HeldMutex.Dispose();
+- }
+- }
+- }
+-
+ }
diff --git a/roslyn-analyzers-no-apphost.patch b/roslyn-analyzers-no-apphost.patch
new file mode 100644
index 0000000..c1fc3dd
--- /dev/null
+++ b/roslyn-analyzers-no-apphost.patch
@@ -0,0 +1,10 @@
+--- a/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj
++++ b/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj
+@@ -4,6 +4,7 @@
+ netcoreapp3.1
+ true
+ true
++ false
+
+
+
diff --git a/roslyn-no-apphost.patch b/roslyn-no-apphost.patch
new file mode 100644
index 0000000..f1767c7
--- /dev/null
+++ b/roslyn-no-apphost.patch
@@ -0,0 +1,10 @@
+--- a/src/Workspaces/Remote/ServiceHub.CoreComponents/Microsoft.CodeAnalysis.Remote.ServiceHub.CoreComponents.csproj
++++ b/src/Workspaces/Remote/ServiceHub.CoreComponents/Microsoft.CodeAnalysis.Remote.ServiceHub.CoreComponents.csproj
+@@ -5,6 +5,7 @@
+ Exe
+ netcoreapp3.1
+
++ false
+ false
+
+
diff --git a/runtime-arm64-lld-fix.patch b/runtime-arm64-lld-fix.patch
new file mode 100644
index 0000000..5972f45
--- /dev/null
+++ b/runtime-arm64-lld-fix.patch
@@ -0,0 +1,13 @@
+diff --git a/eng/native/init-compiler.sh b/eng/native/init-compiler.sh
+index 567d18da474..927b3071e92 100755
+--- a/eng/native/init-compiler.sh
++++ b/eng/native/init-compiler.sh
+@@ -108,7 +108,7 @@ if [[ -z "$CC" ]]; then
+ fi
+
+ if [[ "$compiler" == "clang" ]]; then
+- if command -v "lld$desired_version" > /dev/null; then
++ if command -v lld || command -v "lld$desired_version" > /dev/null; then
+ # Only lld version >= 9 can be considered stable
+ if [[ "$majorVersion" -ge 9 ]]; then
+ LDFLAGS="-fuse-ld=lld"
diff --git a/runtime-mono-remove-ilstrip.patch b/runtime-mono-remove-ilstrip.patch
new file mode 100644
index 0000000..9a711f8
--- /dev/null
+++ b/runtime-mono-remove-ilstrip.patch
@@ -0,0 +1,33 @@
+diff --git a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj
+index 724b704f864..3dabdc81dae 100644
+--- a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj
++++ b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj
+@@ -6,7 +6,7 @@
+
+
+
+-
++
+
+
+
+@@ -15,7 +15,7 @@
+
+
+
+-
++
+
+
+
+diff --git a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props
+index 8a7ede79242..cfd515eeca9 100644
+--- a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props
++++ b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props
+@@ -1,5 +1,5 @@
+
+-
++
+
+
+
diff --git a/sdk-22373-portablerid.patch b/sdk-22373-portablerid.patch
new file mode 100644
index 0000000..8b39eb3
--- /dev/null
+++ b/sdk-22373-portablerid.patch
@@ -0,0 +1,22 @@
+From 499fcf6e3b0e4b01a9c340a06f00cfc3e1fcc5d2 Mon Sep 17 00:00:00 2001
+From: Tom Deseyn
+Date: Tue, 5 Oct 2021 09:04:14 +0200
+Subject: [PATCH] Use the portable rid for --use-current-runtime.
+
+---
+ .../targets/Microsoft.NET.RuntimeIdentifierInference.targets | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
+index 17308aa9160..e764b2d9845 100644
+--- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
++++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets
+@@ -62,7 +62,7 @@ Copyright (c) .NET Foundation. All rights reserved.
+
+
+
+- $(NETCoreSdkRuntimeIdentifier)
++ $(NETCoreSdkPortableRuntimeIdentifier)
+
+
+