Skip to content

Commit

Permalink
Enable building on arm64
Browse files Browse the repository at this point in the history
This change allows source-build to be cloned and built on arm64
machines. It shouldn't affect cross compilation at all, however. I have
tested this on RHEL 8 aarch64.

This change includes backports of the following pull-requests which have
been merged into their respective master branches:

- dotnet/aspnetcore#14790
- dotnet/aspnetcore#15354
- dotnet/installer#4102
- dotnet/core-setup#8468
- dotnet/corefx#40453

There's a number of existing build configuration that are
conditionalized on arm64, such as setting up a root file system. Those
they are actually only meant to be invoked when cross-compiling for
arm64 (on x86_64). This commit modifies those conditions to not apply
when building on an arm64 machine.
  • Loading branch information
omajid authored and crummel committed Nov 22, 2019
1 parent 733b4fd commit 03496f2
Show file tree
Hide file tree
Showing 14 changed files with 405 additions and 26 deletions.
58 changes: 42 additions & 16 deletions build-source-tarball.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@ if [ -z "${1:-}" ]; then
exit 1
fi

# Use uname to determine what the CPU is.
cpuname=$(uname -p)
# Some Linux platforms report unknown for platform, but the arch for machine.
if [[ "$cpuname" == "unknown" ]]; then
cpuname=$(uname -m)
fi

case $cpuname in
aarch64)
targetArchitecture=arm64
;;
amd64|x86_64)
targetArchitecture=x64
;;
armv7l)
targetArchitecture=arm
;;
i686)
targetArchitecture=x86
;;
*)
echo "Unknown CPU $cpuname detected, treating it as x64"
targetArchitecture=x64
;;
esac

TARBALL_ROOT=$1
shift

Expand Down Expand Up @@ -217,28 +243,28 @@ cp $SCRIPT_ROOT/support/tarball/build.sh $TARBALL_ROOT/build.sh
mkdir -p $TARBALL_ROOT/packages/prebuilt
mkdir -p $TARBALL_ROOT/packages/source-built
find $SCRIPT_ROOT/packages/restored/ -name '*.nupkg' -exec cp {} $TARBALL_ROOT/packages/prebuilt/ \;
find $SCRIPT_ROOT/bin/obj/x64/Release/nuget-packages -name '*.nupkg' -exec cp {} $TARBALL_ROOT/packages/prebuilt/ \;
find $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/nuget-packages -name '*.nupkg' -exec cp {} $TARBALL_ROOT/packages/prebuilt/ \;

# Copy reference-packages from bin dir to reference-packages directory.
# See corresponding change in dir.props to change ReferencePackagesBasePath conditionally in offline build.
mkdir -p $TARBALL_ROOT/packages/reference
cp -r $SCRIPT_ROOT/bin/obj/x64/Release/reference-packages/source $TARBALL_ROOT/packages/reference/source
cp -r $SCRIPT_ROOT/bin/obj/x64/Release/reference-packages/staging $TARBALL_ROOT/packages/reference/staging
cp -r $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/reference-packages/source $TARBALL_ROOT/packages/reference/source
cp -r $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/reference-packages/staging $TARBALL_ROOT/packages/reference/staging

# Copy tarballs to ./packages/archive directory
mkdir -p $TARBALL_ROOT/packages/archive
cp -r $SCRIPT_ROOT/bin/obj/x64/Release/external-tarballs/*.tar.gz $TARBALL_ROOT/packages/archive/
cp -r $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/external-tarballs/*.tar.gz $TARBALL_ROOT/packages/archive/

# Copy generated source from bin to src/generatedSrc
cp -r $SCRIPT_ROOT/bin/obj/x64/Release/generatedSrc $TARBALL_ROOT/src/generatedSrc
cp -r $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/generatedSrc $TARBALL_ROOT/src/generatedSrc

if [ -e $SCRIPT_ROOT/testing-smoke/smoke-test-packages ]; then
cp -rf $SCRIPT_ROOT/testing-smoke/smoke-test-packages $TARBALL_ROOT/packages
fi

echo 'Removing source-built packages from tarball prebuilts...'

for built_package in $(find $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/ -name '*.nupkg' | tr '[:upper:]' '[:lower:]')
for built_package in $(find $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/ -name '*.nupkg' | tr '[:upper:]' '[:lower:]')
do
if [ -e $TARBALL_ROOT/packages/prebuilt/$(basename $built_package) ]; then
rm $TARBALL_ROOT/packages/prebuilt/$(basename $built_package)
Expand All @@ -251,16 +277,16 @@ done
echo 'Copying source-built packages to tarball to replace packages needed before they are built...'
mkdir -p $TARBALL_ROOT/packages/source-built
cp -r $SCRIPT_ROOT/Tools/source-built/coreclr-tools $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/*Arcade*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/*SourceLink*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/*Build*Tasks*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/runtime*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/*DotNetHost*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/*DotNetAppHost*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/*Arcade*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/*SourceLink*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/*Build*Tasks*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/runtime*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/*DotNetHost*.nupkg $TARBALL_ROOT/packages/source-built/
cp $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/*DotNetAppHost*.nupkg $TARBALL_ROOT/packages/source-built/

# Setup package version props to include both source-built and running PackageVersions.props
mkdir --parents $TARBALL_ROOT/bin/obj/x64/Release/
cp $SCRIPT_ROOT/support/tarball/PackageVersions.props $TARBALL_ROOT/bin/obj/x64/Release/
mkdir --parents $TARBALL_ROOT/bin/obj/$targetArchitecture/Release/
cp $SCRIPT_ROOT/support/tarball/PackageVersions.props $TARBALL_ROOT/bin/obj/$targetArchitecture/Release/

if [ $INCLUDE_LEAK_DETECTION -eq 1 ]; then
echo 'Building leak detection MSBuild tasks...'
Expand All @@ -270,7 +296,7 @@ fi

echo 'Removing reference-only packages from tarball prebuilts...'

for ref_package in $(find $SCRIPT_ROOT/bin/obj/x64/Release/reference-packages/packages-to-delete/ -name '*.nupkg' | tr '[:upper:]' '[:lower:]')
for ref_package in $(find $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/reference-packages/packages-to-delete/ -name '*.nupkg' | tr '[:upper:]' '[:lower:]')
do
if [ -e $TARBALL_ROOT/packages/prebuilt/$(basename $ref_package) ]; then
rm $TARBALL_ROOT/packages/prebuilt/$(basename $ref_package)
Expand Down Expand Up @@ -328,7 +354,7 @@ fi
echo 'Removing source-built, previously source-built packages and reference packages from il pkg src...'
OLDIFS=$IFS

allBuiltPkgs=(`ls $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/*.nupkg | xargs -n1 basename | tr '[:upper:]' '[:lower:]'`)
allBuiltPkgs=(`ls $SCRIPT_ROOT/bin/obj/$targetArchitecture/Release/blob-feed/packages/*.nupkg | xargs -n1 basename | tr '[:upper:]' '[:lower:]'`)
pushd $TARBALL_ROOT/packages/reference/staging/
ilSrcPaths=(`find . -maxdepth 2 -mindepth 2`)
popd
Expand Down
5 changes: 4 additions & 1 deletion dir.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition="$(Configuration) == ''">Release</Configuration>

<BuildArchitecture>$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant())</BuildArchitecture>
<Platform Condition="'$(Platform)' == '' AND '$(BuildArchitecture)' == 'arm64'">$(BuildArchitecture)</Platform>
<Platform Condition="'$(Platform)' == ''">x64</Platform>

<!-- true if we have bootstrapped buildtools (usually on an unsupported platform -->
Expand Down Expand Up @@ -201,7 +204,7 @@
<ExtraPackageVersionPropsPackageInfo Include="MicrosoftNETCoreAppRuntimePackageVersion" Version="%24(MicrosoftNETCoreDotNetAppHostPackageVersion)" />
<ExtraPackageVersionPropsPackageInfo Include="MicrosoftNETCoreAppRuntimeVersion" Version="%24(MicrosoftNETCoreDotNetAppHostPackageVersion)" />
<ExtraPackageVersionPropsPackageInfo Include="MicrosoftNETCoreAppHostPackageVersion" Version="%24(MicrosoftNETCoreDotNetAppHostPackageVersion)" />
<ExtraPackageVersionPropsPackageInfo Include="MicrosoftAspNetCoreAppRuntimePackageVersion" Version="%24(MicrosoftAspNetCoreAppRuntimeLinuxX64PackageVersion)" />
<ExtraPackageVersionPropsPackageInfo Include="MicrosoftAspNetCoreAppRuntimePackageVersion" Version="%24(MicrosoftAspNetCoreAppRuntimeLinux$(Platform)PackageVersion)" />
<!-- core-sdk uses this property for ASP.NET blob directory -->
<ExtraPackageVersionPropsPackageInfo Include="VSRedistCommonAspNetCoreTargetingPackx6430PackageVersion" Version="$(aspnetcoreOutputPackageVersion)" />
<!-- OSX needs the OSX version instead of Linux. We don't have a lot of flexibility in how we output these properties so we're relying on the previous one being blank if the Linux version of the package is missing. -->
Expand Down
33 changes: 33 additions & 0 deletions patches/aspnetcore/0011-Support-global.json-on-arm64-as-well.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
From 84d274a8f3d416b0a5bd999e3d1c43ae1535e38f Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Wed, 23 Oct 2019 15:43:57 -0400
Subject: [PATCH] Support global.json on arm64 as well

arcade uses the runtime section of global.json to decide which
architecture + runtime combination needs to be installed.

With https://github.com/dotnet/arcade/pull/4132 arcade can install
foreign SDKs in separate locations correctly.

This change, suggested by @dougbu, makes arcade always install the
runtime for the local architecture (which means it should work on arm64
and x64) as well as the x86 architecture (skipped on Linux).

This gets us a working SDK/Runtime combo on arm64.
---
global.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/global.json b/global.json
index 602f4f44e17..40dec559cc9 100644
--- a/global.json
+++ b/global.json
@@ -5,7 +5,7 @@
"tools": {
"dotnet": "3.1.100-preview1-014400",
"runtimes": {
- "dotnet/x64": [
+ "dotnet": [
"$(MicrosoftNETCoreAppRuntimeVersion)"
],
"dotnet/x86": [
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
From e2946a26c11be7f7f0c223721a5b14f58f2ea240 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Mon, 11 Nov 2019 13:37:40 -0500
Subject: [PATCH] Support building for arm64 on arm64 (*nix)

This commit allows ASP.NET Core to be built on arm64 machines directly,
without relying on cross-compilation.

There's a few changes in here:

1. Ask msbuild to look into the BuildArchitecture

By default, our build systems assums the machine is x64. This
modifies the build configuration to check the architecture of the
currently running build machine, and set BuildArchitecture to that.

2. Fix crossgen in Microsoft.AspNetCore.App.Runtime

We run crossgen for supported architectures (including x64 and
arm64). For that, we need a jit that we can point crossgen to.
Generally, we can rely on the build scripts to find the right
`libclrjit.so`. However, arm64 has multiple `libclirjit.so`, for
different use-cases. There's one for arm64 (for running on arm64) and
there's another one for cross-compiling for arm64 on x64. We need to
figure out and use the right one explicitly rather than assuming the
right one gets picked up.

See https://github.com/dotnet/core-setup/pull/8468 for similar
changes made in core-setup.

This also needs https://github.com/aspnet/AspNetCore/pull/14790 to fully
work on arm64.
---
Directory.Build.props | 1 +
.../src/Microsoft.AspNetCore.App.Runtime.csproj | 12 ++++++++----
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/Directory.Build.props b/Directory.Build.props
index b3dc903387f..1bd59d73121 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -108,6 +108,7 @@
<TargetOsName Condition=" '$(TargetOsName)' == '' AND $([MSBuild]::IsOSPlatform('Windows'))">win</TargetOsName>
<TargetOsName Condition=" '$(TargetOsName)' == '' AND $([MSBuild]::IsOSPlatform('OSX'))">osx</TargetOsName>
<TargetOsName Condition=" '$(TargetOsName)' == '' AND $([MSBuild]::IsOSPlatform('Linux'))">linux</TargetOsName>
+ <BuildArchitecture>$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant())</BuildArchitecture>
<TargetArchitecture Condition="'$(TargetArchitecture)' == ''">x64</TargetArchitecture>
<TargetRuntimeIdentifier>$(TargetOsName)-$(TargetArchitecture)</TargetRuntimeIdentifier>

diff --git a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj
index 4c4298a92da..f843ded1241 100644
--- a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj
+++ b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj
@@ -90,15 +90,17 @@ This package is an internal implementation of the .NET Core SDK and is not meant
<PathSeparator Condition="'$(PathSeparator)' == ''">:</PathSeparator>
<PathSeparator Condition=" '$(TargetOsName)' == 'win' ">%3B</PathSeparator>

+ <CrossCompileDirectory Condition=" '$(TargetRuntimeIdentifier)' == 'linux-arm' ">x64_arm</CrossCompileDirectory>
+ <CrossCompileDirectory Condition=" '$(TargetArchitecture)' == 'arm64' AND '$(BuildArchitecture)' != 'arm64' ">x64_arm64</CrossCompileDirectory>
+ <CrossCompileDirectory Condition=" '$(TargetRuntimeIdentifier)' == 'win-arm' ">x86_arm</CrossCompileDirectory>
+
<!-- Crossgen executable name -->
<CrossgenToolFileName>crossgen</CrossgenToolFileName>
<CrossgenToolFileName Condition=" '$(TargetOsName)' == 'win' ">$(CrossgenToolFileName).exe</CrossgenToolFileName>
<!-- Default crossgen executable relative path -->
<CrossgenToolPackagePath>$(CrossgenToolFileName)</CrossgenToolPackagePath>
<!-- Disambiguated RID-specific crossgen executable relative path -->
- <CrossgenToolPackagePath Condition=" '$(TargetRuntimeIdentifier)' == 'linux-arm' ">x64_arm\$(CrossgenToolPackagePath)</CrossgenToolPackagePath>
- <CrossgenToolPackagePath Condition=" '$(TargetRuntimeIdentifier)' == 'linux-arm64' OR '$(TargetRuntimeIdentifier)' == 'linux-musl-arm64' ">x64_arm64\$(CrossgenToolPackagePath)</CrossgenToolPackagePath>
- <CrossgenToolPackagePath Condition=" '$(TargetRuntimeIdentifier)' == 'win-arm' ">x86_arm\$(CrossgenToolPackagePath)</CrossgenToolPackagePath>
+ <CrossgenToolPackagePath Condition=" '$(CrossCompileDirectory)' != '' ">$(CrossCompileDirectory)\$(CrossgenToolPackagePath)</CrossgenToolPackagePath>

<MicrosoftNETCoreAppRuntimeIdentifier>$(RuntimeIdentifier)</MicrosoftNETCoreAppRuntimeIdentifier>
<MicrosoftNETCoreAppRuntimeIdentifier Condition="'$(TargetOsName)' != 'osx'">$(SourceBuildRuntimeIdentifier)</MicrosoftNETCoreAppRuntimeIdentifier>
@@ -293,7 +295,9 @@ This package is an internal implementation of the .NET Core SDK and is not meant
-->
<PropertyGroup>
<CrossgenToolDir>$(IntermediateOutputPath)crossgen\</CrossgenToolDir>
- <CoreCLRJitPath>$(CrossgenToolDir)$(LibPrefix)clrjit$(LibExtension)</CoreCLRJitPath>
+ <!-- Pick the right coreclr jit based on whether we are cross-compiling or not -->
+ <CoreCLRJitPath Condition="'$(CrossCompileDirectory)' == ''">$(RuntimePackageRoot)runtimes\$(RuntimeIdentifier)\native\$(LibPrefix)clrjit$(LibExtension)</CoreCLRJitPath>
+ <CoreCLRJitPath Condition="'$(CrossCompileDirectory)' != ''">$(RuntimepackageRoot)runtimes\$(CrossCompileDirectory)\native\$(LibPrefix)clrjit$(LibExtension)</CoreCLRJitPath>
</PropertyGroup>

<ItemGroup>
Loading

0 comments on commit 03496f2

Please sign in to comment.