public static IList <string> GetAotArguments(Application app, string filename, Abi abi, string outputDir, string outputFile, string llvmOutputFile, string dataFile) { string fname = Path.GetFileName(filename); var args = new List <string> (); bool enable_llvm = (abi & Abi.LLVM) != 0; bool enable_thumb = (abi & Abi.Thumb) != 0; bool enable_debug = app.EnableDebug; bool enable_debug_symbols = app.PackageManagedDebugSymbols; bool llvm_only = app.EnableLLVMOnlyBitCode; bool interp = app.IsInterpreted(Assembly.GetIdentity(filename)); bool interp_full = !interp && app.UseInterpreter; bool is32bit = (abi & Abi.Arch32Mask) > 0; string arch = abi.AsArchString(); args.Add("--debug"); if (enable_llvm) { args.Add("--llvm"); } if (!llvm_only && !interp) { args.Add("-O=gsharedvt"); } if (app.AotOtherArguments != null) { args.AddRange(app.AotOtherArguments); } var aot = new StringBuilder(); aot.Append("--aot=mtriple="); aot.Append(enable_thumb ? arch.Replace("arm", "thumb") : arch); aot.Append("-ios,"); aot.Append("data-outfile=").Append(dataFile).Append(","); aot.Append(app.AotArguments); if (llvm_only) { aot.Append("llvmonly,"); } else if (interp) { if (fname != "mscorlib.dll") { throw ErrorHelper.CreateError(99, Errors.MX0099, fname); } aot.Append("interp,"); } else if (interp_full) { aot.Append("interp,full,"); } else { aot.Append("full,"); } var aname = Path.GetFileNameWithoutExtension(fname); var sdk_or_product = Profile.IsSdkAssembly(aname) || Profile.IsProductAssembly(aname); if (enable_llvm) { aot.Append("nodebug,"); } else if (!(enable_debug || enable_debug_symbols)) { aot.Append("nodebug,"); } else if (app.DebugAll || app.DebugAssemblies.Contains(fname) || !sdk_or_product) { aot.Append("soft-debug,"); } aot.Append("dwarfdebug,"); /* Needed for #4587 */ if (enable_debug && !enable_llvm) { aot.Append("no-direct-calls,"); } if (!app.UseDlsym(filename)) { aot.Append("direct-pinvoke,"); } if (app.EnableMSym) { var msymdir = Path.Combine(outputDir, "Msym"); aot.Append($"msym-dir={msymdir},"); } if (enable_llvm) { aot.Append("llvm-path=").Append(GetFrameworkCurrentDirectory(app)).Append("/LLVM/bin/,"); } aot.Append("outfile=").Append(outputFile); if (enable_llvm) { aot.Append(",llvm-outfile=").Append(llvmOutputFile); } args.Add(aot.ToString()); args.Add(filename); return(args); }
bool IsRequiredSymbol(Symbol symbol, Assembly single_assembly = null, Abi?target_abis = null) { if (symbol.Ignore) { return(false); } // If this symbol is only defined for certain abis, verify if there is an abi match if (target_abis.HasValue && symbol.ValidAbis.HasValue && (target_abis.Value & symbol.ValidAbis.Value) == 0) { return(false); } // Check if this symbol is used in the assembly we're filtering to if (single_assembly != null && !symbol.Members.Any((v) => v.Module.Assembly == single_assembly.AssemblyDefinition)) { return(false); // nope, this symbol is not used in the assembly we're using as filter. } // If we're code-sharing, the managed linker might have found symbols // that are not in any of the assemblies in the current app. // This occurs because the managed linker processes all the // assemblies for all the apps together, but when linking natively // we're only linking with the assemblies that actually go into the app. if (App.Platform != ApplePlatform.MacOSX && App.IsCodeShared && symbol.Assemblies.Count > 0) { // So if this is a symbol related to any assembly, make sure // at least one of those assemblies are in the current app. if (!symbol.Assemblies.Any((v) => Assemblies.Contains(v))) { return(false); } } switch (symbol.Type) { case SymbolType.Field: return(true); case SymbolType.Function: #if MTOUCH // functions are not required if they're used in an assembly which isn't using dlsym, and we're AOT-compiling. if (App.IsSimulatorBuild) { return(true); } if (App.Platform == ApplePlatform.MacCatalyst) { return(true); } if (single_assembly != null) { return(App.UseDlsym(single_assembly.FileName)); } if (symbol.Members?.Any() == true) { foreach (var member in symbol.Members) { if (App.UseDlsym(member.Module.FileName)) { // If any assembly uses dlsym to reference this symbol, it's a required symbol that must be preserved, // because otherwise stripping the binary will cause the symbol (but not the function itself) to be removed, // preventing any assembly using dlsym to find it. return(true); } } // None of the members use dlsym (and we have at least one member), then we don't need to preserve the symbol. return(false); } #endif return(true); case SymbolType.ObjectiveCClass: // Objective-C classes are not required when we're using the static registrar and we're not compiling to shared libraries, // (because the registrar code is linked into the main app, but not each shared library, // so the registrar code won't keep symbols in the shared libraries). if (single_assembly != null) { return(true); } return(App.Registrar != RegistrarMode.Static); default: throw ErrorHelper.CreateError(99, Errors.MX0099, $"invalid symbol type {symbol.Type} for symbol {symbol.Name}"); } }
bool IsRequiredSymbol(Symbol symbol, Assembly single_assembly = null) { if (symbol.Ignore) { return(false); } // Check if this symbol is used in the assembly we're filtering to if (single_assembly != null && !symbol.Members.Any((v) => v.Module.Assembly == single_assembly.AssemblyDefinition)) { return(false); // nope, this symbol is not used in the assembly we're using as filter. } #if MTOUCH // If we're code-sharing, the managed linker might have found symbols // that are not in any of the assemblies in the current app. // This occurs because the managed linker processes all the // assemblies for all the apps together, but when linking natively // we're only linking with the assemblies that actually go into the app. if (App.IsCodeShared && symbol.Assemblies.Count > 0) { // So if this is a symbol related to any assembly, make sure // at least one of those assemblies are in the current app. if (!symbol.Assemblies.Any((v) => Assemblies.Contains(v))) { return(false); } } #endif switch (symbol.Type) { case SymbolType.Field: return(true); case SymbolType.Function: #if MTOUCH // functions are not required if they're used in an assembly which isn't using dlsym, and we're AOT-compiling. if (App.IsSimulatorBuild) { return(true); } if (single_assembly != null) { return(App.UseDlsym(single_assembly.FileName)); } if (symbol.Members != null) { foreach (var member in symbol.Members) { if (!App.UseDlsym(member.Module.FileName)) { return(false); } } } #endif return(true); case SymbolType.ObjectiveCClass: // Objective-C classes are not required when we're using the static registrar and we're not compiling to shared libraries, // (because the registrar code is linked into the main app, but not each shared library, // so the registrar code won't keep symbols in the shared libraries). if (single_assembly != null) { return(true); } return(App.Registrar != RegistrarMode.Static); default: throw ErrorHelper.CreateError(99, $"Internal error: invalid symbol type {symbol.Type} for symbol {symbol.Name}. Please file a bug report with a test case (https://bugzilla.xamarin.com)."); } }