Example #1
0
        public override LinkResult Link(IConsole console, Project superProject, Project project, CompileResult assemblies, string outputDirectory)
        {
            LinkResult result = new LinkResult();

            ProcessStartInfo startInfo = new ProcessStartInfo();

            startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-gcc.exe");

            if (project.Type == ProjectType.StaticLibrary)
            {
                startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-ar.exe");
            }

            startInfo.WorkingDirectory = project.Solution.CurrentDirectory;

            if (!File.Exists(startInfo.FileName))
            {
                result.ExitCode = -1;
                console.WriteLine("Unable to find linker executable (" + startInfo.FileName + ") Check project compiler settings.");
                return result;
            }

            // GenerateLinkerScript(project);

            string objectArguments = string.Empty;
            foreach (string obj in assemblies.ObjectLocations)
            {
                objectArguments += obj + " ";
            }

            string libs = string.Empty;
            foreach (string lib in assemblies.LibraryLocations)
            {
                libs += lib + " ";
            }

            if (!Directory.Exists(outputDirectory))
            {
                Directory.CreateDirectory(outputDirectory);
            }

            string outputName = Path.GetFileNameWithoutExtension(project.Location) + ".elf";

            if (project.Type == ProjectType.StaticLibrary)
            {
                outputName = "lib" + Path.GetFileNameWithoutExtension(project.Name) + ".a";
            }

            var executable = Path.Combine(outputDirectory, outputName);

            string linkedLibraries = string.Empty;

            //foreach (var libraryPath in project.SelectedConfiguration.LinkedLibraries)
            //{
            //    string relativePath = Path.GetDirectoryName(libraryPath);

            //    string libName = Path.GetFileNameWithoutExtension(libraryPath).Substring(3);

            //    linkedLibraries += string.Format(" -L\"{0}\" -l{1}", relativePath, libName);
            //}

            foreach (var lib in project.BuiltinLibraries)
            {
                linkedLibraries += string.Format("-l{0} ", lib);
            }

            // Hide console window
            startInfo.UseShellExecute = false;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;
            startInfo.RedirectStandardInput = true;
            startInfo.CreateNoWindow = true;

            startInfo.Arguments = string.Format("{0} -o{1} {2} -Wl,--start-group {3} {4} -Wl,--end-group", GetLinkerArguments(project), executable, objectArguments, linkedLibraries, libs);

            if (project.Type == ProjectType.StaticLibrary)
            {
                startInfo.Arguments = string.Format("rvs {0} {1}", executable, objectArguments);
            }

            //console.WriteLine(Path.GetFileNameWithoutExtension(startInfo.FileName) + " " + startInfo.Arguments);
            //console.WriteLine ("[LL] - " + startInfo.Arguments);

            using (var process = Process.Start(startInfo))
            {
                process.OutputDataReceived += (sender, e) =>
                {
                    //console.WriteLine(e.Data);
                };

                process.ErrorDataReceived += (sender, e) =>
                {
                    if (e.Data != null && !e.Data.Contains("creating"))
                    {
                        console.WriteLine(e.Data);
                    }
                };

                process.BeginOutputReadLine();

                process.BeginErrorReadLine();

                process.WaitForExit();

                result.ExitCode = process.ExitCode;

                if (result.ExitCode == 0)
                {
                    result.Executable = executable;
                }
            }

            return result;
        }
Example #2
0
        public override CompileResult Compile(IConsole console, Project superProject, Project project, SourceFile file, string outputFile)
        {
            CompileResult result = new CompileResult();

            var startInfo = new ProcessStartInfo();

            if (file.Language == Language.Cpp)
            {
                startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-g++.exe");
            }
            else
            {
                startInfo.FileName = Path.Combine(Settings.ToolChainLocation, "arm-none-eabi-gcc.exe");
            }

            startInfo.WorkingDirectory = project.Solution.CurrentDirectory;

            if (!File.Exists(startInfo.FileName))
            {
                result.ExitCode = -1;
                console.WriteLine("Unable to find compiler (" + startInfo.FileName + ") Please check project compiler settings.");
            }
            else
            {
                string fileArguments = string.Empty;

                if (file.Language == Language.Cpp)
                {
                    fileArguments = "-x c++ -std=c++14 -fno-use-cxa-atexit";
                }

                startInfo.Arguments = string.Format("{0} {1} {2} -o{3} -MMD -MP", GetCompilerArguments(superProject, project, file.Language), fileArguments, file.Location, outputFile);

                // Hide console window
                startInfo.UseShellExecute = false;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                startInfo.CreateNoWindow = true;

               // console.WriteLine (Path.GetFileNameWithoutExtension(startInfo.FileName) + " " + startInfo.Arguments);

                using (var process = Process.Start(startInfo))
                {
                    process.OutputDataReceived += (sender, e) =>
                    {
                        console.WriteLine(e.Data);
                    };

                    process.ErrorDataReceived += (sender, e) =>
                    {
                        if (e.Data != null)
                        {
                            console.WriteLine();
                            console.WriteLine(e.Data);
                        }
                    };

                    process.BeginOutputReadLine();

                    process.BeginErrorReadLine();

                    process.WaitForExit();

                    result.ExitCode = process.ExitCode;
                }
            }

            return result;
        }
        public override async Task<bool> Build(IConsole console, Project project)
        {
            console.WriteLine("Starting Build...");

            bool result = true;
            terminateBuild = false;

            SetFileCount(project);
            buildCount = 0;
            
            var compiledProjects = new List<CompileResult>();

            if (!terminateBuild)
            {
                await CompileProject(console, project, project, compiledProjects);

                if (!terminateBuild)
                {
                    await WaitForCompileJobs();
                    
                    foreach (var compiledReference in compiledProjects)
                    {
                        result = compiledReference.ExitCode == 0;

                        if(!result)
                        {
                            break;
                        }
                    }

                    if (result)
                    {
                        var linkedReferences = new CompileResult();
                        linkedReferences.Project = project;

                        foreach (var compiledProject in compiledProjects)
                        {
                            if (compiledProject.Project != project)
                            {
                                Link(console, project, compiledProject, linkedReferences);
                            }
                            else
                            {
                                if (linkedReferences.Count > 0)
                                {
                                    linkedReferences.ObjectLocations = compiledProject.ObjectLocations;
                                    Link(console, project, linkedReferences, linkedReferences);
                                }
                            }

                            if(linkedReferences.ExitCode != 0)
                            {
                                result = false;
                                break;
                            }
                        }
                    }

                    ClearBuildFlags(project);
                }
            }

            console.WriteLine();

            if(result && !terminateBuild)
            {
                console.WriteLine("Build Successful");
            }
            else
            {
                console.WriteLine("Build Failed");
            }

            return result;
        }
 public abstract LinkResult Link(IConsole console, Project superProject, Project project, CompileResult assemblies, string outputDirectory);
        private async Task CompileProject(IConsole console, Project superProject, Project project, List<CompileResult> results = null)
        {
            if (project.Type == ProjectType.Executable && superProject != project)
            {
                await Build(console, project);
            }
            else
            {
                if (!terminateBuild)
                {
                    if (results == null)
                    {
                        results = new List<CompileResult>();
                    }

                    foreach (var reference in project.References)
                    {
                        var loadedReference = project.GetReference(reference);

                        await CompileProject(console, superProject, loadedReference, results);
                    }

                    var outputDirectory = project.GetOutputDirectory(superProject);

                    if (!Directory.Exists(outputDirectory))
                    {
                        Directory.CreateDirectory(outputDirectory);
                    }

                    bool doWork = false;

                    lock (resultLock)
                    {
                        if (!project.IsBuilding)
                        {
                            project.IsBuilding = true;
                            doWork = true;
                        }
                    }

                    if (doWork)
                    {
                        var objDirectory = project.GetObjectDirectory(superProject);

                        if (!Directory.Exists(objDirectory))
                        {
                            Directory.CreateDirectory(objDirectory);
                        }

                        var compileResults = new CompileResult();
                        compileResults.Project = project;

                        results.Add(compileResults);

                        var tasks = new List<Task>();
                        //var parallelResult = Parallel.ForEach(project.SourceFiles, (file) =>
                        int numLocalTasks = 0;

                        foreach (var file in project.SourceFiles)
                        {
                            if (terminateBuild)
                            {
                                break;
                            }

                            if (Path.GetExtension(file.Location) == ".c" || Path.GetExtension(file.Location) == ".cpp")
                            {
                                var outputName = Path.GetFileNameWithoutExtension(file.Location) + ".o";
                                var dependencyFile = Path.Combine(objDirectory, Path.GetFileNameWithoutExtension(file.Location) + ".d");
                                var objectFile = Path.Combine(objDirectory, outputName);

                                bool dependencyChanged = false;

                                if (File.Exists(dependencyFile))
                                {
                                    List<string> dependencies = new List<string>();

                                    //lock(resultLock)
                                    {
                                        dependencies.AddRange(ProjectExtensions.GetDependencies(dependencyFile));

                                        foreach (var dependency in dependencies)
                                        {
                                            if (!File.Exists(dependency) || File.GetLastWriteTime(dependency) > File.GetLastWriteTime(objectFile))
                                            {
                                                dependencyChanged = true;
                                                break;
                                            }
                                        }
                                    }
                                }

                                if (dependencyChanged || !File.Exists(objectFile))
                                {
                                    while (numTasks >= Jobs)
                                    {
                                        Thread.Yield();
                                    }

                                    lock (resultLock)
                                    {
                                        numLocalTasks++;
                                        numTasks++;
                                        console.OverWrite(string.Format("[CC {0}/{1}]    [{2}]    {3}", ++buildCount, fileCount, project.Name, Path.GetFileName(file.Location)));
                                    }

                                    new Thread(new ThreadStart(() =>
                                    {
                                        var compileResult = Compile(console, superProject, project, file, objectFile);

                                        lock (resultLock)
                                        {
                                            if (compileResults.ExitCode == 0 && compileResult.ExitCode != 0)
                                            {
                                                terminateBuild = true;
                                                compileResults.ExitCode = compileResult.ExitCode;
                                            }
                                            else
                                            {
                                                compileResults.ObjectLocations.Add(objectFile);
                                            }

                                            numTasks--;
                                            numLocalTasks--;
                                        }
                                    })).Start();
                                }
                                else
                                {
                                    buildCount++;
                                    compileResults.ObjectLocations.Add(objectFile);
                                }
                            }
                        }
                    }
                }
            }
        }
        private void Link(IConsole console, Project superProject, CompileResult compileResult, CompileResult linkResults)
        {
            var binDirectory = compileResult.Project.GetBinDirectory(superProject);

            if (!Directory.Exists(binDirectory))
            {
                Directory.CreateDirectory(binDirectory);
            }

            string outputLocation = binDirectory;

            string executable = Path.Combine(outputLocation, compileResult.Project.Name);

            if (compileResult.Project.Type == ProjectType.StaticLibrary)
            {
                executable = Path.Combine(outputLocation, "lib" + compileResult.Project.Name);
                executable += ".a";
            }
            else
            {
                executable += ".elf";
            }

            if (!Directory.Exists(outputLocation))
            {
                Directory.CreateDirectory(outputLocation);
            }

            console.OverWrite(string.Format("[LL]    [{0}]", compileResult.Project.Name));

            var linkResult = Link(console, superProject, compileResult.Project, compileResult, outputLocation);

            if (linkResult.ExitCode == 0)
            {
                if (compileResult.Project.Type == ProjectType.StaticLibrary)
                {
                    linkResults.LibraryLocations.Add(executable);
                }
                else
                {
                    console.WriteLine();
                    Size(console, compileResult.Project, linkResult);
                    linkResults.ExecutableLocations.Add(executable);
                }
            }
            else if(linkResults.ExitCode == 0)
            {
                linkResults.ExitCode = linkResult.ExitCode;
            }
        }