Skip to content

Commit

Permalink
Enable building on arm64
Browse files Browse the repository at this point in the history
This chnage allows source-build to be cloned and built on arm64
 machines. 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
  • Loading branch information
omajid committed Nov 15, 2019
1 parent 3aaca4d commit cb1aef0
Show file tree
Hide file tree
Showing 15 changed files with 414 additions and 25 deletions.
49 changes: 36 additions & 13 deletions build-source-tarball.sh
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 @@ -148,9 +174,6 @@ git submodule foreach --quiet --recursive '
# Now re-uberclone into the tarball src directory. Since we reuse the .gitdirs, this shouldn't hit the network at all.
ignored_repos="https://dev.azure.com/dnceng/internal/_git/dotnet-optimization;https://dev.azure.com/devdiv/DevDiv/_git/DotNet-Trusted;https://devdiv.visualstudio.com/DevDiv/_git/DotNet-Trusted;https://dnceng@dev.azure.com/dnceng/internal/_git/dotnet-optimization;https://dev.azure.com/dnceng/internal/_git/dotnet-core-setup;https://github.com/dotnet/source-build-reference-packages"

#export the LC_LIB_PATH for libgit2 so file as fedora fails to find it in the repodir
export LD_LIBRARY_PATH=$CLI_PATH/tools/.store/microsoft.dotnet.darc/$DarcVersion/microsoft.dotnet.darc/$DarcVersion/tools/netcoreapp2.1/any/runtimes/rhel-x64/native/

"$CLI_PATH/dotnet" "$DARC_DLL" clone --repos-folder=$TARBALL_ROOT/src/ --git-dir-folder $SCRIPT_ROOT/.git/modules/src/ --include-toolset --ignore-repos "$ignored_repos" --azdev-pat bogus --github-pat bogus --depth 0 --debug

# now we don't need .git/modules/src or Darc anymore
Expand Down Expand Up @@ -208,28 +231,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 @@ -250,8 +273,8 @@ cp $SCRIPT_ROOT/bin/obj/x64/Release/blob-feed/packages/*DotNetHost*.nupkg $TARBA
cp $SCRIPT_ROOT/bin/obj/x64/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 @@ -261,7 +284,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 @@ -292,7 +315,7 @@ done
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: 3 additions & 2 deletions build.sh
Expand Up @@ -69,8 +69,9 @@ export NUGET_PACKAGES="$scriptroot/packages/restored/"
set -x
scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"

# runtime 2.1.0 required for darc
"$scriptroot/eng/common/dotnet-install.sh" -runtime dotnet -version 2.1.0
# HACK ALERT. runtime 2.1.0 required for darc. But that doesn't work too well on arm64. Instead, pretend 3.0.0 is 2.1.0.
"$scriptroot/eng/common/dotnet-install.sh" -runtime dotnet -version 3.0.0
[ -f $scriptroot/.dotnet/shared/Microsoft.NETCore.App/2.1.0 ] || ln -s 3.0.0 $scriptroot/.dotnet/shared/Microsoft.NETCore.App/2.1.0

if [ "$alternateTarget" == "true" ]; then
CLIPATH="$scriptroot/.dotnet"
Expand Down
5 changes: 4 additions & 1 deletion dir.props
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 @@ -198,7 +201,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
@@ -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.0.100",
"runtimes": {
- "dotnet/x64": [
+ "dotnet": [
"$(MicrosoftNETCoreAppRuntimeVersion)"
],
"dotnet/x86": [
@@ -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>
<CrossgenPlatformAssembliesDir>$(IntermediateOutputPath)platformAssemblies\</CrossgenPlatformAssembliesDir>
- <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>

0 comments on commit cb1aef0

Please sign in to comment.