Fix unset ZapRelocationType for fixup (#18589)
[platform/upstream/coreclr.git] / Tools / FrameworkTargeting.targets
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
4   <ItemGroup>
5     <TargetingPackDirs Include="$(RefPath)" />
6     <AdditionalReferencePaths Include="@(TargetingPackDirs)" />
7   </ItemGroup>
8
9   <PropertyGroup>
10     <ContractOutputPath>$(RefPath)</ContractOutputPath>
11     <FrameworkPathOverride>$(ContractOutputPath)</FrameworkPathOverride>
12     <AssemblySearchPaths>$(AssemblySearchPaths);$(ContractOutputPath);{RawFileName}</AssemblySearchPaths>
13     <!-- Disable RAR from transitively discovering dependencies for References -->
14     <_FindDependencies>false</_FindDependencies>
15   </PropertyGroup>
16
17   <PropertyGroup Condition=" '$(TargetFrameworkIdentifier)' == ''
18                          and '$(TargetFrameworkVersion)'    == ''
19                          and '$(TargetFrameworkProfile)'    == '' ">
20     <TargetingDefaultPlatform>true</TargetingDefaultPlatform>
21   </PropertyGroup>
22
23   <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == ''">
24      <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
25   </PropertyGroup>
26
27   <!--
28     When targeting an explicit platform other than the default,
29     also allow the target framework directory.
30   -->
31   <PropertyGroup Condition="'$(TargetingDefaultPlatform)' != 'true'">
32     <AssemblySearchPaths>$(AssemblySearchPaths);{TargetFrameworkDirectory}</AssemblySearchPaths>
33   </PropertyGroup>
34
35   <!-- Setup the default target for projects not already explicitly targeting another platform -->
36   <PropertyGroup Condition="'$(TargetingDefaultPlatform)' == 'true'">
37     <!-- Setting a default portable profile, although nothing should resolve from there as we want to use the pacakge refs -->
38     <TargetPlatformIdentifier>Portable</TargetPlatformIdentifier>
39     <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
40     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
41     <!-- We do not want to target a portable profile. -->
42     <TargetFrameworkProfile></TargetFrameworkProfile>
43     <!-- We set this property to avoid MSBuild errors regarding not setting TargetFrameworkProfile (see above line) -->
44     <PortableNuGetMode>true</PortableNuGetMode>
45     <TargetFrameworkMonikerDisplayName>.NET Portable Subset</TargetFrameworkMonikerDisplayName>
46     <ImplicitlyExpandTargetFramework>false</ImplicitlyExpandTargetFramework>
47     <!-- Disable RAR complaining about us referencing higher .NET Portable libraries as we aren't a traditional portable library -->
48     <ResolveAssemblyReferenceIgnoreTargetFrameworkAttributeVersionMismatch>true</ResolveAssemblyReferenceIgnoreTargetFrameworkAttributeVersionMismatch>
49     <NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == ''">.NETCoreApp,Version=v1.0</NuGetTargetMoniker>
50   </PropertyGroup>
51
52   <PropertyGroup Condition="'$(IncludeDefaultReferences)' == ''">
53     <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.csproj'">true</IncludeDefaultReferences>
54     <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.vbproj'">true</IncludeDefaultReferences>
55   </PropertyGroup>
56
57   <Target Name="SetupDefaultReferences">
58     <ItemGroup Condition="'$(IncludeDefaultReferences)' =='true'">
59       <!-- netstandard is a default reference whenever building for NETStandard or building an implementation assembly -->
60       <DefaultReference Condition="($(NuGetTargetMoniker.StartsWith('.NETStandard')) OR '$(IsReferenceAssembly)' != 'true') AND Exists('$(RefPath)netstandard.dll')"
61                         Include="netstandard" />
62     </ItemGroup>
63   </Target>
64
65   <Target Name="UpdateReferenceItems"
66           DependsOnTargets="SetupDefaultReferences"
67           BeforeTargets="BeforeResolveReferences"
68   >
69     <ItemGroup>
70       <Reference Include="@(DefaultReference)" />
71     </ItemGroup>
72
73     <ItemGroup>
74       <!-- Simple name references will be resolved from the targeting pack folders and should never be copied to output -->
75       <Reference Condition="'%(Reference.Extension)' != '.dll'">
76         <Private>false</Private>
77       </Reference>
78     </ItemGroup>
79   </Target>
80
81   <!-- Need to add references to the mscorlib design-time facade for some old-style portable dependencies like xunit -->
82   <Target Name="AddDesignTimeFacadeReferences"
83       Condition="'$(TargetingDefaultPlatform)' == 'true' AND '$(IsReferenceAssembly)' != 'true' AND '$(ExcludeMscorlibFacade)' != 'true'"
84       BeforeTargets="ResolveReferences"
85       DependsOnTargets="GetReferenceAssemblyPaths"
86   >
87     <PropertyGroup>
88       <_resolvedMscorlib Condition="'%(ReferencePath.FileName)' == 'mscorlib'">true</_resolvedMscorlib>
89     </PropertyGroup>
90
91     <ItemGroup>
92       <PossibleTargetFrameworks Include="$(_TargetFrameworkDirectories)" />
93       <ReferencePath Include="%(PossibleTargetFrameworks.Identity)mscorlib.dll"
94                      Condition="'$(_resolvedMscorlib)' != 'true' and '%(PossibleTargetFrameworks.Identity)' != '' and Exists('%(PossibleTargetFrameworks.Identity)mscorlib.dll')" />
95     </ItemGroup>
96   </Target>
97
98   <PropertyGroup>
99     <!-- Disable WindowsAppContainer property to prevent importing AppX targets which we don't need -->
100     <WindowsAppContainer Condition="'$(WindowsAppContainer)'==''">false</WindowsAppContainer>
101   </PropertyGroup>
102
103   <Import Project="depProj.targets"
104           Condition="'$(MSBuildProjectExtension)' == '.depproj'" />
105
106   <Import Project="IL.targets"
107            Condition="'$(MSBuildProjectExtension)' == '.ilproj' AND '$(SkipImportILTargets)'!='true'" />
108
109   <!--
110       workaround file casing issue where it has different casing in different places which fails on linux builds
111       https://github.com/dotnet/buildtools/issues/1464
112   -->
113   <PropertyGroup>
114     <CSharpTargetsFile>$(MSBuildToolsPath)\Microsoft.CSharp.targets</CSharpTargetsFile>
115     <CSharpTargetsFile Condition="!Exists('$(CSharpTargetsFile)')">$(MSBuildToolsPath)\Microsoft.CSharp.Targets</CSharpTargetsFile>
116   </PropertyGroup>
117
118   <Import Project="$(MSBuildExtensionsPath32)\Microsoft.CSharp.targets"
119            Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj' and '$(RunningOnCore)' == 'true'" />
120
121   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets"
122            Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj' and '$(RunningOnCore)' != 'true'" />
123  
124
125   <Import Project="$(CSharpTargetsFile)"
126           Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj'" />
127
128   <Import Project="$(MSBuildExtensionsPath32)\Microsoft.VisualBasic.targets"
129            Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj' and '$(RunningOnCore)' == 'true'" />
130  
131
132   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.VisualBasic.targets"
133           Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj' and '$(RunningOnCore)' != 'true'" />
134
135   <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets"
136           Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj'" />
137
138   <PropertyGroup>
139     <!--
140       We don't use any of MSBuild's resolution logic for resolving the framework, so just set these two properties to any folder
141       that exists to skip the GenerateReferenceAssemblyPaths task (not target) and to prevent it from outputting a warning (MSB3644).
142       Need to set these after the common targets import.
143       -->
144     <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)</_TargetFrameworkDirectories>
145     <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>
146   </PropertyGroup>
147
148   <PropertyGroup>
149     <ResolveReferencesDependsOn>
150       AddProjectReferencesDynamically;
151       $(ResolveReferencesDependsOn);
152     </ResolveReferencesDependsOn>
153     <CleanDependsOn>
154       AddProjectReferencesDynamically;
155       $(CleanDependsOn);
156     </CleanDependsOn>
157   </PropertyGroup>
158   <!--
159     Common targets don't provide a good place to enable adding new ProjectReference items in targets that work
160     with both clean, build, and rebuild entry point targets. We cannot hook off of AssignProjectConfigurations
161     because it is conditioned on "'@(ProjectReference)'!=''" which gets evalulated before the BeforeTargets run
162     so adding ProjectReference as part of a BeforeTarget make still have the AssignProjectConfiguration skipped.
163     To help with this problem we are creating a new target and correctly hooking it up in the resolve and clean
164     depends on target chains.
165
166     For information on evaulation of targets ordering see https://msdn.microsoft.com/en-us/library/ee216359.aspx.
167   -->
168   <Target Name="AddProjectReferencesDynamically" DependsOnTargets="$(AddProjectReferencesDynamicallyDependsOn)" />
169
170   <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework' and '$(OutputType)' == 'exe'">
171     <!-- RAR thinks all EXEs require binding redirects.  That's not the case for CoreCLR -->
172     <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>
173     <GenerateBindingRedirectsOutputType>false</GenerateBindingRedirectsOutputType>
174   </PropertyGroup>
175
176   <!-- We need to point $(FrameworkPathOverride) to the directory that contains explicitly referenced System.Runtime.dll, if any.
177        Otherwise, if $(FrameworkPathOverride)\System.Runtime.dll is not the same file as the one referenced explicitly,
178        VS2013 VB compiler would load it and then it would complain about ambiguous type declarations.
179   -->
180   <PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
181     <CoreCompileDependsOn>$(CoreCompileDependsOn);OverrideFrameworkPathForVisualBasic</CoreCompileDependsOn>
182   </PropertyGroup>
183
184   <Target Name="OverrideFrameworkPathForVisualBasic" AfterTargets="ResolveAssemblyReferences" Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
185     <ItemGroup>
186       <FrameworkPathOverrideCandidate Include="%(ReferencePath.RootDir)%(ReferencePath.Directory)"
187             Condition="'%(ReferencePath.Filename)%(ReferencePath.Extension)' == 'System.Runtime.dll'">
188       </FrameworkPathOverrideCandidate>
189     </ItemGroup>
190
191     <PropertyGroup Condition="'@(FrameworkPathOverrideCandidate->Count())' == '1'">
192       <FrameworkPathOverride>@(FrameworkPathOverrideCandidate)</FrameworkPathOverride>
193     </PropertyGroup>
194   </Target>
195
196   <!--
197     Cross Platform MSBuild has some logic to replace \ with / when invoking commands to fix up path differences between Windows and
198     *NIX. The define command line argument syntax for VB requires that we both surround some items with quotes and escape the quotes with
199     backslashes. However, due to the above MSBuild logic, this causes an invalid command line to be generated when running on *NIX.
200
201     Microsoft/msbuild#422 tracks an actual fix in MSBuild, but for now we work around the issue by using a custom task that
202     transforms the set of defines we are going to use into a response file we can pass along to the Vbc task along with an
203     empty set of defines.
204   -->
205   <UsingTask TaskName="WriteVisualBasicDefineResponseFile"  AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll" />
206
207   <Target Name="ConvertDefinesToResonseFile" BeforeTargets="CoreCompile" Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
208     <WriteVisualBasicDefineResponseFile DefineConstants="$(FinalDefineConstants)"
209                                         File="$(IntermediateOutputPath)/defines.rsp" />
210     <PropertyGroup>
211       <CompilerResponseFile>$(IntermediateOutputPath)/defines.rsp;$(CompilerResponseFile)</CompilerResponseFile>
212       <FinalDefineConstants></FinalDefineConstants>
213     </PropertyGroup>
214   </Target>
215
216   <Target Name="ConvertCommonMetadataToAdditionalProperties" BeforeTargets="AssignProjectConfiguration">
217     <!-- list each append as a seperate item to force re-evaluation of AdditionalProperties metadata -->
218     <ItemGroup>
219
220      <!-- Configuration property shortcuts -->
221      <ProjectReference>
222        <AdditionalProperties Condition="'%(ProjectReference.Configuration)' != ''">Configuration=%(ProjectReference.Configuration);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
223      </ProjectReference>
224       <!-- Packaging property shortcuts -->
225       <ProjectReference>
226         <AdditionalProperties Condition="'%(ProjectReference.PackageTargetFramework)' != ''">PackageTargetFramework=%(ProjectReference.PackageTargetFramework);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
227       </ProjectReference>
228       <ProjectReference>
229         <AdditionalProperties Condition="'%(ProjectReference.PackageTargetPath)' != ''">PackageTargetPath=%(ProjectReference.PackageTargetPath);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
230       </ProjectReference>
231       <ProjectReference>
232         <AdditionalProperties Condition="'%(ProjectReference.PackageTargetRuntime)' != ''">PackageTargetRuntime=%(ProjectReference.PackageTargetRuntime);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
233       </ProjectReference>
234       <ProjectReference>
235         <AdditionalProperties Condition="'%(ProjectReference.Platform)' != ''">Platform=%(ProjectReference.Platform);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
236       </ProjectReference>
237     </ItemGroup>
238   </Target>
239
240   <!-- Binplacing targets and properties -->
241   <PropertyGroup>
242     <BinPlaceUseHardlinksIfPossible Condition="'$(BinPlaceUseHardlinksIfPossible)' == ''">true</BinPlaceUseHardlinksIfPossible>
243     <EnableBinPlacing Condition="'$(EnableBinPlacing)' == '' AND ('$(BinPlaceRef)' == 'true' OR '$(BinPlaceRuntime)' == 'true' OR '$(BinPlaceTest)' == 'true')">true</EnableBinPlacing>
244   </PropertyGroup>
245
246   <Target Name="BinPlace"
247           DependsOnTargets="GetBinPlaceConfiguration;BinPlaceFiles;BinPlaceProps"
248           AfterTargets="CopyFilesToOutputDirectory"
249           Condition="'$(EnableBinPlacing)' == 'true'" />
250
251   <Target Name="BinPlaceFiles"
252           Condition="'@(BinPlaceDir)' != ''"
253           DependsOnTargets="GetBinPlaceItems"
254           Inputs="@(BinPlaceDir);%(BinPlaceDir.ItemName)"
255           Outputs="unused" >
256
257     <PropertyGroup>
258       <_BinPlaceItemName>%(BinPlaceDir.ItemName)</_BinPlaceItemName>
259       <_BinPlaceItemName Condition="'$(_BinPlaceItemName)' == ''">BinPlaceItem</_BinPlaceItemName>
260     </PropertyGroup>
261
262     <Message Importance="low" Text="BinPlaceDir: @(BinPlaceDir)" />
263
264     <Copy SourceFiles="@($(_BinPlaceItemName))"
265           DestinationFolder="%(BinPlaceDir.Identity)"
266           SkipUnchangedFiles="true"
267           OverwriteReadOnlyFiles="true"
268           Retries="$(CopyRetryCount)"
269           RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
270           UseHardlinksIfPossible="$(BinPlaceUseHardlinksIfPossible)">
271       <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
272     </Copy>
273   </Target>
274
275   <UsingTask TaskName="SaveItems" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>
276   <Target Name="BinPlaceProps"
277           Condition="'@(PackageFileDir)' != ''"
278           DependsOnTargets="GetBinPlaceItems"
279           Inputs="%(PackageFileDir.Identity);%(PackageFileDir.ItemName)"
280           Outputs="unused"  >
281     <ItemGroup>
282       <!-- in the case of an overlapping batch (eg: multiple configurations using same directory)
283            use the first -->
284       <_packageFileDir Include="@(PackageFileDir->Distinct())" />
285     </ItemGroup>
286
287     <PropertyGroup>
288       <_propsFilename>$(TargetName).$(TargetGroup)-$(OSGroup)</_propsFilename>
289       <_propsFilename Condition="'$(TargetName)' == ''">$(MSBuildProjectName).$(TargetGroup)-$(OSGroup)</_propsFilename>
290       <_projectDirLength>$(ProjectDir.Length)</_projectDirLength>
291     </PropertyGroup>
292
293     <PropertyGroup>
294       <_BinPlaceItemName>%(_packageFileDir.ItemName)</_BinPlaceItemName>
295       <_BinPlaceItemName Condition="'$(_BinPlaceItemName)' == ''">BinPlaceItem</_BinPlaceItemName>
296     </PropertyGroup>
297
298     <ItemGroup>
299       <_itemsToSave Include="@($(_BinPlaceItemName))">
300         <!-- intentionally empty: to be set by pkgproj -->
301         <TargetPath></TargetPath>
302         <TargetFramework>%(_packageFileDir.BuildConfiguration_NuGetTargetMonikerShort)</TargetFramework>
303       </_itemsToSave>
304
305       <!-- Include doc files. -->
306       <_docFiles Condition="'$(BinPlaceRef)' == 'true'" Include="$(XmlDocDir)/**/$(TargetName).xml" />
307       <_docFiles>
308         <SubFolder Condition="'%(RecursiveDir)' != ''">/$([System.String]::new('%(RecursiveDir)').TrimEnd('\').TrimEnd('/'))</SubFolder>
309       </_docFiles>
310       <_docFiles>
311         <TargetFramework>%(_packageFileDir.BuildConfiguration_NuGetTargetMonikerShort)</TargetFramework>
312       </_docFiles>
313       <_itemsToSave Include="@(_docFiles)"/>
314
315       <!-- Include source files. -->
316       <!-- Here we use "sources" rather than "src" because MyGet treats packages with "src" as symbol packages  -->
317       <_itemsToSave Condition="'@(Compile)' != ''" Include="@(Compile->'%(FullPath)')">
318         <TargetPath>sources</TargetPath>
319         <TargetPath Condition="$([System.String]::Copy('%(FullPath)').StartsWith('$(ProjectDir)'))">sources/$([System.String]::Copy('%(FullPath)').Substring($(_projectDirLength)).Replace('\', '/'))</TargetPath>
320         <IsSourceCodeFile>true</IsSourceCodeFile>
321       </_itemsToSave>
322     </ItemGroup>
323
324     <Message Importance="low" Text="PackageFileDir: @(PackageFileDir)" />
325
326     <SaveItems ItemName="%(_packageFileDir.SaveItemName)"
327                Items="@(_itemsToSave)"
328                Files="%(_packageFileDir.Identity)\$(_propsFilename).props">
329       <Output TaskParameter="Files" ItemName="FileWrites" />
330     </SaveItems>
331   </Target>
332
333   <Target Name="GetBinPlaceItems" DependsOnTargets="GetCopyToOutputDirectoryItems">
334     <ItemGroup>
335       <BinPlaceItem Condition="Exists('$(TargetPath)')" Include="$(TargetPath)" />
336       <BinPlaceItem Condition="Exists('$(TargetDir)$(TargetName).pdb')" Include="$(TargetDir)$(TargetName).pdb" />
337       <BinPlaceItem Condition="'$(BinPlaceReferenceCopyLocalPaths)' != 'false'" Include="@(ReferenceCopyLocalPaths)" />
338       <BinPlaceItem Condition="'$(BinPlaceCopyToOutputDirectoryItems)' != 'false'" Include="@(AllItemsFullPathWithTargetPath)" />
339     </ItemGroup>
340   </Target>
341
342   <UsingTask TaskName="FindBestConfigurations" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>
343   <Target Name="GetBinPlaceConfiguration" DependsOnTargets="GetBuildConfigurations">
344     <!-- find which, if any, build configuration of this project is best
345          for each binplace configuration -->
346     <FindBestConfigurations Properties="@(Property)"
347                             PropertyValues="@(PropertyValue)"
348                             SupportedConfigurations="$(_AllBuildConfigurations)"
349                             Configurations="@(BinPlaceConfiguration)">
350       <Output TaskParameter="BestConfigurations" ItemName="_bestBinlaceConfigurations" />
351     </FindBestConfigurations>
352
353     <ItemGroup>
354       <_currentBinPlaceConfigurations Include="@(_bestBinlaceConfigurations)" Condition="'%(Identity)' == '$(Configuration)' OR '%(Identity)-$(ConfigurationGroup)' == '$(Configuration)'" />
355
356       <BinPlaceDir Condition="'$(BinPlaceTest)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(TestPath)')" />
357       <BinPlaceDir Condition="'$(BinPlaceRuntime)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(RuntimePath)')" />
358       <BinPlaceDir Condition="'$(BinPlaceRef)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(RefPath)')" />
359
360       <PackageFileDir Condition="'$(BinPlaceRuntime)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(PackageFileRuntimePath)')">
361         <SaveItemName Condition="'%(_currentBinPlaceConfigurations.SaveItemName)' == ''">LibFile</SaveItemName>
362       </PackageFileDir>
363       <PackageFileDir Condition="'$(BinPlaceRef)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(PackageFileRefPath)')">
364         <SaveItemName Condition="'%(_currentBinPlaceConfigurations.SaveItemName)' == ''">RefFile</SaveItemName>
365       </PackageFileDir>
366
367       <!-- permit BinplaceConfigurations to define SetProperties metadata,
368            set those properties when BinplaceConfiguration is active -->
369       <_binplacePropertyTuples Include="%(_currentBinPlaceConfigurations.SetProperties)" />
370
371       <_binplaceSetProperty Condition="'%(_binplacePropertyTuples.Identity)' != ''"
372                             Include="$([System.String]::new('%(_binplacePropertyTuples.Identity)').Split('=')[0])">
373         <Value>$([System.String]::new('%(_binplacePropertyTuples.Identity)').Split('=')[1])</Value>
374       </_binplaceSetProperty>
375     </ItemGroup>
376
377     <CreateProperty Value="%(_binplaceSetProperty.Value)" Condition="'@(_binplaceSetProperty)' != ''" >
378       <Output TaskParameter="Value" PropertyName="%(_binplaceSetProperty.Identity)" />
379     </CreateProperty>
380   </Target>
381
382   <!-- IncrementalClean and CoreClean only clean paths under Intermediate or OutDir, handle additional paths -->
383   <ItemGroup>
384     <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(RefPath)')" />
385     <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(RuntimePath)')" />
386     <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(PackageFileRefPath)')" />
387     <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(PackageFileRuntimePath)')" />
388     <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(TestPath)')" />
389   </ItemGroup>
390
391   <Target Name="_CleanGetCurrentAdditionalFileWrites" BeforeTargets="_CleanGetCurrentAndPriorFileWrites" Condition="'@(AdditionalCleanDirectories)' != ''">
392     <!-- find files under paths we care about and add them to _CleanCurrentFileWrites to ensure they are written to the file list -->
393     <FindUnderPath Path="%(AdditionalCleanDirectories.Identity)" Files="@(FileWrites)" UpdateToAbsolutePaths="true">
394       <Output TaskParameter="InPath" ItemName="_CleanCurrentFileWrites" />
395     </FindUnderPath>
396   </Target>
397
398   <!-- delete files under our AdditionalCleanDirectories on Incremental clean -->
399   <Target Name="IncrementalCleanAdditionalDirectories" BeforeTargets="IncrementalClean" Condition="'@(AdditionalCleanDirectories)' != ''">
400     <ItemGroup>
401       <_CleanOrphanAdditionalFileWrites Include="@(_CleanPriorFileWrites)" Exclude="@(_CleanCurrentFileWrites)" />
402     </ItemGroup>
403     <FindUnderPath Path="%(AdditionalCleanDirectories.Identity)" Files="@(_CleanOrphanAdditionalFileWrites)">
404       <Output TaskParameter="InPath" ItemName="_CleanOrphanFileWritesInAdditionalDirectories" />
405     </FindUnderPath>
406
407     <!-- Delete the orphaned files.  IncrementalClean will remove these from the file list -->
408     <Delete Files="@(_CleanOrphanFileWritesInAdditionalDirectories)" TreatErrorsAsWarnings="true">
409       <Output TaskParameter="DeletedFiles" ItemName="_CleanOrphanFilesDeleted" />
410     </Delete>
411   </Target>
412
413   <!-- delete files under our AdditionalCleanDirectories on CoreClean -->
414   <Target Name="CleanAdditionalDirectories" AfterTargets="CoreClean" Condition="'@(AdditionalCleanDirectories)' != ''">
415     <FindUnderPath Path="%(AdditionalCleanDirectories.Identity)" Files="@(_CleanUniqueRemainingFileWrites)">
416       <Output TaskParameter="InPath" ItemName="_CleanUniqueRemainingFileWritesInAdditionalDirectories"/>
417     </FindUnderPath>
418
419     <Delete Files="@(_CleanUniqueRemainingFileWritesInAdditionalDirectories)" TreatErrorsAsWarnings="true">
420       <Output TaskParameter="DeletedFiles" ItemName="_CleanUniqueRemainingFileWritesInAdditionalDirectoriesDeleted" />
421     </Delete>
422
423     <!-- Create a list of everything that wasn't deleted. -->
424     <ItemGroup>
425       <_CleanRemainingFileWritesAfterCleanAdditionalDirectories Include="@(_CleanUniqueRemainingFileWrites)" Exclude="@(_CleanUniqueRemainingFileWritesInAdditionalDirectoriesDeleted)"/>
426     </ItemGroup>
427
428     <!-- Remove duplicates. -->
429     <RemoveDuplicates Inputs="@(_CleanRemainingFileWritesAfterCleanAdditionalDirectories)">
430       <Output TaskParameter="Filtered" ItemName="_CleanAdditionalDirectoriesUniqueRemainingFileWrites"/>
431     </RemoveDuplicates>
432
433     <!-- Make sure the directory exists. -->
434     <MakeDir Directories="$(IntermediateOutputPath)"/>
435
436     <!-- Write new list of current files back to disk. -->
437     <WriteLinesToFile File="$(IntermediateOutputPath)$(CleanFile)" Lines="@(_CleanAdditionalDirectoriesUniqueRemainingFileWrites)" Overwrite="true" />
438   </Target>
439
440 </Project>