LinkerConfiguration(string linker_file)
        {
            if (!File.Exists(linker_file))
            {
                throw new FileNotFoundException($"The custom linker file {linker_file} does not exist.");
            }

            Profile            = new BaseProfile(this);
            DerivedLinkContext = new DerivedLinkContext {
                LinkerConfiguration = this,
            };
            Application   = new Application(this);
            Target        = new Target(Application);
            CompilerFlags = new CompilerFlags(Target);

            var lines            = File.ReadAllLines(linker_file);
            var significantLines = new List <string> ();            // This is the input the cache uses to verify if the cache is still valid

            for (var i = 0; i < lines.Length; i++)
            {
                var line = lines [i].TrimStart();
                if (line.Length == 0 || line [0] == '#')
                {
                    continue;                     // Allow comments
                }
                var eq = line.IndexOf('=');
                if (eq == -1)
                {
                    throw new InvalidOperationException($"Invalid syntax for line {i + 1} in {linker_file}: No equals sign.");
                }

                significantLines.Add(line);

                var key   = line [..eq];
示例#2
0
        public ResultCodes Execute(
            TextWriter outputWriter,
            TextWriter errorWriter,
            TextWriter warningWriter,
            TextWriter logWriter,
            CommandContext context)
        {
            var inputFile  = context.GetToken(0);
            var outputFile = context.GetToken(1);
            var platform   = context.GetToken(2);

            if (inputFile == null)
            {
                errorWriter.WriteLine("Source file is not specified.");
                return(ResultCodes.Failure);
            }

            if (outputFile == null)
            {
                errorWriter.WriteLine("Output file is not specified.");
                return(ResultCodes.Failure);
            }

            if (platform == null)
            {
                errorWriter.WriteLine("Platform is not specified.");
                return(ResultCodes.Failure);
            }

            var compiler = new Compiler();

            var flags = CompilerFlags.CreateDefault();

            foreach (var sw in _switches)
            {
                _setFlag(context, flags, sw.Value.Item1, sw.Key);
            }

            var result = compiler.CompileFromSource(
                errorWriter,
                warningWriter,
                logWriter,
                inputFile,
                outputFile,
                platform,
                flags
                );

            if (result.Successful)
            {
                outputWriter.WriteLine("Compilation finished successfully.");
                return(ResultCodes.Successful);
            }

            //preserving the stack-trace.
            var info = ExceptionDispatchInfo.Capture(result.Exception);

            info.Throw();
            return(ResultCodes.Failure);
        }
示例#3
0
        private void _setFlag(CommandContext context, CompilerFlags flags,
                              Expression <Func <CompilerFlags, object> > prop, string switchName)
        {
            Switch s;

            if ((s = context.GetSwitch(switchName)) != null)
            {
                s.AssertValue();

                var lambda     = prop as LambdaExpression;
                var memberExpr = lambda.Body as MemberExpression;
                if (memberExpr == null)
                {
                    throw new InvalidOperationException();
                }
                var propName = memberExpr.Member.Name;

                var propInfo = flags.GetType().GetProperty(propName);

                if (propInfo.PropertyType == typeof(bool))
                {
                    StatementHelpers.TryParseBooleanFromString(s.Value, out var value);
                    propInfo.SetValue(flags, value);
                }
                else
                {
                    propInfo.SetValue(flags, Convert.ChangeType(s.Value, propInfo.PropertyType));
                }
            }
        }
        public static void GetCatalystCompilerFlags(CompilerFlags flags, Abi abi, Application app)
        {
            GetCompilerFlags(app, flags, false);
            flags.AddOtherFlag($"-target", $"{abi.AsArchString ()}-apple-ios{app.DeploymentTarget}-macabi");
            var isysroot = Driver.GetFrameworkDirectory(app);

            flags.AddOtherFlag($"-isystem", Path.Combine(isysroot, "System", "iOSSupport", "usr", "include"));
            flags.AddOtherFlag($"-iframework", Path.Combine(isysroot, "System", "iOSSupport", "System", "Library", "Frameworks"));
            flags.AddOtherFlag($"-L{Path.Combine (isysroot, "System", "iOSSupport", "usr", "lib")}");
        }
示例#5
0
        protected override void Build()
        {
            if (Driver.IsUsingClang(App))
            {
                // This is because iOS has a forward declaration of NSPortMessage, but no actual declaration.
                // They still use NSPortMessage in other API though, so it can't just be removed from our bindings.
                CompilerFlags.AddOtherFlag("-Wno-receiver-forward-class");
            }

            if (Compile() != 0)
            {
                throw new MonoTouchException(4109, true, "Failed to compile the generated registrar code. Please file a bug report at http://bugzilla.xamarin.com");
            }
        }
示例#6
0
        void GetSharedCompilerFlags(CompilerFlags flags, string install_name)
        {
            if (string.IsNullOrEmpty(install_name))
            {
                throw new ArgumentNullException(nameof(install_name));
            }

            flags.AddOtherFlag("-shared");
            if (!App.EnableMarkerOnlyBitCode && !App.EnableAsmOnlyBitCode)
            {
                flags.AddOtherFlag("-read_only_relocs suppress");
            }
            flags.LinkWithMono();
            flags.AddOtherFlag("-install_name " + Driver.Quote(install_name));
            flags.AddOtherFlag("-fapplication-extension");              // fixes this: warning MT5203: Native linking warning: warning: linking against dylib not safe for use in application extensions: [..]/actionextension.dll.arm64.dylib
        }
示例#7
0
        public static void GetArchFlags(CompilerFlags flags, IEnumerable <Abi> abis)
        {
            bool enable_thumb = false;

            foreach (var abi in abis)
            {
                var arch = abi.AsArchString();
                flags.AddOtherFlag($"-arch", arch);

                enable_thumb |= (abi & Abi.Thumb) != 0;
            }

            if (enable_thumb)
            {
                flags.AddOtherFlag("-mthumb");
            }
        }
示例#8
0
        public static void GetSimulatorCompilerFlags(CompilerFlags flags, bool is_assembler, Application app, string language = null)
        {
            GetCompilerFlags(app, flags, is_assembler, language);

            string sim_platform = Driver.GetPlatformDirectory(app);
            string plist        = Path.Combine(sim_platform, "Info.plist");

            var dict = Driver.FromPList(plist);
            var dp   = dict.Get <PDictionary> ("DefaultProperties");

            if (dp.GetString("GCC_OBJC_LEGACY_DISPATCH") == "YES")
            {
                flags.AddOtherFlag("-fobjc-legacy-dispatch");
            }
            string objc_abi = dp.GetString("OBJC_ABI_VERSION");

            if (!String.IsNullOrWhiteSpace(objc_abi))
            {
                flags.AddOtherFlag($"-fobjc-abi-version={objc_abi}");
            }

            plist = Path.Combine(Driver.GetFrameworkDirectory(app), "SDKSettings.plist");
            string min_prefix = app.CompilerPath.Contains("clang") ? Driver.GetTargetMinSdkName(app) : "iphoneos";

            dict = Driver.FromPList(plist);
            dp   = dict.Get <PDictionary> ("DefaultProperties");
            if (app.DeploymentTarget == new Version())
            {
                string target = dp.GetString("IPHONEOS_DEPLOYMENT_TARGET");
                if (!String.IsNullOrWhiteSpace(target))
                {
                    flags.AddOtherFlag($"-m{min_prefix}-version-min={target}");
                }
            }
            else
            {
                flags.AddOtherFlag($"-m{min_prefix}-version-min={app.DeploymentTarget}");
            }
            string defines = dp.GetString("GCC_PRODUCT_TYPE_PREPROCESSOR_DEFINITIONS");

            if (!String.IsNullOrWhiteSpace(defines))
            {
                flags.AddDefine(defines.Replace(" ", String.Empty));
            }
        }
示例#9
0
        public static void GetCompilerFlags(Application app, CompilerFlags flags, bool is_assembler, string language = null)
        {
            if (!is_assembler)
            {
                flags.AddOtherFlag("-gdwarf-2");
            }

            if (!is_assembler)
            {
                if (string.IsNullOrEmpty(language) || !language.Contains("++"))
                {
                    // error: invalid argument '-std=c99' not allowed with 'C++/ObjC++'
                    flags.AddOtherFlag("-std=c99");
                }
                flags.AddOtherFlag($"-I{StringUtils.Quote (Path.Combine (Driver.GetProductSdkDirectory (app), "usr", "include"))}");
            }
            flags.AddOtherFlag($"-isysroot {StringUtils.Quote (Driver.GetFrameworkDirectory (app))}");
            flags.AddOtherFlag("-Qunused-arguments");              // don't complain about unused arguments (clang reports -std=c99 and -Isomething as unused).
        }
示例#10
0
        public static void GetCompilerFlags(Application app, CompilerFlags flags, bool is_assembler, string language = null)
        {
            if (!is_assembler)
            {
                flags.AddOtherFlag("-gdwarf-2");
            }

            if (!is_assembler)
            {
                if (language != "objective-c")
                {
                    // error: invalid argument '-std=c++14' not allowed with 'Objective-C'
                    flags.AddOtherFlag("-std=c++14");
                }

                flags.AddOtherFlag($"-I{Driver.GetProductSdkIncludeDirectory (app)}");
            }
            flags.AddOtherFlag($"-isysroot", Driver.GetFrameworkDirectory(app));
            flags.AddOtherFlag("-Qunused-arguments");              // don't complain about unused arguments (clang reports -std=c99 and -Isomething as unused).
        }
示例#11
0
        public ResultCodes Execute(
            TextWriter outputWriter,
            TextWriter errorWriter,
            TextWriter warningWriter,
            TextWriter logWriter,
            CommandContext context,
            string sourceCode)
        {
            IPlatform platform;

            var osKind = Environment.OSVersion.Platform;

            if (osKind == PlatformID.Win32NT || osKind == PlatformID.Win32S || osKind == PlatformID.Win32Windows ||
                osKind == PlatformID.WinCE)
            {
                platform = null;
            }
            else
            {
                platform = new UnixBashPlatform();
            }

            var compiler = new Compiler();

            var ctx = compiler.CompileFromSource(
                platform,
                CompilerFlags.CreateDefault(),
                errorWriter,
                warningWriter,
                logWriter,
                TextWriter.Null,
                TextWriter.Null,
                sourceCode
                );

            return(ResultCodes.Successful);
        }
示例#12
0
        public Context(Compiler compiler, IPlatform platform, CompilerFlags flags,
                       TextWriter errorWriter, TextWriter warningWriter, TextWriter logWriter)
        {
            GeneralScope = new Scope(this);

            Compiler = compiler;

            Platform      = platform;
            Transpilers   = platform.Transpilers;
            Api           = platform.Api;
            Flags         = flags;
            ErrorWriter   = errorWriter;
            WarningWriter = warningWriter;
            LogWriter     = logWriter;

            _typeTranspilers = Transpilers.ToDictionary(key => key.StatementType);

            CultureInfo    = CultureInfo.CurrentCulture;
            StringComparer = StringComparer.CurrentCulture;

            Includes = new HashSet <string>();

            InitializeContext();
        }
示例#13
0
        public void TestCompiler()
        {
            //try
            {
                Platforms.AddPlatform(new UnixBashPlatform());

                var compiler = new Compiler();
                var result   = compiler.CompileFromSource(
                    Console.Out,
                    Console.Out,
                    Console.Out,
                    "/home/amk/Temp/ShellScript/variables.shellscript",
                    "/home/amk/Temp/ShellScript/variables.sh",
                    "unix-bash",
                    CompilerFlags.CreateDefault()
                    );

                GC.KeepAlive(result);
            }
            //catch (Exception ex)
            {
                Debugger.Break();
            }
        }
示例#14
0
 void GetStaticCompilerFlags(CompilerFlags flags)
 {
     flags.AddOtherFlag("-c");
 }
示例#15
0
        void GetDeviceCompilerFlags(CompilerFlags flags, bool is_assembler)
        {
            GetCompilerFlags(App, flags, is_assembler, Language);

            flags.AddOtherFlag($"-m{Driver.GetTargetMinSdkName (App)}-version-min={App.DeploymentTarget.ToString ()}");
        }
示例#16
0
 public static void GetArchFlags(CompilerFlags flags, params Abi [] abis)
 {
     GetArchFlags(flags, (IEnumerable <Abi>)abis);
 }
示例#17
0
 void GetBitcodeCompilerFlags(CompilerFlags flags)
 {
     flags.AddOtherFlag(App.EnableMarkerOnlyBitCode ? "-fembed-bitcode-marker" : "-fembed-bitcode");
 }
        public void TestScripts()
        {
            const string TestScriptsRootDirectoryName = "ShellScript.MSTest";
            const string TestScriptsDirectoryName     = "TestScripts";
            const string TempOutputDirectoryName      = "TestScripts.temp";

            var platforms = new[]
            {
                new UnixBashPlatform()
            };
            var compilerFlags = CompilerFlags.CreateDefault();
            //compilerFlags.WriteShellScriptVersion = false;

            string testScriptsRoot = null;
            string tempOutputRoot  = null;

            var cDir = Environment.CurrentDirectory;

            while (!string.IsNullOrWhiteSpace(cDir))
            {
                if (StringComparer.InvariantCultureIgnoreCase.Equals(Path.GetFileName(cDir),
                                                                     TestScriptsRootDirectoryName))
                {
                    testScriptsRoot = Path.Combine(cDir, TestScriptsDirectoryName);
                    tempOutputRoot  = Path.Combine(cDir, TempOutputDirectoryName);
                    break;
                }

                cDir = Path.GetDirectoryName(cDir);
            }

            if (testScriptsRoot == null)
            {
                Assert.Fail("Test scripts directory not found.");
            }

            foreach (var file in Directory.GetFiles(testScriptsRoot, "*.shellscript", SearchOption.AllDirectories))
            {
                foreach (var platform in platforms)
                {
                    var ext           = platform.Name.ToLower();
                    var assertionFile = $"{Path.GetFileNameWithoutExtension(file)}.{ext}";
                    var outputFile    = $"{Path.GetFileNameWithoutExtension(file)}.{ext}";

                    assertionFile = Path.Combine(testScriptsRoot, assertionFile);
                    outputFile    = Path.Combine(tempOutputRoot, outputFile);

                    if (File.Exists(assertionFile))
                    {
                        using (var logWriter = new StringWriter())
                        {
                            Directory.CreateDirectory(tempOutputRoot);

                            var compiler = new Compiler();
                            compiler.CompileFromSource(file, tempOutputRoot, outputFile,
                                                       platform, compilerFlags, logWriter, logWriter, logWriter);

                            using (var assertionFileStream =
                                       new FileStream(assertionFile, FileMode.Open, FileAccess.Read))
                                using (var outputFileStream = new FileStream(outputFile, FileMode.Open, FileAccess.Read))
                                    using (var assertionReader = new StreamReader(assertionFileStream))
                                        using (var outputReader = new StreamReader(outputFileStream))
                                        {
                                            string assertLine;
                                            string outputLine;

                                            int line = 0;

                                            while ((assertLine = assertionReader.ReadLine()) != null &&
                                                   (outputLine = outputReader.ReadLine()) != null)
                                            {
                                                if (line++ >= 2)
                                                {
                                                    if (assertLine != outputLine)
                                                    {
                                                        Assert.Fail($"Assert failed on {file}");
                                                    }
                                                }
                                            }
                                        }
                        }
                    }
                }
            }
        }
示例#19
0
        // The input file is either a .s or a .bc file
        BuildTask CreateCompileTask(string assembly_name, string infile_path, Abi abi)
        {
            var ext          = App.FastDev ? "dylib" : "o";
            var ofile        = Path.ChangeExtension(infile_path, ext);
            var install_name = string.Empty;

            if (App.FastDev)
            {
                if (dylibs == null)
                {
                    dylibs = new List <string> ();
                }
                dylibs.Add(ofile);
                install_name = "lib" + Path.GetFileName(assembly_name) + ".dylib";
            }
            else
            {
                Target.LinkWith(ofile);
            }

            if (Application.IsUptodate(new string [] { infile_path, Driver.CompilerPath }, new string [] { ofile }))
            {
                Driver.Log(3, "Target {0} is up-to-date.", ofile);
                return(null);
            }
            else
            {
                Application.TryDelete(ofile);                  // otherwise the next task might not detect that it will have to rebuild.
                Driver.Log(3, "Target {0} needs to be rebuilt.", ofile);
            }

            var compiler_flags = new CompilerFlags()
            {
                Target = Target
            };

            BuildTask bitcode_task = null;
            BuildTask link_task = null;
            string    link_task_input, link_language = "";

            if (App.EnableAsmOnlyBitCode)
            {
                link_task_input = infile_path + ".ll";
                link_language   = "";
                // linker_flags.Add (" -fembed-bitcode");

                bitcode_task = new BitCodeify()
                {
                    Input            = infile_path,
                    OutputFile       = link_task_input,
                    Platform         = App.Platform,
                    Abi              = abi,
                    DeploymentTarget = App.DeploymentTarget,
                };
            }
            else
            {
                link_task_input = infile_path;
                if (infile_path.EndsWith(".s"))
                {
                    link_language = "assembler";
                }
            }

            if (App.FastDev)
            {
                compiler_flags.AddFrameworks(Frameworks, WeakFrameworks);
                compiler_flags.AddLinkWith(LinkWith, ForceLoad);
                compiler_flags.LinkWithMono();
                compiler_flags.LinkWithXamarin();
                compiler_flags.AddOtherFlags(LinkerFlags);
                if (Target.GetEntryPoints().ContainsKey("UIApplicationMain"))
                {
                    compiler_flags.AddFramework("UIKit");
                }
            }

            link_task = new LinkTask()
            {
                Target        = Target,
                AssemblyName  = assembly_name,
                Abi           = abi,
                InputFile     = link_task_input,
                OutputFile    = ofile,
                InstallName   = install_name,
                CompilerFlags = compiler_flags,
                SharedLibrary = App.FastDev,
                Language      = link_language,
            };

            if (bitcode_task != null)
            {
                bitcode_task.NextTasks = new BuildTask[] { link_task };
                return(bitcode_task);
            }
            return(link_task);
        }
示例#20
0
        public void NativeLink()
        {
            if (!string.IsNullOrEmpty(App.UserGccFlags))
            {
                App.DeadStrip = false;
            }
            if (App.EnableLLVMOnlyBitCode)
            {
                App.DeadStrip = false;
            }

            var compiler_flags = new CompilerFlags()
            {
                Target = this
            };

            // Get global frameworks
            compiler_flags.AddFrameworks(App.Frameworks, App.WeakFrameworks);
            compiler_flags.AddFrameworks(Frameworks, WeakFrameworks);

            // Collect all LinkWith flags and frameworks from all assemblies.
            foreach (var a in Assemblies)
            {
                compiler_flags.AddFrameworks(a.Frameworks, a.WeakFrameworks);
                if (!App.FastDev || App.IsSimulatorBuild)
                {
                    compiler_flags.AddLinkWith(a.LinkWith, a.ForceLoad);
                }
                compiler_flags.AddOtherFlags(a.LinkerFlags);
            }

            var bitcode = App.EnableBitCode;

            if (bitcode)
            {
                compiler_flags.AddOtherFlag(App.EnableMarkerOnlyBitCode ? "-fembed-bitcode-marker" : "-fembed-bitcode");
            }

            if (App.EnablePie.HasValue && App.EnablePie.Value && (App.DeploymentTarget < new Version(4, 2)))
            {
                ErrorHelper.Error(28, "Cannot enable PIE (-pie) when targeting iOS 4.1 or earlier. Please disable PIE (-pie:false) or set the deployment target to at least iOS 4.2");
            }

            if (!App.EnablePie.HasValue)
            {
                App.EnablePie = true;
            }

            if (App.Platform == ApplePlatform.iOS)
            {
                if (App.EnablePie.Value && (App.DeploymentTarget >= new Version(4, 2)))
                {
                    compiler_flags.AddOtherFlag("-Wl,-pie");
                }
                else
                {
                    compiler_flags.AddOtherFlag("-Wl,-no_pie");
                }
            }

            CompileTask.GetArchFlags(compiler_flags, Abis);
            if (App.IsDeviceBuild)
            {
                compiler_flags.AddOtherFlag($"-m{Driver.GetTargetMinSdkName (App)}-version-min={App.DeploymentTarget}");
                compiler_flags.AddOtherFlag($"-isysroot {Driver.Quote (Driver.GetFrameworkDirectory (App))}");
            }
            else
            {
                CompileTask.GetSimulatorCompilerFlags(compiler_flags, null, App);
            }
            compiler_flags.LinkWithMono();
            compiler_flags.LinkWithXamarin();

            compiler_flags.AddLinkWith(link_with);
            compiler_flags.AddOtherFlag($"-o {Driver.Quote (Executable)}");

            compiler_flags.AddOtherFlag("-lz");
            compiler_flags.AddOtherFlag("-liconv");

            bool need_libcpp = false;

            if (App.EnableBitCode)
            {
                need_libcpp = true;
            }
#if ENABLE_BITCODE_ON_IOS
            need_libcpp = true;
#endif
            if (need_libcpp)
            {
                compiler_flags.AddOtherFlag("-lc++");
            }

            // allow the native linker to remove unused symbols (if the caller was removed by the managed linker)
            if (!bitcode)
            {
                // Note that we include *all* (__Internal) p/invoked symbols here
                // We also include any fields from [Field] attributes.
                compiler_flags.ReferenceSymbols(GetRequiredSymbols());
            }

            string mainlib;
            if (App.IsWatchExtension)
            {
                mainlib = "libwatchextension.a";
                compiler_flags.AddOtherFlag(" -e _xamarin_watchextension_main");
            }
            else if (App.IsTVExtension)
            {
                mainlib = "libtvextension.a";
            }
            else if (App.IsExtension)
            {
                mainlib = "libextension.a";
            }
            else
            {
                mainlib = "libapp.a";
            }
            var libdir  = Path.Combine(Driver.GetProductSdkDirectory(App), "usr", "lib");
            var libmain = Path.Combine(libdir, mainlib);
            compiler_flags.AddLinkWith(libmain, true);

            if (App.EnableProfiling)
            {
                string libprofiler;
                if (App.FastDev)
                {
                    libprofiler = Path.Combine(libdir, "libmono-profiler-log.dylib");
                    compiler_flags.AddLinkWith(libprofiler);
                }
                else
                {
                    libprofiler = Path.Combine(libdir, "libmono-profiler-log.a");
                    compiler_flags.AddLinkWith(libprofiler);
                    if (!App.EnableBitCode)
                    {
                        compiler_flags.ReferenceSymbol("mono_profiler_startup_log");
                    }
                }
            }

            if (!string.IsNullOrEmpty(App.UserGccFlags))
            {
                compiler_flags.AddOtherFlag(App.UserGccFlags);
            }

            if (App.DeadStrip)
            {
                compiler_flags.AddOtherFlag("-dead_strip");
            }

            if (App.IsExtension)
            {
                if (App.Platform == ApplePlatform.iOS && Driver.XcodeVersion.Major < 7)
                {
                    compiler_flags.AddOtherFlag("-lpkstart");
                    compiler_flags.AddOtherFlag($"-F {Driver.Quote (Path.Combine (Driver.GetFrameworkDirectory (App), "System/Library/PrivateFrameworks"))} -framework PlugInKit");
                }
                compiler_flags.AddOtherFlag("-fapplication-extension");
            }

            compiler_flags.Inputs = new List <string> ();
            var flags = compiler_flags.ToString();              // This will populate Inputs.

            if (!Application.IsUptodate(compiler_flags.Inputs, new string [] { Executable }))
            {
                // always show the native linker warnings since many of them turn out to be very important
                // and very hard to diagnose otherwise when hidden from the build output. Ref: bug #2430
                var linker_errors = new List <Exception> ();
                var output        = new StringBuilder();
                var code          = Driver.RunCommand(App.CompilerPath, flags, null, output);

                Application.ProcessNativeLinkerOutput(this, output.ToString(), link_with, linker_errors, code != 0);

                if (code != 0)
                {
                    // if the build failed - it could be because of missing frameworks / libraries we identified earlier
                    foreach (var assembly in Assemblies)
                    {
                        if (assembly.UnresolvedModuleReferences == null)
                        {
                            continue;
                        }

                        foreach (var mr in assembly.UnresolvedModuleReferences)
                        {
                            // TODO: add more diagnose information on the warnings
                            var name = Path.GetFileNameWithoutExtension(mr.Name);
                            linker_errors.Add(new MonoTouchException(5215, false, "References to '{0}' might require additional -framework=XXX or -lXXX instructions to the native linker", name));
                        }
                    }
                    // mtouch does not validate extra parameters given to GCC when linking (--gcc_flags)
                    if (!String.IsNullOrEmpty(App.UserGccFlags))
                    {
                        linker_errors.Add(new MonoTouchException(5201, true, "Native linking failed. Please review the build log and the user flags provided to gcc: {0}", App.UserGccFlags));
                    }
                    linker_errors.Add(new MonoTouchException(5202, true, "Native linking failed. Please review the build log.", App.UserGccFlags));
                }
                ErrorHelper.Show(linker_errors);
            }
            else
            {
                cached_executable = true;
                Driver.Log(3, "Target '{0}' is up-to-date.", Executable);
            }
            // the native linker can prefer private (and existing) over public (but non-existing) framework when weak_framework are used
            // on an iOS target version where the framework does not exists, e.g. targeting iOS6 for JavaScriptCore added in iOS7 results in
            // /System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore instead of
            // /System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore
            // more details in https://bugzilla.xamarin.com/show_bug.cgi?id=31036
            if (WeakFrameworks.Count > 0)
            {
                AdjustDylibs();
            }
            Driver.Watch("Native Link", 1);
        }