public void InitializeCommon() { SelectRegistrar(); SelectMonoNative(); RuntimeOptions = RuntimeOptions.Create(this, HttpMessageHandler, TlsProvider); if (RequiresXcodeHeaders && SdkVersion < SdkVersions.GetVersion(Platform)) { throw ErrorHelper.CreateError(91, Errors.MX0091, ProductName, PlatformName, SdkVersions.GetVersion(Platform), SdkVersions.Xcode, Error91LinkerSuggestion); } if (DeploymentTarget != null) { if (DeploymentTarget < Xamarin.SdkVersions.GetMinVersion(Platform)) { throw new ProductException(73, true, Errors.MT0073, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetMinVersion(Platform), PlatformName, ProductName); } if (DeploymentTarget > Xamarin.SdkVersions.GetVersion(Platform)) { throw new ProductException(74, true, Errors.MX0074, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetVersion(Platform), PlatformName, ProductName); } } if (Platform == ApplePlatform.WatchOS && EnableCoopGC.HasValue && !EnableCoopGC.Value) { throw ErrorHelper.CreateError(88, Errors.MT0088); } if (!EnableCoopGC.HasValue) { EnableCoopGC = Platform == ApplePlatform.WatchOS; } if (EnableCoopGC.Value) { switch (MarshalObjectiveCExceptions) { case MarshalObjectiveCExceptionMode.UnwindManagedCode: case MarshalObjectiveCExceptionMode.Disable: throw ErrorHelper.CreateError(89, Errors.MT0089, "--marshal-objectivec-exceptions", MarshalObjectiveCExceptions.ToString().ToLowerInvariant()); } switch (MarshalManagedExceptions) { case MarshalManagedExceptionMode.UnwindNativeCode: case MarshalManagedExceptionMode.Disable: throw ErrorHelper.CreateError(89, Errors.MT0089, "--marshal-managed-exceptions", MarshalManagedExceptions.ToString().ToLowerInvariant()); } } bool isSimulatorOrDesktopDebug = EnableDebug; #if MTOUCH isSimulatorOrDesktopDebug &= IsSimulatorBuild; #endif if (MarshalObjectiveCExceptions == MarshalObjectiveCExceptionMode.Default) { if (EnableCoopGC.Value || (Platform == ApplePlatform.MacOSX && EnableDebug)) { MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.ThrowManagedException; } else { MarshalObjectiveCExceptions = isSimulatorOrDesktopDebug ? MarshalObjectiveCExceptionMode.UnwindManagedCode : MarshalObjectiveCExceptionMode.Disable; } } if (MarshalManagedExceptions == MarshalManagedExceptionMode.Default) { if (EnableCoopGC.Value) { MarshalManagedExceptions = MarshalManagedExceptionMode.ThrowObjectiveCException; } else { MarshalManagedExceptions = isSimulatorOrDesktopDebug ? MarshalManagedExceptionMode.UnwindNativeCode : MarshalManagedExceptionMode.Disable; } IsDefaultMarshalManagedExceptionMode = true; } if (SymbolMode == SymbolMode.Default) { #if MONOTOUCH SymbolMode = EnableBitCode ? SymbolMode.Code : SymbolMode.Linker; #else SymbolMode = SymbolMode.Linker; #endif } #if MONOTOUCH if (EnableBitCode && SymbolMode != SymbolMode.Code) { // This is a warning because: // * The user will get a linker error anyway if they do this. // * I see it as quite unlikely that anybody will in fact try this (it must be manually set in the additional mtouch arguments). // * I find it more probable that Apple will remove the -u restriction, in which case someone might actually want to try this, and if it's a warning, we won't prevent it. ErrorHelper.Warning(115, Errors.MT0115); } #endif if (!DebugTrack.HasValue) { DebugTrack = false; } else if (DebugTrack.Value && !EnableDebug) { ErrorHelper.Warning(32, Errors.MT0032); } if (!package_managed_debug_symbols.HasValue) { package_managed_debug_symbols = EnableDebug; } else if (package_managed_debug_symbols.Value && IsLLVM) { ErrorHelper.Warning(3007, Errors.MX3007); } Optimizations.Initialize(this); }
public void RunRegistrar() { // The static registrar. if (Registrar != RegistrarMode.Static) { throw new ProductException(67, Errors.MT0067, Registrar); // this is only called during our own build } if (RootAssemblies.Count < 1) { throw ErrorHelper.CreateError(130, Errors.MX0130); } var registrar_m = RegistrarOutputLibrary; var RootAssembly = RootAssemblies [0]; var resolvedAssemblies = new Dictionary <string, AssemblyDefinition> (); var resolver = new PlatformResolver() { RootDirectory = Path.GetDirectoryName(RootAssembly), #if MMP CommandLineAssemblies = RootAssemblies, #endif }; if (Platform == ApplePlatform.iOS) { if (Is32Build) { resolver.ArchDirectory = Driver.GetArch32Directory(this); } else { resolver.ArchDirectory = Driver.GetArch64Directory(this); } } var ps = new ReaderParameters(); ps.AssemblyResolver = resolver; foreach (var reference in References) { var r = resolver.Load(reference); if (r == null) { throw ErrorHelper.CreateError(2002, Errors.MT2002, reference); } } var productAssembly = Driver.GetProductAssembly(this); bool foundProductAssembly = false; foreach (var asm in RootAssemblies) { var rootName = Path.GetFileNameWithoutExtension(asm); if (rootName == productAssembly) { foundProductAssembly = true; } try { AssemblyDefinition lastAssembly = ps.AssemblyResolver.Resolve(AssemblyNameReference.Parse(rootName), new ReaderParameters()); if (lastAssembly == null) { ErrorHelper.CreateWarning(7, Errors.MX0007, rootName); continue; } if (resolvedAssemblies.TryGetValue(rootName, out var previousAssembly)) { if (lastAssembly.MainModule.RuntimeVersion != previousAssembly.MainModule.RuntimeVersion) { Driver.Log(2, "Attemping to load an assembly another time {0} (previous {1})", lastAssembly.FullName, previousAssembly.FullName); } continue; } resolvedAssemblies.Add(rootName, lastAssembly); Driver.Log(3, "Loaded {0}", lastAssembly.MainModule.FileName); } catch (Exception ex) { ErrorHelper.Warning(9, ex, Errors.MX0009, $"{rootName}: {ex.Message}"); continue; } } if (!foundProductAssembly) { throw ErrorHelper.CreateError(131, Errors.MX0131, productAssembly, string.Join("', '", RootAssemblies.ToArray())); } #if MONOTOUCH if (SelectAbis(Abis, Abi.SimulatorArchMask).Count > 0) { BuildTarget = BuildTarget.Simulator; } else if (SelectAbis(Abis, Abi.DeviceArchMask).Count > 0) { BuildTarget = BuildTarget.Device; } else { throw ErrorHelper.CreateError(99, Errors.MX0099, "No valid ABI"); } #endif var registrar = new Registrar.StaticRegistrar(this); if (RootAssemblies.Count == 1) { registrar.GenerateSingleAssembly(resolvedAssemblies.Values, Path.ChangeExtension(registrar_m, "h"), registrar_m, Path.GetFileNameWithoutExtension(RootAssembly)); } else { registrar.Generate(resolvedAssemblies.Values, Path.ChangeExtension(registrar_m, "h"), registrar_m); } }
public void InitializeCommon() { Namespaces.Initialize(); SelectRegistrar(); foreach (var target in Targets) { target.SelectMonoNative(); } if (RequiresXcodeHeaders && SdkVersion < SdkVersions.GetVersion(Platform)) { throw ErrorHelper.CreateError(91, "This version of {0} requires the {1} {2} SDK (shipped with Xcode {3}). Either upgrade Xcode to get the required header files or {4} (to try to avoid the new APIs).", ProductName, PlatformName, SdkVersions.GetVersion(Platform), SdkVersions.Xcode, Error91LinkerSuggestion); } if (DeploymentTarget != null) { if (DeploymentTarget < Xamarin.SdkVersions.GetMinVersion(Platform)) { throw new PlatformException(73, true, "{4} {0} does not support a deployment target of {1} for {3} (the minimum is {2}). Please select a newer deployment target in your project's Info.plist.", Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetMinVersion(Platform), PlatformName, ProductName); } if (DeploymentTarget > Xamarin.SdkVersions.GetTargetVersion(Platform)) { throw new PlatformException(74, true, "{4} {0} does not support a deployment target of {1} for {3} (the maximum is {2}). Please select an older deployment target in your project's Info.plist or upgrade to a newer version of {4}.", Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetVersion(Platform), PlatformName, ProductName); } } if (Platform == ApplePlatform.WatchOS && EnableCoopGC.HasValue && !EnableCoopGC.Value) { throw ErrorHelper.CreateError(88, "The GC must be in cooperative mode for watchOS apps. Please remove the --coop:false argument to mtouch."); } if (!EnableCoopGC.HasValue) { EnableCoopGC = Platform == ApplePlatform.WatchOS; } if (EnableCoopGC.Value) { switch (MarshalObjectiveCExceptions) { case MarshalObjectiveCExceptionMode.UnwindManagedCode: case MarshalObjectiveCExceptionMode.Disable: throw ErrorHelper.CreateError(89, "The option '{0}' cannot take the value '{1}' when cooperative mode is enabled for the GC.", "--marshal-objectivec-exceptions", MarshalObjectiveCExceptions.ToString().ToLowerInvariant()); } switch (MarshalManagedExceptions) { case MarshalManagedExceptionMode.UnwindNativeCode: case MarshalManagedExceptionMode.Disable: throw ErrorHelper.CreateError(89, "The option '{0}' cannot take the value '{1}' when cooperative mode is enabled for the GC.", "--marshal-managed-exceptions", MarshalManagedExceptions.ToString().ToLowerInvariant()); } } bool isSimulatorOrDesktopDebug = EnableDebug; #if MTOUCH isSimulatorOrDesktopDebug &= IsSimulatorBuild; #endif if (MarshalObjectiveCExceptions == MarshalObjectiveCExceptionMode.Default) { if (EnableCoopGC.Value || (Platform == ApplePlatform.MacOSX && EnableDebug)) { MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.ThrowManagedException; } else { MarshalObjectiveCExceptions = isSimulatorOrDesktopDebug ? MarshalObjectiveCExceptionMode.UnwindManagedCode : MarshalObjectiveCExceptionMode.Disable; } } if (MarshalManagedExceptions == MarshalManagedExceptionMode.Default) { if (EnableCoopGC.Value) { MarshalManagedExceptions = MarshalManagedExceptionMode.ThrowObjectiveCException; } else { MarshalManagedExceptions = isSimulatorOrDesktopDebug ? MarshalManagedExceptionMode.UnwindNativeCode : MarshalManagedExceptionMode.Disable; } IsDefaultMarshalManagedExceptionMode = true; } if (SymbolMode == SymbolMode.Default) { #if MONOTOUCH SymbolMode = EnableBitCode ? SymbolMode.Code : SymbolMode.Linker; #else SymbolMode = SymbolMode.Linker; #endif } #if MONOTOUCH if (EnableBitCode && SymbolMode != SymbolMode.Code) { // This is a warning because: // * The user will get a linker error anyway if they do this. // * I see it as quite unlikely that anybody will in fact try this (it must be manually set in the additional mtouch arguments). // * I find it more probable that Apple will remove the -u restriction, in which case someone might actually want to try this, and if it's a warning, we won't prevent it. ErrorHelper.Warning(115, "It is recommended to reference dynamic symbols using code (--dynamic-symbol-mode=code) when bitcode is enabled."); } #endif Optimizations.Initialize(this); }
public void RunRegistrar() { // The static registrar. if (Registrar != RegistrarMode.Static) { throw new PlatformException(67, "Invalid registrar: {0}", Registrar); // this is only called during our own build } if (RootAssemblies.Count < 1) { throw ErrorHelper.CreateError(130, "No root assemblies found. You should provide at least one root assembly."); } var registrar_m = RegistrarOutputLibrary; var RootAssembly = RootAssemblies [0]; var resolvedAssemblies = new Dictionary <string, AssemblyDefinition> (); var resolver = new PlatformResolver() { FrameworkDirectory = Driver.GetPlatformFrameworkDirectory(this), RootDirectory = Path.GetDirectoryName(RootAssembly), #if MMP CommandLineAssemblies = RootAssemblies, #endif }; if (Platform == ApplePlatform.iOS || Platform == ApplePlatform.MacOSX) { if (Is32Build) { resolver.ArchDirectory = Driver.GetArch32Directory(this); } else { resolver.ArchDirectory = Driver.GetArch64Directory(this); } } var ps = new ReaderParameters(); ps.AssemblyResolver = resolver; resolvedAssemblies.Add("mscorlib", ps.AssemblyResolver.Resolve(AssemblyNameReference.Parse("mscorlib"), new ReaderParameters())); var productAssembly = Driver.GetProductAssembly(this); bool foundProductAssembly = false; foreach (var asm in RootAssemblies) { var rootName = Path.GetFileNameWithoutExtension(asm); if (rootName == productAssembly) { foundProductAssembly = true; } try { AssemblyDefinition lastAssembly = ps.AssemblyResolver.Resolve(AssemblyNameReference.Parse(rootName), new ReaderParameters()); if (lastAssembly == null) { ErrorHelper.CreateWarning(7, "The root assembly '{0}' does not exist", rootName); continue; } if (resolvedAssemblies.TryGetValue(rootName, out var previousAssembly)) { if (lastAssembly.MainModule.RuntimeVersion != previousAssembly.MainModule.RuntimeVersion) { Driver.Log(2, "Attemping to load an assembly another time {0} (previous {1})", lastAssembly.FullName, previousAssembly.FullName); } continue; } resolvedAssemblies.Add(rootName, lastAssembly); Driver.Log(3, "Loaded {0}", lastAssembly.MainModule.FileName); } catch (Exception ex) { ErrorHelper.Warning(9, ex, "Error while loading assemblies: {0}: {1}", rootName, ex.Message); continue; } } if (!foundProductAssembly) { throw ErrorHelper.CreateError(131, "Product assembly '{0}' not found in assembly list: '{1}'", productAssembly, string.Join("', '", RootAssemblies.ToArray())); } #if MONOTOUCH BuildTarget = BuildTarget.Simulator; #endif var registrar = new Registrar.StaticRegistrar(this); if (RootAssemblies.Count == 1) { registrar.GenerateSingleAssembly(resolvedAssemblies.Values, Path.ChangeExtension(registrar_m, "h"), registrar_m, Path.GetFileNameWithoutExtension(RootAssembly)); } else { registrar.Generate(resolvedAssemblies.Values, Path.ChangeExtension(registrar_m, "h"), registrar_m); } }
public void GatherFrameworks() { Assembly asm = null; AssemblyDefinition productAssembly = null; foreach (var assembly in Assemblies) { if (assembly.AssemblyDefinition.Name.Name == Driver.GetProductAssembly(App)) { asm = assembly; break; } } productAssembly = asm.AssemblyDefinition; // *** make sure any change in the above lists (or new list) are also reflected in // *** Makefile so simlauncher-sgen does not miss any framework HashSet <string> processed = new HashSet <string> (); #if !MONOMAC Version v80 = new Version(8, 0); #endif foreach (ModuleDefinition md in productAssembly.Modules) { foreach (TypeDefinition td in md.Types) { // process only once each namespace (as we keep adding logic below) string nspace = td.Namespace; if (processed.Contains(nspace)) { continue; } processed.Add(nspace); Framework framework; if (Driver.GetFrameworks(App).TryGetValue(nspace, out framework)) { // framework specific processing #if !MONOMAC switch (framework.Name) { case "CoreAudioKit": // CoreAudioKit seems to be functional in the iOS 9 simulator. if (App.IsSimulatorBuild && App.SdkVersion.Major < 9) { continue; } break; case "Metal": case "MetalKit": case "MetalPerformanceShaders": // some frameworks do not exists on simulators and will result in linker errors if we include them if (App.IsSimulatorBuild) { continue; } break; case "PushKit": // in Xcode 6 beta 7 this became an (ld) error - it was a warning earlier :( // ld: embedded dylibs/frameworks are only supported on iOS 8.0 and later (@rpath/PushKit.framework/PushKit) for architecture armv7 // this was fixed in Xcode 6.2 (6.1 was still buggy) see #29786 if ((App.DeploymentTarget < v80) && (Driver.XcodeVersion < new Version(6, 2))) { ErrorHelper.Warning(49, "{0}.framework is supported only if deployment target is 8.0 or later. {0} features might not work correctly.", framework.Name); continue; } break; } #endif if (App.SdkVersion >= framework.Version) { var add_to = App.DeploymentTarget >= framework.Version ? asm.Frameworks : asm.WeakFrameworks; add_to.Add(framework.Name); continue; } } } } // Make sure there are no duplicates between frameworks and weak frameworks. // Keep the weak ones. asm.Frameworks.ExceptWith(asm.WeakFrameworks); }
public void CollectAllSymbols() { if (dynamic_symbols != null) { return; } var cache_location = Path.Combine(App.Cache.Location, "entry-points.txt"); if (cached_link) { dynamic_symbols = new Symbols(); dynamic_symbols.Load(cache_location, this); } else { if (LinkContext == null) { // This happens when using the simlauncher and the msbuild tasks asked for a list // of symbols (--symbollist). In that case just produce an empty list, since the // binary shouldn't end up stripped anyway. dynamic_symbols = new Symbols(); } else { dynamic_symbols = LinkContext.RequiredSymbols; } // keep the debugging helper in debugging binaries only var has_mono_pmip = App.EnableDebug; #if MMP has_mono_pmip &= !Driver.IsUnifiedFullSystemFramework; #endif if (has_mono_pmip) { dynamic_symbols.AddFunction("mono_pmip"); } bool has_dyn_msgSend; #if MONOTOUCH has_dyn_msgSend = App.IsSimulatorBuild; #else has_dyn_msgSend = App.MarshalObjectiveCExceptions != MarshalObjectiveCExceptionMode.Disable && !App.RequiresPInvokeWrappers && Is64Build; #endif if (has_dyn_msgSend) { dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSend"); dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSendSuper"); dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSend_stret"); dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSendSuper_stret"); } dynamic_symbols.Save(cache_location); } foreach (var name in App.IgnoredSymbols) { var symbol = dynamic_symbols.Find(name); if (symbol == null) { ErrorHelper.Warning(5218, $"Can't ignore the dynamic symbol {Driver.Quote (name)} (--ignore-dynamic-symbol={Driver.Quote (name)}) because it was not detected as a dynamic symbol."); } else { symbol.Ignore = true; } } }
public void Initialize(Application app) { // warn if the user asked to optimize something when the optimization can't be applied for (int i = 0; i < values.Length; i++) { if (!values [i].HasValue) { continue; } switch ((Opt)i) { case Opt.StaticBlockToDelegateLookup: if (app.Registrar != RegistrarMode.Static) { ErrorHelper.Warning(2003, $"Option '--optimize={(values [i].Value ? "" : "-")}{opt_names [i]}' will be ignored since the static registrar is not enabled"); values [i] = false; continue; } break; // does not require the linker case Opt.TrimArchitectures: break; // Does not require linker case Opt.RegisterProtocols: case Opt.RemoveDynamicRegistrar: if (app.Registrar != RegistrarMode.Static) { ErrorHelper.Warning(2003, $"Option '--optimize={(values [i].Value ? "" : "-")}{opt_names [i]}' will be ignored since the static registrar is not enabled"); values [i] = false; continue; } goto default; // also requires the linker #if MONOTOUCH case Opt.RemoveUnsupportedILForBitcode: if (app.Platform != Utils.ApplePlatform.WatchOS) { if (!all.HasValue) // Don't show this warning if it was enabled with --optimize=all { ErrorHelper.Warning(2003, $"Option '--optimize={opt_names [(int) Opt.RemoveUnsupportedILForBitcode]}' will be ignored since it's only applicable to watchOS."); } values [i] = false; } break; #endif default: if (app.LinkMode == LinkMode.None) { ErrorHelper.Warning(2003, $"Option '--optimize={(values [i].Value ? "" : "-")}{opt_names [i]}' will be ignored since linking is disabled"); values [i] = false; } break; } } // by default we keep the code to ensure we're executing on the UI thread (for UI code) for debug builds // but this can be overridden to either (a) remove it from debug builds or (b) keep it in release builds if (!RemoveUIThreadChecks.HasValue) { RemoveUIThreadChecks = !app.EnableDebug; } // By default we always eliminate dead code. if (!DeadCodeElimination.HasValue) { DeadCodeElimination = true; } if (!InlineIsDirectBinding.HasValue) { #if MONOTOUCH // By default we always inline calls to NSObject.IsDirectBinding // unless the interpreter is enabled (we can't predict if code will be subclassed) InlineIsDirectBinding = !app.UseInterpreter; #else // NSObject.IsDirectBinding is not a safe optimization to apply to XM apps, // because there may be additional code/assemblies we don't know about at build time. InlineIsDirectBinding = false; #endif } // The default behavior for InlineIntPtrSize depends on the assembly being linked, // which means we can't set it to a global constant. It's handled in the OptimizeGeneratedCodeSubStep directly. #if MONOTOUCH // By default we always inline calls to Runtime.Arch if (!InlineRuntimeArch.HasValue) { InlineRuntimeArch = true; } #endif // We try to optimize calls to BlockLiteral.SetupBlock if the static registrar is enabled if (!OptimizeBlockLiteralSetupBlock.HasValue) { OptimizeBlockLiteralSetupBlock = app.Registrar == RegistrarMode.Static; } // We will register protocols if the static registrar is enabled and loading assemblies is not possible if (!RegisterProtocols.HasValue) { #if MONOTOUCH RegisterProtocols = (app.Registrar == RegistrarMode.Static) && !app.UseInterpreter; #else RegisterProtocols = false; #endif } else if (app.Registrar != RegistrarMode.Static && RegisterProtocols == true) { RegisterProtocols = false; // we've already shown a warning for this. } // By default we always inline calls to Runtime.DynamicRegistrationSupported if (!InlineDynamicRegistrationSupported.HasValue) { InlineDynamicRegistrationSupported = true; } // By default always enable static block-to-delegate lookup (it won't make a difference unless the static registrar is used though) if (!StaticBlockToDelegateLookup.HasValue) { StaticBlockToDelegateLookup = true; } if (!RemoveDynamicRegistrar.HasValue) { if (InlineDynamicRegistrationSupported != true) { // Can't remove the dynamic registrar unless also inlining Runtime.DynamicRegistrationSupported RemoveDynamicRegistrar = false; } else if (StaticBlockToDelegateLookup != true) { // Can't remove the dynamic registrar unless also generating static lookup of block-to-delegates in the static registrar. RemoveDynamicRegistrar = false; } else if (app.Registrar != RegistrarMode.Static || app.LinkMode == LinkMode.None) { // Both the linker and the static registrar are also required RemoveDynamicRegistrar = false; } else { #if MONOTOUCH // we can't predict is unknown (at build time) code will require registration (at runtime) if (app.UseInterpreter) { RemoveDynamicRegistrar = false; } // We don't have enough information yet to determine if we can remove the dynamic // registrar or not, so let the value stay unset until we do know (when running the linker). #else // By default disabled for XM apps RemoveDynamicRegistrar = false; #endif } } #if !MONOTOUCH // By default on macOS trim-architectures for Release and not for debug if (!TrimArchitectures.HasValue) { TrimArchitectures = !app.EnableDebug; } #endif #if MONOTOUCH if (!RemoveUnsupportedILForBitcode.HasValue) { // By default enabled for watchOS device builds. RemoveUnsupportedILForBitcode = app.Platform == Utils.ApplePlatform.WatchOS && app.IsDeviceBuild; } if (!SealAndDevirtualize.HasValue) { // by default run the linker SealerSubStep unless the interpreter is enabled SealAndDevirtualize = !app.UseInterpreter; } #endif // By default Runtime.IsARM64CallingConvention inlining is always enabled. if (!InlineIsARM64CallingConvention.HasValue) { InlineIsARM64CallingConvention = true; } // by default we try to eliminate any .cctor we can if (!StaticConstructorBeforeFieldInit.HasValue) { StaticConstructorBeforeFieldInit = true; } // by default we remove rarely used custom attributes if (!CustomAttributesRemoval.HasValue) { CustomAttributesRemoval = true; } if (Driver.Verbosity > 3) { Driver.Log(4, "Enabled optimizations: {0}", string.Join(", ", values.Select((v, idx) => v == true ? opt_names [idx] : string.Empty).Where((v) => !string.IsNullOrEmpty(v)))); } }
static void ValidateXcode(bool accept_any_xcode_version, bool warn_if_not_found) { if (sdk_root == null) { sdk_root = FindSystemXcode(); if (sdk_root == null) { // FindSystemXcode showed a warning in this case. In particular do not use 'string.IsNullOrEmpty' here, // because FindSystemXcode may return an empty string (with no warning printed) if the xcode-select command // succeeds, but returns nothing. sdk_root = null; } else if (!Directory.Exists(sdk_root)) { ErrorHelper.Warning(60, "Could not find the currently selected Xcode on the system. 'xcode-select --print-path' returned '{0}', but that directory does not exist.", sdk_root); sdk_root = null; } else { if (!accept_any_xcode_version) { ErrorHelper.Warning(61, "No Xcode.app specified (using --sdkroot), using the system Xcode as reported by 'xcode-select --print-path': {0}", sdk_root); } } if (sdk_root == null) { sdk_root = XcodeDefault; if (!Directory.Exists(sdk_root)) { if (warn_if_not_found) { // mmp: and now we give up, but don't throw like mtouch, because we don't want to change behavior (this sometimes worked it appears) ErrorHelper.Warning(56, "Cannot find Xcode in any of our default locations. Please install Xcode, or pass a custom path using --sdkroot=<path>."); return; // Can't validate the version below if we can't even find Xcode... } throw ErrorHelper.CreateError(56, "Cannot find Xcode in the default location (/Applications/Xcode.app). Please install Xcode, or pass a custom path using --sdkroot <path>."); } ErrorHelper.Warning(62, "No Xcode.app specified (using --sdkroot or 'xcode-select --print-path'), using the default Xcode instead: {0}", sdk_root); } } else if (!Directory.Exists(sdk_root)) { throw ErrorHelper.CreateError(55, "The Xcode path '{0}' does not exist.", sdk_root); } // Check what kind of path we got if (File.Exists(Path.Combine(sdk_root, "Contents", "MacOS", "Xcode"))) { // path to the Xcode.app developer_directory = Path.Combine(sdk_root, "Contents", "Developer"); } else if (File.Exists(Path.Combine(sdk_root, "..", "MacOS", "Xcode"))) { // path to Contents/Developer developer_directory = Path.GetFullPath(Path.Combine(sdk_root, "..", "..", "Contents", "Developer")); } else { throw ErrorHelper.CreateError(57, "Cannot determine the path to Xcode.app from the sdk root '{0}'. Please specify the full path to the Xcode.app bundle.", sdk_root); } var plist_path = Path.Combine(Path.GetDirectoryName(DeveloperDirectory), "version.plist"); if (File.Exists(plist_path)) { var plist = FromPList(plist_path); var version = plist.GetString("CFBundleShortVersionString"); xcode_version = new Version(version); xcode_product_version = plist.GetString("ProductBuildVersion"); } else { throw ErrorHelper.CreateError(58, "The Xcode.app '{0}' is invalid (the file '{1}' does not exist).", Path.GetDirectoryName(Path.GetDirectoryName(DeveloperDirectory)), plist_path); } if (!accept_any_xcode_version) { if (min_xcode_version != null && XcodeVersion < min_xcode_version) { throw ErrorHelper.CreateError(51, "{3} {0} requires Xcode {4} or later. The current Xcode version (found in {2}) is {1}.", Constants.Version, XcodeVersion.ToString(), sdk_root, PRODUCT, min_xcode_version); } if (XcodeVersion < SdkVersions.XcodeVersion) { ErrorHelper.Warning(79, "The recommended Xcode version for {4} {0} is Xcode {3} or later. The current Xcode version (found in {2}) is {1}.", Constants.Version, XcodeVersion.ToString(), sdk_root, SdkVersions.Xcode, PRODUCT); } } Driver.Log(1, "Using Xcode {0} ({2}) found in {1}", XcodeVersion, sdk_root, XcodeProductVersion); }
IEnumerable<BuildTask> CreateManagedToAssemblyTasks (string s, Abi abi, string build_dir) { var arch = abi.AsArchString (); var asm_dir = Cache.Location; var asm = Path.Combine (asm_dir, Path.GetFileName (s)) + "." + arch + ".s"; var llvm_asm = Path.Combine (asm_dir, Path.GetFileName (s)) + "." + arch + "-llvm.s"; var data = Path.Combine (asm_dir, Path.GetFileNameWithoutExtension (s)) + "." + arch + ".aotdata"; string llvm_ofile, llvm_aot_ofile = ""; var is_llvm = (abi & Abi.LLVM) == Abi.LLVM; bool assemble_llvm = is_llvm && Driver.LLVMAsmWriter; if (!File.Exists (s)) throw new MonoTouchException (3004, true, "Could not AOT the assembly '{0}' because it doesn't exist.", s); HashSet<string> dependencies = null; List<string> deps = null; List<string> outputs = new List<string> (); var warnings = new List<Exception> (); dependencies = ComputeDependencies (warnings); if (warnings.Count > 0) { ErrorHelper.Show (warnings); ErrorHelper.Warning (3006, "Could not compute a complete dependency map for the project. This will result in slower build times because Xamarin.iOS can't properly detect what needs to be rebuilt (and what does not need to be rebuilt). Please review previous warnings for more details."); } else { deps = new List<string> (dependencies.ToArray ()); deps.Add (s); deps.Add (Driver.GetAotCompiler (Target.Is64Build)); } if (App.EnableLLVMOnlyBitCode) { // // In llvm-only mode, the AOT compiler emits a .bc file and no .s file for JITted code // llvm_ofile = Path.Combine (asm_dir, Path.GetFileName (s)) + "." + arch + ".bc"; outputs.Add (llvm_ofile); llvm_aot_ofile = llvm_ofile; } else { llvm_ofile = Path.Combine (asm_dir, Path.GetFileName (s)) + "." + arch + "-llvm.o"; outputs.Add (asm); if (is_llvm) { if (assemble_llvm) { llvm_aot_ofile = llvm_asm; } else { llvm_aot_ofile = llvm_ofile; Target.LinkWith (llvm_ofile); } outputs.Add (llvm_aot_ofile); } } if (deps != null && Application.IsUptodate (deps, outputs)) { Driver.Log (3, "Target {0} is up-to-date.", asm); if (App.EnableLLVMOnlyBitCode) return CreateCompileTasks (s, null, llvm_ofile, abi); else return CreateCompileTasks (s, asm, assemble_llvm ? llvm_asm : null, abi); } else { Application.TryDelete (asm); // otherwise the next task might not detect that it will have to rebuild. Application.TryDelete (llvm_asm); Application.TryDelete (llvm_ofile); Driver.Log (3, "Target {0} needs to be rebuilt.", asm); } var aotCompiler = Driver.GetAotCompiler (Target.Is64Build); var aotArgs = Driver.GetAotArguments (s, abi, build_dir, asm, llvm_aot_ofile, data); Driver.Log (3, "Aot compiler: {0} {1}", aotCompiler, aotArgs); AotDataFiles.Add (data); IEnumerable<BuildTask> nextTasks; if (App.EnableLLVMOnlyBitCode) nextTasks = CreateCompileTasks (s, null, llvm_ofile, abi); else nextTasks = CreateCompileTasks (s, asm, assemble_llvm ? llvm_asm : null, abi); return new BuildTask [] { new AOTTask () { AssemblyName = s, ProcessStartInfo = Driver.CreateStartInfo (aotCompiler, aotArgs, Path.GetDirectoryName (s)), NextTasks = nextTasks } }; }
public void ExtractNativeLinkInfo() { // ignore framework assemblies, they won't have any LinkWith attributes if (IsFrameworkAssembly) { return; } var assembly = AssemblyDefinition; if (!assembly.HasCustomAttributes) { return; } var exceptions = new List <Exception> (); string path; // // Tasks: // * Remove LinkWith attribute: this is done in the linker. // * Remove embedded resources related to LinkWith attribute from assembly: this is done at a later stage, // here we just compile a list of resources to remove. // * Extract embedded resources related to LinkWith attribute to a file // * Modify the linker flags used to build/link the dylib (if fastdev) or the main binary (if !fastdev) // for (int i = 0; i < assembly.CustomAttributes.Count; i++) { CustomAttribute attr = assembly.CustomAttributes[i]; if (attr.Constructor == null) { continue; } TypeReference type = attr.Constructor.DeclaringType; if (!type.IsPlatformType("ObjCRuntime", "LinkWithAttribute")) { continue; } // Let the linker remove it the attribute from the assembly HasLinkWithAttributes = true; LinkWithAttribute linkWith = GetLinkWithAttribute(attr); string libraryName = linkWith.LibraryName; // Remove the resource from the assembly at a later stage. if (!string.IsNullOrEmpty(libraryName)) { AddResourceToBeRemoved(libraryName); } // We can't add -dead_strip if there are any LinkWith attributes where smart linking is disabled. if (!linkWith.SmartLink) { App.DeadStrip = false; } // Don't add -force_load if the binding's SmartLink value is set and the static registrar is being used. if (linkWith.ForceLoad && !(linkWith.SmartLink && App.Registrar == RegistrarMode.Static)) { ForceLoad = true; } if (!string.IsNullOrEmpty(linkWith.LinkerFlags)) { if (LinkerFlags == null) { LinkerFlags = new List <string> (); } LinkerFlags.Add(linkWith.LinkerFlags); } if (!string.IsNullOrEmpty(linkWith.Frameworks)) { foreach (var f in linkWith.Frameworks.Split(new char[] { ' ' })) { if (Frameworks == null) { Frameworks = new HashSet <string> (); } Frameworks.Add(f); } } if (!string.IsNullOrEmpty(linkWith.WeakFrameworks)) { foreach (var f in linkWith.WeakFrameworks.Split(new char[] { ' ' })) { if (WeakFrameworks == null) { WeakFrameworks = new HashSet <string> (); } WeakFrameworks.Add(f); } } if (linkWith.NeedsGccExceptionHandling) { NeedsGccExceptionHandling = true; } if (linkWith.IsCxx) { EnableCxx = true; } #if MONOTOUCH if (linkWith.Dlsym != DlsymOption.Default) { App.SetDlsymOption(FullPath, linkWith.Dlsym == DlsymOption.Required); } #endif if (!string.IsNullOrEmpty(libraryName)) { path = Path.Combine(App.Cache.Location, libraryName); if (path.EndsWith(".framework", StringComparison.Ordinal)) { #if MONOTOUCH if (App.Platform == Xamarin.Utils.ApplePlatform.iOS && App.DeploymentTarget.Major < 8) { throw ErrorHelper.CreateError(1305, "The binding library '{0}' contains a user framework ({0}), but embedded user frameworks require iOS 8.0 (the deployment target is {1}). Please set the deployment target in the Info.plist file to at least 8.0.", FileName, Path.GetFileName(path), App.DeploymentTarget); } #endif var zipPath = path + ".zip"; if (!Application.IsUptodate(FullPath, zipPath)) { Application.ExtractResource(assembly.MainModule, libraryName, zipPath, false); Driver.Log(3, "Extracted third-party framework '{0}' from '{1}' to '{2}'", libraryName, FullPath, zipPath); LogLinkWithAttribute(linkWith); } else { Driver.Log(3, "Target '{0}' is up-to-date.", path); } if (!File.Exists(zipPath)) { ErrorHelper.Warning(1302, "Could not extract the native framework '{0}' from '{1}'. " + "Please ensure the native framework was properly embedded in the managed assembly " + "(if the assembly was built using a binding project, the native framework must be included in the project, and its Build Action must be 'ObjcBindingNativeFramework').", libraryName, zipPath); } else { if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } if (Driver.RunCommand("/usr/bin/unzip", string.Format("-u -o -d {0} {1}", StringUtils.Quote(path), StringUtils.Quote(zipPath))) != 0) { throw ErrorHelper.CreateError(1303, "Could not decompress the native framework '{0}' from '{1}'. Please review the build log for more information from the native 'unzip' command.", libraryName, zipPath); } } Frameworks.Add(path); } else { if (!Application.IsUptodate(FullPath, path)) { Application.ExtractResource(assembly.MainModule, libraryName, path, false); Driver.Log(3, "Extracted third-party binding '{0}' from '{1}' to '{2}'", libraryName, FullPath, path); LogLinkWithAttribute(linkWith); } else { Driver.Log(3, "Target '{0}' is up-to-date.", path); } if (!File.Exists(path)) { ErrorHelper.Warning(1302, "Could not extract the native library '{0}' from '{1}'. " + "Please ensure the native library was properly embedded in the managed assembly " + "(if the assembly was built using a binding project, the native library must be included in the project, and its Build Action must be 'ObjcBindingNativeLibrary').", libraryName, path); } LinkWith.Add(path); } } } if (exceptions != null && exceptions.Count > 0) { throw new AggregateException(exceptions); } // Make sure there are no duplicates between frameworks and weak frameworks. // Keep the weak ones. if (Frameworks != null && WeakFrameworks != null) { Frameworks.ExceptWith(WeakFrameworks); } if (NeedsGccExceptionHandling) { if (LinkerFlags == null) { LinkerFlags = new List <string> (); } LinkerFlags.Add("-lgcc_eh"); } }
public override AssemblyDefinition Resolve(AssemblyNameReference reference, ReaderParameters parameters) { var name = reference.Name; AssemblyDefinition assembly; if (cache.TryGetValue(name, out assembly)) { return(assembly); } if (CommandLineAssemblies != null && CommandLineAssemblies.Count > 0) { string cmdasm = CommandLineAssemblies.Find(t => { if (String.IsNullOrEmpty(t)) { return(false); } return(String.Compare(name, Path.GetFileNameWithoutExtension(t), StringComparison.Ordinal) == 0); }); assembly = String.IsNullOrEmpty(cmdasm) ? null : Load(cmdasm); if (assembly != null) { return(assembly); } } if (ArchDirectory != null) { assembly = SearchDirectory(name, ArchDirectory); if (assembly != null) { return(assembly); } } assembly = SearchDirectory(name, FrameworkDirectory); if (assembly != null) { return(assembly); } var pclPath = Path.Combine(FrameworkDirectory, "Facades"); if (Directory.Exists(pclPath)) { assembly = SearchDirectory(name, pclPath); if (assembly != null) { return(assembly); } } assembly = SearchDirectory(name, RootDirectory, ".exe"); if (assembly != null) { return(assembly); } if (!string.IsNullOrEmpty(GlobalAssemblyCache)) { var gac_folder = new StringBuilder() .Append(reference.Version) .Append("__"); for (int i = 0; i < reference.PublicKeyToken.Length; i++) { gac_folder.Append(reference.PublicKeyToken [i].ToString("x2")); } var gac_path = Path.Combine(GlobalAssemblyCache, reference.Name, gac_folder.ToString(), reference.Name + ".dll"); if (File.Exists(gac_path)) { if (Driver.IsUnifiedFullXamMacFramework) { ErrorHelper.Warning(176, Errors.MX0176, reference.ToString(), gac_path); } return(Load(gac_path)); } } if (SystemFrameworkDirectories?.Length > 0) { var framework_dir = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName); var framework_dirs = new [] { framework_dir, Path.Combine(framework_dir, "Facades") }; foreach (var dir in framework_dirs) { assembly = SearchDirectory(reference.Name, dir); if (assembly != null) { if (Driver.IsUnifiedFullXamMacFramework) { ErrorHelper.Warning(176, Errors.MX0176, reference.ToString(), assembly.MainModule.FileName); } return(assembly); } } } return(null); }
public void CollectAllSymbols() { if (dynamic_symbols != null) { return; } var cache_location = Path.Combine(App.Cache.Location, "entry-points.txt"); if (cached_link) { dynamic_symbols = new Symbols(); dynamic_symbols.Load(cache_location, this); } else { if (LinkContext == null) { // This happens when using the simlauncher and the msbuild tasks asked for a list // of symbols (--symbollist). In that case just produce an empty list, since the // binary shouldn't end up stripped anyway. dynamic_symbols = new Symbols(); } else { dynamic_symbols = LinkContext.RequiredSymbols; } // keep the debugging helper in debugging binaries only var has_mono_pmip = App.EnableDebug; #if MMP has_mono_pmip &= !Driver.IsUnifiedFullSystemFramework; #endif if (has_mono_pmip) { dynamic_symbols.AddFunction("mono_pmip"); } bool has_dyn_msgSend; if (App.Platform == ApplePlatform.MacOSX) { has_dyn_msgSend = App.MarshalObjectiveCExceptions != MarshalObjectiveCExceptionMode.Disable && !App.RequiresPInvokeWrappers && Is64Build; } else { has_dyn_msgSend = App.IsSimulatorBuild; } if (has_dyn_msgSend) { dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSend"); dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSendSuper"); dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSend_stret"); dynamic_symbols.AddFunction("xamarin_dyn_objc_msgSendSuper_stret"); } #if MONOTOUCH if (App.EnableProfiling && App.LibProfilerLinkMode == AssemblyBuildTarget.StaticObject) { dynamic_symbols.AddFunction("mono_profiler_init_log"); } #endif dynamic_symbols.Save(cache_location); } foreach (var name in App.IgnoredSymbols) { var symbol = dynamic_symbols.Find(name); if (symbol == null) { ErrorHelper.Warning(5218, Errors.MT5218, StringUtils.Quote(name)); } else { symbol.Ignore = true; } } }
public void GatherFrameworks() { Assembly asm = null; foreach (var assembly in Assemblies) { if (assembly.AssemblyDefinition.Name.Name == Driver.GetProductAssembly(App)) { asm = assembly; break; } } if (asm == null) { throw ErrorHelper.CreateError(99, Errors.MX0099, $"could not find the product assembly {Driver.GetProductAssembly(App)} in the list of assemblies referenced by the executable"); } AssemblyDefinition productAssembly = asm.AssemblyDefinition; // *** make sure any change in the above lists (or new list) are also reflected in // *** Makefile so simlauncher-sgen does not miss any framework HashSet <string> processed = new HashSet <string> (); #if !MONOMAC Version v80 = new Version(8, 0); #endif foreach (ModuleDefinition md in productAssembly.Modules) { foreach (TypeDefinition td in md.Types) { // process only once each namespace (as we keep adding logic below) string nspace = td.Namespace; if (processed.Contains(nspace)) { continue; } processed.Add(nspace); Framework framework; if (Driver.GetFrameworks(App).TryGetValue(nspace, out framework)) { // framework specific processing switch (framework.Name) { #if MONOMAC case "QTKit": // we already warn in Frameworks.cs Gather method if (!Driver.LinkProhibitedFrameworks) { continue; } break; #else case "CoreAudioKit": // CoreAudioKit seems to be functional in the iOS 9 simulator. if (App.IsSimulatorBuild && App.SdkVersion.Major < 9) { continue; } break; case "Metal": case "MetalKit": case "MetalPerformanceShaders": // some frameworks do not exists on simulators and will result in linker errors if we include them if (App.IsSimulatorBuild) { continue; } break; case "DeviceCheck": if (App.IsSimulatorBuild && App.SdkVersion.Major < 13) { continue; } break; case "PushKit": // in Xcode 6 beta 7 this became an (ld) error - it was a warning earlier :( // ld: embedded dylibs/frameworks are only supported on iOS 8.0 and later (@rpath/PushKit.framework/PushKit) for architecture armv7 // this was fixed in Xcode 6.2 (6.1 was still buggy) see #29786 if ((App.DeploymentTarget < v80) && (Driver.XcodeVersion < new Version(6, 2))) { ErrorHelper.Warning(49, Errors.MT0049, framework.Name); continue; } break; case "WatchKit": // Xcode 11 doesn't ship WatchKit for iOS if (Driver.XcodeVersion.Major == 11 && App.Platform == ApplePlatform.iOS) { ErrorHelper.Warning(5219, Errors.MT5219); continue; } break; default: if (App.IsSimulatorBuild && !App.IsFrameworkAvailableInSimulator(framework.Name)) { if (App.LinkMode != LinkMode.None) { ErrorHelper.Warning(5223, Errors.MX5223, framework.Name, App.PlatformName); } else { Driver.Log(3, Errors.MX5223, framework.Name, App.PlatformName); } continue; } break; #endif } if (App.SdkVersion >= framework.Version) { var add_to = framework.AlwaysWeakLinked || App.DeploymentTarget < framework.Version ? asm.WeakFrameworks : asm.Frameworks; add_to.Add(framework.Name); continue; } else { Driver.Log(3, "Not linking with the framework {0} (used by the type {1}) because it was introduced in {2} {3}, and we're using the {2} {4} SDK.", framework.Name, td.FullName, App.PlatformName, framework.Version, App.SdkVersion); } } } } // Make sure there are no duplicates between frameworks and weak frameworks. // Keep the weak ones. asm.Frameworks.ExceptWith(asm.WeakFrameworks); }
static void ValidateXcode(bool accept_any_xcode_version, bool warn_if_not_found) { if (sdk_root == null) { sdk_root = FindSystemXcode(); if (sdk_root == null) { // FindSystemXcode showed a warning in this case. In particular do not use 'string.IsNullOrEmpty' here, // because FindSystemXcode may return an empty string (with no warning printed) if the xcode-select command // succeeds, but returns nothing. sdk_root = null; } else if (!Directory.Exists(sdk_root)) { ErrorHelper.Warning(60, Errors.MX0060, sdk_root); sdk_root = null; } else { if (!accept_any_xcode_version) { ErrorHelper.Warning(61, Errors.MT0061, sdk_root); } } if (sdk_root == null) { sdk_root = XcodeDefault; if (!Directory.Exists(sdk_root)) { if (warn_if_not_found) { // mmp: and now we give up, but don't throw like mtouch, because we don't want to change behavior (this sometimes worked it appears) ErrorHelper.Warning(56, Errors.MX0056); return; // Can't validate the version below if we can't even find Xcode... } throw ErrorHelper.CreateError(56, Errors.MX0056); } ErrorHelper.Warning(62, Errors.MT0062, sdk_root); } } else if (!Directory.Exists(sdk_root)) { throw ErrorHelper.CreateError(55, Errors.MT0055, sdk_root); } // Check what kind of path we got if (File.Exists(Path.Combine(sdk_root, "Contents", "MacOS", "Xcode"))) { // path to the Xcode.app developer_directory = Path.Combine(sdk_root, "Contents", "Developer"); } else if (File.Exists(Path.Combine(sdk_root, "..", "MacOS", "Xcode"))) { // path to Contents/Developer developer_directory = Path.GetFullPath(Path.Combine(sdk_root, "..", "..", "Contents", "Developer")); } else { throw ErrorHelper.CreateError(57, Errors.MT0057, sdk_root); } var plist_path = Path.Combine(Path.GetDirectoryName(DeveloperDirectory), "version.plist"); if (File.Exists(plist_path)) { var plist = FromPList(plist_path); var version = plist.GetString("CFBundleShortVersionString"); xcode_version = new Version(version); xcode_product_version = plist.GetString("ProductBuildVersion"); } else { throw ErrorHelper.CreateError(58, Errors.MT0058, Path.GetDirectoryName(Path.GetDirectoryName(DeveloperDirectory)), plist_path); } if (!accept_any_xcode_version) { if (min_xcode_version != null && XcodeVersion < min_xcode_version) { throw ErrorHelper.CreateError(51, Errors.MT0051, Constants.Version, XcodeVersion.ToString(), sdk_root, PRODUCT, min_xcode_version); } if (XcodeVersion < SdkVersions.XcodeVersion) { ErrorHelper.Warning(79, Errors.MT0079, Constants.Version, XcodeVersion.ToString(), sdk_root, SdkVersions.Xcode, PRODUCT); } } Driver.Log(1, "Using Xcode {0} ({2}) found in {1}", XcodeVersion, sdk_root, XcodeProductVersion); }
public void InitializeCommon() { if (Platform == ApplePlatform.WatchOS && EnableCoopGC.HasValue && !EnableCoopGC.Value) { throw ErrorHelper.CreateError(88, "The GC must be in cooperative mode for watchOS apps. Please remove the --coop:false argument to mtouch."); } if (!EnableCoopGC.HasValue) { EnableCoopGC = Platform == ApplePlatform.WatchOS; } if (EnableCoopGC.Value) { switch (MarshalObjectiveCExceptions) { case MarshalObjectiveCExceptionMode.UnwindManagedCode: case MarshalObjectiveCExceptionMode.Disable: throw ErrorHelper.CreateError(89, "The option '{0}' cannot take the value '{1}' when cooperative mode is enabled for the GC.", "--marshal-objectivec-exceptions", MarshalObjectiveCExceptions.ToString().ToLowerInvariant()); } switch (MarshalManagedExceptions) { case MarshalManagedExceptionMode.UnwindNativeCode: case MarshalManagedExceptionMode.Disable: throw ErrorHelper.CreateError(89, "The option '{0}' cannot take the value '{1}' when cooperative mode is enabled for the GC.", "--marshal-managed-exceptions", MarshalManagedExceptions.ToString().ToLowerInvariant()); } } bool isSimulatorOrDesktopDebug = EnableDebug; #if MTOUCH isSimulatorOrDesktopDebug &= IsSimulatorBuild; #endif if (MarshalObjectiveCExceptions == MarshalObjectiveCExceptionMode.Default) { if (EnableCoopGC.Value) { MarshalObjectiveCExceptions = MarshalObjectiveCExceptionMode.ThrowManagedException; } else { MarshalObjectiveCExceptions = isSimulatorOrDesktopDebug ? MarshalObjectiveCExceptionMode.UnwindManagedCode : MarshalObjectiveCExceptionMode.Disable; } } if (MarshalManagedExceptions == MarshalManagedExceptionMode.Default) { if (EnableCoopGC.Value) { MarshalManagedExceptions = MarshalManagedExceptionMode.ThrowObjectiveCException; } else { MarshalManagedExceptions = isSimulatorOrDesktopDebug ? MarshalManagedExceptionMode.UnwindNativeCode : MarshalManagedExceptionMode.Disable; } IsDefaultMarshalManagedExceptionMode = true; } if (SymbolMode == SymbolMode.Default) { #if MONOTOUCH SymbolMode = EnableBitCode ? SymbolMode.Code : SymbolMode.Linker; #else SymbolMode = SymbolMode.Linker; #endif } #if MONOTOUCH if (EnableBitCode && SymbolMode != SymbolMode.Code) { // This is a warning because: // * The user will get a linker error anyway if they do this. // * I see it as quite unlikely that anybody will in fact try this (it must be manually set in the additional mtouch arguments). // * I find it more probable that Apple will remove the -u restriction, in which case someone might actually want to try this, and if it's a warning, we won't prevent it. ErrorHelper.Warning(115, "It is recommended to reference dynamic symbols using code (--dynamic-symbol-mode=code) when bitcode is enabled."); } #endif }