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); }
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); }
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); }
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); }