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];
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); }
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")}"); }
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"); } }
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 }
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"); } }
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)); } }
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). }
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). }
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); }
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(); }
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(); } }
void GetStaticCompilerFlags(CompilerFlags flags) { flags.AddOtherFlag("-c"); }
void GetDeviceCompilerFlags(CompilerFlags flags, bool is_assembler) { GetCompilerFlags(App, flags, is_assembler, Language); flags.AddOtherFlag($"-m{Driver.GetTargetMinSdkName (App)}-version-min={App.DeploymentTarget.ToString ()}"); }
public static void GetArchFlags(CompilerFlags flags, params Abi [] abis) { GetArchFlags(flags, (IEnumerable <Abi>)abis); }
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}"); } } } } } } } } }
// 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); }
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); }