summaryrefslogtreecommitdiff
path: root/Tools-Override/codeOptimization.targets
blob: 4db340f15e744e366ba9c74edeb2a9760eee32f3 (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
113
114
115
116
117
118
<?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>
    <OptimizationDataPackageName Condition="'$(OptimizationDataPackageName)'==''">RoslynDependencies.OptimizationData</OptimizationDataPackageName>
    <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="'$(OS)'=='Windows_NT' 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="'$(OS)'=='Windows_NT' 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"
          BeforeTargets="Sync"
          Condition="'$(EnableProfileGuidedOptimization)'=='true' and '$(RestoreDefaultOptimizationDataPackage)'=='true' and !Exists('$(OptimizationDataDir)project.json')">

    <!-- Dynamically create a project.json file used to restore the optimization data-->
    <Message Text="Generating project.json for optimization data"  Importance="low" />
    <ItemGroup>
      <_OptimizationDataJsonLine Include="{&quot;dependencies&quot;: {" />
      <_OptimizationDataJsonLine Include="&quot;$(OptimizationDataPackageName)&quot; : &quot;$(OptimizationDataVersion)&quot; " />
      <_OptimizationDataJsonLine Include="},&quot;frameworks&quot;: {&quot;netcoreapp1.0&quot;: {},&quot;net46&quot;: {}}}"/>
    </ItemGroup>
    
    <PropertyGroup>
      <OptimizationDataProjectJson>$(OptimizationDataDir)project.json</OptimizationDataProjectJson>
      <OptimizationDataNuGetFeed Condition="'$(OptimizationDataNuGetFeed)'==''">https:%2F%2Fdotnet.myget.org/F/roslyn/api/v3/index.json</OptimizationDataNuGetFeed>
    </PropertyGroup>

    <MakeDir Directories="$(OptimizationDataDir)" ContinueOnError="true" />
    <WriteLinesToFile File="$(OptimizationDataProjectJson)" Lines="@(_OptimizationDataJsonLine)" Overwrite="true" />

    <!-- Restore the OptimizationData package -->
    <Exec Command="$(DnuRestoreCommand) $(OptimizationDataProjectJson) --source $(OptimizationDataNuGetFeed)"
          StandardOutputImportance="Low"/>

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

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