Ejemplo n.º 1
0
        protected async Task <int> CompileAsync()
        {
            if (App.IsDeviceBuild)
            {
                GetDeviceCompilerFlags(CompilerFlags, IsAssembler);
            }
            else
            {
                GetSimulatorCompilerFlags(CompilerFlags, IsAssembler, App, Language);
            }

            if (App.EnableBitCode)
            {
                GetBitcodeCompilerFlags(CompilerFlags);
            }
            GetArchFlags(CompilerFlags, Abi);

            if (SharedLibrary)
            {
                GetSharedCompilerFlags(CompilerFlags, InstallName);
            }
            else
            {
                GetStaticCompilerFlags(CompilerFlags);
            }

            if (App.EnableDebug)
            {
                CompilerFlags.AddDefine("DEBUG");
            }

            CompilerFlags.AddOtherFlag("-o", OutputFile);

            if (!string.IsNullOrEmpty(Language))
            {
                CompilerFlags.AddOtherFlag("-x", Language);
            }

            Directory.CreateDirectory(Path.GetDirectoryName(OutputFile));

            var exceptions      = new List <Exception> ();
            var output          = new List <string> ();
            var assembly_name   = Path.GetFileNameWithoutExtension(OutputFile);
            var output_received = new Action <string> ((string line) => {
                if (line == null)
                {
                    return;
                }
                output.Add(line);
                CheckFor5107(assembly_name, line, exceptions);
            });

            var rv = await Driver.RunCommandAsync(App.CompilerPath, CompilerFlags.ToArray(), null, output_received, suppressPrintOnErrors : true);

            WriteLimitedOutput(rv != 0 ? $"Compilation failed with code {rv}, command:\n{App.CompilerPath} {CompilerFlags.ToString ()}" : null, output, exceptions);

            ErrorHelper.Show(exceptions);

            return(rv);
        }
Ejemplo n.º 2
0
        public void Initialize(bool show_warnings)
        {
            // we want to load our own mscorlib[-runtime].dll, not something else we're being feeded
            // (e.g. bug #6612) since it might not match the libmono[-sgen].a library we'll link with,
            // so load the corlib we want first.

            var corlib_path = Path.Combine(Resolver.FrameworkDirectory, "mscorlib.dll");
            var corlib      = ManifestResolver.Load(corlib_path);

            if (corlib == null)
            {
                throw new MonoTouchException(2006, true, "Can not load mscorlib.dll from: '{0}'. Please reinstall Xamarin.iOS.", corlib_path);
            }

            foreach (var reference in App.References)
            {
                var ad = ManifestResolver.Load(reference);
                if (ad == null)
                {
                    throw new MonoTouchException(2002, true, "Can not resolve reference: {0}", reference);
                }
                if (ad.MainModule.Runtime > TargetRuntime.Net_4_0)
                {
                    ErrorHelper.Show(new MonoTouchException(11, false, "{0} was built against a more recent runtime ({1}) than Xamarin.iOS supports.", Path.GetFileName(reference), ad.MainModule.Runtime));
                }

                // Figure out if we're referencing Xamarin.iOS or monotouch.dll
                if (Path.GetFileNameWithoutExtension(ad.MainModule.FileName) == Driver.GetProductAssembly(App))
                {
                    ProductAssembly = ad;
                }
            }

            ComputeListOfAssemblies();

            if (App.LinkMode == LinkMode.None && App.I18n != I18nAssemblies.None)
            {
                AddI18nAssemblies();
            }

            // an extension is a .dll and it would match itself
            if (App.IsExtension)
            {
                return;
            }

            var root_wo_ext = Path.GetFileNameWithoutExtension(App.RootAssembly);

            foreach (var assembly in Assemblies)
            {
                if (!assembly.FullPath.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
                {
                    if (root_wo_ext == Path.GetFileNameWithoutExtension(assembly.FullPath))
                    {
                        throw new MonoTouchException(23, true, "Application name '{0}.exe' conflicts with another user assembly.", root_wo_ext);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public virtual AssemblyDefinition Load(string fileName)
        {
            if (!File.Exists(fileName))
            {
                return(null);
            }

            AssemblyDefinition assembly;
            var name = Path.GetFileNameWithoutExtension(fileName);

            if (cache.TryGetValue(name, out assembly))
            {
                return(assembly);
            }

            try {
                fileName = Target.GetRealPath(fileName);

                // Check the architecture-specific directory
                if (Path.GetDirectoryName(fileName) == FrameworkDirectory && !string.IsNullOrEmpty(ArchDirectory))
                {
                    var archName = Path.Combine(ArchDirectory, Path.GetFileName(fileName));
                    if (File.Exists(archName))
                    {
                        fileName = archName;
                    }
                }

                var parameters = CreateDefaultReaderParameters(fileName);
                try {
                    assembly = ModuleDefinition.ReadModule(fileName, parameters).Assembly;
                    params_cache [assembly.Name.ToString()] = parameters;
                    if (!assembly.MainModule.HasSymbols)
                    {
                        // We Cecil didn't load symbols, but there's a pdb, then something went wrong loading it (maybe an old-style pdb?).
                        // Warn about this.
                        var pdb = Path.ChangeExtension(fileName, "pdb");
                        if (File.Exists(pdb))
                        {
                            ErrorHelper.Show(ErrorHelper.CreateWarning(178, Errors.MX0178, fileName));
                        }
                    }
                }
                catch (SymbolsNotMatchingException) {
                    parameters.ReadSymbols          = false;
                    parameters.SymbolReaderProvider = null;
                    assembly = ModuleDefinition.ReadModule(fileName, parameters).Assembly;
                    // only report the warning (on symbols) if we can actually load the assembly itself (otherwise it's more confusing than helpful)
                    ErrorHelper.Show(ErrorHelper.CreateWarning(129, Errors.MX0129, fileName));
                }
            }
            catch (Exception e) {
                throw new ProductException(9, true, e, Errors.MX0009, fileName);
            }
            return(CacheAssembly(assembly));
        }
Ejemplo n.º 4
0
        public virtual AssemblyDefinition Load(string fileName)
        {
            if (!File.Exists(fileName))
            {
                return(null);
            }

            AssemblyDefinition assembly;
            var name = Path.GetFileNameWithoutExtension(fileName);

            if (cache.TryGetValue(name, out assembly))
            {
                return(assembly);
            }

            try {
                fileName = Target.GetRealPath(fileName);

                // Check the architecture-specific directory
                if (Path.GetDirectoryName(fileName) == FrameworkDirectory && !string.IsNullOrEmpty(ArchDirectory))
                {
                    var archName = Path.Combine(ArchDirectory, Path.GetFileName(fileName));
                    if (File.Exists(archName))
                    {
                        fileName = archName;
                    }
                }

                var parameters = CreateDefaultReaderParameters(fileName);
                try {
                    assembly = ModuleDefinition.ReadModule(fileName, parameters).Assembly;
                    params_cache [assembly.Name.ToString()] = parameters;
                }
                catch (InvalidOperationException e) {
                    // cecil use the default message so it's not very helpful to detect the root cause
                    if (!e.TargetSite.ToString().Contains("Void ReadSymbols(Mono.Cecil.Cil.ISymbolReader)"))
                    {
                        throw;
                    }
                    parameters.ReadSymbols          = false;
                    parameters.SymbolReaderProvider = null;
                    assembly = ModuleDefinition.ReadModule(fileName, parameters).Assembly;
                    // only report the warning (on symbols) if we can actually load the assembly itself (otherwise it's more confusing than helpful)
                    ErrorHelper.Show(ErrorHelper.CreateWarning(129, $"Debugging symbol file for '{fileName}' does not match the assembly and is ignored."));
                }
            }
            catch (Exception e) {
                throw new ProductException(9, true, e, "Error while loading assemblies: {0}", fileName);
            }
            cache.Add(name, assembly);
            return(assembly);
        }
Ejemplo n.º 5
0
 public static int Main(string [] args)
 {
     try {
         Console.OutputEncoding = new UTF8Encoding(false, false);
         SetCurrentLanguage();
         return(Main2(args));
     } catch (Exception e) {
         ErrorHelper.Show(e);
     } finally {
         Watch("Total time", 0);
     }
     return(0);
 }
Ejemplo n.º 6
0
        protected override async Task ExecuteAsync()
        {
            // 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          = await Driver.RunCommandAsync(Target.App.CompilerPath, CompilerFlags.ToString(), null, output);

            Application.ProcessNativeLinkerOutput(Target, output.ToString(), CompilerFlags.AllLibraries, 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 Target.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(Target.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}", Target.App.UserGccFlags));
                }
                linker_errors.Add(new MonoTouchException(5202, true, "Native linking failed. Please review the build log.", Target.App.UserGccFlags));
            }
            ErrorHelper.Show(linker_errors);

            // 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 (Target.WeakFrameworks.Count > 0)
            {
                Target.AdjustDylibs();
            }
            Driver.Watch("Native Link", 1);
        }
Ejemplo n.º 7
0
        public virtual AssemblyDefinition Load(string fileName)
        {
            if (!File.Exists(fileName))
            {
                return(null);
            }

            AssemblyDefinition assembly;
            var name = Path.GetFileNameWithoutExtension(fileName);

            if (cache.TryGetValue(name, out assembly))
            {
                return(assembly);
            }

            try {
                fileName = Target.GetRealPath(fileName);

                // Check the architecture-specific directory
                if (Path.GetDirectoryName(fileName) == FrameworkDirectory && !string.IsNullOrEmpty(ArchDirectory))
                {
                    var archName = Path.Combine(ArchDirectory, Path.GetFileName(fileName));
                    if (File.Exists(archName))
                    {
                        fileName = archName;
                    }
                }

                var parameters = CreateDefaultReaderParameters(fileName);
                try {
                    assembly = ModuleDefinition.ReadModule(fileName, parameters).Assembly;
                    params_cache [assembly.Name.ToString()] = parameters;
                }
                catch (SymbolsNotMatchingException) {
                    parameters.ReadSymbols          = false;
                    parameters.SymbolReaderProvider = null;
                    assembly = ModuleDefinition.ReadModule(fileName, parameters).Assembly;
                    // only report the warning (on symbols) if we can actually load the assembly itself (otherwise it's more confusing than helpful)
                    ErrorHelper.Show(ErrorHelper.CreateWarning(129, Errors.MX0129, fileName));
                }
            }
            catch (Exception e) {
                throw new ProductException(9, true, e, Errors.MX0009, fileName);
            }
            cache.Add(name, assembly);
            return(assembly);
        }
Ejemplo n.º 8
0
        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
                                      } });
        }
Ejemplo n.º 9
0
        protected override async Task ExecuteAsync()
        {
            // 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 cmd_length    = Target.App.CompilerPath.Length + 1 + CompilerFlags.ToString().Length;

            try {
                var code = await Driver.RunCommandAsync(Target.App.CompilerPath, CompilerFlags.ToArray(), null, output, suppressPrintOnErrors : true);

                Application.ProcessNativeLinkerOutput(Target, output.ToString(), CompilerFlags.AllLibraries, linker_errors, code != 0);

                if (code != 0)
                {
                    Console.WriteLine($"Process exited with code {code}, command:\n{Target.App.CompilerPath} {CompilerFlags.ToString ()}\n{output} ");
                    // if the build failed - it could be because of missing frameworks / libraries we identified earlier
                    foreach (var assembly in Target.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, Errors.MT5215, name));
                        }
                    }
                    // mtouch does not validate extra parameters given to GCC when linking (--gcc_flags)
                    if (Target.App.UserGccFlags?.Count > 0)
                    {
                        linker_errors.Add(new MonoTouchException(5201, true, Errors.MT5201, StringUtils.FormatArguments(Target.App.UserGccFlags)));
                    }
                    else
                    {
                        linker_errors.Add(new MonoTouchException(5202, true, Errors.MT5202));
                    }

                    if (code == 255)
                    {
                        // check command length
                        // getconf ARG_MAX
                        StringBuilder getconf_output = new StringBuilder();
                        if (Driver.RunCommand("getconf", new [] { "ARG_MAX" }, output: getconf_output, suppressPrintOnErrors: true) == 0)
                        {
                            int arg_max;
                            if (int.TryParse(getconf_output.ToString().Trim(' ', '\t', '\n', '\r'), out arg_max))
                            {
                                if (cmd_length > arg_max)
                                {
                                    linker_errors.Add(ErrorHelper.CreateError(5217, Errors.MT5217, cmd_length));
                                }
                                else
                                {
                                    Driver.Log(3, $"Linker failure is probably not due to command-line length (actual: {cmd_length} limit: {arg_max}");
                                }
                            }
                            else
                            {
                                Driver.Log(3, "Failed to parse 'getconf ARG_MAX' output: {0}", getconf_output);
                            }
                        }
                        else
                        {
                            Driver.Log(3, "Failed to execute 'getconf ARG_MAX'\n{0}", getconf_output);
                        }
                    }
                }
            } catch (System.ComponentModel.Win32Exception wex) {
                /* This means we failed to execute the linker, not that the linker itself returned with a failure */
                if (wex.NativeErrorCode == 7 /* E2BIG = Too many arguments */)
                {
                    linker_errors.Add(ErrorHelper.CreateError(5217, wex, Errors.MT5217, cmd_length));
                }
                else
                {
                    linker_errors.Add(ErrorHelper.CreateError(5222, wex, Errors.MX5222, wex.Message));
                }
            }

            ErrorHelper.Show(linker_errors);

            // 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 (CompilerFlags.WeakFrameworks.Count > 0)
            {
                Target.AdjustDylibs(OutputFile);
            }
            Driver.Watch("Native Link", 1);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
0
        protected override async Task ExecuteAsync()
        {
            // 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          = await Driver.RunCommandAsync(Target.App.CompilerPath, CompilerFlags.ToString(), null, output);

            Application.ProcessNativeLinkerOutput(Target, output.ToString(), CompilerFlags.AllLibraries, 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 Target.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(Target.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}", Target.App.UserGccFlags));
                }
                linker_errors.Add(new MonoTouchException(5202, true, "Native linking failed. Please review the build log.", Target.App.UserGccFlags));

                if (code == 255)
                {
                    // check command length
                    // getconf ARG_MAX
                    StringBuilder getconf_output = new StringBuilder();
                    if (Driver.RunCommand("getconf", "ARG_MAX", output: getconf_output, suppressPrintOnErrors: true) == 0)
                    {
                        int arg_max;
                        if (int.TryParse(getconf_output.ToString().Trim(' ', '\t', '\n', '\r'), out arg_max))
                        {
                            var cmd_length = Target.App.CompilerPath.Length + 1 + CompilerFlags.ToString().Length;
                            if (cmd_length > arg_max)
                            {
                                linker_errors.Add(ErrorHelper.CreateWarning(5217, $"Native linking possibly failed because the linker command line was too long ({cmd_length} characters)."));
                            }
                            else
                            {
                                Driver.Log(3, $"Linker failure is probably not due to command-line length (actual: {cmd_length} limit: {arg_max}");
                            }
                        }
                        else
                        {
                            Driver.Log(3, "Failed to parse 'getconf ARG_MAX' output: {0}", getconf_output);
                        }
                    }
                    else
                    {
                        Driver.Log(3, "Failed to execute 'getconf ARG_MAX'\n{0}", getconf_output);
                    }
                }
            }
            ErrorHelper.Show(linker_errors);

            // 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 (CompilerFlags.WeakFrameworks.Count > 0)
            {
                Target.AdjustDylibs(OutputFile);
            }
            Driver.Watch("Native Link", 1);
        }
Ejemplo n.º 12
0
        public void InitializeCommon()
        {
            SelectRegistrar();
            SelectMonoNative();

            RuntimeOptions = RuntimeOptions.Create(this, HttpMessageHandler, TlsProvider);

            if (RequiresXcodeHeaders && SdkVersion < SdkVersions.GetVersion(this))
            {
                switch (Platform)
                {
                case ApplePlatform.iOS:
                case ApplePlatform.TVOS:
                case ApplePlatform.WatchOS:
                    throw ErrorHelper.CreateError(180, Errors.MX0180, ProductName, PlatformName, SdkVersions.GetVersion(this), SdkVersions.Xcode);

                case ApplePlatform.MacOSX:
                    throw ErrorHelper.CreateError(179, Errors.MX0179, ProductName, PlatformName, SdkVersions.GetVersion(this), SdkVersions.Xcode);

                default:
                    // Default to the iOS error message, it's better than showing MX0071 (unknown platform), which would be completely unrelated
                    goto case ApplePlatform.iOS;
                }
            }

            if (DeploymentTarget != null)
            {
                if (DeploymentTarget < Xamarin.SdkVersions.GetMinVersion(this))
                {
                    throw new ProductException(73, true, Errors.MT0073, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetMinVersion(this), PlatformName, ProductName);
                }
                if (DeploymentTarget > Xamarin.SdkVersions.GetVersion(this))
                {
                    throw new ProductException(74, true, Errors.MX0074, Constants.Version, DeploymentTarget, Xamarin.SdkVersions.GetVersion(this), PlatformName, ProductName);
                }
            }

            if (Platform == ApplePlatform.WatchOS && EnableCoopGC.HasValue && !EnableCoopGC.Value)
            {
                throw ErrorHelper.CreateError(88, Errors.MT0088);
            }

            if (!EnableCoopGC.HasValue)
            {
                EnableCoopGC = Platform == ApplePlatform.WatchOS;
            }

            SetObjectiveCExceptionMode();
            SetManagedExceptionMode();

            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, out var messages);
            ErrorHelper.Show(messages);
            if (Driver.Verbosity > 3)
            {
                Driver.Log(4, $"Enabled optimizations: {Optimizations}");
            }
        }