Skip to content

Commit

Permalink
Fix WACK certification error for transitive WinUI references (#4218)
Browse files Browse the repository at this point in the history
WACK expects to be able to find WinMDs for type resolution purposes in the root of the AppX, but when WinUI 2 is referenced via framework package, the WinMD is instead placed in a WinMetadata subdirectory. As a result, applications that reference nuget packages with references to WinUI 2, WACK certification fails. I'm not sure whether placing the WinMD file in that directory is still needed, so to work around this issue in the safest manner, this adds an additional build target that places the WinMD where WACK certification needs it to be.

An example of an issue that will be resolved by this fix: CommunityToolkit/Lottie-Windows#214
  • Loading branch information
llongley authored Mar 15, 2021
1 parent 66661ba commit a4c3714
Show file tree
Hide file tree
Showing 23 changed files with 483 additions and 37 deletions.
5 changes: 5 additions & 0 deletions build/AzurePipelinesTemplates/MUX-NugetReleaseTest-Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ jobs:
.\test\MUXControlsReleaseTest\updateUsedNugetPackageVersion.ps1 $newVersion
displayName: Update proj files to use candidate nupkg.
- template: MUX-BuildProject-Steps.yml
parameters:
solutionPath: test\MUXControlsReleaseTest\RuntimeComponentThatUsesMUX\RuntimeComponentThatUsesMUX.sln
artifactName: ${{ parameters.buildArtifactName }}

- template: MUX-BuildProject-Steps.yml
parameters:
solutionPath: $(solutionPath)
Expand Down
5 changes: 5 additions & 0 deletions build/AzurePipelinesTemplates/MUX-WACKTests-Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ jobs:
- task: PkgESWACKTests@10
inputs:
AppxFolder: '$(artifactDownloadPath)\${{parameters.artifactName}}\$(BuildConfiguration)\$(BuildPlatform)\NugetPackageTestApp\AppPackages\NugetPackageTestApp_Test'
WACKFailbuild: true

- task: PkgESWACKTests@10
inputs:
AppxFolder: '$(artifactDownloadPath)\${{parameters.artifactName}}\$(BuildConfiguration)\$(BuildPlatform)\AppThatUsesMUXIndirectly\AppPackages\AppThatUsesMUXIndirectly_Test'
WACKFailbuild: true
43 changes: 43 additions & 0 deletions build/NuSpecs/MUXControls-Nuget-Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,47 @@
Text="Microsoft.UI.Xaml nuget package requires TargetPlatformVersion >= 10.0.18362.0 (current project is $(MicrosoftUIXamlTargetPlatformCheckValue))"
Condition="$(MicrosoftUIXamlTargetPlatformCheckValue) < 18362" />
</Target>
<!-- WACK certification requires that types referenced by dependent packages exist in WinMD files in the root of the AppX.
However, the BuildNativePackage target requires that it *not* be in that location, or else that target will return an error.
In order to enable apps to pass WACK certification that reference packages that reference us, we'll add it to the package payload
after that target has completed. -->
<ItemGroup>
<XamlWinmd Include="$(MSBuildThisFileDirectory)..\lib\uap10.0\Microsoft.UI.Xaml.winmd">
<SkipHarvestingWinmdRegistration Condition="'$(MicrosoftUIXamlAppxVersion)' != ''">true</SkipHarvestingWinmdRegistration>
<TargetPath>$(WinMetadataDir)\Microsoft.UI.Xaml.winmd</TargetPath>
<OutputGroup>CustomOutputGroupForPackaging</OutputGroup>
<ProjectName>$(ProjectName)</ProjectName>
<Implementation Condition="'$(MicrosoftUIXamlAppxVersion)' == ''">Microsoft.UI.Xaml.dll</Implementation>
</XamlWinmd>
</ItemGroup>
<PropertyGroup>
<XamlWinmdName>Microsoft.UI.Xaml.winmd</XamlWinmdName>
<XamlCompactXbfName>Microsoft.UI.Xaml\DensityStyles\Compact.xbf</XamlCompactXbfName>
</PropertyGroup>
<Target Name="_FixWinmdCopyLocal" AfterTargets="ResolveNuGetPackageAssets">
<ItemGroup>
<XamlWinMdCopyLocal Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)' == '$(XamlWinmdName)'" />
</ItemGroup>
<ItemGroup Condition="'@(XamlWinMdCopyLocal)' != ''">
<ReferenceCopyLocalPaths Remove="@(XamlWinMdCopyLocal)" />
</ItemGroup>
</Target>
<Target Name="_FixWinmdPackaging" BeforeTargets="_ComputeAppxPackagePayload">
<ItemGroup>
<XamlWinmdPackagingOutput Include="@(PackagingOutputs)" Condition="'%(PackagingOutputs.Filename)%(PackagingOutputs.Extension)' == '$(XamlWinmdName)'" />
</ItemGroup>
<ItemGroup Condition="'@(XamlWinmdPackagingOutput)' != ''">
<PackagingOutputs Remove="@(XamlWinmdPackagingOutput)" />
</ItemGroup>
<ItemGroup>
<PackagingOutputs Include="@(XamlWinmd)" />
</ItemGroup>
</Target>
<Target Name="_AddXamlWinmdToPackageLayoutRoot" AfterTargets="BuildNativePackage">

This comment has been minimized.

Copy link
@eugenegff

eugenegff Nov 9, 2021

Contributor

@llongley We have WACK validation errors for only ARM64 arch of the C++/CX app using WinUI 2.7, that does not use .Net framework at all.

The reason is due _AddXamlWinmdToPackageLayoutRoot task being skipped for ARM64 as default .NET native toolchain from C:\Program Files (x86)\MSBuild\15.0.Net.NetNative\15.0.24211\ does not support ARM64 and BuildNativePackage task is not found for ARM64.

<ItemGroup>
<AppxPackagePayload Include="@(XamlWinmd)">
<TargetPath>Microsoft.UI.Xaml.winmd</TargetPath>
</AppxPackagePayload>
</ItemGroup>
</Target>
</Project>
33 changes: 0 additions & 33 deletions build/NuSpecs/MUXControls-Nuget-FrameworkPackage.props
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,4 @@
<ItemGroup Condition="('$(OutputType)' == 'AppContainerExe')">
<SDKReference Include="Microsoft.VCLibs, Version=14.0" />
</ItemGroup>
<!-- This section is to work around the fact that this Nuget package contains only a .winmd and no implementation, but the
VS targets expect that, so convince them it's ok. -->
<ItemGroup>
<XamlWinmd Include="$(MSBuildThisFileDirectory)..\lib\uap10.0\Microsoft.UI.Xaml.winmd">
<SkipHarvestingWinmdRegistration>true</SkipHarvestingWinmdRegistration>
<TargetPath>$(WinMetadataDir)\Microsoft.UI.Xaml.winmd</TargetPath>
<OutputGroup>CustomOutputGroupForPackaging</OutputGroup>
<ProjectName>$(ProjectName)</ProjectName>
</XamlWinmd>
</ItemGroup>
<PropertyGroup>
<XamlWinmdName>Microsoft.UI.Xaml.winmd</XamlWinmdName>
<XamlCompactXbfName>Microsoft.UI.Xaml\DensityStyles\Compact.xbf</XamlCompactXbfName>
</PropertyGroup>
<Target Name="_FixWinmdCopyLocal" AfterTargets="ResolveNuGetPackageAssets">
<ItemGroup>
<XamlWinMdCopyLocal Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)' == '$(XamlWinmdName)'" />
</ItemGroup>
<ItemGroup Condition="'@(XamlWinMdCopyLocal)' != ''">
<ReferenceCopyLocalPaths Remove="@(XamlWinMdCopyLocal)" />
</ItemGroup>
</Target>
<Target Name="_FixWinmdPackaging" BeforeTargets="_ComputeAppxPackagePayload">
<ItemGroup>
<XamlWinmdPackagingOutput Include="@(PackagingOutputs)" Condition="'%(PackagingOutputs.Filename)%(PackagingOutputs.Extension)' == '$(XamlWinmdName)'" />
</ItemGroup>
<ItemGroup Condition="'@(XamlWinmdPackagingOutput)' != ''">
<PackagingOutputs Remove="@(XamlWinmdPackagingOutput)" />
</ItemGroup>
<ItemGroup>
<PackagingOutputs Include="@(XamlWinmd)" />
</ItemGroup>
</Target>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@
<PackageReference Include="MUXCustomBuildTasks">
<Version>1.0.67</Version>
</PackageReference>
<PackageReference Include="RuntimeComponentThatUsesMUX">
<Version>1.0.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LibraryThatUsesMUX\LibraryThatUsesMUX.csproj">
Expand All @@ -158,7 +161,7 @@
</Target>
-->
<Import Project="$(MSBuildProjectDirectory)\..\..\..\CustomInlineTasks.targets" />
<Target Name="AfterBuild">
<Target Name="AfterBuild" Condition="'$(SolutionDir)' != '*Undefined*'">
<RunPowershellScript Path="$(SolutionDir)\tools\ExtractPackageDependencies_ReleaseTest.ps1" Parameters="-sourceFile $(OutDir)\$(AppxPackageName).build.appxrecipe -platform $(PlatformName) -outputFile $(AppxPackageTestDir)\$(AppxPackageName).dependencies.txt" FilesWritten="$(AppxPackageTestDir)\$(AppxPackageName).dependencies.txt" />
</Target>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<StackPanel x:Name="layoutRoot">

</StackPanel>
</Page>
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ namespace AppThatUsesMUXIndirectly
{
public sealed partial class MainPage : Page
{
// This app does NOT directly consume MUX, but it references another library that does use MUX.
// This app does NOT directly consume MUX, but it references a library and a nupkg that use MUX.
public MainPage()
{

this.InitializeComponent();

var userControl = new LibraryThatUsesMUX.TestUserControl1();
layoutRoot.Children.Add(userControl);

var muxcInterfaceImplementation = new RuntimeComponentThatUsesMUX.MUXCInterfaceImplementation();
object dummy;
muxcInterfaceImplementation.TryCreateAnimatedVisual(null, out dummy);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "pch.h"
#include "MUXCInterfaceImplementation.h"
#if __has_include("MUXCInterfaceImplementation.g.cpp")
#include "MUXCInterfaceImplementation.g.cpp"
#endif

using namespace winrt;
using namespace Windows::UI::Xaml;

namespace winrt::RuntimeComponentThatUsesMUX::implementation
{
MUXCInterfaceImplementation::MUXCInterfaceImplementation()
{
}

winrt::Microsoft::UI::Xaml::Controls::IAnimatedVisual MUXCInterfaceImplementation::TryCreateAnimatedVisual(
winrt::Windows::UI::Composition::Compositor const&,
winrt::Windows::Foundation::IInspectable&)
{
return nullptr;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "winrt/Windows.UI.Xaml.h"
#include "winrt/Windows.UI.Xaml.Markup.h"
#include "winrt/Windows.UI.Xaml.Controls.Primitives.h"
#include "winrt/Microsoft.UI.Xaml.Controls.h"
#include "MUXCInterfaceImplementation.g.h"

namespace winrt::RuntimeComponentThatUsesMUX::implementation
{
struct MUXCInterfaceImplementation : MUXCInterfaceImplementationT<MUXCInterfaceImplementation>
{
MUXCInterfaceImplementation();

winrt::Microsoft::UI::Xaml::Controls::IAnimatedVisual TryCreateAnimatedVisual(
winrt::Windows::UI::Composition::Compositor const& compositor,
winrt::Windows::Foundation::IInspectable& diagnostics);
};
}

namespace winrt::RuntimeComponentThatUsesMUX::factory_implementation
{
struct MUXCInterfaceImplementation : MUXCInterfaceImplementationT<MUXCInterfaceImplementation, implementation::MUXCInterfaceImplementation>
{
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace RuntimeComponentThatUsesMUX
{
[default_interface]
runtimeclass MUXCInterfaceImplementation : Microsoft.UI.Xaml.Controls.IAnimatedVisualSource
{
MUXCInterfaceImplementation();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<!--
To customize common C++/WinRT project properties:
* right-click the project node
* expand the Common Properties item
* select the C++/WinRT property page
For more advanced scenarios, and complete documentation, please see:
https://github.com/Microsoft/xlang/tree/master/src/package/cppwinrt/nuget
-->
<PropertyGroup />
<ItemDefinitionGroup />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
EXPORTS
DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!--
Copyright (c) Microsoft Corporation. Licensed under the MIT License
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_WinmdDir>$(MSBuildThisFileDirectory)..\..\lib\uap10.0\</_WinmdDir>
</PropertyGroup>
<ItemGroup>
<Reference Include="$(_WinmdDir)*.winmd">
<Private>false</Private>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)../RuntimeComponentThatUsesMUX.targets"/>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>RuntimeComponentThatUsesMUX</id>
<version>1.0.0</version>
<title>RuntimeComponentThatUsesMUX</title>
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<description>This package tests the functionality of having a NuGet package reference Microsoft.UI.Xaml.</description>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
<group targetFramework="UAP10.0.15063">
<dependency id="Microsoft.NETCore.UniversalWindowsPlatform" version="6.2.8" exclude="Build,Analyzers" />
<dependency id="Microsoft.UI.Xaml" version="2.5.0" exclude="Build,Analyzers" />
</group>
</dependencies>
</metadata>
<files>
<file target="build" src="RuntimeComponentThatUsesMUX.targets"/>
<file target="build\native\RuntimeComponentThatUsesMUX.targets" src="RuntimeComponentThatUsesMUX.native.targets"/>

<file target="lib\uap10.0" src="$BUILDOUTPUT$\$BUILDFLAVOR$\$BUILDARCH$\RuntimeComponentThatUsesMUX\RuntimeComponentThatUsesMUX.winmd"/>

<file target="runtimes\win10-$BUILDARCH$\native" src="$BUILDOUTPUT$\$BUILDFLAVOR$\$BUILDARCH$\RuntimeComponentThatUsesMUX\RuntimeComponentThatUsesMUX.dll"/>
<file target="runtimes\win10-$BUILDARCH$\native" src="$BUILDOUTPUT$\$BUILDFLAVOR$\$BUILDARCH$\RuntimeComponentThatUsesMUX\RuntimeComponentThatUsesMUX.pri"/>
</files>
</package>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30803.129
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RuntimeComponentThatUsesMUX", "RuntimeComponentThatUsesMUX.vcxproj", "{267D7B40-556E-447B-A262-B59B300CC8F6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|arm = Debug|arm
Debug|arm64 = Debug|arm64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|arm = Release|arm
Release|arm64 = Release|arm64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|arm.ActiveCfg = Debug|arm
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|arm.Build.0 = Debug|arm
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|arm64.ActiveCfg = Debug|arm64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|arm64.Build.0 = Debug|arm64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|x64.ActiveCfg = Debug|x64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|x64.Build.0 = Debug|x64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|x86.ActiveCfg = Debug|Win32
{267D7B40-556E-447B-A262-B59B300CC8F6}.Debug|x86.Build.0 = Debug|Win32
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|arm.ActiveCfg = Release|arm
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|arm.Build.0 = Release|arm
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|arm64.ActiveCfg = Release|arm64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|arm64.Build.0 = Release|arm64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|x64.ActiveCfg = Release|x64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|x64.Build.0 = Release|x64
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|x86.ActiveCfg = Release|Win32
{267D7B40-556E-447B-A262-B59B300CC8F6}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E4731583-0CEA-4289-A2E3-75D1563D9671}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!--
Copyright (c) Microsoft Corporation. Licensed under the MIT License
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_RuntimeIdentifier Condition="'$(Platform)' == 'Win32'">win10-x86</_RuntimeIdentifier>
<_RuntimeIdentifier Condition="'$(Platform)' != 'Win32'">win10-$(Platform)</_RuntimeIdentifier>
<_DllDir>$(MSBuildThisFileDirectory)..\runtimes\$(_WinUIRuntimeIdentifier)\native\</_DllDir>
</PropertyGroup>

<ItemGroup>
<ReferenceCopyLocalPaths Include="$(_DllDir)*.dll" />
<ReferenceCopyLocalPaths Include="$(_DllDir)*.pri" />
</ItemGroup>
</Project>

Loading

0 comments on commit a4c3714

Please sign in to comment.