diff --git a/src/bgen/BindingTouch.cs b/src/bgen/BindingTouch.cs index 1e437fe097..d3a9aece57 100644 --- a/src/bgen/BindingTouch.cs +++ b/src/bgen/BindingTouch.cs @@ -42,7 +42,6 @@ using Xamarin.Bundler; using Xamarin.Utils; public class BindingTouch : IDisposable { - TargetFramework? target_framework; #if NET public static ApplePlatform [] AllPlatforms = new ApplePlatform [] { ApplePlatform.iOS, ApplePlatform.MacOSX, ApplePlatform.TVOS, ApplePlatform.MacCatalyst }; public static PlatformName [] AllPlatformNames = new PlatformName [] { PlatformName.iOS, PlatformName.MacOSX, PlatformName.TvOS, PlatformName.MacCatalyst }; @@ -52,7 +51,6 @@ public class BindingTouch : IDisposable { #endif public PlatformName CurrentPlatform; public bool BindThirdPartyLibrary = true; - public bool skipSystemDrawing; public string? outfile; #if !NET @@ -60,12 +58,8 @@ public class BindingTouch : IDisposable { #endif string compiler = string.Empty; string []? compile_command = null; - string? baselibdll; - string? attributedll; string compiled_api_definition_assembly = string.Empty; bool noNFloatUsing; - - List libs = new List (); List references = new List (); public MetadataLoadContext? universe; @@ -82,11 +76,15 @@ public class BindingTouch : IDisposable { TypeCache? typeCache; public TypeCache TypeCache => typeCache!; + public LibraryManager LibraryManager = new (); bool disposedValue; + LibraryInfo? libraryInfo; + public LibraryInfo LibraryInfo => libraryInfo!; + public TargetFramework TargetFramework { - get { return target_framework!.Value; } + get { return LibraryInfo.TargetFramework; } } public static string ToolName { @@ -115,86 +113,6 @@ public class BindingTouch : IDisposable { } } - string GetAttributeLibraryPath () - { - if (!string.IsNullOrEmpty (attributedll)) - return attributedll!; - - if (IsDotNet) - return CurrentPlatform.GetPath ("lib", "Xamarin.Apple.BindingAttributes.dll"); - - switch (CurrentPlatform) { - case PlatformName.iOS: - return CurrentPlatform.GetPath ("lib", "bgen", "Xamarin.iOS.BindingAttributes.dll"); - case PlatformName.WatchOS: - return CurrentPlatform.GetPath ("lib", "bgen", "Xamarin.WatchOS.BindingAttributes.dll"); - case PlatformName.TvOS: - return CurrentPlatform.GetPath ("lib", "bgen", "Xamarin.TVOS.BindingAttributes.dll"); - case PlatformName.MacCatalyst: - return CurrentPlatform.GetPath ("lib", "bgen", "Xamarin.MacCatalyst.BindingAttributes.dll"); - case PlatformName.MacOSX: - if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full) { - return CurrentPlatform.GetPath ("lib", "bgen", "Xamarin.Mac-full.BindingAttributes.dll"); - } else if (target_framework == TargetFramework.Xamarin_Mac_4_5_System) { - return CurrentPlatform.GetPath ("lib", "bgen", "Xamarin.Mac-full.BindingAttributes.dll"); - } else if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile) { - return CurrentPlatform.GetPath ("lib", "bgen", "Xamarin.Mac-mobile.BindingAttributes.dll"); - } else { - throw ErrorHelper.CreateError (1053, target_framework); - } - default: - throw new BindingException (1047, CurrentPlatform); - } - } - - IEnumerable GetLibraryDirectories () - { - if (!IsDotNet) { - switch (CurrentPlatform) { - case PlatformName.iOS: - yield return CurrentPlatform.GetPath ("lib", "mono", "Xamarin.iOS"); - break; - case PlatformName.WatchOS: - yield return CurrentPlatform.GetPath ("lib", "mono", "Xamarin.WatchOS"); - break; - case PlatformName.TvOS: - yield return CurrentPlatform.GetPath ("lib", "mono", "Xamarin.TVOS"); - break; - case PlatformName.MacCatalyst: - yield return CurrentPlatform.GetPath ("lib", "mono", "Xamarin.MacCatalyst"); - break; - case PlatformName.MacOSX: - if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full) { - yield return CurrentPlatform.GetPath ("lib", "reference", "full"); - yield return CurrentPlatform.GetPath ("lib", "mono", "4.5"); - } else if (target_framework == TargetFramework.Xamarin_Mac_4_5_System) { - yield return "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5"; - yield return CurrentPlatform.GetPath ("lib", "mono", "4.5"); - } else if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile) { - yield return CurrentPlatform.GetPath ("lib", "mono", "Xamarin.Mac"); - } else { - throw ErrorHelper.CreateError (1053, target_framework); - } - break; - default: - throw new BindingException (1047, CurrentPlatform); - } - } - foreach (var lib in libs) - yield return lib; - } - - void SetTargetFramework (string fx) - { - TargetFramework tf; - if (!TargetFramework.TryParse (fx, out tf)) - throw ErrorHelper.CreateError (68, fx); - target_framework = tf; - - if (!TargetFramework.IsValidFramework (target_framework.Value)) - throw ErrorHelper.CreateError (70, target_framework.Value, string.Join (" ", TargetFramework.ValidFrameworks.Select ((v) => v.ToString ()).ToArray ())); - } - static int Main2 (string [] args) { using var touch = new BindingTouch (); @@ -215,7 +133,7 @@ public class BindingTouch : IDisposable { { "unsafe", "Sets the unsafe flag for the build", v=> config.IsUnsafe = true }, { "core", "Use this to build product assemblies", v => BindThirdPartyLibrary = false }, { "r|reference=", "Adds a reference", v => references.Add (v) }, - { "lib=", "Adds the directory to the search path for the compiler", v => libs.Add (v) }, + { "lib=", "Adds the directory to the search path for the compiler", v => LibraryManager.Libraries.Add (v) }, { "compiler=", "Sets the compiler to use (Obsolete) ", v => compiler = v, true }, { "compile-command=", "Sets the command to execute the C# compiler (this be an executable + arguments).", v => { @@ -233,8 +151,8 @@ public class BindingTouch : IDisposable { { "x=", "Adds the specified file to the build, used after the core files are compiled", v => config.ExtraSources.Add (v) }, { "e", "Generates smaller classes that can not be subclassed (previously called 'external mode')", v => config.IsExternal = true }, { "p", "Sets private mode", v => config.IsPublicMode = false }, - { "baselib=", "Sets the base library", v => baselibdll = v }, - { "attributelib=", "Sets the attribute library", v => attributedll = v }, + { "baselib=", "Sets the base library", v => config.Baselibdll = v }, + { "attributelib=", "Sets the attribute library", v => config.Attributedll = v }, { "use-zero-copy", v=> config.UseZeroCopy = true }, { "nostdlib", "Does not reference mscorlib.dll library", l => config.OmitStandardLibrary = true }, { "no-mono-path", "Launches compiler with empty MONO_PATH", l => { }, true }, @@ -260,7 +178,7 @@ public class BindingTouch : IDisposable { }, { "unified-full-profile", "Launches compiler pointing to XM Full Profile", l => { /* no-op*/ }, true }, { "unified-mobile-profile", "Launches compiler pointing to XM Mobile Profile", l => { /* no-op*/ }, true }, - { "target-framework=", "Specify target framework to use. Always required, and the currently supported values are: 'Xamarin.iOS,v1.0', 'Xamarin.TVOS,v1.0', 'Xamarin.WatchOS,v1.0', 'XamMac,v1.0', 'Xamarin.Mac,Version=v2.0,Profile=Mobile', 'Xamarin.Mac,Version=v4.5,Profile=Full' and 'Xamarin.Mac,Version=v4.5,Profile=System')", v => SetTargetFramework (v) }, + { "target-framework=", "Specify target framework to use. Always required, and the currently supported values are: 'Xamarin.iOS,v1.0', 'Xamarin.TVOS,v1.0', 'Xamarin.WatchOS,v1.0', 'XamMac,v1.0', 'Xamarin.Mac,Version=v2.0,Profile=Mobile', 'Xamarin.Mac,Version=v4.5,Profile=Full' and 'Xamarin.Mac,Version=v4.5,Profile=System')", v => config.TargetFramework = v }, { "warnaserror:", "An optional comma-separated list of warning codes that should be reported as errors (if no warnings are specified all warnings are reported as errors).", v => { try { if (!string.IsNullOrEmpty (v)) { @@ -299,7 +217,6 @@ public class BindingTouch : IDisposable { int Main3 (string [] args) { ErrorHelper.ClearWarningLevels (); - BindingTouchConfig config = new (); OptionSet os = CreateOptionSet (config); @@ -316,84 +233,8 @@ public class BindingTouch : IDisposable { return 0; } - if (!target_framework.HasValue) - throw ErrorHelper.CreateError (86); - - switch (target_framework.Value.Platform) { - case ApplePlatform.iOS: - CurrentPlatform = PlatformName.iOS; - config.OmitStandardLibrary = true; - if (string.IsNullOrEmpty (baselibdll)) - baselibdll = CurrentPlatform.GetPath ("lib/mono/Xamarin.iOS/Xamarin.iOS.dll"); - if (!IsDotNet) { - references.Add ("Facades/System.Drawing.Common"); - ReferenceFixer.FixSDKReferences (CurrentPlatform, "lib/mono/Xamarin.iOS", references); - } - break; - case ApplePlatform.TVOS: - CurrentPlatform = PlatformName.TvOS; - config.OmitStandardLibrary = true; - if (string.IsNullOrEmpty (baselibdll)) - baselibdll = CurrentPlatform.GetPath ("lib/mono/Xamarin.TVOS/Xamarin.TVOS.dll"); - if (!IsDotNet) { - references.Add ("Facades/System.Drawing.Common"); - ReferenceFixer.FixSDKReferences (CurrentPlatform, "lib/mono/Xamarin.TVOS", references); - } - break; - case ApplePlatform.WatchOS: - CurrentPlatform = PlatformName.WatchOS; - config.OmitStandardLibrary = true; - if (string.IsNullOrEmpty (baselibdll)) - baselibdll = CurrentPlatform.GetPath ("lib/mono/Xamarin.WatchOS/Xamarin.WatchOS.dll"); - if (!IsDotNet) { - references.Add ("Facades/System.Drawing.Common"); - ReferenceFixer.FixSDKReferences (CurrentPlatform, "lib/mono/Xamarin.WatchOS", references); - } - break; - case ApplePlatform.MacCatalyst: - CurrentPlatform = PlatformName.MacCatalyst; - config.OmitStandardLibrary = true; - if (string.IsNullOrEmpty (baselibdll)) - baselibdll = CurrentPlatform.GetPath ("lib/mono/Xamarin.MacCatalyst/Xamarin.MacCatalyst.dll"); - if (!IsDotNet) { - // references.Add ("Facades/System.Drawing.Common"); - ReferenceFixer.FixSDKReferences (CurrentPlatform, "lib/mono/Xamarin.MacCatalyst", references); - } - break; - case ApplePlatform.MacOSX: - CurrentPlatform = PlatformName.MacOSX; - config.OmitStandardLibrary = true; - if (string.IsNullOrEmpty (baselibdll)) { - if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile) - baselibdll = CurrentPlatform.GetPath ("lib", "reference", "mobile", "Xamarin.Mac.dll"); - else if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full || target_framework == TargetFramework.Xamarin_Mac_4_5_System) - baselibdll = CurrentPlatform.GetPath ("lib", "reference", "full", "Xamarin.Mac.dll"); - else if (target_framework == TargetFramework.DotNet_macOS) - baselibdll = CurrentPlatform.GetPath ("lib", "mono", "Xamarin.Mac", "Xamarin.Mac.dll"); - else - throw ErrorHelper.CreateError (1053, target_framework); - } - if (target_framework == TargetFramework.Xamarin_Mac_2_0_Mobile) { - skipSystemDrawing = true; - references.Add ("Facades/System.Drawing.Common"); - ReferenceFixer.FixSDKReferences (CurrentPlatform, "lib/mono/Xamarin.Mac", references); - } else if (target_framework == TargetFramework.Xamarin_Mac_4_5_Full) { - skipSystemDrawing = true; - references.Add ("Facades/System.Drawing.Common"); - ReferenceFixer.FixSDKReferences (CurrentPlatform, "lib/mono/4.5", references); - } else if (target_framework == TargetFramework.Xamarin_Mac_4_5_System) { - skipSystemDrawing = false; - ReferenceFixer.FixSDKReferences ("/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5", references, forceSystemDrawing: true); - } else if (target_framework == TargetFramework.DotNet_macOS) { - skipSystemDrawing = false; - } else { - throw ErrorHelper.CreateError (1053, target_framework); - } - - break; - default: - throw ErrorHelper.CreateError (1053, target_framework); - } + libraryInfo = LibraryInfo.LibraryInfoBuilder.Build (references, config); + CurrentPlatform = LibraryManager.DetermineCurrentPlatform (TargetFramework.Platform); if (config.Sources.Count > 0) { config.ApiSources.Insert (0, config.Sources [0]); @@ -416,24 +257,24 @@ public class BindingTouch : IDisposable { outfile = firstApiDefinitionName + ".dll"; var refs = references.Select ((v) => "-r:" + v); - var paths = libs.Select ((v) => "-lib:" + v); + var paths = LibraryManager.Libraries.Select ((v) => "-lib:" + v); try { - var tmpass = GetCompiledApiBindingsAssembly (config.TemporaryFileDirectory, refs, config.OmitStandardLibrary, config.ApiSources, config.CoreSources, config.Defines, paths); + var tmpass = GetCompiledApiBindingsAssembly (LibraryInfo, config.TemporaryFileDirectory, refs, LibraryInfo.OmitStandardLibrary, config.ApiSources, config.CoreSources, config.Defines, paths); universe = new MetadataLoadContext ( new SearchPathsAssemblyResolver ( - GetLibraryDirectories ().ToArray (), + LibraryManager.GetLibraryDirectories (LibraryInfo, CurrentPlatform).ToArray (), references.ToArray ()), "mscorlib" ); - if (!TryLoadApi (tmpass, out Assembly? apiAssembly) || !TryLoadApi (baselibdll, out Assembly? baselib)) + if (!TryLoadApi (tmpass, out Assembly? apiAssembly) || !TryLoadApi (LibraryInfo.BaseLibDll, out Assembly? baselib)) return 1; Frameworks = new Frameworks (CurrentPlatform); // Explicitly load our attribute library so that IKVM doesn't try (and fail) to find it. - universe.LoadFromAssemblyPath (GetAttributeLibraryPath ()); + universe.LoadFromAssemblyPath (LibraryManager.GetAttributeLibraryPath (LibraryInfo, CurrentPlatform)); typeCache ??= new (universe, Frameworks, CurrentPlatform, apiAssembly, universe.CoreAssembly, baselib, BindThirdPartyLibrary); attributeManager ??= new (typeCache); @@ -479,7 +320,7 @@ public class BindingTouch : IDisposable { namespaceCache ??= new NamespaceCache ( CurrentPlatform, config.HelperClassNamespace ?? firstApiDefinitionName, - skipSystemDrawing + LibraryManager.DetermineSkipSystemDrawing (LibraryInfo.TargetFramework) ); var g = new Generator (this, api, config.IsPublicMode, config.IsExternal, config.IsDebug) { @@ -512,14 +353,14 @@ public class BindingTouch : IDisposable { cargs.AddRange (config.CoreSources); cargs.AddRange (config.ExtraSources); cargs.AddRange (refs); - cargs.Add ("-r:" + baselibdll); + cargs.Add ("-r:" + LibraryInfo.BaseLibDll); cargs.AddRange (config.Resources); - if (config.OmitStandardLibrary) { + if (LibraryInfo.OmitStandardLibrary) { cargs.Add ("-nostdlib"); cargs.Add ("-noconfig"); } - if (!string.IsNullOrEmpty (Path.GetDirectoryName (baselibdll))) - cargs.Add ("-lib:" + Path.GetDirectoryName (baselibdll)); + if (!string.IsNullOrEmpty (Path.GetDirectoryName (LibraryInfo.BaseLibDll))) + cargs.Add ("-lib:" + Path.GetDirectoryName (LibraryInfo.BaseLibDll)); AddNFloatUsing (cargs, config.TemporaryFileDirectory); @@ -532,7 +373,7 @@ public class BindingTouch : IDisposable { } // If anything is modified in this function, check if the _CompileApiDefinitions MSBuild target needs to be updated as well. - string GetCompiledApiBindingsAssembly (string tmpdir, IEnumerable refs, bool nostdlib, List api_sources, List core_sources, List defines, IEnumerable paths) + string GetCompiledApiBindingsAssembly (LibraryInfo libraryInfo, string tmpdir, IEnumerable refs, bool nostdlib, List api_sources, List core_sources, List defines, IEnumerable paths) { if (!string.IsNullOrEmpty (compiled_api_definition_assembly)) return compiled_api_definition_assembly; @@ -548,9 +389,9 @@ public class BindingTouch : IDisposable { cargs.Add ("-target:library"); cargs.Add ("-nowarn:436"); cargs.Add ("-out:" + tmpass); - cargs.Add ("-r:" + GetAttributeLibraryPath ()); + cargs.Add ("-r:" + LibraryManager.GetAttributeLibraryPath (libraryInfo, CurrentPlatform)); cargs.AddRange (refs); - cargs.Add ("-r:" + baselibdll); + cargs.Add ("-r:" + libraryInfo.BaseLibDll); foreach (var def in defines) cargs.Add ("-define:" + def); #if NET @@ -563,8 +404,8 @@ public class BindingTouch : IDisposable { } cargs.AddRange (api_sources); cargs.AddRange (core_sources); - if (!string.IsNullOrEmpty (Path.GetDirectoryName (baselibdll))) - cargs.Add ("-lib:" + Path.GetDirectoryName (baselibdll)); + if (!string.IsNullOrEmpty (Path.GetDirectoryName (libraryInfo.BaseLibDll))) + cargs.Add ("-lib:" + Path.GetDirectoryName (libraryInfo.BaseLibDll)); AddNFloatUsing (cargs, tmpdir); diff --git a/src/bgen/LibraryManager.cs b/src/bgen/LibraryManager.cs new file mode 100644 index 0000000000..951389a572 --- /dev/null +++ b/src/bgen/LibraryManager.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using ObjCRuntime; +using Xamarin.Utils; + +#nullable enable + +public class LibraryManager { + public List Libraries = new (); + public string GetAttributeLibraryPath (LibraryInfo libraryInfo, PlatformName currentPlatform) + { + if (!string.IsNullOrEmpty (libraryInfo.AttributeDll)) + return libraryInfo.AttributeDll!; + + if (libraryInfo.IsDotNet) + return currentPlatform.GetPath ("lib", "Xamarin.Apple.BindingAttributes.dll"); + + switch (currentPlatform) { + case PlatformName.iOS: + return currentPlatform.GetPath ("lib", "bgen", "Xamarin.iOS.BindingAttributes.dll"); + case PlatformName.WatchOS: + return currentPlatform.GetPath ("lib", "bgen", "Xamarin.WatchOS.BindingAttributes.dll"); + case PlatformName.TvOS: + return currentPlatform.GetPath ("lib", "bgen", "Xamarin.TVOS.BindingAttributes.dll"); + case PlatformName.MacCatalyst: + return currentPlatform.GetPath ("lib", "bgen", "Xamarin.MacCatalyst.BindingAttributes.dll"); + case PlatformName.MacOSX: + if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_4_5_Full) { + return currentPlatform.GetPath ("lib", "bgen", "Xamarin.Mac-full.BindingAttributes.dll"); + } else if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_4_5_System) { + return currentPlatform.GetPath ("lib", "bgen", "Xamarin.Mac-full.BindingAttributes.dll"); + } else if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_2_0_Mobile) { + return currentPlatform.GetPath ("lib", "bgen", "Xamarin.Mac-mobile.BindingAttributes.dll"); + } else { + throw ErrorHelper.CreateError (1053, libraryInfo.TargetFramework); + } + default: + throw new BindingException (1047, currentPlatform); + } + } + + public IEnumerable GetLibraryDirectories (LibraryInfo libraryInfo, PlatformName currentPlatform) + { + if (!libraryInfo.IsDotNet) { + switch (currentPlatform) { + case PlatformName.iOS: + yield return currentPlatform.GetPath ("lib", "mono", "Xamarin.iOS"); + break; + case PlatformName.WatchOS: + yield return currentPlatform.GetPath ("lib", "mono", "Xamarin.WatchOS"); + break; + case PlatformName.TvOS: + yield return currentPlatform.GetPath ("lib", "mono", "Xamarin.TVOS"); + break; + case PlatformName.MacCatalyst: + yield return currentPlatform.GetPath ("lib", "mono", "Xamarin.MacCatalyst"); + break; + case PlatformName.MacOSX: + if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_4_5_Full) { + yield return currentPlatform.GetPath ("lib", "reference", "full"); + yield return currentPlatform.GetPath ("lib", "mono", "4.5"); + } else if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_4_5_System) { + yield return "/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5"; + yield return currentPlatform.GetPath ("lib", "mono", "4.5"); + } else if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_2_0_Mobile) { + yield return currentPlatform.GetPath ("lib", "mono", "Xamarin.Mac"); + } else { + throw ErrorHelper.CreateError (1053, libraryInfo.TargetFramework); + } + break; + default: + throw new BindingException (1047, currentPlatform); + } + } + foreach (var lib in Libraries) + yield return lib; + } + + public static bool DetermineSkipSystemDrawing (TargetFramework targetFramework) => + targetFramework.Platform is ApplePlatform.MacOSX && + (targetFramework == TargetFramework.Xamarin_Mac_2_0_Mobile || + targetFramework == TargetFramework.Xamarin_Mac_4_5_Full); + + public static PlatformName DetermineCurrentPlatform (ApplePlatform applePlatform) + { + switch (applePlatform) { + case ApplePlatform.iOS: + return PlatformName.iOS; + case ApplePlatform.TVOS: + return PlatformName.TvOS; + case ApplePlatform.WatchOS: + return PlatformName.WatchOS; + case ApplePlatform.MacCatalyst: + return PlatformName.MacCatalyst; + case ApplePlatform.MacOSX: + return PlatformName.MacOSX; + default: + return PlatformName.None; + } + } +} + diff --git a/src/bgen/Models/BindingTouchConfig.cs b/src/bgen/Models/BindingTouchConfig.cs index 59dede67e4..f536a47a57 100644 --- a/src/bgen/Models/BindingTouchConfig.cs +++ b/src/bgen/Models/BindingTouchConfig.cs @@ -12,7 +12,7 @@ public class BindingTouchConfig { public bool IsUnsafe = true; public bool IsExternal = false; public bool IsPublicMode = true; - public bool OmitStandardLibrary = false; + public bool? OmitStandardLibrary = null; public bool? InlineSelectors = null; public List Sources = new (); public List Resources = new (); @@ -23,4 +23,7 @@ public class BindingTouchConfig { public List Defines = new (); public string? GeneratedFileList = null; public bool ProcessEnums = false; + public string? TargetFramework = null; + public string? Baselibdll = null; + public string? Attributedll = null; } diff --git a/src/bgen/Models/LibraryInfo.cs b/src/bgen/Models/LibraryInfo.cs new file mode 100644 index 0000000000..c8d2c3402d --- /dev/null +++ b/src/bgen/Models/LibraryInfo.cs @@ -0,0 +1,140 @@ +using System.Collections.Generic; +using System.Linq; +using ObjCRuntime; +using Xamarin.Utils; + +#nullable enable + +public class LibraryInfo { + private LibraryInfo () { } + public string? AttributeDll { get; set; } + public TargetFramework TargetFramework { get; set; } + public string? BaseLibDll { get; set; } + public bool OmitStandardLibrary { get; set; } + + public bool IsDotNet { + get { return TargetFramework.IsDotNet; } + } + + public static class LibraryInfoBuilder { + public static LibraryInfo Build (List refs, BindingTouchConfig config) + { + LibraryInfo libraryInfo = new (); + SetTargetFramework (config.TargetFramework, libraryInfo); + libraryInfo.OmitStandardLibrary = DetermineOmitStdLibrary (config.OmitStandardLibrary, libraryInfo.TargetFramework.Platform); + libraryInfo.BaseLibDll = DetermineBaseLibDll (libraryInfo.TargetFramework, config.Baselibdll); + libraryInfo.AttributeDll = config.Attributedll; + AddAndFixReferences (libraryInfo, refs); + return libraryInfo; + } + + static void SetTargetFramework (string? fx, LibraryInfo libraryInfo) + { + if (fx is null) + throw ErrorHelper.CreateError (86); + TargetFramework tf; + if (!TargetFramework.TryParse (fx, out tf)) + throw ErrorHelper.CreateError (68, fx); + + if (!TargetFramework.IsValidFramework (tf)) + throw ErrorHelper.CreateError (70, tf, + string.Join (" ", TargetFramework.ValidFrameworks.Select ((v) => v.ToString ()).ToArray ())); + + libraryInfo.TargetFramework = tf; + } + + static bool DetermineOmitStdLibrary (bool? omitStandardLibary, ApplePlatform currentPlatform) + { + if (omitStandardLibary is not null) + return (bool) omitStandardLibary; + + switch (currentPlatform) { + case ApplePlatform.iOS: + case ApplePlatform.TVOS: + case ApplePlatform.WatchOS: + case ApplePlatform.MacCatalyst: + case ApplePlatform.MacOSX: + return true; + default: + throw ErrorHelper.CreateError (1053, currentPlatform); + } + } + + static string? DetermineBaseLibDll (TargetFramework TargetFramework, string? baselibdll) + { + if (!string.IsNullOrEmpty (baselibdll)) + return baselibdll; + + PlatformName currentPlatform = LibraryManager.DetermineCurrentPlatform (TargetFramework.Platform); + switch (currentPlatform) { + case PlatformName.iOS: + return currentPlatform.GetPath ("lib/mono/Xamarin.iOS/Xamarin.iOS.dll"); + case PlatformName.TvOS: + return currentPlatform.GetPath ("lib/mono/Xamarin.TVOS/Xamarin.TVOS.dll"); + case PlatformName.WatchOS: + return currentPlatform.GetPath ("lib/mono/Xamarin.WatchOS/Xamarin.WatchOS.dll"); + case PlatformName.MacCatalyst: + return currentPlatform.GetPath ("lib/mono/Xamarin.MacCatalyst/Xamarin.MacCatalyst.dll"); + case PlatformName.MacOSX: + if (TargetFramework == TargetFramework.Xamarin_Mac_2_0_Mobile) + return currentPlatform.GetPath ("lib", "reference", "mobile", "Xamarin.Mac.dll"); + if (TargetFramework == TargetFramework.Xamarin_Mac_4_5_Full || + TargetFramework == TargetFramework.Xamarin_Mac_4_5_System) + return currentPlatform.GetPath ("lib", "reference", "full", "Xamarin.Mac.dll"); + if (TargetFramework == TargetFramework.DotNet_macOS) + return currentPlatform.GetPath ("lib", "mono", "Xamarin.Mac", "Xamarin.Mac.dll"); + throw ErrorHelper.CreateError (1053, TargetFramework); + default: + throw ErrorHelper.CreateError (1053, TargetFramework); + } + } + + static void AddAndFixReferences (LibraryInfo libraryInfo, List references) + { + PlatformName currentPlatform = LibraryManager.DetermineCurrentPlatform (libraryInfo.TargetFramework.Platform); + switch (libraryInfo.TargetFramework.Platform) { + case ApplePlatform.iOS: + if (!libraryInfo.IsDotNet) { + references.Add ("Facades/System.Drawing.Common"); + ReferenceFixer.FixSDKReferences (currentPlatform, "lib/mono/Xamarin.iOS", references); + } + break; + case ApplePlatform.TVOS: + if (!libraryInfo.IsDotNet) { + references.Add ("Facades/System.Drawing.Common"); + ReferenceFixer.FixSDKReferences (currentPlatform, "lib/mono/Xamarin.TVOS", references); + } + break; + case ApplePlatform.WatchOS: + if (!libraryInfo.IsDotNet) { + references.Add ("Facades/System.Drawing.Common"); + ReferenceFixer.FixSDKReferences (currentPlatform, "lib/mono/Xamarin.WatchOS", references); + } + break; + case ApplePlatform.MacCatalyst: + if (!libraryInfo.IsDotNet) { + ReferenceFixer.FixSDKReferences (currentPlatform, "lib/mono/Xamarin.MacCatalyst", references); + } + break; + case ApplePlatform.MacOSX: + if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_2_0_Mobile) { + references.Add ("Facades/System.Drawing.Common"); + ReferenceFixer.FixSDKReferences (currentPlatform, "lib/mono/Xamarin.Mac", references); + } else if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_4_5_Full) { + references.Add ("Facades/System.Drawing.Common"); + ReferenceFixer.FixSDKReferences (currentPlatform, "lib/mono/4.5", references); + } else if (libraryInfo.TargetFramework == TargetFramework.Xamarin_Mac_4_5_System) { + ReferenceFixer.FixSDKReferences ("/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5", + references, forceSystemDrawing: true); + } else if (libraryInfo.TargetFramework == TargetFramework.DotNet_macOS) { + // Do nothing + } else { + throw ErrorHelper.CreateError (1053, libraryInfo.TargetFramework); + } + break; + default: + throw ErrorHelper.CreateError (1053, libraryInfo.TargetFramework); + } + } + } +} diff --git a/src/generator.csproj b/src/generator.csproj index 1ea167b0d4..9405776086 100644 --- a/src/generator.csproj +++ b/src/generator.csproj @@ -111,6 +111,7 @@ + @@ -159,6 +160,7 @@ +