Skip to content

Commit

Permalink
Merge pull request #11370 from unoplatform/dev/jela/winappsdk-mix
Browse files Browse the repository at this point in the history
fix: Show an error message when incompatible winappsdk to net7.0 with uno is found
  • Loading branch information
jeromelaban authored Feb 22, 2023
2 parents 203e427 + af70bc1 commit c940696
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 0 deletions.
1 change: 1 addition & 0 deletions build/Uno.UI.Build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@

<ItemGroup>
<_Sha1Replace Include="..\src\SourceGenerators\Uno.UI.Tasks\**\*.cs" />
<_Sha1Replace Include="..\build\uno.winui.winappsdk.targets" />
<_Sha1Replace Include="..\src\SourceGenerators\Uno.UI.Tasks\Uno.UI.Tasks.csproj" />
<_Sha1Replace Include="..\src\SourceGenerators\Uno.UI.Tasks\Content\Uno.UI.Tasks*.*" />
</ItemGroup>
Expand Down
10 changes: 10 additions & 0 deletions build/uno.winui.common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@
Condition="'$(PkgUno_UI)'!='' and '$(PkgUno_WinUI)'!=''" />
</Target>

<!--
Include a marker for _FindInvalidWinAppSDKUnoPlatformReference to determine if a net7.0-only project is referenced
from a WinAppSDK project.
-->
<Target Name="_UnoUpdateAdditionalProperties" BeforeTargets="GetTargetFrameworksWithPlatformForSingleTargetFramework">
<ItemGroup>
<AdditionalTargetFrameworkInfoProperty Include="_IsUnoPlatform" />
</ItemGroup>
</Target>

<Import Project="$(SourceGeneratorBasePath)Uno.UI.SourceGenerators.props" />
<Import Project="$(UnoUIMSBuildTasksTargetPath)Uno.UI.Tasks.targets" />

Expand Down
20 changes: 20 additions & 0 deletions build/uno.winui.winappsdk.targets
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<UnoUIMSBuildTasksPath Condition="'$(UnoUIMSBuildTasksPath)'==''">Uno.UI.Tasks</UnoUIMSBuildTasksPath>
</PropertyGroup>

<UsingTask AssemblyFile="$(UnoUIMSBuildTasksPath)\Uno.UI.Tasks.v0.dll" TaskName="Uno.UI.Tasks.WinAppSDKValidations.ValidateWinAppSDKReferences_v0" />

<PropertyGroup>
<_UnoRemoveReferences_BeforeTargets>
Expand Down Expand Up @@ -64,4 +70,18 @@

</Target>

<Target Name="_FindInvalidWinAppSDKUnoPlatformReference"
BeforeTargets="ResolveAssemblyReferences"
Condition="'$(UnoDisableUNOB0002Validation)'!='true'">

<!--
Determine if any ProjectReference contains AdditionalProperties which contains _IsUnoPlatform, a property
defined only when WinAppSDK is not included.
This scenario can happen when a WinAppSDK project is referencing a net7.0-only project which contains a reference to
Uno.WinUI, which is not compatible with WinAppSDK. Fixing this requires adding a netX.0-windows10.x target to the project.
-->
<ValidateWinAppSDKReferences_v0 ReferencedProjects="@(TargetPathWithTargetPlatformMoniker)" />
</Target>

</Project>
3 changes: 3 additions & 0 deletions doc/articles/get-started-dotnet-new.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
---
uid: GetStarted.dotnet-new
---
# dotnet new templates for Uno Platform

The Uno Platform provides a set of command-line templates to create cross-platform applications.
Expand Down
3 changes: 3 additions & 0 deletions doc/articles/guides/how-to-create-control-libraries.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
---
uid: Guide.HowTo.Create-Control-Library
---
# How to Create Control Libraries

Uno Platform, like WinUI and UWP, supports Control Libraries. Control Libraries are a way to reuse UI components across multiple projects, either inside the solution or by using NuGet to distribute to other projects.
Expand Down
2 changes: 2 additions & 0 deletions doc/articles/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@
items:
- name: Troubleshooting build errors
href: uno-builds-troubleshooting.md
- name: Build error codes
href: uno-build-error-codes.md
- name: 'Debugging C# on WASM'
href: debugging-wasm.md
- name: XAML Hot Reload
Expand Down
20 changes: 20 additions & 0 deletions doc/articles/uno-build-error-codes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
uid: Build.Solution.error-codes
---
# Uno Build error codes

## UNOB0001: Cannot build with both Uno.WinUI and Uno.UI NuGet packages referenced

This error code means that a project has determined what both `Uno.WinUI` and `Uno.UI` packages are referenced.

To fix this issue, you may be explicitly referencing `Uno.UI` and `Uno.WinUI` in your `csproj`, or you may be referencing a NuGet package that is incompatible with your current project's configuration.

For instance, if your project references `Uno.WinUI`, and you try to reference `SkiaSharp.View.Uno`, you will get this error. To fix it, you'll need to reference `SkiaSharp.View.Uno.WinUI` instead.

## UNOB0002: Project XX contains a reference to Uno Platform but does not contain a WinAppSDK compatible target framework.

This error code means that a WinAppSDK project is referencing a project in your solution which is not providing a `net6.0-windows10.xx` TargetFramework.

This can happen if a project contains only a `net7.0` TargetFramework and has a NuGet reference to `Uno.WinUI`.

To fix this, it is best to start from a `Cross Platform Library` project template provided by the Uno Platform [visual studio extension](xref:Guide.HowTo.Create-Control-Library), or using [`dotnet new`](xref:GetStarted.dotnet-new).
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#nullable enable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Build.Framework;

namespace Uno.UI.Tasks.WinAppSDKValidations;

/// <summary>
/// A task used to merge linker definition files and embed the result in an assembly
/// </summary>
public class ValidateWinAppSDKReferences_v0 : Microsoft.Build.Utilities.Task
{
[Required]
public ITaskItem[] ReferencedProjects { get; set; } = Array.Empty<ITaskItem>();

public override bool Execute()
{
foreach (var project in ReferencedProjects)
{
string nearestTargetFramework = project.GetMetadata("NearestTargetFramework");

if (string.IsNullOrEmpty(nearestTargetFramework) || !(project.GetMetadata("AdditionalPropertiesFromProject") is { Length: > 0 }))
{
// Referenced project doesn't have the right metadata. This may be because it's a different project type (C++, for example)
// In this case just skip the checks
continue;
}

var additionalPropertiesXml = XElement.Parse(project.GetMetadata("AdditionalPropertiesFromProject"));

XElement targetFrameworkElement =
additionalPropertiesXml
.Elements()
.Where(el => el.HasAttributes && el.FirstAttribute.Value.Equals(nearestTargetFramework))
.Single();

Dictionary<string, string> projectAdditionalProperties = new(StringComparer.OrdinalIgnoreCase);

if (targetFrameworkElement is not null)
{
foreach (var propertyElement in targetFrameworkElement.Elements())
{
projectAdditionalProperties[propertyElement.Name.LocalName] = propertyElement.Value;
}

if (projectAdditionalProperties.TryGetValue("_IsUnoPlatform", out var isUnoPlatformValue)
&& bool.TryParse(isUnoPlatformValue, out bool isUnoPlatform)
&& isUnoPlatform)
{
Log.LogError(
subcategory: null,
errorCode: "UNOB0002",
helpKeyword: null,
file: null,
lineNumber: 0,
columnNumber: 0,
endLineNumber: 0,
endColumnNumber: 0,
message: "Project {0} contains a reference to Uno Platform but does not contain a WinAppSDK compatible target framework. https://aka.platform.uno/UNOB0002",
messageArgs: project.ItemSpec
);

return false;
}
}
}

return true;
}
}

0 comments on commit c940696

Please sign in to comment.