Skip to content

Commit 46b56aa

Browse files
Enable compiling with crossgen2 (#32508)
* Enable compiling Asp.NET with crossgen2 * Use use linux crossgen2 instead of linux-musl crossgen2 when targetting linux-musl from the build * Attempt to make musl work * Fix typo * Use correct bits to compile take #3 * Add Pgo data * Fix mistaken at symbol * Move to Core-Eng build agents - should resolve problems w/ disk space in "Tests: Helix ARM64 matrix" job - need `node` in this job for some reason * Remove `crossgen` tool infrastructure - remove many properties related only to the `crossgen` tool - may have missed a few of course nits: - `crossgen` -> `crossgen2` in a few comments - add / expand a few comments to improve clarity Co-authored-by: David Wrighton <[email protected]>
1 parent 8556a7a commit 46b56aa

File tree

3 files changed

+82
-51
lines changed

3 files changed

+82
-51
lines changed

.azure/pipelines/helix-matrix.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ jobs:
5858
jobDisplayName: "Tests: Helix ARM64 matrix"
5959
agentOs: Linux
6060
timeoutInMinutes: 480
61+
useHostedUbuntu: false
6162
steps:
6263
- script: ./eng/build.sh --ci --nobl --pack --arch arm64
6364
/p:CrossgenOutput=false /p:ASPNETCORE_TEST_LOG_DIR=artifacts/log
@@ -69,7 +70,7 @@ jobs:
6970
env:
7071
HelixApiAccessToken: $(HelixApiAccessToken) # Needed for internal queues
7172
SYSTEM_ACCESSTOKEN: $(System.AccessToken) # We need to set this env var to publish helix results to Azure Dev Ops
72-
installNodeJs: false
73+
installNodeJs: true
7374
artifacts:
7475
- name: Helix_arm64_logs
7576
path: artifacts/log/

eng/Dependencies.props

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ and are generated based on the last package release.
9292
<LatestPackageReference Include="Microsoft.NETCore.App.Runtime.linux-musl-x64" />
9393
<LatestPackageReference Include="Microsoft.NETCore.App.Runtime.linux-musl-arm" />
9494
<LatestPackageReference Include="Microsoft.NETCore.App.Runtime.linux-musl-arm64" />
95+
96+
<!-- Crossgen2 compiler -->
97+
<LatestPackageReference Include="Microsoft.NETCore.App.Crossgen2.osx-x64" />
98+
<LatestPackageReference Include="Microsoft.NETCore.App.Crossgen2.osx-arm64" />
99+
<LatestPackageReference Include="Microsoft.NETCore.App.Crossgen2.linux-musl-x64" />
100+
<LatestPackageReference Include="Microsoft.NETCore.App.Crossgen2.linux-x64" />
101+
<LatestPackageReference Include="Microsoft.NETCore.App.Crossgen2.win-x64" />
102+
<LatestPackageReference Include="Microsoft.NETCore.App.Crossgen2.win-arm64" />
95103
</ItemGroup>
96104

97105
<ItemGroup Label=".NET team dependencies (Non-source-build)" Condition="'$(DotNetBuildFromSource)' != 'true'">
@@ -205,7 +213,7 @@ and are generated based on the last package release.
205213
-->
206214
<LatestPackageReference Update="@(LatestPackageReference->WithMetadataValue('Version', ''))">
207215
<Version
208-
Condition=" $([System.String]::new('%(Identity)').StartsWith('Microsoft.NETCore.App.Runtime.')) ">$(MicrosoftNETCoreAppRuntimeVersion)</Version>
216+
Condition=" $([System.String]::new('%(Identity)').StartsWith('Microsoft.NETCore.App.Runtime.')) or $([System.String]::new('%(Identity)').StartsWith('Microsoft.NETCore.App.Crossgen2.'))">$(MicrosoftNETCoreAppRuntimeVersion)</Version>
209217
</LatestPackageReference>
210218
</ItemGroup>
211219
</Project>

src/Framework/App.Runtime/src/Microsoft.AspNetCore.App.Runtime.csproj

Lines changed: 71 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ This package is an internal implementation of the .NET Core SDK and is not meant
4242
<!-- Pack .map files in symbols package (native symbols for Linux) -->
4343
<AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder>$(AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder);.map</AllowedOutputExtensionsInSymbolsPackageBuildOutputFolder>
4444

45-
<!-- Optimize the framework using the crossgen tool -->
45+
<!-- Optimize the framework using the crossgen2 tool -->
4646
<CrossgenOutput Condition=" '$(CrossgenOutput)' == '' AND '$(Configuration)' != 'Debug' ">true</CrossgenOutput>
4747

48-
<!-- Produce crossgen profiling symbols (.ni.pdb or .map files). -->
48+
<!-- Produce crossgen2 profiling symbols (.ni.pdb or .map files). -->
4949
<GenerateCrossgenProfilingSymbols>true</GenerateCrossgenProfilingSymbols>
5050
<GenerateCrossgenProfilingSymbols Condition=" '$(CrossgenOutput)' != 'true' OR '$(TargetOsName)' == 'osx' ">false</GenerateCrossgenProfilingSymbols>
5151

@@ -80,34 +80,31 @@ This package is an internal implementation of the .NET Core SDK and is not meant
8080
<!-- This project should not be referenced via the `<Reference>` implementation. -->
8181
<IsProjectReferenceProvider>false</IsProjectReferenceProvider>
8282

83-
<!-- Properties related to crossgen -->
83+
<!-- Properties related to crossgen2 -->
8484
<CrossGenSymbolsType>PerfMap</CrossGenSymbolsType>
8585
<CrossGenSymbolsType Condition="'$(TargetOsName)' == 'win'">PDB</CrossGenSymbolsType>
8686

87+
<!--
88+
hostfxr and hostpolicy libraries are named libhostfxr.so and libhostpolicy.so in non-Windows
89+
microsoft.netcore.app.runtime packages.
90+
-->
8791
<LibPrefix Condition=" '$(TargetOsName)' != 'win' ">lib</LibPrefix>
88-
<LibExtension>.so</LibExtension>
89-
<LibExtension Condition=" '$(TargetOsName)' == 'win' ">.dll</LibExtension>
90-
<LibExtension Condition=" '$(TargetOsName)' == 'osx' ">.dylib</LibExtension>
91-
<ExeExtension Condition=" '$(TargetOsName)' == 'win' ">.exe</ExeExtension>
92-
<!-- 3B = semicolon in ASCII -->
93-
<PathSeparator Condition="'$(PathSeparator)' == ''">:</PathSeparator>
94-
<PathSeparator Condition=" '$(TargetOsName)' == 'win' ">%3B</PathSeparator>
95-
96-
<CrossCompileDirectory Condition=" '$(TargetRuntimeIdentifier)' == 'linux-arm' OR '$(TargetRuntimeIdentifier)' == 'linux-musl-arm'">x64_arm</CrossCompileDirectory>
97-
<CrossCompileDirectory Condition=" '$(TargetArchitecture)' == 'arm64' AND '$(BuildArchitecture)' != 'arm64' ">x64_arm64</CrossCompileDirectory>
98-
<CrossCompileDirectory Condition=" '$(TargetRuntimeIdentifier)' == 'win-arm' ">x86_arm</CrossCompileDirectory>
99-
100-
<!-- Crossgen executable name -->
101-
<CrossgenToolFileName>crossgen</CrossgenToolFileName>
102-
<CrossgenToolFileName Condition=" '$(TargetOsName)' == 'win' ">$(CrossgenToolFileName).exe</CrossgenToolFileName>
103-
<!-- Default crossgen executable relative path -->
104-
<CrossgenToolPackagePath>$(CrossgenToolFileName)</CrossgenToolPackagePath>
105-
<!-- Disambiguated RID-specific crossgen executable relative path -->
106-
<CrossgenToolPackagePath Condition=" '$(CrossCompileDirectory)' != '' ">$(CrossCompileDirectory)\$(CrossgenToolPackagePath)</CrossgenToolPackagePath>
92+
93+
<!-- crossgen2 executable name -->
94+
<Crossgen2ToolFileName>crossgen2</Crossgen2ToolFileName>
95+
<Crossgen2ToolFileName Condition=" '$(TargetOsName)' == 'win' ">$(Crossgen2ToolFileName).exe</Crossgen2ToolFileName>
10796

10897
<!-- E.g. "PkgMicrosoft_NETCore_App_Runtime_win-x64" (set in obj/Microsoft.AspNetCore.App.Runtime.csproj.nuget.g.props). -->
10998
<RuntimePackageRootVariableName>PkgMicrosoft_NETCore_App_Runtime_$(RuntimeIdentifier)</RuntimePackageRootVariableName>
11099

100+
<!--
101+
Determine the crossgen2 package path property name. Special case linux-musl-arm and linux-musl-arm64 because they
102+
are built on an Ubuntu container with cross compilation tools. linux-musl-x64 is built in an alpine container.
103+
-->
104+
<BuildOsName>$(TargetOsName)</BuildOsName>
105+
<BuildOsName Condition="'$(TargetOsName)' == 'linux-musl' and '$(TargetArchitecture)'!='x64'">linux</BuildOsName>
106+
<Crossgen2PackageRootVariableName>PkgMicrosoft_NETCore_App_Crossgen2_$(BuildOsName)-$(BuildArchitecture)</Crossgen2PackageRootVariableName>
107+
111108
<AssetTargetFallback>$(AssetTargetFallback);native,Version=0.0</AssetTargetFallback>
112109

113110
<NativePlatform>$(TargetArchitecture)</NativePlatform>
@@ -125,6 +122,15 @@ This package is an internal implementation of the .NET Core SDK and is not meant
125122
PrivateAssets="All"
126123
GeneratePathProperty="true" />
127124

125+
<!--
126+
This package contains the crossgen2 tool. Unfortunately, it doesn't make the tool easy to use.
127+
$(GeneratePathProperty) and hacks in the _ExpandRuntimePackageRoot target work around the gaps.
128+
-->
129+
<Reference Include="Microsoft.NETCore.App.Crossgen2.$(BuildOsName)-$(BuildArchitecture)"
130+
ExcludeAssets="All"
131+
PrivateAssets="All"
132+
GeneratePathProperty="true" />
133+
128134
<ProjectReference Condition=" '$(BuildIisNativeProjects)' == 'true' AND $(BuildNative) "
129135
Include="$(RepoRoot)src\Servers\IIS\AspNetCoreModuleV2\InProcessRequestHandler\InProcessRequestHandler.vcxproj">
130136
<SetPlatform>Platform=$(NativePlatform)</SetPlatform>
@@ -286,7 +292,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
286292
<BuildOutputFiles Include="@(ReferenceCopyLocalPaths)" Condition=" '%(ReferenceCopyLocalPaths.IsNativeImage)' != 'true' " />
287293
<!-- Include all .pdbs in build output. Some .pdb files are part of ReferenceCopyLocalPaths, but this can change when running /t:Pack /p:NoBuild=true. -->
288294
<BuildOutputFiles Include="$(TargetDir)*.pdb" Exclude="@(ReferenceCopyLocalPaths)" />
289-
<!-- Crossgen symbols for Linux include a GUID in the file name which cannot be predicted. -->
295+
<!-- crossgen2 symbols for Linux include a GUID in the file name which cannot be predicted. -->
290296
<BuildOutputFiles Include="$(TargetDir)*.map" Condition="'$(CrossGenSymbolsType)' == 'PerfMap'" />
291297

292298
<!-- Strip duplicate Files by checking for distinct %(FileName)%(Extension) -->
@@ -341,18 +347,24 @@ This package is an internal implementation of the .NET Core SDK and is not meant
341347

342348
<Target Name="_ExpandRuntimePackageRoot">
343349
<!--
344-
Use an item group for expansion of $($(RuntimePackageRootVariableName)) (an illegal MSBuild expression)
345-
i.e. the prop value's value.
350+
Use an item group for expansion of $($(RuntimePackageRootVariableName)) and $($(Crossgen2PackageRootMapping))
351+
(both illegal MSBuild expressions) i.e. the prop value's value.
346352
-->
347353
<ItemGroup>
348354
<RuntimePackageRootMapping Include="$(RuntimePackageRootVariableName)" />
349355
<RuntimePackageRootMapping>
350356
<RuntimePackageRoot>$(%(Identity))</RuntimePackageRoot>
351357
</RuntimePackageRootMapping>
358+
<Crossgen2PackageRootMapping Include="$(Crossgen2PackageRootVariableName)" />
359+
<Crossgen2PackageRootMapping>
360+
<Crossgen2PackageRoot>$(%(Identity))</Crossgen2PackageRoot>
361+
</Crossgen2PackageRootMapping>
352362
</ItemGroup>
353363
<PropertyGroup>
354364
<RuntimePackageRoot>@(RuntimePackageRootMapping->'%(RuntimePackageRoot)')</RuntimePackageRoot>
355365
<RuntimePackageRoot>$([MSBuild]::EnsureTrailingSlash('$(RuntimePackageRoot)'))</RuntimePackageRoot>
366+
<Crossgen2PackageRoot>@(Crossgen2PackageRootMapping->'%(Crossgen2PackageRoot)')</Crossgen2PackageRoot>
367+
<Crossgen2PackageRoot>$([MSBuild]::EnsureTrailingSlash('$(Crossgen2PackageRoot)'))</Crossgen2PackageRoot>
356368
</PropertyGroup>
357369
</Target>
358370

@@ -362,11 +374,11 @@ This package is an internal implementation of the .NET Core SDK and is not meant
362374
<!-- The output directories of assemblies built in this repo contain a mix of ref and impl assemblies. Copy impl assemblies to a separate directory. -->
363375
<Copy SourceFiles="@(ReferenceCopyLocalPaths)" DestinationFolder="$(CrossgenPlatformAssembliesDir)" Condition="'%(ReferenceCopyLocalPaths.ProjectPath)' != ''"/>
364376

365-
<!-- Resolve list of assemblies to crossgen -->
377+
<!-- Resolve list of assemblies to crossgen2 -->
366378
<ItemGroup>
367379
<IntermediateCrossgenAssembly Include="@(ReferenceCopyLocalPaths)" Condition=" '%(ReferenceCopyLocalPaths.IsNativeImage)' != 'true' AND '%(ReferenceCopyLocalPaths.Extension)' != '.pdb'" />
368380

369-
<!-- These are the paths used by crossgen to find assemblies that are expected to exist at runtime in the shared frameworks. -->
381+
<!-- These are the paths used by crossgen2 to find assemblies that are expected to exist at runtime in the shared frameworks. -->
370382
<_PlatformAssemblyPaths Include="$(CrossgenToolDir)" />
371383
<!-- Include the directories of the assemblies not built in this repo. These contain only implementation assemblies. -->
372384
<_PlatformAssemblyPaths Include="@(ReferenceCopyLocalPaths->'%(RootDir)%(Directory)')" Condition="'%(ReferenceCopyLocalPaths.ProjectPath)' == ''"/>
@@ -375,54 +387,64 @@ This package is an internal implementation of the .NET Core SDK and is not meant
375387

376388
<ReferenceCopyLocalPaths Remove="@(IntermediateCrossgenAssembly)" />
377389
<ReferenceCopyLocalPaths Include="@(IntermediateCrossgenAssembly->'$(TargetDir)%(FileName)%(Extension)')" />
390+
391+
<_DistinctPlatformAssemblyPaths Include="@(_PlatformAssemblyPaths->Distinct())"/>
392+
<_DistinctPlatformAssemblyPaths>
393+
<CommandLineOption>-r:%(Identity)*.dll</CommandLineOption>
394+
</_DistinctPlatformAssemblyPaths>
395+
396+
<Crossgen2PlatformAssemblyPaths Include="@(_DistinctPlatformAssemblyPaths->'%(CommandLineOption)')" />
378397
</ItemGroup>
379398

380399
<PropertyGroup>
381-
<CrossgenToolPath>$([System.IO.Path]::Combine('$(RuntimePackageRoot)', 'tools', '$(CrossgenToolPackagePath)'))</CrossgenToolPath>
400+
<CrossgenToolPath>$([System.IO.Path]::Combine('$(Crossgen2PackageRoot)', 'tools', '$(Crossgen2ToolFileName)'))</CrossgenToolPath>
382401
<CrossgenSymbolsTargetDir>$(TargetDir)</CrossgenSymbolsTargetDir>
383-
<CrossgenPlatformAssemblyPaths>@(_PlatformAssemblyPaths->Distinct(), '$(PathSeparator)')</CrossgenPlatformAssemblyPaths>
384402

385403
<!-- Escaping (double backslash at end) required due to the way batch processes backslashes. -->
386404
<CrossgenSymbolsTargetDir Condition="HasTrailingSlash($(CrossgenSymbolsTargetDir)) AND '$(OS)' == 'Windows_NT'">$(TargetDir)\</CrossgenSymbolsTargetDir>
387-
<CrossgenPlatformAssemblyPaths Condition="HasTrailingSlash($(CrossgenPlatformAssemblyPaths)) AND '$(OS)' == 'Windows_NT'">$(CrossgenPlatformAssemblyPaths)\</CrossgenPlatformAssemblyPaths>
388405
</PropertyGroup>
389406

390407
<WriteLinesToFile
391-
Lines="-platform_assemblies_paths &quot;$(CrossgenPlatformAssemblyPaths)&quot;"
392-
File="$(CrossgenToolDir)PlatformAssembliesPaths.rsp"
408+
Lines="@(Crossgen2PlatformAssemblyPaths)"
409+
File="$(CrossgenToolDir)PlatformAssembliesPathsCrossgen2.rsp"
393410
Overwrite="true" />
394411

395412
<ItemGroup>
396413
<RuntimePackageFiles Include="$(RuntimePackageRoot)runtimes\**\*" />
397414
</ItemGroup>
398415

399-
<Error Text="Could not find crossgen $(CrossgenToolPath)" Condition=" ! Exists($(CrossgenToolPath))" />
416+
<Error Text="Could not find crossgen2 $(CrossgenToolPath)" Condition=" ! Exists($(CrossgenToolPath))" />
400417

401-
<!-- Create tool directory with crossgen executable and runtime assemblies -->
402-
<Copy SourceFiles="@(RuntimePackageFiles);$(CrossgenToolPath)" DestinationFolder="$(CrossGenToolDir)"/>
403-
<Exec Command="chmod +x &quot;$(CrossGenToolDir)$(CrossgenToolFileName)&quot;" Condition="'$(OS)' != 'Windows_NT'" />
418+
<!-- Create tool directory with runtime assemblies -->
419+
<Copy SourceFiles="@(RuntimePackageFiles)" DestinationFolder="$(CrossGenToolDir)"/>
404420
</Target>
405421

422+
<!-- Target executes once per @(IntermediateCrossgenAssembly) item. -->
406423
<Target Name="_BatchCrossGenAssemblies"
407424
DependsOnTargets="_ExpandRuntimePackageRoot"
408425
Inputs="@(IntermediateCrossgenAssembly)"
409426
Outputs="@(IntermediateCrossgenAssembly->'$(TargetDir)%(FileName)%(Extension)')">
410427
<PropertyGroup>
411-
<!-- Pick the right coreclr jit based on whether we are cross-compiling or not. -->
412-
<CoreCLRJitPath
413-
Condition="'$(CrossCompileDirectory)' == ''">$(RuntimePackageRoot)runtimes\$(RuntimeIdentifier)\native\$(LibPrefix)clrjit$(LibExtension)</CoreCLRJitPath>
414-
<CoreCLRJitPath
415-
Condition="'$(CrossCompileDirectory)' != ''">$(RuntimePackageRoot)runtimes\$(CrossCompileDirectory)\native\$(LibPrefix)clrjit$(LibExtension)</CoreCLRJitPath>
428+
<!--
429+
Handle different names for the target OS on the crossgen2 command line. This often matches neither
430+
$(TargetOsName) nor $(BuildOsName).
431+
-->
432+
<Crossgen2TargetOs>$(TargetOsName)</Crossgen2TargetOs>
433+
<Crossgen2TargetOs Condition="'$(TargetOsName)' == 'win'">windows</Crossgen2TargetOs>
434+
<Crossgen2TargetOs Condition="'$(TargetOsName)' == 'linux-musl'">linux</Crossgen2TargetOs>
435+
436+
<!-- Compose the crossgen2 command line. -->
437+
<Crossgen2Args>--targetarch:$(TargetArchitecture)</Crossgen2Args>
438+
<Crossgen2Args>$(Crossgen2Args) --targetos:$(Crossgen2TargetOs)</Crossgen2Args>
439+
<Crossgen2Args>$(Crossgen2Args) -O</Crossgen2Args>
440+
<Crossgen2Args>$(Crossgen2Args) @&quot;$(CrossgenToolDir)PlatformAssembliesPathsCrossgen2.rsp&quot;</Crossgen2Args>
441+
<Crossgen2Args Condition="Exists('$(RuntimePackageRoot)tools\StandardOptimizationData.mibc')">$(Crossgen2Args) &quot;-m:$(RuntimePackageRoot)tools\StandardOptimizationData.mibc&quot;</Crossgen2Args>
442+
<Crossgen2Args Condition="'$(GenerateCrossgenProfilingSymbols)' == 'true' and '$(TargetOsName)' == 'win'">$(Crossgen2Args) --pdb --pdb-path:&quot;$(CrossgenSymbolsTargetDir)&quot;</Crossgen2Args>
443+
<Crossgen2Args Condition="'$(GenerateCrossgenProfilingSymbols)' == 'true' and '$(TargetOsName)' != 'win'">$(Crossgen2Args) --perfmap --perfmap-path:&quot;$(CrossgenSymbolsTargetDir)&quot;</Crossgen2Args>
416444
</PropertyGroup>
417445

418-
<Exec Command="&quot;$(CrossgenToolDir)$(CrossgenToolFileName)&quot; -nologo -readytorun -in &quot;%(IntermediateCrossgenAssembly.Identity)&quot; -out &quot;$(TargetDir)%(FileName)%(Extension)&quot; -jitpath &quot;$(CoreCLRJitPath)&quot; &quot;@$(CrossgenToolDir)PlatformAssembliesPaths.rsp&quot;"
419-
EnvironmentVariables="COMPlus_PartialNGen=0"
420-
IgnoreStandardErrorWarningFormat="true"
421-
StandardOutputImportance="High" />
422-
423-
<Exec Condition=" '$(GenerateCrossgenProfilingSymbols)' == 'true' "
424-
Command="&quot;$(CrossgenToolDir)$(CrossgenToolFileName)&quot; -nologo -readytorun -in &quot;$(TargetDir)%(IntermediateCrossgenAssembly.FileName)%(Extension)&quot; -Create$(CrossGenSymbolsType) &quot;$(CrossgenSymbolsTargetDir)&quot; &quot;@$(CrossgenToolDir)PlatformAssembliesPaths.rsp&quot;"
425-
EnvironmentVariables="COMPlus_PartialNGen=0"
446+
<!-- All metadata in batched task comes from current @(IntermediateCrossgenAssembly) item. -->
447+
<Exec Command="&quot;$(CrossgenToolPath)&quot; $(Crossgen2Args) -o:&quot;$(TargetDir)%(FileName)%(Extension)&quot; &quot;%(IntermediateCrossgenAssembly.Identity)&quot;"
426448
IgnoreStandardErrorWarningFormat="true"
427449
StandardOutputImportance="High" />
428450
</Target>

0 commit comments

Comments
 (0)