コード例 #1
0
        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);
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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;
                }
            }
        }
コード例 #7
0
        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))));
            }
        }
コード例 #8
0
ファイル: Driver.cs プロジェクト: wachaudh/xamarin-macios
        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);
        }
コード例 #9
0
ファイル: Assembly.cs プロジェクト: joobn72/xamarin-macios
		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
				}
			};
		}
コード例 #10
0
ファイル: Assembly.cs プロジェクト: wvrfish/xamarin-macios
        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");
            }
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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;
                }
            }
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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
        }