コード例 #1
0
        public override void Invoke()
        {
            // Prepare engine.
            this.Prepare();

            // Emit the project.
            Dictionary <string, string> modules = this.context.Project.Emit();

            // Create a new tool invoker instace.
            ToolInvoker toolInvoker = new ToolInvoker(this.context.Options);

            // Create a list of emitted Bitcode files.
            List <string> outputBitcodeFiles = new List <string>();

            // Create a list of emitted IR files.
            List <string> outputIrFiles = new List <string>();

            // Loop through all the emitted results.
            foreach ((string fileName, string output) in modules)
            {
                // Print output if standard output mode is enabled.
                if (this.context.Options.PrintOutputIr)
                {
                    Log.Output(output, fileName);
                }

                // Form the final, expected output file name.
                string outputFileName = Path.ChangeExtension(fileName, FileExtension.IR);

                // Resolve output IR file's path.
                string outputIrFilePath = this.context.Options.PathResolver.Output(outputFileName);

                // Append IR file to the emitted list.
                outputIrFiles.Add(outputIrFilePath);

                // Write output IR file.
                File.WriteAllText(outputIrFilePath, output);

                // TODO: Ensure it was created/it exists (IR output file).

                // Invoke the LLC tool to compile to object code (Bitcode).
                toolInvoker.Invoke(ToolType.Llc, this.GetBuildToolArgs(outputIrFilePath));

                // TODO: Also ensure it was created/it exists (Bitcode output file).

                // Determine the output bitcode file extension based on the OS.
                string extension = Util.IsWindowsOS ? FileExtension.BitcodeObj : FileExtension.BitcodeO;

                // Prepare outputted bitcode filename.
                string outputBitcodeFilePath = Path.ChangeExtension(outputIrFilePath, extension);

                // Append Bitcode file to the emitted list.
                outputBitcodeFiles.Add(outputBitcodeFilePath);
            }

            // Compute the executable's filename.
            string outputExecutableFileName = this.GetExecutableFileName();

            // Create the output executable full path.
            string outputExecutablePath = this.context.Options.PathResolver.Output(outputExecutableFileName);

            // Prepare the linker's arguments array.
            string[] linkerArgs;

            // TODO: Use wrapper for this.
            // Determine whether to use Windows configuration.
            if (Util.IsWindowsOS)
            {
                linkerArgs = this.LinkWindowsTarget(outputBitcodeFiles, outputExecutablePath);
            }
            // Otherwise, build on Unix-like.
            else
            {
                linkerArgs = this.LinkLinuxTarget(outputBitcodeFiles, outputExecutablePath);
            }

            // Compute the (linker) tool type to use.
            ToolType toolType = this.GetLinkToolType();

            // Invoke the linker with the arguments as an array.
            toolInvoker.Invoke(toolType, linkerArgs);

            // Invoke the cleanup method.
            this.Cleanup(outputIrFiles, outputBitcodeFiles);

            // Ensure program was compiled successful.
            if (!File.Exists(outputExecutablePath))
            {
                Log.Error("Could not create output executable.");
            }

            // Inform the user that the compilation was successfull.
            Log.Success("Compilation successful.");
        }
コード例 #2
0
ファイル: BuildEngine.cs プロジェクト: ronthecookie/Ion.CLI
        public override void Invoke()
        {
            // Prepare engine.
            this.Prepare();

            // Emit the project.
            Dictionary <string, string> modules = this.context.Project.Emit();

            // Create a new tool invoker instace.
            ToolInvoker toolInvoker = new ToolInvoker(this.context.Options);

            // Create a list of emitted Bitcode files.
            List <string> outputBitcodeFiles = new List <string>();

            // Create a list of emitted IR files.
            List <string> outputIrFiles = new List <string>();

            // Loop through all the emitted results.
            foreach ((string fileName, string output) in modules)
            {
                // Form the final, expected output file name.
                string outputFileName = Path.ChangeExtension(fileName, FileExtension.IR);

                // Resolve output IR file's path.
                string outputIrFilePath = this.context.Options.PathResolver.Output(outputFileName);

                // Append IR file to the emitted list.
                outputIrFiles.Add(outputIrFilePath);

                // Write output IR file.
                File.WriteAllText(outputIrFilePath, output);

                // TODO: Ensure it was created/it exists (IR output file).

                // Invoke the LLC tool to compile to object code (Bitcode).
                toolInvoker.Invoke(ToolType.LLC, new string[]
                {
                    "-filetype=obj",

                    // TODO: Hard-coded target.
                    "-mtriple=x86_64-pc-windows-msvc",
                    outputIrFilePath
                });

                // TODO: Also ensure it was created/it exists (Bitcode output file).

                // Prepare outputted bitcode filename.
                string outputBitcodeFilePath = Path.ChangeExtension(outputIrFilePath, FileExtension.Bitcode);

                // Append Bitcode file to the emitted list.
                outputBitcodeFiles.Add(outputBitcodeFilePath);
            }

            // TODO: Hard-coded extension.
            // Retrieve the application's identifier.
            string packageIdentifier = $"{this.context.Package.Identifier}.exe";

            // Create the output executable full path.
            string outputExecutablePath = this.context.Options.PathResolver.Output(packageIdentifier);

            // Resolve the Link tool's root path.
            string linkToolRoot = this.context.Options.PathResolver.ToolRoot(ToolType.Link);

            // TODO: Hard-coded for Windows.
            // Create the argument list for LLD.
            List <string> args = new List <string>
            {
                "/DEFAULTLIB:libcmt",
                $"/OUT:{outputExecutablePath}",
                $"/LIBPATH:{linkToolRoot}"
            };

            // Append all emitted bitcode files.
            args.AddRange(outputBitcodeFiles);

            // Invoke the linker with the arguments as an array.
            toolInvoker.Invoke(ToolType.Link, args.ToArray());

            // Ensure program was compiled successful.
            if (!File.Exists(outputExecutablePath))
            {
                Log.Error("Could not create output executable.");
            }

            if (!this.context.Options.KeepEmittedFiles)
            {
                // Inform the user that cleaning process has begun.
                Log.Verbose("Cleaning up output files.");

                // Cleanup emitted IR files.
                foreach (string outputIrFile in outputIrFiles)
                {
                    // Delete the file.
                    File.Delete(outputIrFile);
                }

                // Cleanup emitted Bitcode files.
                foreach (string outputBitcodeFile in outputBitcodeFiles)
                {
                    // Delete the file.
                    File.Delete(outputBitcodeFile);
                }
            }
            // Otherwise, inform the user.
            else
            {
                // Inform the user that the cleaning process will not be executed.
                Log.Verbose("Keeping emitted files.");
            }

            // Inform the user that the compilation was successfull.
            Log.Success("Compilation successful.");
        }