[dotnet] Add support for some of the single-project MSBuild properties. (#10545)

* [tests] Add test case for single-project properties in .NET.

* [msbuild] Add support for the single-project ApplicationId MSBuild property.

* [msbuild] Add support for the single-project ApplicationTitle, ApplicationVersion and AppleShortVersion MSBuild properties.

* [dotnet] Enable the single-project MSBuild properties by default.

* [dotnet] Add a short doc about single project properties.

* [tests] Fix the GeneratePlistTaskTests.BundleIdentifier test according to bundle identifier changes.

This test asserts that the CFBundleIdentifier value in the Info.plist isn't
overwritten, and does so by calling the CompileAppManifest task, giving it a
different value for the bundle identifier than what's in the Info.plist.

The behavior change is that now we do things in the following manner:

DetectSigningIdentityTask will read the Info.plist, compute a bundle
identifier (which will be the value from the Info.plist if it's there), and
returns it to the MSBuild code. Eventually that value will be passed to the
CompileAppManifestTask, which will write it to the Info.plist.

However, this test doesn't run the DetectSigningIdentityTask, which means that
the initial value for the bundle identifier doesn't come from the Info.plist.
This commit is contained in:
Rolf Bjarne Kvinge 2021-01-29 17:37:37 +01:00 коммит произвёл GitHub
Родитель bad792983e
Коммит a9c21ef791
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 97 добавлений и 11 удалений

27
dotnet/SingleProject.md Normal file
Просмотреть файл

@ -0,0 +1,27 @@
# .NET "Single Project"
In order to improve the cross-platform experience between Android and our
Apple platforms, there are certain properties that can be set in the project
file that will be added to the app in a platform-specific way.
More a more detailed description see this document: [OneDotNetSingleProject.md][1]
For our Apple platforms this means we're mapping the following MSBuild
properties to Info.plist keys (this mapping will only take place if the
Info.plist in the project doesn't already contain entries for these keys):
| MSBuild Property | Info.plist key | Notes |
| --------------------|----------------------------|-------------------------------------------|
| ApplicationId | CFBundleIdentifier | |
| ApplicationTitle | CFBundleDisplayName | |
| ApplicationVersion | CFBundleVersion | |
| AppleShortVersion | CFBundleShortVersionString | Defaults to ApplicationVersion when blank |
This is only enabled if the `GenerateApplicationManifest` is set to `true`
(which is the default for `.NET 6`, and not for "legacy"
Xamarin.iOS/Xamarin.Mac)
Ref: [Issue #10473][2]
[1]: https://github.com/xamarin/xamarin-android/blob/40cedfa89c2660479fcb5e2482d2463fbcad1d04/Documentation/guides/OneDotNetSingleProject.md
[2]: https://github.com/xamarin/xamarin-macios/issues/10473

Просмотреть файл

@ -9,6 +9,9 @@
<_XamarinTaskAssembly Condition="'$(_PlatformName)' != 'macOS'">$(_XamarinSdkRootDirectory)\tools\msbuild\iOS\Xamarin.iOS.Tasks.dll</_XamarinTaskAssembly>
<_XamarinTaskAssembly Condition="'$(_PlatformName)' == 'macOS'">$(_XamarinSdkRootDirectory)\tools\msbuild\macOS\Xamarin.Mac.Tasks.dll</_XamarinTaskAssembly>
<!-- Use single-project MSBuild properties to generate the application manifest by default -->
<GenerateApplicationManifest Condition="'$(GenerateApplicationManifest)' == ''">true</GenerateApplicationManifest>
</PropertyGroup>
<UsingTask TaskName="Xamarin.MacDev.Tasks.CompileNativeCode" AssemblyFile="$(_XamarinTaskAssembly)" />

Просмотреть файл

@ -13,6 +13,15 @@ namespace Xamarin.MacDev.Tasks
{
#region Inputs
// Single-project property that maps to CFBundleShortVersionString for Apple platforms
public string AppleShortVersion { get; set; }
// Single-project property that maps to CFBundleDisplayName for Apple platforms
public string ApplicationTitle { get; set; }
// Single-project property that maps to CFBundleVersion for Apple platforms
public string ApplicationVersion { get; set; }
[Required]
public string AppBundleName { get; set; }
@ -36,6 +45,9 @@ namespace Xamarin.MacDev.Tasks
[Required]
public string DefaultSdkVersion { get; set; }
// Single-project property that determines whether other single-project properties should have any effect
public bool GenerateApplicationManifest { get; set; }
[Required]
public bool IsAppExtension { get; set; }
@ -88,14 +100,32 @@ namespace Xamarin.MacDev.Tasks
return false;
}
plist.SetIfNotPresent (ManifestKeys.CFBundleIdentifier, BundleIdentifier);
plist.SetCFBundleIdentifier (BundleIdentifier); // no ifs and buts, we've computed the final bundle identifier (BundleIdentifier) in DetectSigningIdentityTask.
plist.SetIfNotPresent (ManifestKeys.CFBundleInfoDictionaryVersion, "6.0");
plist.SetIfNotPresent (ManifestKeys.CFBundlePackageType, IsAppExtension ? "XPC!" : "APPL");
plist.SetIfNotPresent (ManifestKeys.CFBundleSignature, "????");
plist.SetIfNotPresent (ManifestKeys.CFBundleVersion, "1.0");
plist.SetIfNotPresent (ManifestKeys.CFBundleExecutable, AssemblyName);
plist.SetIfNotPresent (ManifestKeys.CFBundleName, AppBundleName);
if (GenerateApplicationManifest && !string.IsNullOrEmpty (ApplicationTitle))
plist.SetIfNotPresent (ManifestKeys.CFBundleDisplayName, ApplicationTitle);
string defaultBundleVersion = "1.0";
if (GenerateApplicationManifest && !string.IsNullOrEmpty (ApplicationVersion))
defaultBundleVersion = ApplicationVersion;
plist.SetIfNotPresent (ManifestKeys.CFBundleVersion, defaultBundleVersion);
string defaultBundleShortVersion = null;
if (GenerateApplicationManifest) {
if (!string.IsNullOrEmpty (AppleShortVersion))
defaultBundleShortVersion = AppleShortVersion;
else if (!string.IsNullOrEmpty (ApplicationVersion))
defaultBundleShortVersion = ApplicationVersion;
}
if (string.IsNullOrEmpty (defaultBundleShortVersion))
defaultBundleShortVersion = plist.GetCFBundleVersion ();
plist.SetIfNotPresent (ManifestKeys.CFBundleShortVersionString, defaultBundleShortVersion);
if (!Compile (plist))
return false;

Просмотреть файл

@ -105,6 +105,12 @@ namespace Xamarin.MacDev.Tasks
[Required]
public string AppManifest { get; set; }
// Single-project property that maps to CFBundleIdentifier for Apple platforms
public string ApplicationId { get; set; }
// Single-project property that determines whether other single-project properties should have any effect
public bool GenerateApplicationManifest { get; set; }
public string Keychain { get; set; }
public string SigningKey { get; set; }
@ -518,8 +524,12 @@ namespace Xamarin.MacDev.Tasks
identity.BundleId = plist.GetCFBundleIdentifier ();
if (string.IsNullOrEmpty (identity.BundleId)) {
Log.LogError (null, null, null, AppManifest, 0, 0, 0, 0, MSBStrings.E0139, AppManifest);
return false;
if (GenerateApplicationManifest && !string.IsNullOrEmpty (ApplicationId)) {
identity.BundleId = ApplicationId;
} else {
Log.LogError (null, null, null, AppManifest, 0, 0, 0, 0, MSBStrings.E0139, AppManifest);
return false;
}
}
DetectedBundleId = identity.BundleId;
DetectedAppId = DetectedBundleId; // default value that can be changed below

Просмотреть файл

@ -231,6 +231,9 @@ Copyright (C) 2018 Microsoft. All rights reserved.
<CompileAppManifest
SessionId="$(BuildSessionId)"
Condition="'$(IsMacEnabled)' == 'true'"
AppleShortVersion="$(AppleShortVersion)"
ApplicationTitle="$(ApplicationTitle)"
ApplicationVersion="$(ApplicationVersion)"
AppBundleName="$(_AppBundleName)"
AppManifest="$(_AppManifest)"
AppManifestBundleDirectory="$(_AppBundlePath)$(_AppBundleManifestRelativePath)"
@ -238,6 +241,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
BundleIdentifier="$(_BundleIdentifier)"
Debug="$(_BundlerDebug)"
DefaultSdkVersion="$(_SdkVersion)"
GenerateApplicationManifest="$(GenerateApplicationManifest)"
IsAppExtension="$(IsAppExtension)"
IsWatchApp="$(IsWatchApp)"
IsWatchExtension="$(IsWatchExtension)"
@ -779,8 +783,10 @@ Copyright (C) 2018 Microsoft. All rights reserved.
<DetectSigningIdentity
SessionId="$(BuildSessionId)"
Condition="'$(IsMacEnabled)' == 'true'"
ApplicationId="$(ApplicationId)"
AppBundleName="$(_AppBundleName)"
AppManifest="$(_AppManifest)"
GenerateApplicationManifest="$(GenerateApplicationManifest)"
Keychain="$(CodesignKeychain)"
RequireCodeSigning="$(_RequireCodeSigning)"
RequireProvisioningProfile="$(_RequireProvisioningProfile)"

Просмотреть файл

@ -65,7 +65,6 @@ namespace Xamarin.iOS.Tasks
plist.SetIfNotPresent (ManifestKeys.CFBundleResourceSpecification, Path.GetFileName (ResourceRules));
if (!plist.ContainsKey (ManifestKeys.CFBundleSupportedPlatforms))
plist[ManifestKeys.CFBundleSupportedPlatforms] = new PArray { SdkPlatform };
plist.SetIfNotPresent (ManifestKeys.CFBundleShortVersionString, plist.GetCFBundleVersion ());
string dtCompiler = null;
string dtPlatformBuild = null;

Просмотреть файл

@ -14,10 +14,6 @@
</array>
<key>MinimumOSVersion</key>
<string>7.0</string>
<key>CFBundleDisplayName</key>
<string>ApplicationName</string>
<key>CFBundleIdentifier</key>
<string>com.xamarin.mysingleview</string>
<key>XSAppIconAssets</key>
<string>Resources/Images.xcassets/AppIcons.appiconset</string>
<key>XSLaunchImageAssets</key>

Просмотреть файл

@ -4,5 +4,9 @@
<TargetFramework>net6.0-ios</TargetFramework>
<RuntimeIdentifier>ios-x64</RuntimeIdentifier>
<OutputType>Exe</OutputType>
<ApplicationTitle>MySingleTitle</ApplicationTitle>
<ApplicationId>com.xamarin.mysingletitle</ApplicationId>
<ApplicationVersion>3.14</ApplicationVersion>
</PropertyGroup>
</Project>

Просмотреть файл

@ -43,6 +43,9 @@
<Compile Include="..\..\common\BinLog.cs">
<Link>external\BinLog.cs</Link>
</Compile>
<Compile Include="..\..\..\external\Xamarin.MacDev\Xamarin.MacDev\PListObject.cs">
<Link>external\PListObject.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="external\" />

Просмотреть файл

@ -9,6 +9,7 @@ using NUnit.Framework;
using Xamarin.Utils;
using Xamarin.Tests;
using Xamarin.MacDev;
namespace Xamarin.Tests {
[TestFixture]
@ -55,7 +56,14 @@ namespace Xamarin.Tests {
Clean (project_path);
var result = DotNet.AssertBuild (project_path, verbosity);
AssertThatLinkerExecuted (result);
AssertAppContents (platform, Path.Combine (Path.GetDirectoryName (project_path), "bin", "Debug", "net6.0-ios", "ios-x64", "MySingleView.app"));
var appPath = Path.Combine (Path.GetDirectoryName (project_path), "bin", "Debug", "net6.0-ios", "ios-x64", "MySingleView.app");
AssertAppContents (platform, appPath);
var infoPlistPath = Path.Combine (appPath, "Info.plist");
var infoPlist = PDictionary.FromFile (infoPlistPath);
Assert.AreEqual ("com.xamarin.mysingletitle", infoPlist.GetString ("CFBundleIdentifier").Value, "CFBundleIdentifier");
Assert.AreEqual ("MySingleTitle", infoPlist.GetString ("CFBundleDisplayName").Value, "CFBundleDisplayName");
Assert.AreEqual ("3.14", infoPlist.GetString ("CFBundleVersion").Value, "CFBundleVersion");
Assert.AreEqual ("3.14", infoPlist.GetString ("CFBundleShortVersionString").Value, "CFBundleShortVersionString");
}
[Test]

Просмотреть файл

@ -128,7 +128,7 @@ namespace Xamarin.iOS.Tasks
public virtual void BundleIdentifier ()
{
Assert.That (CompiledPlist.ContainsKey (ManifestKeys.CFBundleIdentifier), "#1");
Assert.AreEqual (CompiledPlist.Get<PString> (ManifestKeys.CFBundleIdentifier).Value, identifier, "#2");
Assert.AreEqual (CompiledPlist.Get<PString> (ManifestKeys.CFBundleIdentifier).Value, bundleIdentifier, "#2");
}
[Test]