summaryrefslogtreecommitdiff
path: root/packages/microsoft.dotnet.buildtools/2.1.0-rc1-03006-01/lib/FrameworkTargeting.targets
blob: 225bef6185bf681d25278a0f5d970cd72d8f7bf4 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <ItemGroup>
    <TargetingPackDirs Include="$(RefPath)" />
    <AdditionalReferencePaths Include="@(TargetingPackDirs)" />
  </ItemGroup>

  <PropertyGroup>
    <ContractOutputPath>$(RefPath)</ContractOutputPath>
    <FrameworkPathOverride>$(ContractOutputPath)</FrameworkPathOverride>
    <AssemblySearchPaths>$(AssemblySearchPaths);$(ContractOutputPath);{RawFileName}</AssemblySearchPaths>
    <!-- Disable RAR from transitively discovering dependencies for References -->
    <_FindDependencies>false</_FindDependencies>
  </PropertyGroup>

  <PropertyGroup Condition=" '$(TargetFrameworkIdentifier)' == ''
                         and '$(TargetFrameworkVersion)'    == ''
                         and '$(TargetFrameworkProfile)'    == '' ">
    <TargetingDefaultPlatform>true</TargetingDefaultPlatform>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == ''">
     <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
  </PropertyGroup>

  <!--
    When targeting an explicit platform other than the default,
    also allow the target framework directory.
  -->
  <PropertyGroup Condition="'$(TargetingDefaultPlatform)' != 'true'">
    <AssemblySearchPaths>$(AssemblySearchPaths);{TargetFrameworkDirectory}</AssemblySearchPaths>
  </PropertyGroup>

  <!-- Setup the default target for projects not already explicitly targeting another platform -->
  <PropertyGroup Condition="'$(TargetingDefaultPlatform)' == 'true'">
    <!-- Setting a default portable profile, although nothing should resolve from there as we want to use the pacakge refs -->
    <TargetPlatformIdentifier>Portable</TargetPlatformIdentifier>
    <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <!-- We do not want to target a portable profile. -->
    <TargetFrameworkProfile></TargetFrameworkProfile>
    <!-- We set this property to avoid MSBuild errors regarding not setting TargetFrameworkProfile (see above line) -->
    <PortableNuGetMode>true</PortableNuGetMode>
    <TargetFrameworkMonikerDisplayName>.NET Portable Subset</TargetFrameworkMonikerDisplayName>
    <ImplicitlyExpandTargetFramework>false</ImplicitlyExpandTargetFramework>
    <!-- Disable RAR complaining about us referencing higher .NET Portable libraries as we aren't a traditional portable library -->
    <ResolveAssemblyReferenceIgnoreTargetFrameworkAttributeVersionMismatch>true</ResolveAssemblyReferenceIgnoreTargetFrameworkAttributeVersionMismatch>
    <NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == ''">.NETCoreApp,Version=v1.0</NuGetTargetMoniker>
  </PropertyGroup>

  <PropertyGroup Condition="'$(IncludeDefaultReferences)' == ''">
    <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.csproj'">true</IncludeDefaultReferences>
    <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.vbproj'">true</IncludeDefaultReferences>
  </PropertyGroup>

  <Target Name="SetupDefaultReferences">
    <ItemGroup Condition="'$(IncludeDefaultReferences)' =='true'">
      <!-- netstandard is a default reference whenever building for NETStandard or building an implementation assembly -->
      <DefaultReference Condition="($(NuGetTargetMoniker.StartsWith('.NETStandard')) OR '$(IsReferenceAssembly)' != 'true') AND Exists('$(RefPath)netstandard.dll')"
                        Include="netstandard" />
    </ItemGroup>
  </Target>

  <Target Name="UpdateReferenceItems"
          DependsOnTargets="SetupDefaultReferences"
          BeforeTargets="BeforeResolveReferences"
  >
    <ItemGroup>
      <Reference Include="@(DefaultReference)" />
    </ItemGroup>

    <ItemGroup>
      <!-- Simple name references will be resolved from the targeting pack folders and should never be copied to output -->
      <Reference Condition="'%(Reference.Extension)' != '.dll'">
        <Private>false</Private>
      </Reference>
    </ItemGroup>
  </Target>

  <!-- Need to add references to the mscorlib design-time facade for some old-style portable dependencies like xunit -->
  <Target Name="AddDesignTimeFacadeReferences"
      Condition="'$(TargetingDefaultPlatform)' == 'true' AND '$(IsReferenceAssembly)' != 'true' AND '$(ExcludeMscorlibFacade)' != 'true'"
      BeforeTargets="ResolveReferences"
      DependsOnTargets="GetReferenceAssemblyPaths"
  >
    <PropertyGroup>
      <_resolvedMscorlib Condition="'%(ReferencePath.FileName)' == 'mscorlib'">true</_resolvedMscorlib>
    </PropertyGroup>

    <ItemGroup>
      <PossibleTargetFrameworks Include="$(_TargetFrameworkDirectories)" />
      <ReferencePath Include="%(PossibleTargetFrameworks.Identity)mscorlib.dll"
                     Condition="'$(_resolvedMscorlib)' != 'true' and '%(PossibleTargetFrameworks.Identity)' != '' and Exists('%(PossibleTargetFrameworks.Identity)mscorlib.dll')" />
    </ItemGroup>
  </Target>

  <PropertyGroup>
    <!-- Disable WindowsAppContainer property to prevent importing AppX targets which we don't need -->
    <WindowsAppContainer Condition="'$(WindowsAppContainer)'==''">false</WindowsAppContainer>
  </PropertyGroup>

  <Import Project="depProj.targets"
          Condition="'$(MSBuildProjectExtension)' == '.depproj'" />

  <Import Project="IL.targets"
           Condition="'$(MSBuildProjectExtension)' == '.ilproj' AND '$(SkipImportILTargets)'!='true'" />

  <!--
      workaround file casing issue where it has different casing in different places which fails on linux builds
      https://github.com/dotnet/buildtools/issues/1464
  -->
  <PropertyGroup>
    <CSharpTargetsFile>$(MSBuildToolsPath)\Microsoft.CSharp.targets</CSharpTargetsFile>
    <CSharpTargetsFile Condition="!Exists('$(CSharpTargetsFile)')">$(MSBuildToolsPath)\Microsoft.CSharp.Targets</CSharpTargetsFile>
  </PropertyGroup>

  <Import Project="$(MSBuildExtensionsPath32)\Microsoft.CSharp.targets"
           Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj' and '$(RunningOnCore)' == 'true'" />

  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets"
           Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj' and '$(RunningOnCore)' != 'true'" />
 

  <Import Project="$(CSharpTargetsFile)"
          Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj'" />

  <Import Project="$(MSBuildExtensionsPath32)\Microsoft.VisualBasic.targets"
           Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj' and '$(RunningOnCore)' == 'true'" />
 

  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.VisualBasic.targets"
          Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj' and '$(RunningOnCore)' != 'true'" />

  <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets"
          Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj'" />

  <PropertyGroup>
    <!--
      We don't use any of MSBuild's resolution logic for resolving the framework, so just set these two properties to any folder
      that exists to skip the GenerateReferenceAssemblyPaths task (not target) and to prevent it from outputting a warning (MSB3644).
      Need to set these after the common targets import.
      -->
    <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)</_TargetFrameworkDirectories>
    <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>
  </PropertyGroup>

  <PropertyGroup>
    <ResolveReferencesDependsOn>
      AddProjectReferencesDynamically;
      $(ResolveReferencesDependsOn);
    </ResolveReferencesDependsOn>
    <CleanDependsOn>
      AddProjectReferencesDynamically;
      $(CleanDependsOn);
    </CleanDependsOn>
  </PropertyGroup>
  <!--
    Common targets don't provide a good place to enable adding new ProjectReference items in targets that work
    with both clean, build, and rebuild entry point targets. We cannot hook off of AssignProjectConfigurations
    because it is conditioned on "'@(ProjectReference)'!=''" which gets evalulated before the BeforeTargets run
    so adding ProjectReference as part of a BeforeTarget make still have the AssignProjectConfiguration skipped.
    To help with this problem we are creating a new target and correctly hooking it up in the resolve and clean
    depends on target chains.

    For information on evaulation of targets ordering see https://msdn.microsoft.com/en-us/library/ee216359.aspx.
  -->
  <Target Name="AddProjectReferencesDynamically" DependsOnTargets="$(AddProjectReferencesDynamicallyDependsOn)" />

  <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework' and '$(OutputType)' == 'exe'">
    <!-- RAR thinks all EXEs require binding redirects.  That's not the case for CoreCLR -->
    <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>
    <GenerateBindingRedirectsOutputType>false</GenerateBindingRedirectsOutputType>
  </PropertyGroup>

  <!-- We need to point $(FrameworkPathOverride) to the directory that contains explicitly referenced System.Runtime.dll, if any.
       Otherwise, if $(FrameworkPathOverride)\System.Runtime.dll is not the same file as the one referenced explicitly,
       VS2013 VB compiler would load it and then it would complain about ambiguous type declarations.
  -->
  <PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
    <CoreCompileDependsOn>$(CoreCompileDependsOn);OverrideFrameworkPathForVisualBasic</CoreCompileDependsOn>
  </PropertyGroup>

  <Target Name="OverrideFrameworkPathForVisualBasic" AfterTargets="ResolveAssemblyReferences" Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
    <ItemGroup>
      <FrameworkPathOverrideCandidate Include="%(ReferencePath.RootDir)%(ReferencePath.Directory)"
            Condition="'%(ReferencePath.Filename)%(ReferencePath.Extension)' == 'System.Runtime.dll'">
      </FrameworkPathOverrideCandidate>
    </ItemGroup>

    <PropertyGroup Condition="'@(FrameworkPathOverrideCandidate->Count())' == '1'">
      <FrameworkPathOverride>@(FrameworkPathOverrideCandidate)</FrameworkPathOverride>
    </PropertyGroup>
  </Target>

  <!--
    Cross Platform MSBuild has some logic to replace \ with / when invoking commands to fix up path differences between Windows and
    *NIX. The define command line argument syntax for VB requires that we both surround some items with quotes and escape the quotes with
    backslashes. However, due to the above MSBuild logic, this causes an invalid command line to be generated when running on *NIX.

    Microsoft/msbuild#422 tracks an actual fix in MSBuild, but for now we work around the issue by using a custom task that
    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
    empty set of defines.
  -->
  <UsingTask TaskName="WriteVisualBasicDefineResponseFile"  AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll" />

  <Target Name="ConvertDefinesToResonseFile" BeforeTargets="CoreCompile" Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
    <WriteVisualBasicDefineResponseFile DefineConstants="$(FinalDefineConstants)"
                                        File="$(IntermediateOutputPath)/defines.rsp" />
    <PropertyGroup>
      <CompilerResponseFile>$(IntermediateOutputPath)/defines.rsp;$(CompilerResponseFile)</CompilerResponseFile>
      <FinalDefineConstants></FinalDefineConstants>
    </PropertyGroup>
  </Target>

  <Target Name="ConvertCommonMetadataToAdditionalProperties" BeforeTargets="AssignProjectConfiguration">
    <!-- list each append as a seperate item to force re-evaluation of AdditionalProperties metadata -->
    <ItemGroup>

     <!-- Configuration property shortcuts -->
     <ProjectReference>
       <AdditionalProperties Condition="'%(ProjectReference.Configuration)' != ''">Configuration=%(ProjectReference.Configuration);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
     </ProjectReference>
      <!-- Packaging property shortcuts -->
      <ProjectReference>
        <AdditionalProperties Condition="'%(ProjectReference.PackageTargetFramework)' != ''">PackageTargetFramework=%(ProjectReference.PackageTargetFramework);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
      </ProjectReference>
      <ProjectReference>
        <AdditionalProperties Condition="'%(ProjectReference.PackageTargetPath)' != ''">PackageTargetPath=%(ProjectReference.PackageTargetPath);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
      </ProjectReference>
      <ProjectReference>
        <AdditionalProperties Condition="'%(ProjectReference.PackageTargetRuntime)' != ''">PackageTargetRuntime=%(ProjectReference.PackageTargetRuntime);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
      </ProjectReference>
      <ProjectReference>
        <AdditionalProperties Condition="'%(ProjectReference.Platform)' != ''">Platform=%(ProjectReference.Platform);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
      </ProjectReference>
    </ItemGroup>
  </Target>

  <!-- Binplacing targets and properties -->
  <PropertyGroup>
    <BinPlaceUseHardlinksIfPossible Condition="'$(BinPlaceUseHardlinksIfPossible)' == ''">true</BinPlaceUseHardlinksIfPossible>
    <EnableBinPlacing Condition="'$(EnableBinPlacing)' == '' AND ('$(BinPlaceRef)' == 'true' OR '$(BinPlaceRuntime)' == 'true' OR '$(BinPlaceTest)' == 'true')">true</EnableBinPlacing>
  </PropertyGroup>

  <Target Name="BinPlace"
          DependsOnTargets="GetBinPlaceConfiguration;BinPlaceFiles;BinPlaceProps"
          AfterTargets="CopyFilesToOutputDirectory"
          Condition="'$(EnableBinPlacing)' == 'true'" />

  <Target Name="BinPlaceFiles"
          Condition="'@(BinPlaceDir)' != ''"
          DependsOnTargets="GetBinPlaceItems"
          Inputs="@(BinPlaceDir);%(BinPlaceDir.ItemName)"
          Outputs="unused" >

    <PropertyGroup>
      <_BinPlaceItemName>%(BinPlaceDir.ItemName)</_BinPlaceItemName>
      <_BinPlaceItemName Condition="'$(_BinPlaceItemName)' == ''">BinPlaceItem</_BinPlaceItemName>
    </PropertyGroup>

    <Message Importance="low" Text="BinPlaceDir: @(BinPlaceDir)" />

    <Copy SourceFiles="@($(_BinPlaceItemName))"
          DestinationFolder="%(BinPlaceDir.Identity)"
          SkipUnchangedFiles="true"
          OverwriteReadOnlyFiles="true"
          Retries="$(CopyRetryCount)"
          RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
          UseHardlinksIfPossible="$(BinPlaceUseHardlinksIfPossible)">
      <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
    </Copy>
  </Target>

  <UsingTask TaskName="SaveItems" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>
  <Target Name="BinPlaceProps"
          Condition="'@(PackageFileDir)' != ''"
          DependsOnTargets="GetBinPlaceItems"
          Inputs="%(PackageFileDir.Identity);%(PackageFileDir.ItemName)"
          Outputs="unused"  >
    <ItemGroup>
      <!-- in the case of an overlapping batch (eg: multiple configurations using same directory)
           use the first -->
      <_packageFileDir Include="@(PackageFileDir->Distinct())" />
    </ItemGroup>

    <PropertyGroup>
      <_propsFilename>$(TargetName).$(TargetGroup)-$(OSGroup)</_propsFilename>
      <_propsFilename Condition="'$(TargetName)' == ''">$(MSBuildProjectName).$(TargetGroup)-$(OSGroup)</_propsFilename>
      <_projectDirLength>$(ProjectDir.Length)</_projectDirLength>
    </PropertyGroup>

    <PropertyGroup>
      <_BinPlaceItemName>%(_packageFileDir.ItemName)</_BinPlaceItemName>
      <_BinPlaceItemName Condition="'$(_BinPlaceItemName)' == ''">BinPlaceItem</_BinPlaceItemName>
    </PropertyGroup>

    <ItemGroup>
      <_itemsToSave Include="@($(_BinPlaceItemName))">
        <!-- intentionally empty: to be set by pkgproj -->
        <TargetPath></TargetPath>
        <TargetFramework>%(_packageFileDir.BuildConfiguration_NuGetTargetMonikerShort)</TargetFramework>
      </_itemsToSave>

      <!-- Include doc files. -->
      <_docFiles Condition="'$(BinPlaceRef)' == 'true'" Include="$(XmlDocDir)/**/$(TargetName).xml" />
      <_docFiles>
        <SubFolder Condition="'%(RecursiveDir)' != ''">/$([System.String]::new('%(RecursiveDir)').TrimEnd('\').TrimEnd('/'))</SubFolder>
      </_docFiles>
      <_docFiles>
        <TargetFramework>%(_packageFileDir.BuildConfiguration_NuGetTargetMonikerShort)</TargetFramework>
      </_docFiles>
      <_itemsToSave Include="@(_docFiles)"/>

      <!-- Include source files. -->
      <!-- Here we use "sources" rather than "src" because MyGet treats packages with "src" as symbol packages  -->
      <_itemsToSave Condition="'@(Compile)' != ''" Include="@(Compile->'%(FullPath)')">
        <TargetPath>sources</TargetPath>
        <TargetPath Condition="$([System.String]::Copy('%(FullPath)').StartsWith('$(ProjectDir)'))">sources/$([System.String]::Copy('%(FullPath)').Substring($(_projectDirLength)).Replace('\', '/'))</TargetPath>
        <IsSourceCodeFile>true</IsSourceCodeFile>
      </_itemsToSave>
    </ItemGroup>

    <Message Importance="low" Text="PackageFileDir: @(PackageFileDir)" />

    <SaveItems ItemName="%(_packageFileDir.SaveItemName)"
               Items="@(_itemsToSave)"
               Files="%(_packageFileDir.Identity)\$(_propsFilename).props">
      <Output TaskParameter="Files" ItemName="FileWrites" />
    </SaveItems>
  </Target>

  <Target Name="GetBinPlaceItems" DependsOnTargets="GetCopyToOutputDirectoryItems">
    <ItemGroup>
      <BinPlaceItem Condition="Exists('$(TargetPath)')" Include="$(TargetPath)" />
      <BinPlaceItem Condition="Exists('$(TargetDir)$(TargetName).pdb')" Include="$(TargetDir)$(TargetName).pdb" />
      <BinPlaceItem Condition="'$(BinPlaceReferenceCopyLocalPaths)' != 'false'" Include="@(ReferenceCopyLocalPaths)" />
      <BinPlaceItem Condition="'$(BinPlaceCopyToOutputDirectoryItems)' != 'false'" Include="@(AllItemsFullPathWithTargetPath)" />
    </ItemGroup>
  </Target>

  <UsingTask TaskName="FindBestConfigurations" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>
  <Target Name="GetBinPlaceConfiguration" DependsOnTargets="GetBuildConfigurations">
    <!-- find which, if any, build configuration of this project is best
         for each binplace configuration -->
    <FindBestConfigurations Properties="@(Property)"
                            PropertyValues="@(PropertyValue)"
                            SupportedConfigurations="$(_AllBuildConfigurations)"
                            Configurations="@(BinPlaceConfiguration)">
      <Output TaskParameter="BestConfigurations" ItemName="_bestBinlaceConfigurations" />
    </FindBestConfigurations>

    <ItemGroup>
      <_currentBinPlaceConfigurations Include="@(_bestBinlaceConfigurations)" Condition="'%(Identity)' == '$(Configuration)' OR '%(Identity)-$(ConfigurationGroup)' == '$(Configuration)'" />

      <BinPlaceDir Condition="'$(BinPlaceTest)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(TestPath)')" />
      <BinPlaceDir Condition="'$(BinPlaceRuntime)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(RuntimePath)')" />
      <BinPlaceDir Condition="'$(BinPlaceRef)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(RefPath)')" />

      <PackageFileDir Condition="'$(BinPlaceRuntime)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(PackageFileRuntimePath)')">
        <SaveItemName Condition="'%(_currentBinPlaceConfigurations.SaveItemName)' == ''">LibFile</SaveItemName>
      </PackageFileDir>
      <PackageFileDir Condition="'$(BinPlaceRef)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(PackageFileRefPath)')">
        <SaveItemName Condition="'%(_currentBinPlaceConfigurations.SaveItemName)' == ''">RefFile</SaveItemName>
      </PackageFileDir>

      <!-- permit BinplaceConfigurations to define SetProperties metadata,
           set those properties when BinplaceConfiguration is active -->
      <_binplacePropertyTuples Include="%(_currentBinPlaceConfigurations.SetProperties)" />

      <_binplaceSetProperty Condition="'%(_binplacePropertyTuples.Identity)' != ''"
                            Include="$([System.String]::new('%(_binplacePropertyTuples.Identity)').Split('=')[0])">
        <Value>$([System.String]::new('%(_binplacePropertyTuples.Identity)').Split('=')[1])</Value>
      </_binplaceSetProperty>
    </ItemGroup>

    <CreateProperty Value="%(_binplaceSetProperty.Value)" Condition="'@(_binplaceSetProperty)' != ''" >
      <Output TaskParameter="Value" PropertyName="%(_binplaceSetProperty.Identity)" />
    </CreateProperty>
  </Target>

  <!-- IncrementalClean and CoreClean only clean paths under Intermediate or OutDir, handle additional paths -->
  <ItemGroup>
    <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(RefPath)')" />
    <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(RuntimePath)')" />
    <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(PackageFileRefPath)')" />
    <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(PackageFileRuntimePath)')" />
    <AdditionalCleanDirectories Include="@(BinPlaceConfiguration->'%(TestPath)')" />
  </ItemGroup>

  <Target Name="_CleanGetCurrentAdditionalFileWrites" BeforeTargets="_CleanGetCurrentAndPriorFileWrites" Condition="'@(AdditionalCleanDirectories)' != ''">
    <!-- find files under paths we care about and add them to _CleanCurrentFileWrites to ensure they are written to the file list -->
    <FindUnderPath Path="%(AdditionalCleanDirectories.Identity)" Files="@(FileWrites)" UpdateToAbsolutePaths="true">
      <Output TaskParameter="InPath" ItemName="_CleanCurrentFileWrites" />
    </FindUnderPath>
  </Target>

  <!-- delete files under our AdditionalCleanDirectories on Incremental clean -->
  <Target Name="IncrementalCleanAdditionalDirectories" BeforeTargets="IncrementalClean" Condition="'@(AdditionalCleanDirectories)' != ''">
    <ItemGroup>
      <_CleanOrphanAdditionalFileWrites Include="@(_CleanPriorFileWrites)" Exclude="@(_CleanCurrentFileWrites)" />
    </ItemGroup>
    <FindUnderPath Path="%(AdditionalCleanDirectories.Identity)" Files="@(_CleanOrphanAdditionalFileWrites)">
      <Output TaskParameter="InPath" ItemName="_CleanOrphanFileWritesInAdditionalDirectories" />
    </FindUnderPath>

    <!-- Delete the orphaned files.  IncrementalClean will remove these from the file list -->
    <Delete Files="@(_CleanOrphanFileWritesInAdditionalDirectories)" TreatErrorsAsWarnings="true">
      <Output TaskParameter="DeletedFiles" ItemName="_CleanOrphanFilesDeleted" />
    </Delete>
  </Target>

  <!-- delete files under our AdditionalCleanDirectories on CoreClean -->
  <Target Name="CleanAdditionalDirectories" AfterTargets="CoreClean" Condition="'@(AdditionalCleanDirectories)' != ''">
    <FindUnderPath Path="%(AdditionalCleanDirectories.Identity)" Files="@(_CleanUniqueRemainingFileWrites)">
      <Output TaskParameter="InPath" ItemName="_CleanUniqueRemainingFileWritesInAdditionalDirectories"/>
    </FindUnderPath>

    <Delete Files="@(_CleanUniqueRemainingFileWritesInAdditionalDirectories)" TreatErrorsAsWarnings="true">
      <Output TaskParameter="DeletedFiles" ItemName="_CleanUniqueRemainingFileWritesInAdditionalDirectoriesDeleted" />
    </Delete>

    <!-- Create a list of everything that wasn't deleted. -->
    <ItemGroup>
      <_CleanRemainingFileWritesAfterCleanAdditionalDirectories Include="@(_CleanUniqueRemainingFileWrites)" Exclude="@(_CleanUniqueRemainingFileWritesInAdditionalDirectoriesDeleted)"/>
    </ItemGroup>

    <!-- Remove duplicates. -->
    <RemoveDuplicates Inputs="@(_CleanRemainingFileWritesAfterCleanAdditionalDirectories)">
      <Output TaskParameter="Filtered" ItemName="_CleanAdditionalDirectoriesUniqueRemainingFileWrites"/>
    </RemoveDuplicates>

    <!-- Make sure the directory exists. -->
    <MakeDir Directories="$(IntermediateOutputPath)"/>

    <!-- Write new list of current files back to disk. -->
    <WriteLinesToFile File="$(IntermediateOutputPath)$(CleanFile)" Lines="@(_CleanAdditionalDirectoriesUniqueRemainingFileWrites)" Overwrite="true" />
  </Target>

</Project>