AvalonStudio.Toolchains.Clang.ClangGCCToolchain.Link C# (CSharp) Method

Link() public method

public Link ( IConsole console, IStandardProject superProject, IStandardProject project, CompileResult assemblies, string outputPath ) : LinkResult
console IConsole
superProject IStandardProject
project IStandardProject
assemblies AvalonStudio.Toolchains.Standard.CompileResult
outputPath string
return AvalonStudio.Toolchains.Standard.LinkResult
		public override LinkResult Link(IConsole console, IStandardProject superProject, IStandardProject project,
			CompileResult assemblies, string outputPath)
		{
			var settings = GetSettings(superProject);
			var result = new LinkResult();

			var startInfo = new ProcessStartInfo();

			startInfo.FileName = Path.Combine(BaseDirectory, "arm-none-eabi-gcc" + Platform.ExecutableExtension);

			if (project.Type == ProjectType.StaticLibrary)
			{
				startInfo.FileName = Path.Combine(BaseDirectory, "arm-none-eabi-ar" + Platform.ExecutableExtension);
			}

			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;
			}

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

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

			var outputDir = Path.GetDirectoryName(outputPath);

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

			var outputName = Path.GetFileNameWithoutExtension(outputPath) + ExecutableExtension;

			if (project.Type == ProjectType.StaticLibrary)
			{
				outputName = Path.GetFileNameWithoutExtension(outputPath) + StaticLibraryExtension;
			}
			else
			{
				GenerateLinkerScript(superProject);
			}

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

			var linkedLibraries = string.Empty;

			foreach (var libraryPath in project.StaticLibraries)
			{
				var relativePath = Path.GetDirectoryName(libraryPath);

				var 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);
			}


			// TODO linked libraries won't make it in on nano... Please fix -L directory placement in compile string.
			switch (settings.LinkSettings.Library)
			{
				case LibraryType.NanoCLib:
					linkedLibraries += "-lm -lc_nano -lsupc++_nano -lstdc++_nano ";
					break;

				case LibraryType.BaseCLib:
					linkedLibraries += "-lm -lc -lstdc++ -lsupc++ ";
					break;

				case LibraryType.SemiHosting:
					linkedLibraries += "-lm -lgcc -lc -lrdimon ";
					break;

				case LibraryType.Retarget:
					linkedLibraries += "-lm -lc -lnosys -lstdc++ -lsupc++ ";
					break;
			}

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

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

			//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;
		}