diff --git a/Nerfed.Compiler/CSProject.cs b/Nerfed.Compiler/CSProject.cs
new file mode 100644
index 0000000..9e58acd
--- /dev/null
+++ b/Nerfed.Compiler/CSProject.cs
@@ -0,0 +1,62 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Nerfed.Compiler;
+
+public class CSProject
+{
+ public string Name { get; set; }
+ public string Guid { get; set; }
+ //public bool IsEditor { get; set; }
+ // Add platform stuff here..?
+ // Add dll's here..?
+ // Add dependencies here..?
+
+ public static bool Create(string projectFilePath, string name, out CSProject project)
+ {
+ project = null;
+
+ if (File.Exists(projectFilePath))
+ {
+ Console.WriteLine($"ERROR: File already exists!");
+ return false;
+ }
+
+ // Create project file.
+ project = new CSProject
+ {
+ Name = name,
+ Guid = System.Guid.NewGuid().ToString("B").ToUpper(),
+ };
+
+ return true;
+ }
+
+ public static bool Save(CSProject project, string projectFilePath)
+ {
+ string jsonString = JsonSerializer.Serialize(project, CSProjectContext.Default.CSProject);
+
+ File.WriteAllText(projectFilePath, jsonString);
+
+ return true;
+ }
+
+ public static bool Open(string projectFilePath, out CSProject project)
+ {
+ string jsonString = File.ReadAllText(projectFilePath);
+ project = JsonSerializer.Deserialize(jsonString, CSProjectContext.Default.CSProject);
+
+ if (project == null)
+ {
+ Console.WriteLine($"ERROR: Could not open {typeof(CSProject)}.");
+ return false;
+ }
+
+ return true;
+ }
+}
+
+[JsonSerializable(typeof(CSProject))]
+public partial class CSProjectContext : JsonSerializerContext
+{
+}
\ No newline at end of file
diff --git a/Nerfed.Compiler/Compiler.cs b/Nerfed.Compiler/Compiler.cs
new file mode 100644
index 0000000..9433833
--- /dev/null
+++ b/Nerfed.Compiler/Compiler.cs
@@ -0,0 +1,229 @@
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Text.Json;
+
+namespace Nerfed.Compiler;
+
+public static class Compiler
+{
+ public const string CSProjectFileName = ".csproject";
+ public const string CSProjFileName = ".csproj";
+
+ public static bool Compile(string projectFilePath, string configuration = "Debug")
+ {
+ string projectPath = Path.GetDirectoryName(projectFilePath);
+
+ if (!File.Exists(projectFilePath))
+ {
+ Console.WriteLine($"ERROR: Project file not found at {projectPath}.");
+ return false;
+ }
+
+ if (!Project.Open(projectFilePath, out Project project))
+ {
+ return false;
+ }
+
+ // TODO: Check project version, to make sure we can compile it or something...
+
+ // Generate solution.
+ GenerateSolution(projectPath, project, out string solutionFilePath);
+
+ // Compile solution.
+ ProcessStartInfo processInfo = new()
+ {
+ WorkingDirectory = Path.GetDirectoryName(solutionFilePath),
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardError = true,
+ RedirectStandardOutput = true,
+ };
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ processInfo.FileName = "/bin/bash";
+ processInfo.Arguments = $"-c \"dotnet build '{Path.GetFileName(solutionFilePath)}'\"" + (string.IsNullOrWhiteSpace(configuration) ? $" --configuration {configuration}" : "");
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ processInfo.FileName = "cmd.exe";
+ processInfo.Arguments = $"/c dotnet build \"{Path.GetFileName(solutionFilePath)}\"" + (string.IsNullOrWhiteSpace(configuration) ? $" --configuration {configuration}" : "");
+ }
+ else
+ {
+ return false;
+ }
+
+ Process process = Process.Start(processInfo) ?? throw new Exception();
+ process.OutputDataReceived += (sender, dataArgs) => {
+ string data = dataArgs.Data;
+
+ if (data is null)
+ {
+ return;
+ }
+
+ Console.WriteLine(data);
+ };
+
+ process.BeginOutputReadLine();
+ process.BeginErrorReadLine();
+ process.ErrorDataReceived += (sender, dataArgs) => {
+ if (dataArgs.Data is not null)
+ {
+ Console.WriteLine(dataArgs.Data);
+ }
+ };
+
+ process.WaitForExit();
+
+ int exitCode = process.ExitCode;
+ process.Close();
+
+ return true;
+ }
+
+ public static void GenerateSolution(string projectPath, Project project, out string solutionPath)
+ {
+ // Clear files.
+ string[] csProjectFiles = Directory.GetFiles(projectPath, CSProjFileName, SearchOption.TopDirectoryOnly);
+ foreach (string csProjFile in csProjectFiles)
+ {
+ File.Delete(csProjFile);
+ }
+
+ // Generate projects.
+ string[] csProjectFilePaths = Directory.GetFiles(projectPath, CSProjectFileName, SearchOption.AllDirectories);
+ foreach (string csProjectFilePath in csProjectFilePaths)
+ {
+ GenerateCSProject(csProjectFilePath, projectPath);
+ }
+
+ // Generate solution.
+ string[] csProjPaths = Directory.GetFiles(projectPath, CSProjFileName, SearchOption.TopDirectoryOnly);
+ string[] csProjGuids = new string[csProjPaths.Length];
+ for (int i = 0; i < csProjPaths.Length; i++)
+ {
+ csProjGuids[i] = Guid.NewGuid().ToString("B").ToUpper();
+ }
+
+ StringBuilder solutionContent = new StringBuilder();
+
+ // Write the solution file header
+ solutionContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00");
+ solutionContent.AppendLine("# Visual Studio Version 17");
+ solutionContent.AppendLine("VisualStudioVersion = 17.10.35013.160");
+ solutionContent.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1");
+
+ // Add each project to the solution file
+ for (int i = 0; i < csProjPaths.Length; i++)
+ {
+ string csProjPath = csProjPaths[i];
+ string projectGuid = csProjGuids[i];
+ string projectName = Path.GetFileNameWithoutExtension(csProjPath);
+ // FAE04EC0-301F-11D3-BF4B-00C04F79EFBC for C# projects.
+ solutionContent.AppendLine($"Project(\"{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}\") = \"{projectName}\", \"{csProjPath}\", \"{projectGuid}\"");
+ solutionContent.AppendLine("EndProject");
+ }
+
+ // Add global sections (these can be extended as needed)
+ solutionContent.AppendLine("Global");
+ solutionContent.AppendLine(" GlobalSection(SolutionConfigurationPlatforms) = preSolution");
+ solutionContent.AppendLine(" Test|x64 = Test|x64");
+ solutionContent.AppendLine(" Release|x64 = Release|x64");
+ solutionContent.AppendLine(" Debug|x64 = Debug|x64");
+ solutionContent.AppendLine(" EndGlobalSection");
+ solutionContent.AppendLine(" GlobalSection(ProjectConfigurationPlatforms) = postSolution");
+
+ for (int i = 0; i < csProjPaths.Length; i++)
+ {
+ string projectGuid = csProjGuids[i];
+ solutionContent.AppendLine($" {projectGuid}.Test|x64.ActiveCfg = Test|x64");
+ solutionContent.AppendLine($" {projectGuid}.Test|x64.Build.0 = Test|x64");
+ solutionContent.AppendLine($" {projectGuid}.Release|x64.ActiveCfg = Release|x64");
+ solutionContent.AppendLine($" {projectGuid}.Release|x64.Build.0 = Release|x64");
+ solutionContent.AppendLine($" {projectGuid}.Debug|x64.ActiveCfg = Debug|x64");
+ solutionContent.AppendLine($" {projectGuid}.Debug|x64.Build.0 = Debug|x64");
+ }
+
+ solutionContent.AppendLine(" EndGlobalSection");
+ solutionContent.AppendLine(" GlobalSection(SolutionProperties) = preSolution");
+ solutionContent.AppendLine(" HideSolutionNode = FALSE");
+ solutionContent.AppendLine(" EndGlobalSection");
+ solutionContent.AppendLine("EndGlobal");
+
+ // Write the solution file content to disk
+ string solutionName = project.Name + ".sln";
+ string filePath = Path.Combine(projectPath, solutionName);
+ File.WriteAllText(filePath, solutionContent.ToString());
+
+ solutionPath = filePath;
+ }
+
+ private static void GenerateCSProject(string csProjectFilePath, string projectPath)
+ {
+ if (!File.Exists(csProjectFilePath))
+ {
+ return;
+ }
+
+ string jsonString = File.ReadAllText(csProjectFilePath);
+ CSProject csProject = JsonSerializer.Deserialize(jsonString, CSProjectContext.Default.CSProject);
+
+ Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
+ Assembly runtimeAssembly = loadedAssemblies.FirstOrDefault(assembly => assembly.GetName().Name == "Nerfed.Runtime") ?? throw new Exception("Failed to find Runtime Assembly!");
+
+ // TODO: get all dependencies.
+ // TODO: properly get assemblies.
+
+ StringBuilder projectContent = new StringBuilder();
+
+ projectContent.AppendLine("");
+
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine(" net8.0");
+ projectContent.AppendLine(" enable");
+ projectContent.AppendLine(" disable");
+ projectContent.AppendLine(" true");
+ projectContent.AppendLine(" true");
+ projectContent.AppendLine(" true");
+ projectContent.AppendLine(" false");
+ projectContent.AppendLine(" false");
+ projectContent.AppendLine(" Debug;Test;Release");
+ projectContent.AppendLine(" x64");
+ projectContent.AppendLine(" ");
+
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine(" TRACE;LOG_INFO;PROFILING");
+ projectContent.AppendLine(" ");
+
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine(" TRACE;LOG_ERROR;PROFILING");
+ projectContent.AppendLine(" true");
+ projectContent.AppendLine(" ");
+
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine(" TRACE;LOG_ERROR");
+ projectContent.AppendLine(" true");
+ projectContent.AppendLine(" ");
+
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine($" ");
+ projectContent.AppendLine(" ");
+
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine($" {runtimeAssembly.Location}");
+ projectContent.AppendLine(" false");
+ projectContent.AppendLine(" ");
+ projectContent.AppendLine(" ");
+
+ projectContent.AppendLine("");
+
+ string projectName = csProject.Name + ".Runtime.csproj";
+ string filePath = Path.Combine(projectPath, projectName);
+ File.WriteAllText(filePath, projectContent.ToString());
+ }
+}
diff --git a/Nerfed.Compiler/Nerfed.Compiler.csproj b/Nerfed.Compiler/Nerfed.Compiler.csproj
new file mode 100644
index 0000000..9e543bb
--- /dev/null
+++ b/Nerfed.Compiler/Nerfed.Compiler.csproj
@@ -0,0 +1,26 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ disable
+ false
+ false
+ Debug;Test;Release
+ x64
+
+
+
+ false
+
+
+
+ true
+
+
+
+ true
+
+
+
diff --git a/Nerfed.Compiler/Program.cs b/Nerfed.Compiler/Program.cs
new file mode 100644
index 0000000..1c34f84
--- /dev/null
+++ b/Nerfed.Compiler/Program.cs
@@ -0,0 +1,10 @@
+namespace Nerfed.Compiler
+{
+ public class Program
+ {
+ internal static void Main(string[] args)
+ {
+ Compiler.Compile(args[0], args[1]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Nerfed.Compiler/Project.cs b/Nerfed.Compiler/Project.cs
new file mode 100644
index 0000000..e709622
--- /dev/null
+++ b/Nerfed.Compiler/Project.cs
@@ -0,0 +1,52 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace Nerfed.Compiler;
+
+public class Project
+{
+ public string Name { get; set; }
+
+ public static bool Create(string path, string name, out Project project)
+ {
+ project = null;
+
+ // Create project file.
+ project = new Project
+ {
+ Name = name,
+ };
+
+ Save(project, path);
+
+ return true;
+ }
+
+ public static bool Save(Project project, string projectFilePath)
+ {
+ string jsonString = JsonSerializer.Serialize(project, ProjectContext.Default.Project);
+
+ File.WriteAllText(projectFilePath, jsonString);
+
+ return true;
+ }
+
+ public static bool Open(string path, out Project project)
+ {
+ string jsonString = File.ReadAllText(path);
+ project = JsonSerializer.Deserialize(jsonString, ProjectContext.Default.Project);
+
+ if (project == null)
+ {
+ Console.WriteLine($"ERROR: Could not open {typeof(Project)}.");
+ return false;
+ }
+
+ return true;
+ }
+}
+
+[JsonSerializable(typeof(Project))]
+public partial class ProjectContext : JsonSerializerContext
+{
+}
\ No newline at end of file
diff --git a/Nerfed.sln b/Nerfed.sln
index c36f1bf..a698767 100644
--- a/Nerfed.sln
+++ b/Nerfed.sln
@@ -5,38 +5,46 @@ VisualStudioVersion = 17.10.35013.160
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Runtime", "Nerfed.Runtime\Nerfed.Runtime.csproj", "{98E09BAF-587F-4238-89BD-7693C036C233}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nerfed.Builder", "Nerfed.Builder\Nerfed.Builder.csproj", "{1B88DE56-2AD8-441E-9B10-073AA43840BF}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Builder", "Nerfed.Builder\Nerfed.Builder.csproj", "{1B88DE56-2AD8-441E-9B10-073AA43840BF}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nerfed.Editor", "Nerfed.Editor\Nerfed.Editor.csproj", "{FF7D032D-7F0B-4700-A818-0606D66AECF8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Editor", "Nerfed.Editor\Nerfed.Editor.csproj", "{FF7D032D-7F0B-4700-A818-0606D66AECF8}"
ProjectSection(ProjectDependencies) = postProject
{1B88DE56-2AD8-441E-9B10-073AA43840BF} = {1B88DE56-2AD8-441E-9B10-073AA43840BF}
EndProjectSection
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerfed.Compiler", "Nerfed.Compiler\Nerfed.Compiler.csproj", "{3DFEB8A4-5354-41EA-A249-27ADC7F666CF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Test|x64 = Test|x64
- Release|x64 = Release|x64
Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ Test|x64 = Test|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Test|x64.ActiveCfg = Test|x64
- {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Test|x64.Build.0 = Test|x64
- {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Release|x64.ActiveCfg = Release|x64
- {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Release|x64.Build.0 = Release|x64
- {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Debug|x64.ActiveCfg = Debug|x64
- {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Debug|x64.Build.0 = Debug|x64
- {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Test|x64.ActiveCfg = Test|x64
- {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Test|x64.Build.0 = Test|x64
- {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Release|x64.ActiveCfg = Release|x64
- {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Release|x64.Build.0 = Release|x64
- {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Debug|x64.ActiveCfg = Debug|x64
- {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Debug|x64.Build.0 = Debug|x64
- {98E09BAF-587F-4238-89BD-7693C036C233}.Test|x64.ActiveCfg = Test|x64
- {98E09BAF-587F-4238-89BD-7693C036C233}.Test|x64.Build.0 = Test|x64
- {98E09BAF-587F-4238-89BD-7693C036C233}.Release|x64.ActiveCfg = Release|x64
- {98E09BAF-587F-4238-89BD-7693C036C233}.Release|x64.Build.0 = Release|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Debug|x64.ActiveCfg = Debug|x64
{98E09BAF-587F-4238-89BD-7693C036C233}.Debug|x64.Build.0 = Debug|x64
+ {98E09BAF-587F-4238-89BD-7693C036C233}.Release|x64.ActiveCfg = Release|x64
+ {98E09BAF-587F-4238-89BD-7693C036C233}.Release|x64.Build.0 = Release|x64
+ {98E09BAF-587F-4238-89BD-7693C036C233}.Test|x64.ActiveCfg = Test|x64
+ {98E09BAF-587F-4238-89BD-7693C036C233}.Test|x64.Build.0 = Test|x64
+ {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Debug|x64.ActiveCfg = Debug|x64
+ {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Debug|x64.Build.0 = Debug|x64
+ {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Release|x64.ActiveCfg = Release|x64
+ {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Release|x64.Build.0 = Release|x64
+ {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Test|x64.ActiveCfg = Test|x64
+ {1B88DE56-2AD8-441E-9B10-073AA43840BF}.Test|x64.Build.0 = Test|x64
+ {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Debug|x64.ActiveCfg = Debug|x64
+ {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Debug|x64.Build.0 = Debug|x64
+ {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Release|x64.ActiveCfg = Release|x64
+ {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Release|x64.Build.0 = Release|x64
+ {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Test|x64.ActiveCfg = Test|x64
+ {FF7D032D-7F0B-4700-A818-0606D66AECF8}.Test|x64.Build.0 = Test|x64
+ {3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Debug|x64.ActiveCfg = Debug|x64
+ {3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Debug|x64.Build.0 = Debug|x64
+ {3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Release|x64.ActiveCfg = Release|x64
+ {3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Release|x64.Build.0 = Release|x64
+ {3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Test|x64.ActiveCfg = Test|x64
+ {3DFEB8A4-5354-41EA-A249-27ADC7F666CF}.Test|x64.Build.0 = Test|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE