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