232 lines
11 KiB
Plaintext
Raw Normal View History

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CrossGenDuringPublish Condition=" '$(CrossGenDuringPublish)' == '' And '$(RuntimeIdentifier)' != '' ">true</CrossGenDuringPublish>
</PropertyGroup>
<PropertyGroup>
<IntermediateOptimizedDirName Condition=" '$(IntermediateOptimizedDirName)' == '' ">optimized</IntermediateOptimizedDirName>
<IntermediateOptimizedDir Condition=" '$(IntermediateOptimizedDir)' == '' ">$(IntermediateOutputPath)$(IntermediateOptimizedDirName)</IntermediateOptimizedDir>
<IntermediateCrossGenDirName Condition=" '$(IntermediateCrossGenDirName)' == '' ">crossgen</IntermediateCrossGenDirName>
<IntermediateCrossGenDir Condition=" '$(IntermediateCrossGenDir)' == '' ">$(IntermediateOutputPath)$(IntermediateCrossGenDirName)</IntermediateCrossGenDir>
</PropertyGroup>
<PropertyGroup>
<ComputeCrossGenFilesToPublishAfter Condition=" '$(LinkDuringPublish)' == 'true' ">ComputeLinkedFilesToPublish</ComputeCrossGenFilesToPublishAfter>
<ComputeCrossGenFilesToPublishBefore Condition=" '$(LinkDuringPublish)' != 'true' ">ComputeFilesToPublish</ComputeCrossGenFilesToPublishBefore>
</PropertyGroup>
<!-- Rewrite inputs to ComputeFilesToPublish, so that crossgen'd
files get published instead of the pre-crossgen assemblies. -->
<Target Name="ComputeCrossGenFilesToPublish"
BeforeTargets="$(ComputeCrossGenFilesToPublishBefore)"
AfterTargets="$(ComputeCrossGenFilesToPublishAfter)"
Condition=" '$(CrossGenDuringPublish)' == 'true' "
DependsOnTargets="_CrossGenForPublish">
<!-- Rewrite ResolvedAssembliesToPublish, preserving metadata. -->
<ItemGroup>
<_CrossGenResolvedAssembliesToPublishCandidates Include="@(ResolvedAssembliesToPublish->'$(IntermediateOptimizedDir)/%(Filename)%(Extension)')" />
<_CrossGenResolvedAssembliesToPublish Include="@(_CrossGenResolvedAssembliesToPublishCandidates)" Condition="Exists('%(Identity)')" />
<!-- FilesToCrossGen doesn't contain System.Private.CoreLib, so
it will still be published. -->
<ResolvedAssembliesToPublish Remove="@(FilesToCrossGen)" />
<ResolvedAssembliesToPublish Include="@(_CrossGenResolvedAssembliesToPublish)" />
</ItemGroup>
<!-- Rewrite IntermediateAssembly, preserving metadata. -->
<ItemGroup>
<_CrossGenIntermediateAssemblyCandidates Include="@(IntermediateAssembly->'$(IntermediateOptimizedDir)/%(Filename)%(Extension)')" />
<_CrossGenIntermediateAssembly Include="@(_CrossGenIntermediateAssemblyCandidates)" Condition="Exists('%(Identity)')" />
<IntermediateAssembly Remove="@(FilesToCrossGen)" />
<IntermediateAssembly Include="@(_CrossGenIntermediateAssembly)" />
</ItemGroup>
</Target>
<!-- The target that runs crossgen on all input assemblies. We could
probably also reuse _RunCrossgen, but this gets its inputs from
ResolvedFileToPublish, so we would need to run crossgen after
ComputeFilesToPublish. -->
<Target Name="_CrossGenForPublish"
DependsOnTargets="PrepOptimizer;_ComputeCrossGenInputs">
<MakeDir Directories="$(IntermediateOptimizedDir)" />
<PropertyGroup>
<_CrossGenPlatformAssemblies>@(_CrossGenPlatformAssemblies)</_CrossGenPlatformAssemblies>
</PropertyGroup>
<ItemGroup>
<CrossGenInvocations Include="$(MSBuildProjectFullPath)">
<Properties>
CrossGenExe=$(Crossgen);
CrossGenInput=%(FilesToCrossGen.FullPath);
CrossGenOutput=$(IntermediateOptimizedDir)/%(Filename)%(Extension);
CrossGenPlatformAssemblies=$(_CrossGenPlatformAssemblies)
</Properties>
</CrossGenInvocations>
</ItemGroup>
<MSBuild Projects="@(CrossGenInvocations)"
Targets="RunCrossGenForPublish" />
</Target>
<!-- Workarounds for SDK issues around the interdependency between
ComposeStore targets and CrossGen targets. These let us reuse
PrepOptimizer from the SDK to obtain a crossgen executable for
the target RID. -->
<!-- _RestoreCrossgen (a dependency of PrepOptimizer) requires _TFM
to be set, but it is only set in an unrelated target called
during ComposeStore (PrepareForComposeStore). -->
<Target Name="_SetTFMForCrossGenRestore"
BeforeTargets="_RestoreCrossgen"
Condition=" '$(CrossGenDuringPublish)' == 'true' ">
<PropertyGroup>
<_TFM Condition=" '$(_TFM)' == '' ">$(TargetFramework)</_TFM>
</PropertyGroup>
</Target>
<!-- _RestoreCrossgen also requires _CrossProjAssetsFile to be
set. This path is computed from ComposeWorkingDir in the target
_GetCrossgenProps, but ComposeWorkingDir is set only in
store-related targets. We hook into _GetCrossgenProps to
specify where to restore crossgen. -->
<Target Name="_SetComposeWorkingDirForCrossGenRestore"
AfterTargets="_GetCrossgenProps"
Condition=" '$(CrossGenDuringPublish)' == 'true' ">
<PropertyGroup>
<_CrossProjFileDir>$([System.IO.Path]::GetFullPath($(IntermediateCrossGenDir)))</_CrossProjFileDir>
<_NetCoreRefDir>$([System.IO.Path]::Combine($(_CrossProjFileDir), "netcoreapp"))</_NetCoreRefDir>
<_CrossProjAssetsFile>$([System.IO.Path]::Combine($(_CrossProjFileDir), project.assets.json))</_CrossProjAssetsFile>
</PropertyGroup>
<MakeDir Directories="$(_CrossProjFileDir)" />
</Target>
<!-- PrepforRestoreForComposeStore (a dependency of
_RestoreCrossgen) sets BaseIntermediateOutputPath and
ProjectAssetsFile to the compose working directory. We don't
want this because we are not composing a package store, so we
save and restore these properties. -->
<Target Name="_SavePropsModifiedByPrepforRestoreForComposeStore"
BeforeTargets="PrepforRestoreForComposeStore"
Condition=" '$(CrossGenDuringPublish)' == 'true' ">
<PropertyGroup>
<_SavedBaseIntermediateOutputPath>$(BaseIntermediateOutputPath)</_SavedBaseIntermediateOutputPath>
<_SavedProjectAssetsFile>$(ProjectAssetsFile)</_SavedProjectAssetsFile>
</PropertyGroup>
</Target>
<Target Name="_RestorePropsModifiedByPrepforRestoreForComposeStore"
AfterTargets="PrepforRestoreForComposeStore">
<PropertyGroup>
<BaseIntermediateOutputPath>$(_SavedBaseIntermediateOutputPath)</BaseIntermediateOutputPath>
<ProjectAssetsFile>$(_SavedProjectAssetsFile)</ProjectAssetsFile>
</PropertyGroup>
</Target>
<!-- Run crossgen on a single input assembly. -->
<Target Name="RunCrossGenForPublish"
Inputs="$(CrossGenInput);$(CrossGenPlatformAssemblies)"
Outputs="$(CrossGenOutput)">
<!-- The property CrossGenPlatformAssemblies must be
semicolon-delimited for incremental build to work correctly,
but the directory paths have to be passed with
platform-specific path separators in the crossgen command.
-->
<ItemGroup>
<_CrossGenPlatformAssemblies Include="$(CrossGenPlatformAssemblies)" />
<__CrossGenPlatformAssembliesPaths Include="@(_CrossGenPlatformAssemblies->'%(RootDir)%(Directory)')" />
<_CrossGenPlatformAssembliesPaths Include="@(__CrossGenPlatformAssembliesPaths->Distinct())" />
</ItemGroup>
<PropertyGroup>
<_PathSeparator>$([System.IO.Path]::PathSeparator)</_PathSeparator>
<_CrossGenPlatformAssembliesPaths>@(_CrossGenPlatformAssembliesPaths, '$(_PathSeparator)')</_CrossGenPlatformAssembliesPaths>
</PropertyGroup>
<PropertyGroup>
<CrossGenCommand>$(CrossGenExe) -readytorun -in $(CrossGenInput) -out $(CrossGenOutput) -platform_assemblies_paths $(_CrossGenPlatformAssembliesPaths)</CrossGenCommand>
</PropertyGroup>
<Message Text="$(CrossGenCommand)" />
<Exec Command="$(CrossGenCommand)" />
</Target>
<Target Name="_ComputeCrossGenInputs"
DependsOnTargets="_ComputeCrossGenPlatformAssemblies;_ComputeFilesToCrossGen" />
<!-- Compute the platform assembly paths, a parameter to crossgen
that lets it find dependencies of the input file. This needs to
include the path to the input file and its dependency closure,
including System.Private.CoreLib. -->
<Target Name="_ComputeCrossGenPlatformAssemblies"
DependsOnTargets="_ComputeManagedResolvedAssembliesForCrossGen">
<ItemGroup>
<_CrossGenPlatformAssemblies Include="@(_ManagedResolvedAssembliesForCrossGen)" />
<_CrossGenPlatformAssemblies Include="@(IntermediateAssembly)" />
</ItemGroup>
</Target>
<!-- _ManagedResolvedAssembliesForCrossGen includes the app's
managed dependency closure, including System.Private.CoreLib,
but not the app itself or resource assemblies. -->
<Target Name="_ComputeManagedResolvedAssembliesForCrossGen">
<ComputeManagedAssemblies Assemblies="@(ResolvedAssembliesToPublish)">
<Output TaskParameter="ManagedAssemblies" ItemName="_ManagedResolvedAssembliesForCrossGen" />
</ComputeManagedAssemblies>
<ItemGroup>
<_ManagedResolvedAssembliesForCrossGen Remove="@(_ManagedResolvedAssembliesForCrossGen->WithMetadataValue('AssetType', 'resources'))" />
</ItemGroup>
</Target>
<UsingTask TaskName="FilterByMetadata" AssemblyFile="$(LinkTaskDllPath)" />
<!-- This computes the default set of files that we want to be
crossgen'd. Some of these may already be R2R images, and these
will not be crossgen'd again. The default is to crossgen the
app and platform libraries. Defaults will be used only if
FilesToCrossGen hasn't been set elsewhere, allowing users and
other props/targets to select what will be crossgen'd. -->
<Target Name="_ComputeDefaultFilesToCrossGen"
DependsOnTargets="_ComputeManagedResolvedAssembliesForCrossGen;_ComputePlatformLibraries"
Condition=" '@(FilesToCrossGen->Count())' == '0' ">
<FilterByMetadata Items="@(_ManagedResolvedAssembliesForCrossGen)"
MetadataName="Filename"
MetadataValues="@(PlatformLibraries->'%(Filename)')">
<Output TaskParameter="FilteredItems" ItemName="_PlatformLibrariesForCrossGen" />
</FilterByMetadata>
<ItemGroup>
<FilesToCrossGen Include="@(IntermediateAssembly)" />
<FilesToCrossGen Include="@(_PlatformLibrariesForCrossGen)" />
</ItemGroup>
<Error Text="System.Private.CoreLib should already be crossgen compiled."
Condition=" '%(FilesToCrossGen.Filename)' == 'System.Private.CoreLib' " />
</Target>
<UsingTask TaskName="ComputeReadyToRunAssemblies" AssemblyFile="$(LinkTaskDllPath)" />
<Target Name="_ComputeFilesToCrossGen"
DependsOnTargets="_ComputeDefaultFilesToCrossGen">
<ComputeReadyToRunAssemblies Assemblies="@(FilesToCrossGen)">
<Output TaskParameter="ReadyToRunAssemblies" ItemName="_ReadyToRunFiles" />
</ComputeReadyToRunAssemblies>
<!-- Don't try to run crossgen on assemblies that are already R2R. -->
<ItemGroup>
<FilesToCrossGen Remove="@(_ReadyToRunFiles)" />
</ItemGroup>
<Message Text="files to crossgen: @(FilesToCrossGen)" />
</Target>
</Project>