1 <?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
5 <TargetingPackDirs Include="$(RefPath)" />
6 <AdditionalReferencePaths Include="@(TargetingPackDirs)" />
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>
17 <PropertyGroup Condition=" '$(TargetFrameworkIdentifier)' == ''
18 and '$(TargetFrameworkVersion)' == ''
19 and '$(TargetFrameworkProfile)' == '' ">
20 <TargetingDefaultPlatform>true</TargetingDefaultPlatform>
23 <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == ''">
24 <TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
28 When targeting an explicit platform other than the default,
29 also allow the target framework directory.
31 <PropertyGroup Condition="'$(TargetingDefaultPlatform)' != 'true'">
32 <AssemblySearchPaths>$(AssemblySearchPaths);{TargetFrameworkDirectory}</AssemblySearchPaths>
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>
52 <PropertyGroup Condition="'$(IncludeDefaultReferences)' == ''">
53 <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.csproj'">true</IncludeDefaultReferences>
54 <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.vbproj'">true</IncludeDefaultReferences>
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" />
65 <Target Name="UpdateReferenceItems"
66 DependsOnTargets="SetupDefaultReferences"
67 BeforeTargets="BeforeResolveReferences"
70 <Reference Include="@(DefaultReference)" />
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>
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"
88 <_resolvedMscorlib Condition="'%(ReferencePath.FileName)' == 'mscorlib'">true</_resolvedMscorlib>
92 <PossibleTargetFrameworks Include="$(_TargetFrameworkDirectories)" />
93 <ReferencePath Include="%(PossibleTargetFrameworks.Identity)mscorlib.dll"
94 Condition="'$(_resolvedMscorlib)' != 'true' and '%(PossibleTargetFrameworks.Identity)' != '' and Exists('%(PossibleTargetFrameworks.Identity)mscorlib.dll')" />
99 <!-- Disable WindowsAppContainer property to prevent importing AppX targets which we don't need -->
100 <WindowsAppContainer Condition="'$(WindowsAppContainer)'==''">false</WindowsAppContainer>
103 <Import Project="depProj.targets"
104 Condition="'$(MSBuildProjectExtension)' == '.depproj'" />
106 <Import Project="IL.targets"
107 Condition="'$(MSBuildProjectExtension)' == '.ilproj' AND '$(SkipImportILTargets)'!='true'" />
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
114 <CSharpTargetsFile>$(MSBuildToolsPath)\Microsoft.CSharp.targets</CSharpTargetsFile>
115 <CSharpTargetsFile Condition="!Exists('$(CSharpTargetsFile)')">$(MSBuildToolsPath)\Microsoft.CSharp.Targets</CSharpTargetsFile>
118 <Import Project="$(MSBuildExtensionsPath32)\Microsoft.CSharp.targets"
119 Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj' and '$(RunningOnCore)' == 'true'" />
121 <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets"
122 Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj' and '$(RunningOnCore)' != 'true'" />
125 <Import Project="$(CSharpTargetsFile)"
126 Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable' and '$(MSBuildProjectExtension)' == '.csproj'" />
128 <Import Project="$(MSBuildExtensionsPath32)\Microsoft.VisualBasic.targets"
129 Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj' and '$(RunningOnCore)' == 'true'" />
132 <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.VisualBasic.targets"
133 Condition="'$(TargetFrameworkIdentifier)' == '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj' and '$(RunningOnCore)' != 'true'" />
135 <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets"
136 Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj'" />
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.
144 <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)</_TargetFrameworkDirectories>
145 <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>
149 <ResolveReferencesDependsOn>
150 AddProjectReferencesDynamically;
151 $(ResolveReferencesDependsOn);
152 </ResolveReferencesDependsOn>
154 AddProjectReferencesDynamically;
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.
166 For information on evaulation of targets ordering see https://msdn.microsoft.com/en-us/library/ee216359.aspx.
168 <Target Name="AddProjectReferencesDynamically" DependsOnTargets="$(AddProjectReferencesDynamicallyDependsOn)" />
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>
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.
180 <PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
181 <CoreCompileDependsOn>$(CoreCompileDependsOn);OverrideFrameworkPathForVisualBasic</CoreCompileDependsOn>
184 <Target Name="OverrideFrameworkPathForVisualBasic" AfterTargets="ResolveAssemblyReferences" Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
186 <FrameworkPathOverrideCandidate Include="%(ReferencePath.RootDir)%(ReferencePath.Directory)"
187 Condition="'%(ReferencePath.Filename)%(ReferencePath.Extension)' == 'System.Runtime.dll'">
188 </FrameworkPathOverrideCandidate>
191 <PropertyGroup Condition="'@(FrameworkPathOverrideCandidate->Count())' == '1'">
192 <FrameworkPathOverride>@(FrameworkPathOverrideCandidate)</FrameworkPathOverride>
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.
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.
205 <UsingTask TaskName="WriteVisualBasicDefineResponseFile" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll" />
207 <Target Name="ConvertDefinesToResonseFile" BeforeTargets="CoreCompile" Condition="'$(MSBuildProjectExtension)' == '.vbproj'">
208 <WriteVisualBasicDefineResponseFile DefineConstants="$(FinalDefineConstants)"
209 File="$(IntermediateOutputPath)/defines.rsp" />
211 <CompilerResponseFile>$(IntermediateOutputPath)/defines.rsp;$(CompilerResponseFile)</CompilerResponseFile>
212 <FinalDefineConstants></FinalDefineConstants>
216 <Target Name="ConvertCommonMetadataToAdditionalProperties" BeforeTargets="AssignProjectConfiguration">
217 <!-- list each append as a seperate item to force re-evaluation of AdditionalProperties metadata -->
220 <!-- Configuration property shortcuts -->
222 <AdditionalProperties Condition="'%(ProjectReference.Configuration)' != ''">Configuration=%(ProjectReference.Configuration);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
224 <!-- Packaging property shortcuts -->
226 <AdditionalProperties Condition="'%(ProjectReference.PackageTargetFramework)' != ''">PackageTargetFramework=%(ProjectReference.PackageTargetFramework);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
229 <AdditionalProperties Condition="'%(ProjectReference.PackageTargetPath)' != ''">PackageTargetPath=%(ProjectReference.PackageTargetPath);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
232 <AdditionalProperties Condition="'%(ProjectReference.PackageTargetRuntime)' != ''">PackageTargetRuntime=%(ProjectReference.PackageTargetRuntime);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
235 <AdditionalProperties Condition="'%(ProjectReference.Platform)' != ''">Platform=%(ProjectReference.Platform);%(ProjectReference.AdditionalProperties)</AdditionalProperties>
240 <!-- Binplacing targets and properties -->
242 <BinPlaceUseHardlinksIfPossible Condition="'$(BinPlaceUseHardlinksIfPossible)' == ''">true</BinPlaceUseHardlinksIfPossible>
243 <EnableBinPlacing Condition="'$(EnableBinPlacing)' == '' AND ('$(BinPlaceRef)' == 'true' OR '$(BinPlaceRuntime)' == 'true' OR '$(BinPlaceTest)' == 'true')">true</EnableBinPlacing>
246 <Target Name="BinPlace"
247 DependsOnTargets="GetBinPlaceConfiguration;BinPlaceFiles;BinPlaceProps"
248 AfterTargets="CopyFilesToOutputDirectory"
249 Condition="'$(EnableBinPlacing)' == 'true'" />
251 <Target Name="BinPlaceFiles"
252 Condition="'@(BinPlaceDir)' != ''"
253 DependsOnTargets="GetBinPlaceItems"
254 Inputs="@(BinPlaceDir);%(BinPlaceDir.ItemName)"
258 <_BinPlaceItemName>%(BinPlaceDir.ItemName)</_BinPlaceItemName>
259 <_BinPlaceItemName Condition="'$(_BinPlaceItemName)' == ''">BinPlaceItem</_BinPlaceItemName>
262 <Message Importance="low" Text="BinPlaceDir: @(BinPlaceDir)" />
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" />
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)"
282 <!-- in the case of an overlapping batch (eg: multiple configurations using same directory)
284 <_packageFileDir Include="@(PackageFileDir->Distinct())" />
288 <_propsFilename>$(TargetName).$(TargetGroup)-$(OSGroup)</_propsFilename>
289 <_propsFilename Condition="'$(TargetName)' == ''">$(MSBuildProjectName).$(TargetGroup)-$(OSGroup)</_propsFilename>
290 <_projectDirLength>$(ProjectDir.Length)</_projectDirLength>
294 <_BinPlaceItemName>%(_packageFileDir.ItemName)</_BinPlaceItemName>
295 <_BinPlaceItemName Condition="'$(_BinPlaceItemName)' == ''">BinPlaceItem</_BinPlaceItemName>
299 <_itemsToSave Include="@($(_BinPlaceItemName))">
300 <!-- intentionally empty: to be set by pkgproj -->
301 <TargetPath></TargetPath>
302 <TargetFramework>%(_packageFileDir.BuildConfiguration_NuGetTargetMonikerShort)</TargetFramework>
305 <!-- Include doc files. -->
306 <_docFiles Condition="'$(BinPlaceRef)' == 'true'" Include="$(XmlDocDir)/**/$(TargetName).xml" />
308 <SubFolder Condition="'%(RecursiveDir)' != ''">/$([System.String]::new('%(RecursiveDir)').TrimEnd('\').TrimEnd('/'))</SubFolder>
311 <TargetFramework>%(_packageFileDir.BuildConfiguration_NuGetTargetMonikerShort)</TargetFramework>
313 <_itemsToSave Include="@(_docFiles)"/>
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>
324 <Message Importance="low" Text="PackageFileDir: @(PackageFileDir)" />
326 <SaveItems ItemName="%(_packageFileDir.SaveItemName)"
327 Items="@(_itemsToSave)"
328 Files="%(_packageFileDir.Identity)\$(_propsFilename).props">
329 <Output TaskParameter="Files" ItemName="FileWrites" />
333 <Target Name="GetBinPlaceItems" DependsOnTargets="GetCopyToOutputDirectoryItems">
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)" />
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>
354 <_currentBinPlaceConfigurations Include="@(_bestBinlaceConfigurations)" Condition="'%(Identity)' == '$(Configuration)' OR '%(Identity)-$(ConfigurationGroup)' == '$(Configuration)'" />
356 <BinPlaceDir Condition="'$(BinPlaceTest)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(TestPath)')" />
357 <BinPlaceDir Condition="'$(BinPlaceRuntime)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(RuntimePath)')" />
358 <BinPlaceDir Condition="'$(BinPlaceRef)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(RefPath)')" />
360 <PackageFileDir Condition="'$(BinPlaceRuntime)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(PackageFileRuntimePath)')">
361 <SaveItemName Condition="'%(_currentBinPlaceConfigurations.SaveItemName)' == ''">LibFile</SaveItemName>
363 <PackageFileDir Condition="'$(BinPlaceRef)' == 'true'" Include="@(_currentBinPlaceConfigurations->'%(PackageFileRefPath)')">
364 <SaveItemName Condition="'%(_currentBinPlaceConfigurations.SaveItemName)' == ''">RefFile</SaveItemName>
367 <!-- permit BinplaceConfigurations to define SetProperties metadata,
368 set those properties when BinplaceConfiguration is active -->
369 <_binplacePropertyTuples Include="%(_currentBinPlaceConfigurations.SetProperties)" />
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>
377 <CreateProperty Value="%(_binplaceSetProperty.Value)" Condition="'@(_binplaceSetProperty)' != ''" >
378 <Output TaskParameter="Value" PropertyName="%(_binplaceSetProperty.Identity)" />
382 <!-- IncrementalClean and CoreClean only clean paths under Intermediate or OutDir, handle additional paths -->
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)')" />
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" />
398 <!-- delete files under our AdditionalCleanDirectories on Incremental clean -->
399 <Target Name="IncrementalCleanAdditionalDirectories" BeforeTargets="IncrementalClean" Condition="'@(AdditionalCleanDirectories)' != ''">
401 <_CleanOrphanAdditionalFileWrites Include="@(_CleanPriorFileWrites)" Exclude="@(_CleanCurrentFileWrites)" />
403 <FindUnderPath Path="%(AdditionalCleanDirectories.Identity)" Files="@(_CleanOrphanAdditionalFileWrites)">
404 <Output TaskParameter="InPath" ItemName="_CleanOrphanFileWritesInAdditionalDirectories" />
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" />
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"/>
419 <Delete Files="@(_CleanUniqueRemainingFileWritesInAdditionalDirectories)" TreatErrorsAsWarnings="true">
420 <Output TaskParameter="DeletedFiles" ItemName="_CleanUniqueRemainingFileWritesInAdditionalDirectoriesDeleted" />
423 <!-- Create a list of everything that wasn't deleted. -->
425 <_CleanRemainingFileWritesAfterCleanAdditionalDirectories Include="@(_CleanUniqueRemainingFileWrites)" Exclude="@(_CleanUniqueRemainingFileWritesInAdditionalDirectoriesDeleted)"/>
428 <!-- Remove duplicates. -->
429 <RemoveDuplicates Inputs="@(_CleanRemainingFileWritesAfterCleanAdditionalDirectories)">
430 <Output TaskParameter="Filtered" ItemName="_CleanAdditionalDirectoriesUniqueRemainingFileWrites"/>
433 <!-- Make sure the directory exists. -->
434 <MakeDir Directories="$(IntermediateOutputPath)"/>
436 <!-- Write new list of current files back to disk. -->
437 <WriteLinesToFile File="$(IntermediateOutputPath)$(CleanFile)" Lines="@(_CleanAdditionalDirectoriesUniqueRemainingFileWrites)" Overwrite="true" />