From dda1d33f7bea9e85e6abcd5dab2642f22e9a8093 Mon Sep 17 00:00:00 2001 From: Juan Hoyos <juan.hoyos@microsoft.com> Date: Thu, 10 Sep 2020 10:59:37 -0700 Subject: [PATCH] Enable ARM64 installers build. (#25579) Changes WiX toolset used to 3.14 to support ARM64 Generates targeting pack from the x86/x64 leg, as it gets produced using a zip that gets generated there. The ARM64 leg now produces all the necessary msi's, exe, and wixlib needed for the installer to generate a bundle. --- .azure/pipelines/ci.yml | 61 +++++++++++++++---- build.ps1 | 5 +- eng/Build.props | 14 ++++- eng/targets/Wix.Common.props | 4 +- .../Windows/SharedFramework/Product.wxs | 4 +- .../SharedFramework/SharedFramework.wixproj | 4 ++ .../Windows/SharedFrameworkBundle/Bundle.wxs | 2 + .../SharedFrameworkBundle.wixproj | 43 ++++++++----- .../Windows/SharedFrameworkLib/Library.wxs | 3 + .../Windows/TargetingPack/Product.wxs | 4 +- src/Installers/Windows/Wix.targets | 5 ++ 11 files changed, 113 insertions(+), 36 deletions(-) diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index a3cce2ea12e..a7dc48c1289 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -51,6 +51,8 @@ variables: /p:DotNetPublishUsingPipelines=$(_PublishUsingPipelines) /p:DotNetArtifactsCategory=$(_DotNetArtifactsCategory) # Do not log most Windows steps in official builds; this is the slowest job. Site extensions step always logs. + - name: WindowsArm64LogArgs + value: -ExcludeCIBinaryLog - name: Windows64LogArgs value: -ExcludeCIBinaryLog - name: Windows86LogArgs @@ -59,12 +61,16 @@ variables: value: -ExcludeCIBinaryLog - name: WindowsInstallersLogArgs value: -ExcludeCIBinaryLog + - name: WindowsArm64InstallersLogArgs + value: -ExcludeCIBinaryLog - ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: - name: _BuildArgs value: '/p:SkipTestBuild=true' - name: _PublishArgs value: '' # Write binary logs for all main Windows build steps except the x86 one in public and PR builds. + - name: WindowsArm64LogArgs + value: /bl:artifacts/log/Release/Build.arm64.binlog - name: Windows64LogArgs value: /bl:artifacts/log/Release/Build.x64.binlog - name: Windows86LogArgs @@ -73,6 +79,8 @@ variables: value: /bl:artifacts/log/Release/Build.CodeSign.binlog - name: WindowsInstallersLogArgs value: /bl:artifacts/log/Release/Build.Installers.binlog + - name: WindowsArm64InstallersLogArgs + value: /bl:artifacts/log/Release/Build.Installers.Arm64.binlog - ${{ if ne(variables['System.TeamProject'], 'internal') }}: - name: _UseHelixOpenQueues value: 'true' @@ -263,18 +271,6 @@ stages: jobName: Windows_arm64_build jobDisplayName: "Build: Windows ARM64" agentOs: Windows - buildArgs: - -arch arm64 - -sign - -pack - -noBuildNodeJS - -noBuildJava - /p:DotNetSignType=$(_SignType) - /p:OnlyPackPlatformSpecificPackages=true - /p:AssetManifestFileName=aspnetcore-win-arm64.xml - $(_BuildArgs) - $(_PublishArgs) - $(_InternalRuntimeDownloadArgs) installNodeJs: false installJdk: false artifacts: @@ -286,6 +282,47 @@ stages: path: artifacts/packages/ - name: Windows_arm64_Installers path: artifacts/installers/ + steps: + - script: ./build.cmd + -ci + -arch arm64 + -sign + -pack + -noBuildJava + -noBuildNative + /p:DotNetSignType=$(_SignType) + /p:OnlyPackPlatformSpecificPackages=true + $(_BuildArgs) + $(_InternalRuntimeDownloadArgs) + $(WindowsArm64LogArgs) + displayName: Build ARM64 + + # Windows installers bundle for arm64 + - script: ./build.cmd + -ci + -noBuildRepoTasks + -arch arm64 + -sign + -buildInstallers + -noBuildNative + /p:DotNetSignType=$(_SignType) + /p:AssetManifestFileName=aspnetcore-win-arm64.xml + $(_BuildArgs) + $(_PublishArgs) + $(_InternalRuntimeDownloadArgs) + $(WindowsArm64InstallersLogArgs) + displayName: Build Arm64 Installers + + # A few files must also go to the VS package feed. + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: NuGetCommand@2 + displayName: Push Visual Studio packages + inputs: + command: push + packagesToPush: 'artifacts/packages/**/VS.Redist.Common.AspNetCore.*.nupkg' + nuGetFeedType: external + publishFeedCredentials: 'DevDiv - VS package feed' + # Build MacOS - template: jobs/default-build.yml diff --git a/build.ps1 b/build.ps1 index 96e5cb7bf07..0d82c3b2657 100644 --- a/build.ps1 +++ b/build.ps1 @@ -296,12 +296,11 @@ if ($BuildNodeJS) { $dotnetBuildArguments += "/p:BuildNodeJS=true" } # Don't bother with two builds if just one will build everything. Ignore super-weird cases like # "-Projects ... -NoBuildJava -NoBuildManaged -NoBuildNodeJS". An empty `./build.ps1` command will build both # managed and native projects. -$performDesktopBuild = ($BuildInstallers -or $BuildNative) -and ` - -not $Architecture.StartsWith("arm", [System.StringComparison]::OrdinalIgnoreCase) +$performDesktopBuild = ($BuildInstallers -and $Architecture -ne "arm") -or ` + ($BuildNative -and -not $Architecture.StartsWith("arm", [System.StringComparison]::OrdinalIgnoreCase)) $performDotnetBuild = $BuildJava -or $BuildManaged -or $BuildNodeJS -or ` ($All -and -not ($NoBuildJava -and $NoBuildManaged -and $NoBuildNodeJS)) -or ` ($Projects -and -not ($BuildInstallers -or $specifiedBuildNative)) - $foundJdk = $false $javac = Get-Command javac -ErrorAction Ignore -CommandType Application $localJdkPath = "$PSScriptRoot\.tools\jdk\win-x64\" diff --git a/eng/Build.props b/eng/Build.props index f0cb8db0b8a..497ba8f4f80 100644 --- a/eng/Build.props +++ b/eng/Build.props @@ -50,7 +50,7 @@ </ItemGroup> </When> <Otherwise> - <ItemGroup Condition=" '$(BuildInstallers)' == 'true' AND '$(TargetOsName)' == 'win' "> + <ItemGroup Condition=" '$(BuildInstallers)' == 'true' AND '$(TargetOsName)' == 'win' AND ('$(TargetArchitecture)' == 'x86' OR '$(TargetArchitecture)' == 'x64') "> <!-- Build the ANCM custom action --> <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\AspNetCoreModule-Setup\CustomAction\aspnetcoreCA.vcxproj" AdditionalProperties="Platform=x64" /> <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\AspNetCoreModule-Setup\CustomAction\aspnetcoreCA.vcxproj" AdditionalProperties="Platform=Win32" /> @@ -64,6 +64,10 @@ <!-- Build the targeting pack installers --> <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\TargetingPack\TargetingPack.wixproj" AdditionalProperties="Platform=x64" /> <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\TargetingPack\TargetingPack.wixproj" AdditionalProperties="Platform=x86" /> + <!-- This really shouldn't be here, but instead of harvesting from the intermediate/output directories, the targetting pack installer logic + harvests from a zip of the reference assemblies. Producing it in each leg ends up with multiple targeting packs + getting produced and the BAR will reject the build. Centralize building the targeting pack in the x86/x64 leg. --> + <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\TargetingPack\TargetingPack.wixproj" AdditionalProperties="Platform=arm64" /> <!-- Build the SharedFramework installers --> <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkBundle\SharedFrameworkBundle.wixproj" AdditionalProperties="Platform=x64" /> @@ -77,6 +81,14 @@ <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\WindowsHostingBundle\WindowsHostingBundle.wixproj" AdditionalProperties="Platform=x86" /> </ItemGroup> + <ItemGroup Condition=" '$(BuildInstallers)' == 'true' AND '$(TargetOsName)' == 'win' AND '$(TargetArchitecture)' == 'arm64' "> + <!-- We don't build the bundle here because we'd have to bundle the x86 installer which gets built in a different leg. + Instead we only provide the ARM64 MSI--> + + <!-- Build the SharedFramework wixlib --> + <ProjectToBuild Include="$(RepoRoot)src\Installers\Windows\SharedFrameworkLib\SharedFrameworkLib.wixproj" AdditionalProperties="Platform=arm64" /> + </ItemGroup> + <ItemGroup Condition="'$(BuildInstallers)' == 'true' AND '$(TargetRuntimeIdentifier)' == 'linux-x64'"> <ProjectToBuild Condition=" '$(LinuxInstallerType)' == 'deb' " Include="$(RepoRoot)src\Installers\Debian\**\*.*proj" /> diff --git a/eng/targets/Wix.Common.props b/eng/targets/Wix.Common.props index e6b1337fcba..9a29437eb2e 100644 --- a/eng/targets/Wix.Common.props +++ b/eng/targets/Wix.Common.props @@ -3,8 +3,8 @@ <PropertyGroup> <SchemaVersion>2.0</SchemaVersion> - <ProductVersion>3.11</ProductVersion> - <WixVersion>3.11.1</WixVersion> + <ProductVersion>3.14</ProductVersion> + <WixVersion>3.14.0-dotnet</WixVersion> </PropertyGroup> <PropertyGroup> diff --git a/src/Installers/Windows/SharedFramework/Product.wxs b/src/Installers/Windows/SharedFramework/Product.wxs index 2a71da323a2..3375094918c 100644 --- a/src/Installers/Windows/SharedFramework/Product.wxs +++ b/src/Installers/Windows/SharedFramework/Product.wxs @@ -2,7 +2,7 @@ <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCode)"> - <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" /> + <Package InstallerVersion="$(var.InstallerVersion)" Compressed="yes" InstallScope="perMachine" /> <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." Schedule="afterInstallFinalize" /> <Media Id="1" Cabinet="$(var.Cabinet)" CompressionLevel="high" EmbedCab="$(var.EmbedCab)" /> @@ -21,7 +21,7 @@ <?if $(var.Platform)=x86?> <?define PFilesFolder=ProgramFilesFolder?> - <?elseif $(var.Platform)=x64?> + <?elseif $(var.Platform)=x64 or $(var.Platform)=arm64?> <?define PFilesFolder=ProgramFiles64Folder?> <?else?> <?error Invalid Platform ($(var.Platform))?> diff --git a/src/Installers/Windows/SharedFramework/SharedFramework.wixproj b/src/Installers/Windows/SharedFramework/SharedFramework.wixproj index edbb9f5bef0..6c87d777470 100644 --- a/src/Installers/Windows/SharedFramework/SharedFramework.wixproj +++ b/src/Installers/Windows/SharedFramework/SharedFramework.wixproj @@ -61,12 +61,16 @@ <!-- TODO: https://github.com/dotnet/aspnetcore/issues/6304. Harvest shared frameworks from a project reference --> <Target Name="ExtractIntermediateSharedFx" BeforeTargets="PrepareForBuild"> <PropertyGroup> + <SharedFrameworkArm64HarvestRootPath Condition="'$(SharedFrameworkArm64HarvestRootPath)' == ''">$(InstallersOutputPath)</SharedFrameworkArm64HarvestRootPath> <SharedFrameworkX64HarvestRootPath Condition="'$(SharedFrameworkX64HarvestRootPath)' == ''">$(InstallersOutputPath)</SharedFrameworkX64HarvestRootPath> <SharedFrameworkX86HarvestRootPath Condition="'$(SharedFrameworkX86HarvestRootPath)' == ''">$(InstallersOutputPath)</SharedFrameworkX86HarvestRootPath> + <IntermediateArm64SharedFxZip>$(SharedFrameworkArm64HarvestRootPath)aspnetcore-runtime-internal-$(PackageVersion)-win-arm64.zip</IntermediateArm64SharedFxZip> <IntermediateX64SharedFxZip>$(SharedFrameworkX64HarvestRootPath)aspnetcore-runtime-internal-$(PackageVersion)-win-x64.zip</IntermediateX64SharedFxZip> <IntermediateX86SharedFxZip>$(SharedFrameworkX86HarvestRootPath)aspnetcore-runtime-internal-$(PackageVersion)-win-x86.zip</IntermediateX86SharedFxZip> </PropertyGroup> + <Unzip Condition="'$(Platform)' == 'arm64'" + SourceFiles="$(IntermediateArm64SharedFxZip)" DestinationFolder="$(HarvestSource)" /> <Unzip Condition="'$(Platform)' == 'x64'" SourceFiles="$(IntermediateX64SharedFxZip)" DestinationFolder="$(HarvestSource)" /> <Unzip Condition="'$(Platform)' == 'x86'" diff --git a/src/Installers/Windows/SharedFrameworkBundle/Bundle.wxs b/src/Installers/Windows/SharedFrameworkBundle/Bundle.wxs index 7f89a593091..f54d1446b40 100644 --- a/src/Installers/Windows/SharedFrameworkBundle/Bundle.wxs +++ b/src/Installers/Windows/SharedFrameworkBundle/Bundle.wxs @@ -43,6 +43,8 @@ <PackageGroupRef Id="PG_AspNetCoreSharedFramework_x86"/> <?elseif $(var.Platform)=x64?> <PackageGroupRef Id="PG_AspNetCoreSharedFramework_x64"/> + <?elseif $(var.Platform)=arm64?> + <PackageGroupRef Id="PG_AspNetCoreSharedFramework_arm64"/> <?endif?> </Chain> </Bundle> diff --git a/src/Installers/Windows/SharedFrameworkBundle/SharedFrameworkBundle.wixproj b/src/Installers/Windows/SharedFrameworkBundle/SharedFrameworkBundle.wixproj index 7aa16e58ec0..f9f285c8739 100644 --- a/src/Installers/Windows/SharedFrameworkBundle/SharedFrameworkBundle.wixproj +++ b/src/Installers/Windows/SharedFrameworkBundle/SharedFrameworkBundle.wixproj @@ -29,20 +29,35 @@ <Content Include="thm.xml" /> </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\SharedFrameworkLib\SharedFrameworkLib.wixproj" SetPlatform="Platform=x86"> - <Name>SharedFrameworkLib</Name> - <Project>{5244BC49-2568-4701-80A6-EAB8950AB5FA}</Project> - <Private>True</Private> - <DoNotHarvest>True</DoNotHarvest> - </ProjectReference> - <ProjectReference Include="..\SharedFrameworkLib\SharedFrameworkLib.wixproj" SetPlatform="Platform=x64"> - <Name>SharedFrameworkLib</Name> - <Project>{5244BC49-2568-4701-80A6-EAB8950AB5FA}</Project> - <Private>True</Private> - <DoNotHarvest>True</DoNotHarvest> - </ProjectReference> - </ItemGroup> + <Choose> + <When Condition="'$(Platform)' == 'arm64'"> + <ItemGroup> + <ProjectReference Include="..\SharedFrameworkLib\SharedFrameworkLib.wixproj" SetPlatform="Platform=arm64"> + <Name>SharedFrameworkLib</Name> + <Project>{5244BC49-2568-4701-80A6-EAB8950AB5FA}</Project> + <Private>True</Private> + <DoNotHarvest>True</DoNotHarvest> + </ProjectReference> + </ItemGroup> + </When> + <Otherwise> + <ItemGroup> + <ProjectReference Include="..\SharedFrameworkLib\SharedFrameworkLib.wixproj" SetPlatform="Platform=x86"> + <Name>SharedFrameworkLib</Name> + <Project>{5244BC49-2568-4701-80A6-EAB8950AB5FA}</Project> + <Private>True</Private> + <DoNotHarvest>True</DoNotHarvest> + </ProjectReference> + <ProjectReference Include="..\SharedFrameworkLib\SharedFrameworkLib.wixproj" SetPlatform="Platform=x64"> + <Name>SharedFrameworkLib</Name> + <Project>{5244BC49-2568-4701-80A6-EAB8950AB5FA}</Project> + <Private>True</Private> + <DoNotHarvest>True</DoNotHarvest> + </ProjectReference> + </ItemGroup> + </Otherwise> + </Choose> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), Directory.Build.targets))\Directory.Build.targets" /> diff --git a/src/Installers/Windows/SharedFrameworkLib/Library.wxs b/src/Installers/Windows/SharedFrameworkLib/Library.wxs index dde16acbd7f..c30f743d0bb 100644 --- a/src/Installers/Windows/SharedFrameworkLib/Library.wxs +++ b/src/Installers/Windows/SharedFrameworkLib/Library.wxs @@ -16,6 +16,9 @@ <?elseif $(var.Platform)=x64?> <?define SharedFrameworkInstallCondition=VersionNT64 AND (NOT OPT_NO_SHAREDFX)?> <?define DotNetHome=DOTNETHOME_X64?> + <?elseif $(var.Platform)=arm64?> + <?define SharedFrameworkInstallCondition=VersionNT64 AND (NOT OPT_NO_SHAREDFX)?> + <?define DotNetHome=DOTNETHOME_ARM64?> <?endif?> <MsiPackage Id="AspNetCoreSharedFramework_$(var.Platform)" diff --git a/src/Installers/Windows/TargetingPack/Product.wxs b/src/Installers/Windows/TargetingPack/Product.wxs index ce7bda6695e..a43f6ab4e17 100644 --- a/src/Installers/Windows/TargetingPack/Product.wxs +++ b/src/Installers/Windows/TargetingPack/Product.wxs @@ -2,7 +2,7 @@ <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Product Id="$(var.ProductCode)" Name="$(var.ProductName)" Language="1033" Version="$(var.Version)" Manufacturer="Microsoft Corporation" UpgradeCode="$(var.UpgradeCode)"> - <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" /> + <Package InstallerVersion="$(var.InstallerVersion)" Compressed="yes" InstallScope="perMachine" /> <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." Schedule="afterInstallFinalize" /> <Media Id="1" Cabinet="$(var.Cabinet)" CompressionLevel="high" EmbedCab="$(var.EmbedCab)" /> @@ -21,7 +21,7 @@ <?if $(var.Platform)=x86?> <?define PFilesFolder=ProgramFilesFolder?> - <?elseif $(var.Platform)=x64?> + <?elseif $(var.Platform)=x64 or $(var.Platform)=arm64?> <?define PFilesFolder=ProgramFiles64Folder?> <?else?> <?error Invalid Platform ($(var.Platform))?> diff --git a/src/Installers/Windows/Wix.targets b/src/Installers/Windows/Wix.targets index ec321d4c41a..4112082782a 100644 --- a/src/Installers/Windows/Wix.targets +++ b/src/Installers/Windows/Wix.targets @@ -8,6 +8,11 @@ <_FileRevisionVersion Condition=" '$(_FileRevisionVersion)' == '' ">42424</_FileRevisionVersion> <BundleVersion>$(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion).$(_FileRevisionVersion)</BundleVersion> + <!-- ARM64 MSIs require the installer version to be at least 500. --> + <!-- See: https://docs.microsoft.com/en-us/windows/win32/msi/64-bit-windows-installer-packages --> + <DefineConstants Condition=" '$(Platform)' == 'arm64' ">$(DefineConstants);InstallerVersion=500</DefineConstants> + <DefineConstants Condition=" '$(Platform)' != 'arm64' ">$(DefineConstants);InstallerVersion=200</DefineConstants> + <DefineConstants>$(DefineConstants);MajorVersion=$(AspNetCoreMajorVersion)</DefineConstants> <DefineConstants>$(DefineConstants);MinorVersion=$(AspNetCoreMinorVersion)</DefineConstants> <DefineConstants>$(DefineConstants);Version=$(Version)</DefineConstants> -- GitLab