Cosmos/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs

205 lines
9.1 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Win32;
using Cosmos.Build.Common;
using Cosmos.Build.MSBuild;
using Cosmos.Core.Plugs.Asm;
using Cosmos.Debug.Kernel.Plugs.Asm;
using Cosmos.IL2CPU;
using IL2CPU;
namespace Cosmos.TestRunner.Core
{
partial class Engine
{
private void RunProcess(string fileName, string workingDirectory, string[] arguments)
{
if (arguments == null)
{
throw new ArgumentNullException("arguments");
}
var xArgsString = arguments.Aggregate("", (a, b) => a + " \"" + b + "\"");
var xResult = BaseToolTask.ExecuteTool(workingDirectory, fileName, xArgsString, "IL2CPU", OutputHandler.LogError, OutputHandler.LogMessage);
if (!xResult)
{
throw new Exception("Error running process!");
}
}
private void RunExtractMapFromElfFile(string workingDir, string kernelFileName)
{
ExtractMapFromElfFile.RunObjDump(CosmosPaths.Build, workingDir, kernelFileName, OutputHandler.LogError, OutputHandler.LogMessage);
}
// TODO: Move this and GetProjectReferences to an msbuild task.
//private string GetProjectJsonLockFilePath(string kernelFileName)
//{
// string xProjectJsonPath = null;
// var xParent = Directory.GetParent(kernelFileName);
// while (xParent != null)
// {
// var xProjectJson = xParent.GetFiles("project.lock.json");
// if (xProjectJson.Any())
// {
// xProjectJsonPath = xProjectJson[0].FullName;
// break;
// }
// xParent = xParent.Parent;
// }
// if (!string.IsNullOrWhiteSpace(xProjectJsonPath))
// {
// return xProjectJsonPath;
// }
// throw new FileNotFoundException("Project json lock file not found!");
//}
//private void GetProjectReferences(string kernelFileName)
//{
// string xLockFilePath = GetProjectJsonLockFilePath(kernelFileName);
// if (File.Exists(xLockFilePath))
// {
// var xLockFile = NuGet.ProjectModel.LockFileUtilities.GetLockFile(xLockFilePath, null);
// if (xLockFile != null)
// {
// var pathContext = NuGet.Configuration.NuGetPathContext.Create(Path.GetDirectoryName(xLockFilePath));
// if (xLockFile.Libraries.Any())
// {
// var lockFileTarget = xLockFile.Targets.First(x => x.RuntimeIdentifier != null);
// if (lockFileTarget == null)
// {
// throw new Exception("No runtime targets found in the jernel project.");
// }
// foreach (var lockFileTargetLibrary in lockFileTarget.Libraries)
// {
// if (!lockFileTargetLibrary.NativeLibraries.Any())
// {
// foreach (var assembly in lockFileTargetLibrary.RuntimeAssemblies)
// {
// var lockFileLibrary = xLockFile.GetLibrary(lockFileTargetLibrary.Name, lockFileTargetLibrary.Version);
// string xAssemblyPath = Path.Combine(pathContext.UserPackageFolder, lockFileLibrary.Path, assembly.Path);
// var fileInfo = new FileInfo(xAssemblyPath);
// if (fileInfo.Exists && fileInfo.Length > 0 && AdditionalReferences.FirstOrDefault(x => x.Contains(fileInfo.Name)) == null)
// {
// AdditionalReferences.Add(fileInfo.FullName);
// }
// }
// }
// else
// {
// foreach (var assembly in lockFileTargetLibrary.NativeLibraries)
// {
// var lockFileLibrary = xLockFile.GetLibrary(lockFileTargetLibrary.Name, lockFileTargetLibrary.Version);
// string xAssemblyPath = Path.Combine(pathContext.UserPackageFolder, lockFileLibrary.Path, assembly.Path);
// var fileInfo = new FileInfo(xAssemblyPath);
// if (fileInfo.Exists && fileInfo.Length > 0 && AdditionalReferences.FirstOrDefault(x => x.Contains(fileInfo.Name)) == null)
// {
// AdditionalReferences.Add(fileInfo.FullName);
// }
// }
// }
// }
// }
// }
// }
//}
private void RunIL2CPU(string kernelFileName, string outputFile)
{
string xPath = Path.GetDirectoryName(kernelFileName);
References = new List<string>();
References.Add(kernelFileName);
References.Add(Path.Combine(xPath, "Cosmos.Core.Plugs.dll"));
References.Add(Path.Combine(xPath, "Cosmos.Core.Plugs.Asm.dll"));
References.Add(Path.Combine(xPath, "Cosmos.System.Plugs.dll"));
References.Add(Path.Combine(xPath, "Cosmos.Debug.Kernel.Plugs.Asm.dll"));
var xArguments = new List<string>
{
"DebugEnabled:true",
"StackCorruptionDetectionEnabled:" + EnableStackCorruptionChecks,
"StackCorruptionDetectionLevel:" + StackCorruptionChecksLevel,
"DebugMode:Source",
"TraceAssemblies:" + TraceAssembliesLevel,
"DebugCom:1",
"UseNAsm:True",
"OutputFilename:" + outputFile,
"EnableLogging:True",
"EmitDebugSymbols:True",
"IgnoreDebugStubAttribute:False"
};
xArguments.AddRange(References.Select(xRef => "References:" + xRef));
if (RunIL2CPUInProcess)
{
if (KernelsToRun.Count > 1)
{
throw new Exception("Cannot run multiple kernels with in-process compilation!");
}
// ensure we're using the referenced (= solution) version
CosmosAssembler.ReadDebugStubFromDisk = false;
var xResult = Program.Run(xArguments.ToArray(), OutputHandler.LogMessage, OutputHandler.LogError);
if (xResult != 0)
{
throw new Exception("Error running IL2CPU");
}
}
else
{
RunProcess(typeof(global::IL2CPU.Program).GetTypeInfo().Assembly.Location,
mBaseWorkingDirectory,
xArguments.ToArray());
}
}
private void RunNasm(string inputFile, string outputFile, bool isElf)
{
NASM.Program.LogMessage = OutputHandler.LogMessage;
NASM.Program.LogError = OutputHandler.LogError;
int xResult =NASM.Program.Run(new[]
{
$"InputFile:{inputFile}",
$"OutputFile:{outputFile}",
$"IsElf:{isElf}",
$"ExePath:{Path.Combine(GetCosmosUserkitFolder(), "build", "tools", "nasm", "nasm.exe")}"
}, OutputHandler.LogMessage, OutputHandler.LogError);
if (xResult != 0)
{
throw new Exception("Error running Nasm");
}
}
private void RunLd(string inputFile, string outputFile)
{
RunProcess(Path.Combine(GetCosmosUserkitFolder(), "build", "tools", "cygwin", "ld.exe"),
mBaseWorkingDirectory,
new[]
{
"-Ttext", "0x2000000",
"-Tdata", " 0x1000000",
"-e", "Kernel_Start",
"-o",outputFile.Replace('\\', '/'),
inputFile.Replace('\\', '/')
});
}
private static string GetCosmosUserkitFolder()
{
CosmosPaths.Initialize();
return CosmosPaths.UserKit;
}
private void MakeIso(string objectFile, string isoFile)
{
IsoMaker.Generate(objectFile, isoFile);
if (!File.Exists(isoFile))
{
throw new Exception("Error building iso");
}
}
}
}