Add WindowsDesktop closure validation
authorDavis Goodin <dagood@microsoft.com>
Mon, 6 May 2019 17:29:55 +0000 (12:29 -0500)
committerDavis Goodin <dagood@microsoft.com>
Fri, 10 May 2019 20:01:09 +0000 (15:01 -0500)
Commit migrated from https://github.com/dotnet/core-setup/commit/8f5e1164182d5cac7c7430723509871bf36e9fa0

src/installer/pkg/packaging-tools/framework.dependency.targets
src/installer/pkg/packaging-tools/framework.packaging.targets
src/installer/pkg/packaging-tools/skip.GetPackageReport.targets [new file with mode: 0644]
src/installer/pkg/projects/dir.targets
src/installer/pkg/projects/windowsdesktop/pkg/Microsoft.WindowsDesktop.App.pkgproj

index d1bfff6..b8b03c7 100644 (file)
           BeforeTargets="GetFilesToPackage"
           DependsOnTargets="PrepareForCrossGen;GetCrossGenSymbolsFiles" />
 
+  <Target Name="GetReferenceFilenames"
+          Returns="@(Reference -> '%(Filename)')"
+          DependsOnTargets="ResolveNuGetPackages" />
+
   <!-- Target overrides (can't be shared with pkgproj) -->
 
   <Target Name="Build" DependsOnTargets="GenerateHashVersionsFile;GetFilesToPackage" />
index a7fe44b..9188524 100644 (file)
     </PropertyGroup>
   </Target>
 
+  <!-- Closure verification targets for WindowsDesktop. -->
+  <PropertyGroup>
+    <!-- Avoid MSBuild quirk: AfterTargets failure doesn't cause the build to fail. -->
+    <BuildDependsOn>$(BuildDependsOn);VerifyClosure;VerifyDuplicateTypes</BuildDependsOn>
+  </PropertyGroup>
+
+  <Target Name="GetClosureFiles">
+    <!-- Set up ClosureFile items organized by file-set. -->
+    <ItemGroup>
+      <ExistingLibraryFile
+        Include="@(File)"
+        Condition="
+          Exists('%(FullPath)') AND
+          (
+            '%(Extension)' == '.dll' OR
+            '%(Extension)' == '$(LibraryFileExtension)'
+          )"/>
+
+      <ClosureFile
+        Include="@(ExistingLibraryFile)"
+        Condition="'%(ExistingLibraryFile.TargetPath)' == 'ref/$(TargetFramework)'"
+        FileSet="reference" />
+
+      <ClosureFile
+        Include="@(ExistingLibraryFile)"
+        Condition="
+          '%(ExistingLibraryFile.TargetPath)' == 'runtimes/$(PackageTargetRuntime)/lib/$(TargetFramework)' OR
+          '%(ExistingLibraryFile.TargetPath)' == 'runtimes/$(PackageTargetRuntime)/native'"
+        FileSet="runtime" />
+
+      <!-- Remove resource files. -->
+      <ClosureFile
+        Remove="@(ClosureFile)"
+        Condition="'%(ClosureFile.DestinationSubDirectory)' != ''" />
+    </ItemGroup>
+  </Target>
+
+  <Target Name="VerifyClosure"
+          DependsOnTargets="GetClosureFiles"
+          Condition="'$(SkipValidatePackage)' != 'true'"
+          Inputs="%(ClosureFile.FileSet)"
+          Outputs="batching-on-FileSet-metadata">
+    <ItemGroup>
+      <_closureFileNames Include="@(ClosureFile->'%(FileName)')" Original="%(Identity)" />
+
+      <_closureFileNamesFiltered Include="@(_closureFileNames)" Exclude="@(ExcludeFromClosure)"/>
+      <_closureFileFiltered Include="@(_closureFileNamesFiltered->'%(Original)')"/>
+    </ItemGroup>
+
+    <Message Importance="High" Text="Verifying closure of $(Id) %(ClosureFile.FileSet) assemblies" />
+    <VerifyClosure
+      Sources="@(_closureFileFiltered)"
+      IgnoredReferences="@(IgnoredReference)"
+      DependencyGraphFilePath="$(PackageReportDir)$(Id)$(NuspecSuffix)-%(ClosureFile.FileSet).dgml" />
+  </Target>
+
+  <Target Name="VerifyDuplicateTypes"
+          DependsOnTargets="GetClosureFiles"
+          Condition="'$(SkipValidatePackage)' != 'true'"
+          Inputs="%(ClosureFile.FileSet)"
+          Outputs="batching-on-FileSet-metadata">
+    <PropertyGroup>
+      <_fileSet>%(ClosureFile.FileSet)</_fileSet>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <_dupTypeFileName Include="@(ClosureFile->'%(FileName)')" Original="%(Identity)" />
+      <_dupTypeFileName
+        Include="@(FrameworkClosureFile->'%(FileName)')"
+        Exclude="@(_dupTypeFileName)"
+        Condition="'$(_fileSet)' == '%(FrameworkClosureFile.FileSet)'"
+        Original="%(Identity)" />
+
+      <_dupTypeFileNamesFiltered Include="@(_dupTypeFileName)" Exclude="@(ExcludeFromDuplicateTypes)"/>
+      <_dupTypeFileFiltered Include="@(_dupTypeFileNamesFiltered->'%(Original)')"/>
+    </ItemGroup>
+
+    <Message Importance="High" Text="Verifying no duplicate types in $(Id) %(ClosureFile.FileSet) assemblies" />
+    <VerifyTypes
+      Sources="@(_dupTypeFileFiltered)"
+      IgnoredTypes="@(IgnoredDuplicateType)" />
+  </Target>
+
   <!-- Target overrides (can't be shared with other package projects) -->
 
-  <Target Name="GetPackageReport" />
+  <Import
+    Project="$(MSBuildThisFileDirectory)skip.GetPackageReport.targets"
+    Condition="'$(SkipValidatePackage)' == 'true'"/>
 
 </Project>
diff --git a/src/installer/pkg/packaging-tools/skip.GetPackageReport.targets b/src/installer/pkg/packaging-tools/skip.GetPackageReport.targets
new file mode 100644 (file)
index 0000000..aa20228
--- /dev/null
@@ -0,0 +1,5 @@
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <Target Name="GetPackageReport" />
+
+</Project>
index fc9583c..aad832a 100644 (file)
       <NonWindowsSymbolFile Include="@(NonWindowsNativeFile -> '%(Identity)$(SymbolFileExtension)')" />
       <ExistingNonWindowsSymbolFile Include="@(NonWindowsSymbolFile)" Condition="Exists('%(Identity)')" />
 
-      <File Include="@(ExistingWindowsSymbolFile);@(ExistingNonWindowsSymbolFile)">
-        <IsSymbolFile>true</IsSymbolFile>
-      </File>
+      <!--
+        These files might be directly redisted, and already in File. Duplicates cause validation
+        errors, so don't add files that are already known.
+      -->
+      <DiscoveredSymbolFile
+        Include="@(ExistingWindowsSymbolFile);@(ExistingNonWindowsSymbolFile)"
+        IsSymbolFile="true" />
+      
+      <NormalizedFile Include="$([MSBuild]::NormalizePath('%(File.Identity)'))" />
+
+      <File Include="@(DiscoveredSymbolFile)" Exclude="@(NormalizedFile)" />
     </ItemGroup>
 
     <PropertyGroup>
index 96838e4..b62df59 100644 (file)
       available. This lets us skip them on the non-Windows official build legs.
     -->
     <BuildOnUnknownPlatforms>false</BuildOnUnknownPlatforms>
+
+    <TargetFrameworkName>netcoreapp</TargetFrameworkName>
+    <TargetFrameworkVersion>3.0</TargetFrameworkVersion>
+    <TargetFramework>$(TargetFrameworkName)$(TargetFrameworkVersion)</TargetFramework>
+
+    <!--
+      Turn on package validation to validate the dependency closure. Important because the
+      WPF/WinForms packages don't declare their transitive dependencies and the depproj has to fill
+      it in correctly. Being wrong means dependency failures at runtime.
+    -->
+    <SkipValidatePackage>false</SkipValidatePackage>
   </PropertyGroup>
 
-  <!-- Identity / Reference package content -->
-  <ItemGroup Condition="'$(PackageTargetRuntime)' == ''">
-    <!-- reference RID specific packages to generate lineup -->
-    <ProjectReference Include="@(RuntimeProject)" />
+  <ItemGroup>
+    <ExcludeFromDuplicateTypes Include="PresentationFramework.Aero" />
+    <ExcludeFromDuplicateTypes Include="PresentationFramework.Aero2" />
+    <ExcludeFromDuplicateTypes Include="PresentationFramework.AeroLite" />
+    <ExcludeFromDuplicateTypes Include="PresentationFramework.Classic" />
+    <ExcludeFromDuplicateTypes Include="PresentationFramework.Luna" />
+    <ExcludeFromDuplicateTypes Include="PresentationFramework.Royale" />
   </ItemGroup>
+  
+  <ItemGroup>
+    <!-- There is a known cycle. More info at https://github.com/dotnet/wpf/issues/607 -->
+    <IgnoredReference Include="PresentationFramework" />
+    <IgnoredReference Include="ReachFramework" />
+    <IgnoredReference Include="System.Printing" />
+
+    <!-- We don't have a ref assembly for DirectWriteForwarder -->
+    <IgnoredReference Condition="'$(PackageTargetRuntime)' == ''" Include="DirectWriteForwarder" />
+  </ItemGroup>
+
+  <Target Name="GetNETCoreAppIgnoredReference" BeforeTargets="VerifyClosure">
+    <MSBuild
+      Projects="../../netcoreapp/src/netcoreapp.depproj"
+      Properties="Configuration=netcoreapp"
+      Targets="GetReferenceFilenames">
+      <Output TaskParameter="TargetOutputs"  ItemName="IgnoredReference" />
+    </MSBuild>
+  </Target>
 
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+
+  <!-- Don't validate this package as it doesn't actually represent a framework. -->
+  <Target Name="ValidateFrameworkPackage" />
+
 </Project>