Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Make.versions
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ WATCHOS_NUGET_OS_VERSION=11.0
MACOS_NUGET_OS_VERSION=15.0
MACCATALYST_NUGET_OS_VERSION=18.0

# The following are the OS versions we first supported with the current .NET version.
# These versions must *not* change with minor .NET updates, only major .NET releases.
IOS_TARGET_PLATFORM_VERSION_LIBRARY=18.0
TVOS_TARGET_PLATFORM_VERSION_LIBRARY=18.0
MACOS_TARGET_PLATFORM_VERSION_LIBRARY=15.0
MACCATALYST_TARGET_PLATFORM_VERSION_LIBRARY=18.0

# In theory we should define the default platform version if it's not specified in the TFM. The default should not change for a given .NET version:
# * We release support for iOS 14.5 with .NET 6
Expand Down Expand Up @@ -100,6 +106,13 @@ MACCATALYST_NUGET_OS_VERSION=18.0
# So we've made the decision that the default target platform version is
# always the latest target platform version.

# However, this turns out to be somewhat of a complication for library developers,
# because they typically don't need Xcode to build their projects, and if we auto-
# update their TargetPlatformVersion to the latest, then all their customers
# have to also update their workloads, which for some people end up being a rather
# nasty surprise (because with the above algorithm it happens without developer
# action). Thus we follow .NET's default platform version scheme for library projects:
# it won't change in minor .NET releases.

#
# Here we list all the releases we support for each platform.
Expand Down
3 changes: 2 additions & 1 deletion dotnet/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ targets/Microsoft.$(1).Sdk.Versions.props: targets/Microsoft.Sdk.Versions.templa
-e "s/@PLATFORM@/$(1)/g" \
-e "s/@NUGET_VERSION_NO_METADATA@/$$($(2)_NUGET_VERSION_NO_METADATA)/g" \
-e "s/@NUGET_VERSION_FULL@/$$($(2)_NUGET_VERSION_FULL)/g" \
-e "s/@TARGET_PLATFORM_VERSION@/$$($(2)_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_EXE@/$$($(2)_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_LIBRARY@/$$($(2)_TARGET_PLATFORM_VERSION_LIBRARY)/g" \
-e "s/@CURRENT_BRANCH@/$$(CURRENT_BRANCH_SED_ESCAPED)/g" \
-e "s/@CURRENT_HASH_LONG@/$$(CURRENT_HASH_LONG)/g" \
-e 's*@VALID_RUNTIME_IDENTIFIERS@*$(foreach rid,$(3),\n\t\t<_XamarinValidRuntimeIdentifier Include="$(rid)" Platform="$(1)" />)*' \
Expand Down
3 changes: 2 additions & 1 deletion dotnet/targets/Microsoft.Sdk.Versions.template.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

<_ShortPackageVersion>@NUGET_VERSION_NO_METADATA@</_ShortPackageVersion>
<_PackageVersion>@NUGET_VERSION_FULL@</_PackageVersion>
<_XamarinTargetPlatformVersion>@TARGET_PLATFORM_VERSION@</_XamarinTargetPlatformVersion>
<_XamarinTargetPlatformVersionExecutable>@TARGET_PLATFORM_VERSION_EXE@</_XamarinTargetPlatformVersionExecutable>
<_XamarinTargetPlatformVersionLibrary>@TARGET_PLATFORM_VERSION_LIBRARY@</_XamarinTargetPlatformVersionLibrary>
<_XamarinIsPreviewRelease>@XCODE_IS_PREVIEW@</_XamarinIsPreviewRelease>
<_XamarinDotNetVersion>@DOTNET_TFM@</_XamarinDotNetVersion>
<_XamarinPackSuffix>@DOTNET_TFM@_@NUGET_OS_VERSION@</_XamarinPackSuffix>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

<!-- Set the default TargetPlatformVersion if it wasn't specified in the TargetFramework variable. This must be set after importing Sdk.targets (in Xamarin.Shared.Sdk.targets) -->
<PropertyGroup>
<TargetPlatformVersion Condition="'$(TargetPlatformVersion)' == ''">$(_XamarinTargetPlatformVersion)</TargetPlatformVersion>
<TargetPlatformVersion Condition="'$(TargetPlatformVersion)' == '' And ('$(OutputType)' == 'Exe' Or '$(IsAppExtension)' == 'true')">$(_XamarinTargetPlatformVersionExecutable)</TargetPlatformVersion>
<TargetPlatformVersion Condition="'$(TargetPlatformVersion)' == ''">$(_XamarinTargetPlatformVersionLibrary)</TargetPlatformVersion>
</PropertyGroup>
</Project>
51 changes: 44 additions & 7 deletions tests/dotnet/UnitTests/ApplePlatformExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

namespace Xamarin.Utils {
public static class ApplePlatformExtensionsWithVersions {
public static string ToFrameworkWithPlatformVersion (this ApplePlatform @this)
public static string ToFrameworkWithPlatformVersion (this ApplePlatform @this, bool isExecutable /* and not library */)
{
var netVersion = Configuration.DotNetTfm;
var targetPlatformVersion = GetTargetPlatformVersion (@this);
var targetPlatformVersion = isExecutable ? GetDefaultTargetPlatformVersionExecutable (@this) : GetDefaultTargetPlatformVersionLibrary (@this);
switch (@this) {
case ApplePlatform.iOS:
return netVersion + "-ios" + targetPlatformVersion;
Expand All @@ -20,16 +20,53 @@ public static string ToFrameworkWithPlatformVersion (this ApplePlatform @this)
}
}

public static string GetTargetPlatformVersion (this ApplePlatform @this)
public static string GetDefaultTargetPlatformVersionExecutable (this ApplePlatform @this)
{
switch (@this) {
case ApplePlatform.iOS: return SdkVersions.TargetPlatformVersioniOS;
case ApplePlatform.TVOS: return SdkVersions.TargetPlatformVersiontvOS;
case ApplePlatform.MacOSX: return SdkVersions.TargetPlatformVersionmacOS;
case ApplePlatform.MacCatalyst: return SdkVersions.TargetPlatformVersionMacCatalyst;
case ApplePlatform.iOS: return SdkVersions.TargetPlatformVersionExecutableiOS;
case ApplePlatform.TVOS: return SdkVersions.TargetPlatformVersionExecutabletvOS;
case ApplePlatform.MacOSX: return SdkVersions.TargetPlatformVersionExecutablemacOS;
case ApplePlatform.MacCatalyst: return SdkVersions.TargetPlatformVersionExecutableMacCatalyst;
default:
return "Unknown";
}
}

public static string GetDefaultTargetPlatformVersionLibrary (this ApplePlatform @this)
{
switch (@this) {
case ApplePlatform.iOS: return SdkVersions.TargetPlatformVersionLibraryiOS;
case ApplePlatform.TVOS: return SdkVersions.TargetPlatformVersionLibrarytvOS;
case ApplePlatform.MacOSX: return SdkVersions.TargetPlatformVersionLibrarymacOS;
case ApplePlatform.MacCatalyst: return SdkVersions.TargetPlatformVersionLibraryMacCatalyst;
default:
return "Unknown";
}
}
}

[TestFixture]
public class TargetFrameworkTest {
[TestCase (ApplePlatform.iOS)]
[TestCase (ApplePlatform.MacCatalyst)]
[TestCase (ApplePlatform.TVOS)]
[TestCase (ApplePlatform.MacOSX)]
public void DefaultLibraryTargetPlatformVersion (ApplePlatform platform)
{
// We might have to change the assert if the first minor OS version we release for a given .NET version is >0 (this happened for both .NET 7 and .NET 8).
Assert.That (platform.GetDefaultTargetPlatformVersionLibrary (), Does.EndWith (".0"), "Default TPV for a library must end with .0");
}

[TestCase (ApplePlatform.iOS)]
[TestCase (ApplePlatform.MacCatalyst)]
[TestCase (ApplePlatform.TVOS)]
[TestCase (ApplePlatform.MacOSX)]
public void MajorTargetPlatformVersion (ApplePlatform platform)
{
var vLibrary = Version.Parse (platform.GetDefaultTargetPlatformVersionLibrary ());
var vExecutable = Version.Parse (platform.GetDefaultTargetPlatformVersionExecutable ());
// We might have to change the assert if we release support for a new major OS version within a .NET releases (this happened for .NET 8)
Assert.AreEqual (vExecutable.Major, vLibrary.Major, "The major version must be the same between the default TPV for library and executable projects.");
}
}
}
2 changes: 1 addition & 1 deletion tests/dotnet/UnitTests/MlaunchTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void GetMlaunchRunArguments (ApplePlatform platform, string runtimeIdenti
expectedArguments.Append (appPath.Substring (Path.GetDirectoryName (project_path)!.Length + 1)).Append ('/');
if (isSim) {
expectedArguments.Append (" --device \"");
expectedArguments.Append (device.Replace ("%TPV%", platform.GetTargetPlatformVersion ().Replace ('.', '-')));
expectedArguments.Append (device);
expectedArguments.Append ('"');
}
expectedArguments.Append ($" --wait-for-exit:true");
Expand Down
22 changes: 12 additions & 10 deletions tests/dotnet/UnitTests/PackTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public void BindingFrameworksProject (ApplePlatform platform, bool noBindingEmbe

var archive = ZipFile.OpenRead (nupkg);
var files = archive.Entries.Select (v => v.FullName).ToHashSet ();
var tfm = platform.ToFrameworkWithPlatformVersion (isExecutable: false);
var hasSymlinks = noBindingEmbedding && (platform == ApplePlatform.MacCatalyst || platform == ApplePlatform.MacOSX);
if (noBindingEmbedding) {
Assert.That (archive.Entries.Count, Is.EqualTo (hasSymlinks ? 6 : 10), $"nupkg file count - {nupkg}");
Expand All @@ -71,17 +72,17 @@ public void BindingFrameworksProject (ApplePlatform platform, bool noBindingEmbe
Assert.That (files, Does.Contain (project + ".nuspec"), "nuspec");
Assert.That (files, Does.Contain ("_rels/.rels"), ".rels");
Assert.That (files, Does.Contain ("[Content_Types].xml"), "[Content_Types].xml");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.dll"), $"{project}.dll");
Assert.That (files, Does.Contain ($"lib/{tfm}/{project}.dll"), $"{project}.dll");
Assert.That (files, Has.Some.Matches<string> (v => v.StartsWith ("package/services/metadata/core-properties/", StringComparison.Ordinal) && v.EndsWith (".psmdcp", StringComparison.Ordinal)), "psmdcp");
if (noBindingEmbedding) {
if (hasSymlinks) {
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.resources.zip"), $"{project}.resources.zip");
Assert.That (files, Does.Contain ($"lib/{tfm}/{project}.resources.zip"), $"{project}.resources.zip");
} else {
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.resources/XStaticArTest.framework/XStaticArTest"), $"XStaticArTest.framework/XStaticArTest");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.resources/XStaticObjectTest.framework/XStaticObjectTest"), $"XStaticObjectTest.framework/XStaticObjectTest");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.resources/XTest.framework/XTest"), $"XTest.framework/XTest");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.resources/XTest.framework/Info.plist"), $"XTest.framework/Info.plist");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.resources/manifest"), $"manifest");
Assert.That (files, Does.Contain ($"lib/{tfm}/{project}.resources/XStaticArTest.framework/XStaticArTest"), $"XStaticArTest.framework/XStaticArTest");
Assert.That (files, Does.Contain ($"lib/{tfm}/{project}.resources/XStaticObjectTest.framework/XStaticObjectTest"), $"XStaticObjectTest.framework/XStaticObjectTest");
Assert.That (files, Does.Contain ($"lib/{tfm}/{project}.resources/XTest.framework/XTest"), $"XTest.framework/XTest");
Assert.That (files, Does.Contain ($"lib/{tfm}/{project}.resources/XTest.framework/Info.plist"), $"XTest.framework/Info.plist");
Assert.That (files, Does.Contain ($"lib/{tfm}/{project}.resources/manifest"), $"manifest");
}
}
}
Expand Down Expand Up @@ -127,14 +128,15 @@ public void BindingXcFrameworksProject (ApplePlatform platform, bool noBindingEm

var archive = ZipFile.OpenRead (nupkg);
var files = archive.Entries.Select (v => v.FullName).ToHashSet ();
var tfm = platform.ToFrameworkWithPlatformVersion (isExecutable: false);
Assert.That (archive.Entries.Count, Is.EqualTo (noBindingEmbedding ? 6 : 5), $"nupkg file count - {nupkg}");
Assert.That (files, Does.Contain (assemblyName + ".nuspec"), "nuspec");
Assert.That (files, Does.Contain ("_rels/.rels"), ".rels");
Assert.That (files, Does.Contain ("[Content_Types].xml"), "[Content_Types].xml");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{assemblyName}.dll"), $"{assemblyName}.dll");
Assert.That (files, Does.Contain ($"lib/{tfm}/{assemblyName}.dll"), $"{assemblyName}.dll");
Assert.That (files, Has.Some.Matches<string> (v => v.StartsWith ("package/services/metadata/core-properties/", StringComparison.Ordinal) && v.EndsWith (".psmdcp", StringComparison.Ordinal)), "psmdcp");
if (noBindingEmbedding) {
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{assemblyName}.resources.zip"), $"{assemblyName}.resources.zip");
Assert.That (files, Does.Contain ($"lib/{tfm}/{assemblyName}.resources.zip"), $"{assemblyName}.resources.zip");
}
}

Expand Down Expand Up @@ -164,7 +166,7 @@ public void LibraryProject (ApplePlatform platform)
Assert.That (files, Does.Contain (project + ".nuspec"), "nuspec");
Assert.That (files, Does.Contain ("_rels/.rels"), ".rels");
Assert.That (files, Does.Contain ("[Content_Types].xml"), "[Content_Types].xml");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion ()}/{project}.dll"), $"{project}.dll");
Assert.That (files, Does.Contain ($"lib/{platform.ToFrameworkWithPlatformVersion (isExecutable: false)}/{project}.dll"), $"{project}.dll");
Assert.That (files, Has.Some.Matches<string> (v => v.StartsWith ("package/services/metadata/core-properties/", StringComparison.Ordinal) && v.EndsWith (".psmdcp", StringComparison.Ordinal)), "psmdcp");
}

Expand Down
5 changes: 3 additions & 2 deletions tests/dotnet/UnitTests/XcodeProjectTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@ public void PackBinding (ApplePlatform platform)
Assert.That (expectedNupkgOutput, Does.Exist, $"Expected pack output '{expectedNupkgOutput}' did not exist.");

List<string> zipContent = ZipHelpers.List (expectedNupkgOutput);
var expectedFxPath = $"lib/{platform.ToFrameworkWithPlatformVersion ()}/{TestName}.resources/{xcodeProjName}{platform.AsString ()}.xcframework/Info.plist";
var tfm = platform.ToFrameworkWithPlatformVersion (isExecutable: false);
var expectedFxPath = $"lib/{tfm}/{TestName}.resources/{xcodeProjName}{platform.AsString ()}.xcframework/Info.plist";
if (platform == ApplePlatform.MacOSX || platform == ApplePlatform.MacCatalyst) {
zipContent = ZipHelpers.ListInnerZip (expectedNupkgOutput, $"lib/{platform.ToFrameworkWithPlatformVersion ()}/{TestName}.resources.zip");
zipContent = ZipHelpers.ListInnerZip (expectedNupkgOutput, $"lib/{tfm}/{TestName}.resources.zip");
expectedFxPath = $"{xcodeProjName}{platform.AsString ()}.xcframework/Info.plist";
}
Assert.Contains (expectedFxPath, zipContent, $"Expected xcframework output was not found in '{expectedNupkgOutput}'.");
Expand Down
13 changes: 9 additions & 4 deletions tools/common/Make.common
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,15 @@ $(abspath ../common/SdkVersions.cs): ../common/SdkVersions.in.cs Makefile $(TOP)
-e "s/@MACOS_NUGET_VERSION@/$(MACOS_NUGET_VERSION)/g" \
-e "s/@MACOS_NUGET_REVISION@/$(NUGET_PRERELEASE_IDENTIFIER)$(MACOS_NUGET_COMMIT_DISTANCE)$(NUGET_BUILD_METADATA)/g" \
\
-e "s/@TARGET_PLATFORM_VERSION_IOS@/$(IOS_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_TVOS@/$(TVOS_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_MACOS@/$(MACOS_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_MACCATALYST@/$(MACCATALYST_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_EXECUTABLE_IOS@/$(IOS_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_EXECUTABLE_TVOS@/$(TVOS_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_EXECUTABLE_MACOS@/$(MACOS_NUGET_OS_VERSION)/g" \
-e "s/@TARGET_PLATFORM_VERSION_EXECUTABLE_MACCATALYST@/$(MACCATALYST_NUGET_OS_VERSION)/g" \
\
-e "s/@TARGET_PLATFORM_VERSION_LIBRARY_IOS@/$(IOS_TARGET_PLATFORM_VERSION_LIBRARY)/g" \
-e "s/@TARGET_PLATFORM_VERSION_LIBRARY_TVOS@/$(TVOS_TARGET_PLATFORM_VERSION_LIBRARY)/g" \
-e "s/@TARGET_PLATFORM_VERSION_LIBRARY_MACOS@/$(MACOS_TARGET_PLATFORM_VERSION_LIBRARY)/g" \
-e "s/@TARGET_PLATFORM_VERSION_LIBRARY_MACCATALYST@/$(MACCATALYST_TARGET_PLATFORM_VERSION_LIBRARY)/g" \
\
-e "s/@PRODUCT_HASH@/$(CURRENT_HASH_LONG)/g" \
\
Expand Down
13 changes: 9 additions & 4 deletions tools/common/SdkVersions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ static class SdkVersions {
public const string MaxWatchDeploymentTarget = "11.0";
public const string MaxTVOSDeploymentTarget = "18.0";

public const string TargetPlatformVersioniOS = "18.0";
public const string TargetPlatformVersiontvOS = "18.0";
public const string TargetPlatformVersionmacOS = "15.0";
public const string TargetPlatformVersionMacCatalyst = "18.0";
public const string TargetPlatformVersionExecutableiOS = "18.0";
public const string TargetPlatformVersionExecutabletvOS = "18.0";
public const string TargetPlatformVersionExecutablemacOS = "15.0";
public const string TargetPlatformVersionExecutableMacCatalyst = "18.0";

public const string TargetPlatformVersionLibraryiOS = "18.0";
public const string TargetPlatformVersionLibrarytvOS = "18.0";
public const string TargetPlatformVersionLibrarymacOS = "15.0";
public const string TargetPlatformVersionLibraryMacCatalyst = "18.0";

public static Version OSXVersion { get { return new Version (OSX); } }
public static Version iOSVersion { get { return new Version (iOS); } }
Expand Down
13 changes: 9 additions & 4 deletions tools/common/SdkVersions.in.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ static class SdkVersions {
public const string MaxWatchDeploymentTarget = "@MAX_WATCH_DEPLOYMENT_TARGET@";
public const string MaxTVOSDeploymentTarget = "@MAX_TVOS_DEPLOYMENT_TARGET@";

public const string TargetPlatformVersioniOS = "@TARGET_PLATFORM_VERSION_IOS@";
public const string TargetPlatformVersiontvOS = "@TARGET_PLATFORM_VERSION_TVOS@";
public const string TargetPlatformVersionmacOS = "@TARGET_PLATFORM_VERSION_MACOS@";
public const string TargetPlatformVersionMacCatalyst = "@TARGET_PLATFORM_VERSION_MACCATALYST@";
public const string TargetPlatformVersionExecutableiOS = "@TARGET_PLATFORM_VERSION_EXECUTABLE_IOS@";
public const string TargetPlatformVersionExecutabletvOS = "@TARGET_PLATFORM_VERSION_EXECUTABLE_TVOS@";
public const string TargetPlatformVersionExecutablemacOS = "@TARGET_PLATFORM_VERSION_EXECUTABLE_MACOS@";
public const string TargetPlatformVersionExecutableMacCatalyst = "@TARGET_PLATFORM_VERSION_EXECUTABLE_MACCATALYST@";

public const string TargetPlatformVersionLibraryiOS = "@TARGET_PLATFORM_VERSION_LIBRARY_IOS@";
public const string TargetPlatformVersionLibrarytvOS = "@TARGET_PLATFORM_VERSION_LIBRARY_TVOS@";
public const string TargetPlatformVersionLibrarymacOS = "@TARGET_PLATFORM_VERSION_LIBRARY_MACOS@";
public const string TargetPlatformVersionLibraryMacCatalyst = "@TARGET_PLATFORM_VERSION_LIBRARY_MACCATALYST@";

public static Version OSXVersion { get { return new Version (OSX); } }
public static Version iOSVersion { get { return new Version (iOS); } }
Expand Down