Skip to content

Commit

Permalink
[One .NET] fix $(PackageTargetFallback) and $(TargetPlatformVersion) (d…
Browse files Browse the repository at this point in the history
…otnet#5835)

Fixes: dotnet#5819

A project using Maui and `TargetFramework=net6.0-android` can hit the
warning:

    warning CA1416: This call site is reachable on all platforms. 'Class1' is only supported on: 'android' 30.0 and later.

I found the project had:

    TargetPlatformVersion = 30

Projects that emit no warnings have `TargetPlatformVersion = 30.0`.

Update the `<GenerateSupportedPlatforms/>` MSBuild task to always
append `.0`:

    version.ApiLevel.ToString ("0.0", CultureInfo.InvariantCulture)

This solves the warning, but we still get an error in other projects
in the solution:

    error CS1061: 'Class1<TVirtualView, TNativeView>' does not contain a definition for 'Context' and no accessible extension method 'Context' accepting a first argument of type 'Class1<TVirtualView, TNativeView>' could be found (are you missing a using directive or an assembly reference?)

The build used:

    ~\.nuget\packages\microsoft.maui.core\6.0.100-preview.3.269\lib\netstandard2.1\Microsoft.Maui.dll

Instead of:

    ~\.nuget\packages\microsoft.maui.core\6.0.100-preview.3.269\lib\net6.0-android30.0\Microsoft.Maui.dll

I found this project uses `TargetFramework=net6.0-android30.0`, which
resulted in a weird value for `$(PackageTargetFallback)`:

    PackageTargetFallback =
        net6.0-android30.0.0;
        monoandroid12.0;
        monoandroid11.0;
        monoandroid10.0;
        monoandroid90;
        monoandroid81;
        monoandroid80;
        monoandroid70;
        monoandroid60;
        monoandroid50;

To fix this, I conditionally added the `.0` and the project builds
successfully.

We will hopefully be able to remove usage of
`$(PackageTargetFallback)` soon, as it was a workaround until NuGet
has official support for .NET 6 & MonoAndroid target frameworks.

I added a new test that covers these cases. I also added a new
`AssertHasNoWarnings()` extension method to simplify checking for
warnings. I also updated a couple tests that no longer emit warnings.
  • Loading branch information
jonathanpeppers committed Apr 14, 2021
1 parent 522d7fb commit b36df8f
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.IO;
using System.Globalization;
using System.Linq;
using System.Xml;
using Microsoft.Build.Framework;
Expand Down Expand Up @@ -61,7 +62,7 @@ public override bool Execute ()
writer.WriteEndElement (); // </TargetPlatformSupported>
writer.WriteStartElement ("TargetPlatformVersion");
writer.WriteAttributeString ("Condition", " '$(TargetPlatformVersion)' == '' ");
writer.WriteString (versions.MaxStableVersion.ApiLevel.ToString ());
writer.WriteString (versions.MaxStableVersion.ApiLevel.ToString ("0.0", CultureInfo.InvariantCulture));
writer.WriteEndElement (); // </TargetPlatformVersion>
writer.WriteEndElement (); // </PropertyGroup>

Expand All @@ -70,7 +71,7 @@ public override bool Execute ()
.Where (v => v.ApiLevel >= MinimumApiLevel)
.OrderBy (v => v.ApiLevel)) {
writer.WriteStartElement ("AndroidSdkSupportedTargetPlatformVersion");
writer.WriteAttributeString ("Include", version.ApiLevel.ToString ());
writer.WriteAttributeString ("Include", version.ApiLevel.ToString ("0.0", CultureInfo.InvariantCulture));
writer.WriteEndElement (); // </AndroidSdkSupportedTargetPlatformVersion>
}
writer.WriteStartElement ("SdkSupportedTargetPlatformVersion");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ This file contains *temporary* workarounds for NuGet in .NET 5.
<UsingTask TaskName="Xamarin.Android.Tasks.FixupNuGetReferences" AssemblyFile="$(_XamarinAndroidBuildTasksAssembly)" />

<PropertyGroup>
<_AndroidPlatformVersion>$(TargetPlatformVersion)</_AndroidPlatformVersion>
<_AndroidPlatformVersion Condition=" !$(_AndroidPlatformVersion.EndsWith ('.0')) ">$(_AndroidPlatformVersion).0</_AndroidPlatformVersion>
<!-- Clear $(AssetTargetFallback), so only $(PackageTargetFallback) is used. -->
<AssetTargetFallback></AssetTargetFallback>
<!--
Use $(PackageTargetFallback), even though it is deprecated.
It doesn't suffer from: https://github.com/NuGet/docs.microsoft.com-nuget/issues/1955
-->
<PackageTargetFallback>
net6.0-android$(TargetPlatformVersion).0;
net6.0-android$(_AndroidPlatformVersion);
monoandroid12.0;
monoandroid11.0;
monoandroid10.0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public void BuildHasNoWarnings (bool isRelease, bool xamarinForms, bool multidex
}
using (var b = CreateApkBuilder (Path.Combine ("temp", TestName))) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
Assert.IsTrue (StringAssertEx.ContainsText (b.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
b.AssertHasNoWarnings ();
Assert.IsFalse (StringAssertEx.ContainsText (b.LastBuildOutput, "Warning: end of file not at end of a line"),
"Should not get a warning from the <CompileNativeAssembly/> task.");
var lockFile = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, ".__lock");
Expand All @@ -195,7 +195,7 @@ public void ClassLibraryHasNoWarnings ()
proj.SetProperty ("AndroidEnableMultiDex", "true");
using (var b = CreateDllBuilder ()) {
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
Assert.IsTrue (StringAssertEx.ContainsText (b.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
b.AssertHasNoWarnings ();

// $(AndroidEnableMultiDex) should not add android-support-multidex.jar!
if (Builder.UseDotNet) {
Expand Down Expand Up @@ -4066,10 +4066,7 @@ public void XA4310 ([Values ("apk", "aab")] string packageFormat)

StringAssertEx.Contains ("error XA4310", builder.LastBuildOutput, "Error should be XA4310");
StringAssertEx.Contains ("`DoesNotExist`", builder.LastBuildOutput, "Error should include the name of the nonexistent file");
if (!Builder.UseDotNet) {
// ILLink produces lots of warnings in .NET 5+
StringAssertEx.Contains ("0 Warning(s)", builder.LastBuildOutput, "Should have no MSBuild warnings.");
}
builder.AssertHasNoWarnings ();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,7 @@ public void CheckSignApk ([Values(true, false)] bool useApkSigner, [Values(true,
using (var b = CreateApkBuilder (Path.Combine ("temp", TestContext.CurrentContext.Test.Name))) {
var bin = Path.Combine (Root, b.ProjectDirectory, proj.OutputPath);
Assert.IsTrue (b.Build (proj), "First build failed");
if (!Builder.UseDotNet) {
// In .NET 5+, there are ILLink warnings
Assert.IsTrue (StringAssertEx.ContainsText (b.LastBuildOutput, " 0 Warning(s)"),
"First build should not contain warnings! Contains\n" +
string.Join ("\n", b.LastBuildOutput.Where (line => line.Contains ("warning"))));
}
b.AssertHasNoWarnings ();

//Make sure the APKs are signed
foreach (var apk in Directory.GetFiles (bin, "*-Signed.apk")) {
Expand All @@ -425,12 +420,7 @@ public void CheckSignApk ([Values(true, false)] bool useApkSigner, [Values(true,
item.TextContent = () => proj.StringsXml.Replace ("${PROJECT_NAME}", "Foo");
item.Timestamp = null;
Assert.IsTrue (b.Build (proj), "Second build failed");
if (!Builder.UseDotNet) {
// In .NET 5+, there are ILLink warnings
Assert.IsTrue (StringAssertEx.ContainsText (b.LastBuildOutput, " 0 Warning(s)"),
"Second build should not contain warnings! Contains\n" +
string.Join ("\n", b.LastBuildOutput.Where (line => line.Contains ("warning"))));
}
b.AssertHasNoWarnings ();

//Make sure the APKs are signed
foreach (var apk in Directory.GetFiles (bin, "*-Signed.apk")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,17 @@ public static void AssertEntryContents (this ZipArchive zip, string zipPath, str
Assert.AreEqual (contents, actual, $"{archivePath} should contain {contents}");
}
}

[DebuggerHidden]
public static void AssertHasNoWarnings (this ProjectBuilder builder)
{
Assert.IsTrue (StringAssertEx.ContainsText (builder.LastBuildOutput, " 0 Warning(s)"), $"{builder.BuildLogFile} should have no MSBuild warnings.");
}

[DebuggerHidden]
public static void AssertHasNoWarnings (this DotNetCLI dotnet)
{
Assert.IsTrue (StringAssertEx.ContainsText (dotnet.LastBuildOutput, " 0 Warning(s)"), $"{dotnet.BuildLogFile} should have no MSBuild warnings.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease)

var dotnet = CreateDotNetBuilder (proj);
Assert.IsTrue (dotnet.Build (), "`dotnet build` should succeed");

Assert.IsTrue (StringAssertEx.ContainsText (dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
dotnet.AssertHasNoWarnings ();

var outputPath = Path.Combine (FullProjectDirectory, proj.OutputPath);
var intermediateOutputPath = Path.Combine (FullProjectDirectory, proj.IntermediateOutputPath);
Expand Down Expand Up @@ -460,7 +459,7 @@ public void DotNetBuildXamarinForms ()
var proj = new XamarinFormsXASdkProject ();
var dotnet = CreateDotNetBuilder (proj);
Assert.IsTrue (dotnet.Build (), "`dotnet build` should succeed");
Assert.IsTrue (StringAssertEx.ContainsText (dotnet.LastBuildOutput, " 0 Warning(s)"), "Should have no MSBuild warnings.");
dotnet.AssertHasNoWarnings ();
}

[Test]
Expand Down Expand Up @@ -554,6 +553,43 @@ public void XamarinLegacySdk ()
nupkg.AssertContainsEntry (nupkgPath, $"lib/{legacyTargetFramework}/{proj.ProjectName}.dll");
}

[Test]
public void MauiTargetFramework ([Values ("net6.0-android", "net6.0-android30", "net6.0-android30.0")] string targetFramework)
{
var library = new XASdkProject (outputType: "Library") {
TargetFramework = targetFramework,
};
library.ExtraNuGetConfigSources.Add ("https://pkgs.dev.azure.com/azure-public/vside/_packaging/xamarin-impl/nuget/v3/index.json");
library.Sources.Clear ();
library.Sources.Add (new BuildItem.Source ("Foo.cs") {
TextContent = () =>
@"using Microsoft.Maui;
using Microsoft.Maui.Handlers;
public abstract class Foo<TVirtualView, TNativeView> : AbstractViewHandler<TVirtualView, TNativeView>
where TVirtualView : class, IView
#if ANDROID
where TNativeView : Android.Views.View
#else
where TNativeView : class
#endif
{
protected Foo (PropertyMapper mapper) : base(mapper)
{
#if ANDROID
var t = this.Context;
#endif
}
}",
});

library.PackageReferences.Add (new Package { Id = "Microsoft.Maui.Core", Version = "6.0.100-preview.3.269" });

var dotnet = CreateDotNetBuilder (library);
Assert.IsTrue (dotnet.Build (), $"{library.ProjectName} should succeed");
dotnet.AssertHasNoWarnings ();
}

[Test]
public void DotNetIncremental ()
{
Expand Down

0 comments on commit b36df8f

Please sign in to comment.