public BitcodeConverter(string input, string outputFile, ApplePlatform platform, Abi abi, Version deploymentTarget)
 {
     this.input = input;
     this.outputFile = outputFile;
     this.abi = abi;
     this.platform = platform;
     deployment_target = deploymentTarget;
 }
Esempio n. 2
0
 public bool IsArchEnabled(Abi arch)
 {
     return IsArchEnabled (abis, arch);
 }
Esempio n. 3
0
 public static bool IsArchEnabled(IEnumerable<Abi> abis, Abi arch)
 {
     foreach (var abi in abis) {
         if ((abi & arch) != 0)
             return true;
     }
     return false;
 }
Esempio n. 4
0
        public static void Create(List<BuildTask> tasks, Abi abi, Target target, string ifile)
        {
            var arch = abi.AsArchString ();
            var ofile = Path.Combine (Cache.Location, "registrar." + arch + ".o");

            if (!Application.IsUptodate (ifile, ofile)) {
                tasks.Add (new RegistrarTask ()
                {
                    Target = target,
                    Abi = abi,
                    InputFile = ifile,
                    OutputFile = ofile,
                    SharedLibrary = false,
                    Language = "objective-c++",
                });
            } else {
                Driver.Log (3, "Target '{0}' is up-to-date.", ofile);
            }

            target.LinkWith (ofile);
        }
Esempio n. 5
0
        public static void Create(List<BuildTask> tasks, Target target, Abi abi, IEnumerable<Assembly> assemblies, string assemblyName, IList<string> registration_methods)
        {
            var arch = abi.AsArchString ();
            var ofile = Path.Combine (Cache.Location, "main." + arch + ".o");
            var ifile = Path.Combine (Cache.Location, "main." + arch + ".m");

            var files = assemblies.Select (v => v.FullPath);

            if (!Application.IsUptodate (files, new string [] { ifile })) {
                Driver.GenerateMain (assemblies, assemblyName, abi, ifile, registration_methods);
            } else {
                Driver.Log (3, "Target '{0}' is up-to-date.", ifile);
            }

            if (!Application.IsUptodate (ifile, ofile)) {
                var main = new MainTask ()
                {
                    Target = target,
                    Abi = abi,
                    AssemblyName = assemblyName,
                    InputFile = ifile,
                    OutputFile = ofile,
                    SharedLibrary = false,
                    Language = "objective-c++",
                };
                main.CompilerFlags.AddDefine ("MONOTOUCH");
                tasks.Add (main);
            } else {
                Driver.Log (3, "Target '{0}' is up-to-date.", ofile);
            }

            target.LinkWith (ofile);
        }
Esempio n. 6
0
 // Select all abi from the list matching the specified mask.
 List<Abi> SelectAbis(IEnumerable<Abi> abis, Abi mask)
 {
     var rv = new List<Abi> ();
     foreach (var abi in abis) {
         if ((abi & mask) != 0)
             rv.Add (abi);
     }
     return rv;
 }
Esempio n. 7
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), App.EnableMSym ? "gen-compact-seq-points" : null),
                    NextTasks = nextTasks
                }
            };
        }
Esempio n. 8
0
        IEnumerable<BuildTask> CreateCompileTasks(string s, string asm_infile, string llvm_infile, Abi abi)
        {
            var compile_tasks = new List<BuildTask> ();
            if (asm_infile != null) {
                var task = CreateCompileTask (s, asm_infile, abi);
                if (task != null)
                    compile_tasks.Add (task);
            }

            if (llvm_infile != null) {
                var taskllvm = CreateCompileTask (s, llvm_infile, abi);
                if (taskllvm != null)
                    compile_tasks.Add (taskllvm);
            }
            return compile_tasks.Count > 0 ? compile_tasks : null;
        }
Esempio n. 9
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;
        }
Esempio n. 10
0
		// note: this is executed under Parallel.ForEach
		public static string GenerateMain (IEnumerable<Assembly> assemblies, string assembly_name, Abi abi, string main_source, IList<string> registration_methods)
		{
			var assembly_externs = new StringBuilder ();
			var assembly_aot_modules = new StringBuilder ();
			var register_assemblies = new StringBuilder ();
			var enable_llvm = (abi & Abi.LLVM) != 0;

			foreach (var s in assemblies) {
				if ((abi & Abi.SimulatorArchMask) == 0) {
					var info = s.AssemblyDefinition.Name.Name;
					info = EncodeAotSymbol (info);
					assembly_externs.Append ("extern void *mono_aot_module_").Append (info).AppendLine ("_info;");
					assembly_aot_modules.Append ("\tmono_aot_register_module (mono_aot_module_").Append (info).AppendLine ("_info);");
				}
				string sname = s.FileName;
				if (assembly_name != sname && IsBoundAssembly (s))
					register_assemblies.Append ("\txamarin_open_and_register (\"").Append (sname).Append ("\");").AppendLine ();
			}

			try {
				StringBuilder sb = new StringBuilder ();
				using (var sw = new StringWriter (sb)) {
					sw.WriteLine ("#include \"xamarin/xamarin.h\"");
					// Trial builds are only executable in the next 24 hours
					
					sw.WriteLine ();
					sw.WriteLine (assembly_externs);

					sw.WriteLine ("void xamarin_register_modules_impl ()");
					sw.WriteLine ("{");
					sw.WriteLine (assembly_aot_modules);
					sw.WriteLine ("}");
					sw.WriteLine ();

					sw.WriteLine ("void xamarin_register_assemblies_impl ()");
					sw.WriteLine ("{");
					sw.WriteLine (register_assemblies);
					sw.WriteLine ("}");
					sw.WriteLine ();

					if (registration_methods != null) {
						foreach (var method in registration_methods) {
							sw.Write ("void ");
							sw.Write (method);
							sw.WriteLine ("();");
						}
					}
					sw.WriteLine ("void xamarin_setup_impl ()");
					sw.WriteLine ("{");

					if (App.EnableLLVMOnlyBitCode)
						sw.WriteLine ("\tmono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY);");

					if (app.Registrar == RegistrarMode.LegacyDynamic || app.Registrar == RegistrarMode.LegacyStatic)
						sw.WriteLine ("\txamarin_use_old_dynamic_registrar = TRUE;");
					else
						sw.WriteLine ("\txamarin_use_old_dynamic_registrar = FALSE;");

					if (registration_methods != null) {
						for (int i = 0; i < registration_methods.Count; i++) {
							sw.Write ("\t");
							sw.Write (registration_methods [i]);
							sw.WriteLine ("();");
						}
					}

					if (app.EnableDebug)
						sw.WriteLine ("\txamarin_gc_pump = {0};", debug_track.Value ? "TRUE" : "FALSE");
					sw.WriteLine ("\txamarin_init_mono_debug = {0};", app.PackageMdb ? "TRUE" : "FALSE");
					sw.WriteLine ("\txamarin_compact_seq_points = {0};", app.EnableMSym ? "TRUE" : "FALSE");
					sw.WriteLine ("\txamarin_executable_name = \"{0}\";", assembly_name);
					sw.WriteLine ("\txamarin_use_new_assemblies = {0};", app.IsUnified ? "1" : "0");
					sw.WriteLine ("\tmono_use_llvm = {0};", enable_llvm ? "TRUE" : "FALSE");
					sw.WriteLine ("\txamarin_log_level = {0};", verbose);
					sw.WriteLine ("\txamarin_arch_name = \"{0}\";", abi.AsArchString ());
					if (app.EnableDebug)
						sw.WriteLine ("\txamarin_debug_mode = TRUE;");
					if (!string.IsNullOrEmpty (app.MonoGCParams))
						sw.WriteLine ("\tsetenv (\"MONO_GC_PARAMS\", \"{0}\", 1);", app.MonoGCParams);
					foreach (var kvp in environment_variables)
						sw.WriteLine ("\tsetenv (\"{0}\", \"{1}\", 1);", kvp.Key.Replace ("\"", "\\\""), kvp.Value.Replace ("\"", "\\\""));
					sw.WriteLine ("}");
					sw.WriteLine ();
					sw.Write ("int ");
					sw.Write (app.IsWatchExtension ? "xamarin_watchextension_main" : "main");
					sw.WriteLine (" (int argc, char **argv)");
					sw.WriteLine ("{");
					sw.WriteLine ("\tNSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];");
					if (app.IsExtension) {
						// the name of the executable must be the bundle id (reverse dns notation)
						// but we do not want to impose that (ugly) restriction to the managed .exe / project name / ...
						sw.WriteLine ("\targv [0] = \"{0}\";", Path.GetFileNameWithoutExtension (app.RootAssembly));
						sw.WriteLine ("\tint rv = xamarin_main (argc, argv, true);");
					} else {
						sw.WriteLine ("\tint rv = xamarin_main (argc, argv, false);");
					}
					sw.WriteLine ("\t[pool drain];");
					sw.WriteLine ("\treturn rv;");
					sw.WriteLine ("}");

					sw.WriteLine ("void xamarin_initialize_callbacks () __attribute__ ((constructor));");
					sw.WriteLine ("void xamarin_initialize_callbacks ()");
					sw.WriteLine ("{");
					sw.WriteLine ("\txamarin_setup = xamarin_setup_impl;");
					sw.WriteLine ("\txamarin_register_assemblies = xamarin_register_assemblies_impl;");
					sw.WriteLine ("\txamarin_register_modules = xamarin_register_modules_impl;");
					sw.WriteLine ("}");

				}
				WriteIfDifferent (main_source, sb.ToString ());
			} catch (MonoTouchException) {
				throw;
			} catch (Exception e) {
				throw new MonoTouchException (4001, true, e, "The main template could not be expanded to `{0}`.", main_source);
			}

			return main_source;
		}
Esempio n. 11
0
		public static string GetAotArguments (string filename, Abi abi, string outputDir, string outputFile, string llvmOutputFile, string dataFile)
		{
			string fname = Path.GetFileName (filename);
			StringBuilder args = new StringBuilder ();
			bool enable_llvm = (abi & Abi.LLVM) != 0;
			bool enable_thumb = (abi & Abi.Thumb) != 0;
			bool enable_debug = app.EnableDebug;
			bool enable_mdb = app.PackageMdb;
			bool llvm_only = app.EnableLLVMOnlyBitCode;
			string arch = abi.AsArchString ();

			args.Append ("--debug ");

			if (enable_llvm)
				args.Append ("--llvm ");

			if (!llvm_only)
				args.Append ("-O=gsharedvt ");
			args.Append (aot_other_args).Append (" ");
			args.Append ("--aot=mtriple=");
			args.Append (enable_thumb ? arch.Replace ("arm", "thumb") : arch);
			args.Append ("-ios,");
			args.Append ("data-outfile=").Append (Quote (dataFile)).Append (",");
			args.Append (aot_args);
			if (llvm_only)
				args.Append ("llvmonly,");
			else
				args.Append ("full,");

			var aname = Path.GetFileNameWithoutExtension (fname);
			var sdk_or_product = Profile.IsSdkAssembly (aname) || Profile.IsProductAssembly (aname);

			if (enable_llvm)
				args.Append ("nodebug,");
			else if (!(enable_debug || enable_mdb))
				args.Append ("nodebug,");
			else if (debug_all || debug_assemblies.Contains (fname) || !sdk_or_product)
				args.Append ("soft-debug,");

			args.Append ("dwarfdebug,");

			/* Needed for #4587 */
			if (enable_debug && !enable_llvm)
				args.Append ("no-direct-calls,");

			if (!app.UseDlsym (filename))
				args.Append ("direct-pinvoke,");

			if (app.EnableMSym)
				args.Append ("gen-seq-points-file,");

			if (enable_llvm)
				args.Append ("llvm-path=").Append (MonoTouchDirectory).Append ("/LLVM/bin/,");

			if (!llvm_only)
				args.Append ("outfile=").Append (Quote (outputFile));
			if (!llvm_only && enable_llvm)
				args.Append (",");
			if (enable_llvm)
				args.Append ("llvm-outfile=").Append (Quote (llvmOutputFile));
			args.Append (" \"").Append (filename).Append ("\"");
			return args.ToString ();
		}
Esempio n. 12
0
        string GenerateConstructor(Abi constructorAbi)
        {
            string inputConstructorArg = string.Empty;
            string inputEncoders       = string.Empty;
            bool   hasInputs           = constructorAbi?.Inputs.Length > 0;

            if (hasInputs)
            {
                var inputs = GenerateInputs(constructorAbi.Inputs);
                inputConstructorArg = GenerateInputString(inputs) + ", ";

                var encoderLines = new string[inputs.Length];

                for (var i = 0; i < inputs.Length; i++)
                {
                    var    input = inputs[i];
                    string encoderLine;
                    if (input.AbiType.IsMultiDimensionalArray)
                    {
                        encoderLine = $"EncoderFactory.LoadMultiDimArrayEncoder(\"{input.SolidityTypeName}\", {input.Identifier})";
                    }
                    else if (input.AbiType.IsArrayType)
                    {
                        string arrayElementType = GetArrayElementClrTypeName(input.AbiType);
                        string arrayItemEncoder = $"EncoderFactory.LoadEncoder(\"{input.AbiType.ArrayItemInfo.SolidityName}\", default({arrayElementType}))";
                        encoderLine = $"EncoderFactory.LoadEncoder(\"{input.SolidityTypeName}\", {input.Identifier}, {arrayItemEncoder})";
                    }
                    else
                    {
                        encoderLine = $"EncoderFactory.LoadEncoder(\"{input.SolidityTypeName}\", {input.Identifier})";
                    }

                    encoderLines[i] = encoderLine;
                }

                inputEncoders = string.Join(", ", encoderLines);
            }

            var(summaryDoc, paramsDoc) = constructorAbi != null?GetSummaryXmlDoc(constructorAbi) : (string.Empty, string.Empty);

            string extraSummaryDoc = GetContractSummaryXmlDoc();

            var contractAttrString = $"TypeAttributeCache<{_contractName}, {typeof(SolidityContractAttribute).FullName}>.Attribute";

            string deploymentLine;
            string encodedParamsLine = string.Empty;

            if (constructorAbi?.Inputs?.Length > 0)
            {
                encodedParamsLine = $@"
                    var encodedParams = {typeof(EncoderUtil).FullName}.{nameof(EncoderUtil.Encode)}(
                        {inputEncoders}
                    );";
            }
            else
            {
                encodedParamsLine = "var encodedParams = Array.Empty<byte>();";
            }

            deploymentLine = $"var contractAddr = await ContractFactory.Deploy({contractAttrString}, rpcClient, BYTECODE_BYTES.Value, transactionParams, encodedParams);";

            string xmlDoc = $@"
                    /// <summary>
                    /// Deploys the contract. {extraSummaryDoc} <para/>{summaryDoc}
                    /// </summary>
                    {paramsDoc}
                    /// <param name=""rpcClient"">The RPC client to be used for this contract instance.</param>
                    /// <param name=""defaultFromAccount"">If null then the first account returned by eth_accounts will be used.</param>
                    /// <returns>An contract instance pointed at the deployed contract address.</returns>
            ";

            string methodAttributes = string.Empty;

            if (string.IsNullOrEmpty(_contractInfo.Bytecode))
            {
                methodAttributes = "[Obsolete(\"This contract does not implement all functions and cannot be deployed.\")]";
            }

            return($@"
                    public {_contractName}() {{ }}
                    {xmlDoc}
                    {methodAttributes}
                    public static async Task<{_contractName}> Deploy(
                            {inputConstructorArg}
                            {JsonRpcClientType} rpcClient,
                            TransactionParams transactionParams = null,
                        Address? defaultFromAccount = null)
                    {{
                        transactionParams = transactionParams ?? new TransactionParams();
                        defaultFromAccount = defaultFromAccount ?? transactionParams.From ?? (await rpcClient.Accounts())[0];
                        transactionParams.From = transactionParams.From ?? defaultFromAccount;
                    
                        {encodedParamsLine}
                        {deploymentLine}

                        return new {_contractName}(rpcClient, contractAddr, defaultFromAccount.Value);
                    }}

                    {xmlDoc}
                    {methodAttributes}
                    public static ContractDeployer<{_contractName}> New(
                            {inputConstructorArg}
                            {JsonRpcClientType} rpcClient,
                            TransactionParams transactionParams = null,
                        Address? defaultFromAccount = null)
                    {{
                        {encodedParamsLine}

                        return new ContractDeployer<{_contractName}>(rpcClient, BYTECODE_BYTES.Value, transactionParams, defaultFromAccount, encodedParams);
                    }}
            ");
        }