summaryrefslogtreecommitdiff
path: root/Tools/codeOptimization.targets
blob: 7eecb164c3250b32aa115dca72dc7cfadafccc7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="ZipFileExtractToDirectory" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>

  <PropertyGroup>
    <OptimizationDataVersion Condition="'$(OptimizationDataVersion)'==''">2.0.0-rc-61101-16</OptimizationDataVersion>
    <CoreFxOptimizationDataVersion Condition="'$(CoreFxOptimizationDataVersion)'==''">99.99.99-master-20180815-0120</CoreFxOptimizationDataVersion>
    <OptimizationDataPackageName Condition="'$(OptimizationDataPackageName)'==''">RoslynDependencies.OptimizationData</OptimizationDataPackageName>
    <CoreFxOptimizationDataPackageName Condition="'$(CoreFxOptimizationDataPackageName)'=='' and '$(IBCTarget)'=='Linux'">optimization.linux-x64.IBC.CoreFx</CoreFxOptimizationDataPackageName>
    <CoreFxOptimizationDataPackageName Condition="'$(CoreFxOptimizationDataPackageName)'==''">optimization.windows_nt-x64.IBC.CoreFx</CoreFxOptimizationDataPackageName>
    <OptimizationDataDir Condition="'$(OptimizationDataDir)'==''">$(ToolsDir)OptimizationData/</OptimizationDataDir>
    <RestoreDefaultOptimizationDataPackage Condition="'$(RestoreDefaultOptimizationDataPackage)'==''">true</RestoreDefaultOptimizationDataPackage>
    <UsePartialNGENOptimization Condition="'$(UsePartialNGENOptimization)'==''">true</UsePartialNGENOptimization>
  </PropertyGroup>

  <!-- If IBC data hasn't been merged with the IL yet, preprocess it first -->
  <Target Name="PreProcessIBCData"
          BeforeTargets="OptimizeWithTrainingData"
          DependsOnTargets="ResolveOptionalTools"
          Condition="'$(RunningOnUnix)'!='true' and '$(EnableProfileGuidedOptimization)'=='true' and Exists('$(OptimizationDataDir)$(AssemblyName).dll')">

    <!-- Find IBCMerge as a resolved optional tool. -->
    <PropertyGroup>
      <IBCMergeToolPath Condition="'%(Filename)%(Extension)'=='ibcmerge.exe'">@(ResolvedOptionalToolReferences)</IBCMergeToolPath>
    </PropertyGroup>

    <!-- Enumerate the various files that need merging -->
    <PropertyGroup>
      <InputAssemblyFile>$(OptimizationDataDir)$(AssemblyName).dll</InputAssemblyFile>
      <TargetOptimizationDataFile>$(OptimizationDataDir)$(AssemblyName).pgo</TargetOptimizationDataFile>
    </PropertyGroup>
    <ItemGroup>
      <RawOptimizationDataFiles Include="$(OptimizationDataDir)$(AssemblyName).ibc" />
    </ItemGroup>

    <!-- Merge the optimization data into the source DLL -->
    <Exec Command="$(IBCMergeToolPath) -q -f -delete -mo $(InputAssemblyFile) @(RawOptimizationDataFiles, ' ')" />

    <!-- Verify that the optimization data has been merged -->
    <Exec Command="$(IBCMergeToolPath) -mi $(InputAssemblyFile)" />

    <!-- Save the module as *.pgo to match the convention expected in target OptimizeWithTrainingData -->
    <Copy SourceFiles="$(InputAssemblyFile)" DestinationFiles="$(TargetOptimizationDataFile)" />
  </Target>

  <!-- We should only run this target on Windows and only if EnableProfileGuidedOptimization is set and we have training data -->
  <Target Name="OptimizeWithTrainingData"
          AfterTargets="AfterBuild"
          BeforeTargets="CopyFilesToOutputDirectory"
          DependsOnTargets="ResolveOptionalTools"
          Condition="'$(RunningOnUnix)'!='true' and '$(EnableProfileGuidedOptimization)'=='true' and Exists('$(OptimizationDataDir)$(AssemblyName).pgo')">

    <!-- Find IBCMerge as a resolved optional tool. -->
    <PropertyGroup>
      <IBCMergeToolPath Condition="'%(Filename)%(Extension)'=='ibcmerge.exe'">@(ResolvedOptionalToolReferences)</IBCMergeToolPath>
    </PropertyGroup>

    <PropertyGroup>
      <OptimizedAssemblyDir>$(IntermediateOutputPath)/OptimizedAssembly</OptimizedAssemblyDir>
      <OptimizedAssemblyFile>$(OptimizedAssemblyDir)/$(AssemblyName).dll</OptimizedAssemblyFile>
    </PropertyGroup>

    <!-- Customize IBCMerge's arguments depending on input props -->
    <PropertyGroup>
      <IBCMergeArguments>-q -f -mo $(OptimizedAssemblyFile) -incremental $(OptimizationDataDir)$(AssemblyName).pgo</IBCMergeArguments>
      <IBCMergeArguments Condition="$(UsePartialNGENOptimization)">$(IBCMergeArguments) -partialNGEN -minify</IBCMergeArguments>
    </PropertyGroup>

    <!-- Copy the compiled assembly into a folder for further processing -->
    <MakeDir Directories="$(OptimizedAssemblyDir)" />
    <Copy SourceFiles="@(IntermediateAssembly)" DestinationFolder="$(OptimizedAssemblyDir)" />

    <!-- Apply optimization data to the compiled assembly -->
    <Exec Command="$(IBCMergeToolPath) $(IBCMergeArguments)" />

    <!-- Verify that the optimization data has been applied -->
    <Exec Command="$(IBCMergeToolPath) -mi $(OptimizedAssemblyFile)" />

    <!-- We need to make sure that the assembly that gets packaged is the one with the optimization data -->
    <ItemGroup>
      <IntermediateAssembly Remove="@(IntermediateAssembly)"/>
      <IntermediateAssembly Include="$(OptimizedAssemblyDir)/$(AssemblyName).dll"/>
    </ItemGroup>
  </Target>

  <!-- We need the OptimizationData package in order to be able to optimize the assembly -->
  <Target Name="RestoreOptimizationDataPackage"
          Condition="'$(EnableProfileGuidedOptimization)'=='true' and '$(RestoreDefaultOptimizationDataPackage)'=='true' and !Exists('$(OptimizationDataDir)project.csproj')">
    <!-- Dynamically create a project.json file used to restore the optimization data-->
    <PropertyGroup>
      <OptimizationDataProject>$(MSBuildThisFileDirectory)OptimizationData.msbuild</OptimizationDataProject>
      <OptimizationDataNuGetFeed Condition="'$(OptimizationDataNuGetFeed)'==''">https:%2F%2Fdotnet.myget.org/F/roslyn/api/v3/index.json</OptimizationDataNuGetFeed>
      <CoreFxOptimizationDataNuGetFeed Condition="'$(CoreFxOptimizationDataNuGetFeed)'==''">https:%2F%2Fdotnet.myget.org/F/dotnet-core-optimization-data/api/v3/index.json</CoreFxOptimizationDataNuGetFeed>
    </PropertyGroup>

    <!-- Restore the OptimizationData package -->
    <Exec Command="$(DnuRestoreCommand) $(OptimizationDataProject) --source $(OptimizationDataNuGetFeed) /p:OptimizationDataPackageName=$(OptimizationDataPackageName) /p:OptimizationDataVersion=$(OptimizationDataVersion) /p:BaseIntermediateOutputPath=$(OptimizationDataDir)" StandardOutputImportance="Low"/>
    <Exec Command="$(DnuRestoreCommand) $(OptimizationDataProject) --source $(CorefxOptimizationDataNuGetFeed) /p:OptimizationDataPackageName=$(CoreFxOptimizationDataPackageName) /p:OptimizationDataVersion=$(CoreFxOptimizationDataVersion) /p:BaseIntermediateOutputPath=$(OptimizationDataDir)" StandardOutputImportance="Low"/>

    <!-- Copy the restored files into a more accessible location -->
    <ItemGroup>
      <_OptimizationDataFiles Include="$(PackagesDir)/$(OptimizationDataPackageName)/$(OptimizationDataVersion)/content/OptimizationData/*.pgo" />
      <_OptimizationDataFiles Include="$(PackagesDir)/$(CoreFxOptimizationDataPackageName)/$(CoreFxOptimizationDataVersion)/data/*.dll" />
      <_OptimizationDataFiles Include="$(PackagesDir)/$(CoreFxOptimizationDataPackageName)/$(CoreFxOptimizationDataVersion)/data/*.ibc" />
    </ItemGroup>

    <Copy SourceFiles="@(_OptimizationDataFiles)"
          DestinationFiles="@(_OptimizationDataFiles->'$(OptimizationDataDir)%(Filename)%(Extension)')"
          SkipUnchangedFiles="true"
          ContinueOnError="true"/>
  </Target>
</Project>