From 2e7152ae6886091ef68ad9d50c0711b73d25370b Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Thu, 11 Jul 2019 12:32:41 +0200 Subject: [PATCH] tmp --- .../XTest.framework.linkwith.cs | 1 + .../bindings-framework-test.csproj | 3 + tests/test-libraries/Makefile | 32 ++++++++ tools/common/Assembly.cs | 79 +++++++++++++++++++ tools/common/CompilerFlags.cs | 4 +- 5 files changed, 117 insertions(+), 2 deletions(-) diff --git a/tests/bindings-framework-test/XTest.framework.linkwith.cs b/tests/bindings-framework-test/XTest.framework.linkwith.cs index 17601048cd44..cfbabf346f43 100644 --- a/tests/bindings-framework-test/XTest.framework.linkwith.cs +++ b/tests/bindings-framework-test/XTest.framework.linkwith.cs @@ -10,6 +10,7 @@ [assembly: LinkWith ("XTest.framework", Frameworks = LinkWithConstants.Frameworks)] [assembly: LinkWith ("XStaticObjectTest.framework", LinkerFlags = "-lz", Frameworks = LinkWithConstants.Frameworks)] [assembly: LinkWith ("XStaticArTest.framework", Frameworks = LinkWithConstants.Frameworks)] +[assembly: LinkWith ("XCTest.xcframework", Frameworks = LinkWithConstants.Frameworks)] #endif static class LinkWithConstants diff --git a/tests/bindings-framework-test/bindings-framework-test.csproj b/tests/bindings-framework-test/bindings-framework-test.csproj index db0661a1567a..b3ab098334f1 100644 --- a/tests/bindings-framework-test/bindings-framework-test.csproj +++ b/tests/bindings-framework-test/bindings-framework-test.csproj @@ -63,6 +63,9 @@ XStaticArTest.framework + + XCTest.xcframework + diff --git a/tests/test-libraries/Makefile b/tests/test-libraries/Makefile index eb1b9b7a84db..a4ac1524bb22 100644 --- a/tests/test-libraries/Makefile +++ b/tests/test-libraries/Makefile @@ -150,6 +150,38 @@ $(eval $(call LibTemplate,arm64+x86_64,.libs/tvos/libtest.arm64.o,.libs/tvos/lib $(eval $(call LibTemplate,armv7k+x86,.libs/watchos/libtest.armv7k.o,.libs/watchos/libtest.x86.o,watchos,WATCHOS)) + +define XCTemplate +.libs/by-platform/$(1)/XCTest.framework/XCTest: $(foreach arch,$(3),.libs/$(2)/libtest$(4).$(arch).dylib) | .libs/by-platform/$(1)/XCTest.framework + $$(call Q_2,LIPO [$(1)]) $(XCODE_DEVELOPER_ROOT)/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo $$^ -create -output $$@ + +.libs/by-platform/$(1)/XCTest.framework/Info.plist: XTest-Info.plist | .libs/by-platform/$(1)/XCTest.framework + $$(Q) $(CP) $$^ $$@ + +.libs/by-platform/$(1)/XCTest.framework: + $$(Q) mkdir -p $$@ + +XTEST_XCFRAMEWORKS += .libs/by-platform/$(1)/XCTest.framework +XTEST_XCTARGETS += \ + .libs/by-platform/$(1)/XCTest.framework/XCTest \ + .libs/by-platform/$(1)/XCTest.framework/Info.plist \ + +endef + +$(eval $(call XCTemplate,iphoneos,ios,armv7 armv7s arm64,-dev)) +$(eval $(call XCTemplate,iphonesimulator,ios,i386 x86_64,-sim)) +$(eval $(call XCTemplate,appletv,tvos,arm64,-dev)) +$(eval $(call XCTemplate,appletvsimulator,tvos,x86_64,-sim)) +$(eval $(call XCTemplate,watchos,watchos,armv7k arm64_32,-dev)) +$(eval $(call XCTemplate,watchsimulator,watchos,i386,-sim)) +$(eval $(call XCTemplate,macos,macos,x86_64,-sim)) + +.libs/XCTest.xcframework: $(XTEST_XCTARGETS) Makefile + $(Q) rm -rf $@ + $(Q_GEN) $(XCODE_DEVELOPER_ROOT)/usr/bin/xcodebuild -quiet -create-xcframework $(foreach fw,$(XTEST_XCFRAMEWORKS),-framework $(fw)) -output $@ + +all-local:: .libs/XCTest.xcframework + # Xamarin.Mac MAC_CLANG = DEVELOPER_DIR=$(XCODE_DEVELOPER_ROOT) $(MAC_CC) diff --git a/tools/common/Assembly.cs b/tools/common/Assembly.cs index 0627c019f243..23bbb4baf9d1 100644 --- a/tools/common/Assembly.cs +++ b/tools/common/Assembly.cs @@ -262,6 +262,10 @@ void ProcessLinkWithAttributes (AssemblyDefinition assembly) AssertiOSVersionSupportsUserFrameworks (linkWith.LibraryName); Frameworks.Add (ExtractFramework (assembly, metadata)); + } else if (linkWith.LibraryName.EndsWith (".xcframework", StringComparison.OrdinalIgnoreCase)) { + AssertXcodeVersioSupportXCFrameworks (linkWith.LibraryName); + var xcframework = ExtractFramework (assembly, metadata); + Frameworks.UnionWith (SelectFrameworks (xcframework)); } else { LinkWith.Add (ExtractNativeLibrary (assembly, metadata)); } @@ -269,6 +273,74 @@ void ProcessLinkWithAttributes (AssemblyDefinition assembly) } } + IEnumerable SelectFrameworks (string xcframework) + { + var info_plist = Path.Combine (xcframework, "Info.plist"); + if (!File.Exists (info_plist)) + throw ErrorHelper.CreateError (9999, "The binding library '{0}' contains an invalid cross-platform user framework ({1}): could not find an Info.plist.", FileName, Path.GetFileName (xcframework)); + + var plist = Driver.FromPList (info_plist); + var version_string = (Xamarin.MacDev.PString) plist ["XCFrameworkFormatVersion"]; + var package_type = (Xamarin.MacDev.PString) plist ["CFBundlePackageType"]; + if (!Version.TryParse (version_string.Value, out var format_version)) { + throw ErrorHelper.CreateError (9999, "The binding library '{0}' contains a cross-platform user framework ({1}) whose format version could not be parsed ({2}).", FileName, Path.GetFileName (xcframework), version_string.Value); + } else if (format_version > new Version (1, 0)) { + throw ErrorHelper.CreateError (9999, "The binding library '{0}' contains a cross-platform user framework ({1}) whose format version is higher than expected (excepted v1.0 or earlier, found {2}).", FileName, Path.GetFileName (xcframework), version_string.Value); + } + + if (package_type.Value != "XFWK") + throw ErrorHelper.CreateError (9999, "The binding library '{0}' contains a cross-platform user framework ({1}) of unknown package type (expected 'XFWK', found{2}).", FileName, Path.GetFileName (xcframework), package_type.Value); + + var libraries = plist.GetArray ("AvailableLibraries"); + var platform = string.Empty; + var platform_variant = string.Empty; + switch (App.Platform) { + case ApplePlatform.iOS: + platform = "ios"; + break; + case ApplePlatform.TVOS: + platform = "tvos"; + break; + case ApplePlatform.WatchOS: + platform = "watchos"; + break; + case ApplePlatform.MacOSX: + platform = "macos"; + break; + default: + throw ErrorHelper.CreateError (71, "Unknown platform: {0}. This usually indicates a bug in {1}; please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new with a test case.", App.Platform, App.SdkVersion); + } +#if MTOUCH + if (App.IsSimulatorBuild) + platform_variant = "simulator"; +#endif + foreach (var entry in libraries) { + var entry_dict = (Xamarin.MacDev.PDictionary) entry; + var supported_platform = (Xamarin.MacDev.PString) entry_dict ["SupportedPlatform"]; + if (supported_platform.Value != platform) + continue; + entry_dict.TryGetValue ("SupportedPlatformVariant", out var supported_platform_variant); + if (platform_variant != supported_platform_variant?.Value) + continue; + + var architectures = (Xamarin.MacDev.PArray) entry_dict ["SupportedArchitectures"]; + foreach (var arch in architectures) { + var str_arch = ((Xamarin.MacDev.PString) arch).Value; + if (!Enum.TryParse (str_arch, true, out var abi)) { + ErrorHelper.Warning (9999, "Unknown architecture in xcframework: {0}", str_arch); + continue; + } + + if (!App.IsArchEnabled (abi)) + continue; + + var library_identifier = (Xamarin.MacDev.PString) entry_dict ["LibraryIdentifier"]; + var library_path = (Xamarin.MacDev.PString) entry_dict ["LibraryPath"]; + yield return Path.Combine (xcframework, library_identifier.Value, library_path); + } + } + } + void AssertiOSVersionSupportsUserFrameworks (string path) { #if MONOTOUCH @@ -279,6 +351,13 @@ void AssertiOSVersionSupportsUserFrameworks (string path) #endif } + void AssertXcodeVersioSupportXCFrameworks (string path) + { + if (Driver.XcodeVersion.Major >= 11) + return; + throw ErrorHelper.CreateError (9999, "The binding library '{0}' contains a cross-platform user framework ({1}), but the current version of Xcode doesn't support cross-platform user frameworks. Please upgrade to Xcode 11 or later.", FileName, Path.GetFileName (path)); + } + void ProcessNativeReferenceOptions (NativeReferenceMetadata metadata) { // We can't add -dead_strip if there are any LinkWith attributes where smart linking is disabled. diff --git a/tools/common/CompilerFlags.cs b/tools/common/CompilerFlags.cs index 9bc3feb65f50..5122212779e0 100644 --- a/tools/common/CompilerFlags.cs +++ b/tools/common/CompilerFlags.cs @@ -193,7 +193,7 @@ public void Prepare () WeakFrameworks = new HashSet (); foreach (var fwk in Frameworks) { - if (!fwk.EndsWith (".framework", StringComparison.Ordinal)) { + if (!fwk.EndsWith (".framework", StringComparison.OrdinalIgnoreCase) && !fwk.EndsWith (".xcframework", StringComparison.OrdinalIgnoreCase)) { var add_to = WeakFrameworks; var framework = Driver.GetFrameworks (Application).Find (fwk); if (framework != null) { @@ -308,7 +308,7 @@ void ProcessFrameworksForArguments (StringBuilder args) void ProcessFrameworkForArguments (StringBuilder args, string fw, bool is_weak, ref bool any_user_framework) { var name = Path.GetFileNameWithoutExtension (fw); - if (fw.EndsWith (".framework", StringComparison.Ordinal)) { + if (fw.EndsWith (".framework", StringComparison.OrdinalIgnoreCase)) { // user framework, we need to pass -F to the linker so that the linker finds the user framework. any_user_framework = true; AddInput (Path.Combine (fw, name));