pack/unpack class
This commit is contained in:
62
compiler/NubLib.cs
Normal file
62
compiler/NubLib.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using System.IO.Compression;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Compiler;
|
||||||
|
|
||||||
|
public class NubLib
|
||||||
|
{
|
||||||
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
WriteIndented = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void Pack(string outputPath, string archivePath, Manifest manifest)
|
||||||
|
{
|
||||||
|
using var fs = new FileStream(outputPath, FileMode.Create);
|
||||||
|
using var zip = new ZipArchive(fs, ZipArchiveMode.Create);
|
||||||
|
|
||||||
|
var manifestEntry = zip.CreateEntry("manifest.json");
|
||||||
|
using (var writer = new StreamWriter(manifestEntry.Open()))
|
||||||
|
{
|
||||||
|
var serialized = JsonSerializer.Serialize(manifest, JsonOptions);
|
||||||
|
|
||||||
|
writer.Write(serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
var archiveEntry = zip.CreateEntry("lib.a");
|
||||||
|
|
||||||
|
using var entryStream = archiveEntry.Open();
|
||||||
|
using var fileStream = File.OpenRead(archivePath);
|
||||||
|
|
||||||
|
fileStream.CopyTo(entryStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NublibLoadResult Unpack(string nublibPath)
|
||||||
|
{
|
||||||
|
using var fs = new FileStream(nublibPath, FileMode.Open, FileAccess.Read);
|
||||||
|
using var zip = new ZipArchive(fs, ZipArchiveMode.Read);
|
||||||
|
|
||||||
|
var manifestEntry = zip.GetEntry("manifest.json") ?? throw new FileNotFoundException("Manifest not found in nublib", "manifest.json");
|
||||||
|
|
||||||
|
Manifest manifest;
|
||||||
|
using (var reader = new StreamReader(manifestEntry.Open()))
|
||||||
|
{
|
||||||
|
var json = reader.ReadToEnd();
|
||||||
|
manifest = JsonSerializer.Deserialize<Manifest>(json, JsonOptions) ?? throw new InvalidDataException("Failed to deserialize manifest.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
var archiveEntry = zip.Entries.FirstOrDefault(e => e.Name.EndsWith(".a")) ?? throw new FileNotFoundException("Archive not found in nublib", "*.a");
|
||||||
|
|
||||||
|
string tempArchivePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".a");
|
||||||
|
using (var entryStream = archiveEntry.Open())
|
||||||
|
using (var tempFile = File.Create(tempArchivePath))
|
||||||
|
{
|
||||||
|
entryStream.CopyTo(tempFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NublibLoadResult(manifest, tempArchivePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public record NublibLoadResult(Manifest Manifest, string ArchivePath);
|
||||||
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Text.Json;
|
|
||||||
using Compiler;
|
using Compiler;
|
||||||
|
|
||||||
var nubFiles = new List<string>();
|
var nubFiles = new List<string>();
|
||||||
@@ -66,7 +64,7 @@ var archivePaths = new List<string>();
|
|||||||
|
|
||||||
foreach (var libPath in libFiles)
|
foreach (var libPath in libFiles)
|
||||||
{
|
{
|
||||||
var lib = ReadNublib(libPath);
|
var lib = NubLib.Unpack(libPath);
|
||||||
archivePaths.Add(lib.ArchivePath);
|
archivePaths.Add(lib.ArchivePath);
|
||||||
moduleGraphBuilder.AddManifest(lib.Manifest);
|
moduleGraphBuilder.AddManifest(lib.Manifest);
|
||||||
}
|
}
|
||||||
@@ -137,7 +135,7 @@ if (compileLib)
|
|||||||
File.WriteAllText(".build/out.c", output);
|
File.WriteAllText(".build/out.c", output);
|
||||||
Process.Start("gcc", ["-Og", "-fvisibility=hidden", "-fno-builtin", "-c", "-o", ".build/out.o", ".build/out.c", .. archivePaths]).WaitForExit();
|
Process.Start("gcc", ["-Og", "-fvisibility=hidden", "-fno-builtin", "-c", "-o", ".build/out.o", ".build/out.c", .. archivePaths]).WaitForExit();
|
||||||
Process.Start("ar", ["rcs", ".build/out.a", ".build/out.o"]).WaitForExit();
|
Process.Start("ar", ["rcs", ".build/out.a", ".build/out.o"]).WaitForExit();
|
||||||
WriteNublib(".build/out.nublib", ".build/out.a", moduleGraph.CreateManifest());
|
NubLib.Pack(".build/out.nublib", ".build/out.a", moduleGraph.CreateManifest());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -162,56 +160,3 @@ static void CleanDirectory(string dirName)
|
|||||||
subdir.Delete();
|
subdir.Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteNublib(string outputPath, string archivePath, Manifest manifest)
|
|
||||||
{
|
|
||||||
using var fs = new FileStream(outputPath, FileMode.Create);
|
|
||||||
using var zip = new ZipArchive(fs, ZipArchiveMode.Create);
|
|
||||||
|
|
||||||
var serialized = JsonSerializer.Serialize(manifest, new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
||||||
WriteIndented = true,
|
|
||||||
});
|
|
||||||
|
|
||||||
var manifestEntry = zip.CreateEntry("manifest.json");
|
|
||||||
using (var writer = new StreamWriter(manifestEntry.Open()))
|
|
||||||
{
|
|
||||||
writer.Write(serialized);
|
|
||||||
}
|
|
||||||
|
|
||||||
var archiveEntry = zip.CreateEntry("lib.a");
|
|
||||||
|
|
||||||
using var entryStream = archiveEntry.Open();
|
|
||||||
using var fileStream = File.OpenRead(archivePath);
|
|
||||||
|
|
||||||
fileStream.CopyTo(entryStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
static NublibLoadResult ReadNublib(string nublibPath)
|
|
||||||
{
|
|
||||||
using var fs = new FileStream(nublibPath, FileMode.Open, FileAccess.Read);
|
|
||||||
using var zip = new ZipArchive(fs, ZipArchiveMode.Read);
|
|
||||||
|
|
||||||
var manifestEntry = zip.GetEntry("manifest.json") ?? throw new FileNotFoundException("Manifest not found in nublib", "manifest.json");
|
|
||||||
|
|
||||||
Manifest manifest;
|
|
||||||
using (var reader = new StreamReader(manifestEntry.Open()))
|
|
||||||
{
|
|
||||||
var json = reader.ReadToEnd();
|
|
||||||
manifest = JsonSerializer.Deserialize<Manifest>(json) ?? throw new InvalidDataException("Failed to deserialize manifest.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
var archiveEntry = zip.Entries.FirstOrDefault(e => e.Name.EndsWith(".a")) ?? throw new FileNotFoundException("Archive not found in nublib", "*.a");
|
|
||||||
|
|
||||||
string tempArchivePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".a");
|
|
||||||
using (var entryStream = archiveEntry.Open())
|
|
||||||
using (var tempFile = File.Create(tempArchivePath))
|
|
||||||
{
|
|
||||||
entryStream.CopyTo(tempFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NublibLoadResult(manifest, tempArchivePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public record NublibLoadResult(Manifest Manifest, string ArchivePath);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user