diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml
index 836cd9b..3bc1125 100644
--- a/.github/workflows/cicd.yml
+++ b/.github/workflows/cicd.yml
@@ -36,6 +36,12 @@ jobs:
- name: Build (CD)
if: ${{ github.event.inputs.version != '' }}
run: dotnet build src/bflat/bflat.csproj -t:BuildLayouts -c:Release -p:Version=${{ github.event.inputs.version }}
+ - name: Debloat the libs
+ run: |
+ dotnet run --project src/debloat/debloat.csproj layouts/windows-x64/lib
+ dotnet run --project src/debloat/debloat.csproj layouts/windows-arm64/lib
+ dotnet run --project src/debloat/debloat.csproj layouts/linux-glibc-x64/lib
+ dotnet run --project src/debloat/debloat.csproj layouts/linux-glibc-arm64/lib
- name: Prepare symbols
run: |
mv layouts/windows-x64/bflat.pdb layouts/obj/windows-x64/
diff --git a/src/bflat/BuildCommand.cs b/src/bflat/BuildCommand.cs
index 5dc4734..05e4b86 100644
--- a/src/bflat/BuildCommand.cs
+++ b/src/bflat/BuildCommand.cs
@@ -350,13 +350,18 @@ public override int Handle(ParseResult result)
{
char separator = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ';' : ':';
+ string currentLibPath = Path.Combine(homePath, "lib");
+
+ libPath = currentLibPath;
+
string osPart = targetOS switch
{
- TargetOS.Linux when libc == "bionic" => "linux-bionic",
- TargetOS.Linux => "linux-glibc",
+ TargetOS.Linux => "linux",
TargetOS.Windows => "windows",
_ => throw new Exception(targetOS.ToString()),
};
+ currentLibPath = Path.Combine(currentLibPath, osPart);
+ libPath = currentLibPath + separator + libPath;
string archPart = targetArchitecture switch
{
@@ -364,15 +369,20 @@ public override int Handle(ParseResult result)
TargetArchitecture.X64 => "x64",
_ => throw new Exception(targetArchitecture.ToString()),
};
+ currentLibPath = Path.Combine(currentLibPath, archPart);
+ libPath = currentLibPath + separator + libPath;
- string osArchPath = Path.Combine(homePath, "lib", $"{osPart}-{archPart}");
- if (!Directory.Exists(osArchPath))
+ if (targetOS == TargetOS.Linux)
{
- Console.Error.WriteLine($"Directory '{osArchPath}' doesn't exist.");
- return 1;
+ currentLibPath = Path.Combine(currentLibPath, libc ?? "glibc");
+ libPath = currentLibPath + separator + libPath;
}
- libPath = String.Concat(osArchPath, separator.ToString(), Path.Combine(homePath, "lib"));
+ if (!Directory.Exists(currentLibPath))
+ {
+ Console.Error.WriteLine($"Directory '{currentLibPath}' doesn't exist.");
+ return 1;
+ }
}
if (!bare)
diff --git a/src/bflat/bflat.csproj b/src/bflat/bflat.csproj
index 1ee1145..c4b9084 100644
--- a/src/bflat/bflat.csproj
+++ b/src/bflat/bflat.csproj
@@ -13,7 +13,7 @@
7.0.0-rtm.22529.1
https://github.com/bflattened/runtime/releases/download/
- 1.2
+ 1.3
https://github.com/bflattened/blobs/releases/download/
4.4.0-1.final
@@ -62,11 +62,21 @@
-
-
-
-
-
+
+ windows\x64\
+
+
+ windows\arm64\
+
+
+ linux\x64\glibc\
+
+
+ linux\arm64\glibc
+
+
+ linux\arm64\bionic
+
@@ -146,7 +156,7 @@
Outputs="@(SupportedTarget->'$(IntermediateOutputPath)\bflat-libs-%(Identity)-$(RuntimeVersion).semaphore')">
+ DestinationFolder="$(OutputPath)lib\%(SupportedTarget.LibPath)" />
diff --git a/src/debloat/Program.cs b/src/debloat/Program.cs
new file mode 100644
index 0000000..12dbe59
--- /dev/null
+++ b/src/debloat/Program.cs
@@ -0,0 +1,94 @@
+// bflat C# compiler
+// Copyright (C) 2021-2022 Michal Strehovsky
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.IO;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+
+Merge(args[0]);
+
+static void Merge(string directory)
+{
+ foreach (string subDirectory in Directory.EnumerateDirectories(directory))
+ Merge(subDirectory);
+
+ Dictionary> candidates = new Dictionary>();
+ int expectedFiles = 0;
+ foreach (string subDirectory in Directory.EnumerateDirectories(directory))
+ {
+ expectedFiles++;
+ foreach (var f in Directory.EnumerateFiles(subDirectory, "*.dll"))
+ {
+ string key = Path.GetFileName(f);
+ if (!candidates.TryGetValue(key, out List list))
+ candidates.Add(key, list = new List());
+ list.Add(f);
+ }
+ }
+
+ foreach (var maybeSameFiles in candidates.Values)
+ {
+ if (maybeSameFiles.Count != expectedFiles)
+ continue;
+
+ bool allSame = true;
+ ReadOnlySpan expected = SanitizedAssemblyBytes(maybeSameFiles[0]);
+ for (int i = 1; i < maybeSameFiles.Count; i++)
+ {
+ ReadOnlySpan actual = SanitizedAssemblyBytes(maybeSameFiles[i]);
+ if (!expected.SequenceEqual(actual))
+ {
+ allSame = false;
+ break;
+ }
+ }
+
+ if (allSame)
+ {
+ File.Move(maybeSameFiles[0], Path.Combine(directory, Path.GetFileName(maybeSameFiles[0])));
+ string pdbFile = Path.ChangeExtension(maybeSameFiles[0], "pdb");
+ if (File.Exists(pdbFile))
+ File.Move(pdbFile, Path.Combine(directory, Path.GetFileName(pdbFile)));
+
+ for (int i = 1; i < maybeSameFiles.Count; i++)
+ {
+ File.Delete(maybeSameFiles[i]);
+ pdbFile = Path.ChangeExtension(maybeSameFiles[i], "pdb");
+ if (File.Exists(pdbFile))
+ File.Delete(pdbFile);
+ }
+ }
+ }
+}
+
+static byte[] SanitizedAssemblyBytes(string fileName)
+{
+ byte[] b = File.ReadAllBytes(fileName);
+ Span span = b;
+ PEReader perdr = new PEReader(ImmutableArray.Create(b));
+ span.Slice(perdr.PEHeaders.CoffHeaderStartOffset + 4, 4).Clear();
+ MetadataReader mdrdr = perdr.GetMetadataReader();
+ Guid mvid = mdrdr.GetGuid(mdrdr.GetModuleDefinition().Mvid);
+ span.Slice(span.IndexOf(mvid.ToByteArray()), 16).Clear();
+ foreach (var ddentry in perdr.ReadDebugDirectory())
+ span.Slice(ddentry.DataPointer, ddentry.DataSize).Clear();
+ if (perdr.PEHeaders.TryGetDirectoryOffset(perdr.PEHeaders.PEHeader.DebugTableDirectory, out int debugDir))
+ span.Slice(debugDir, perdr.PEHeaders.PEHeader.DebugTableDirectory.Size).Clear();
+ return b;
+}
\ No newline at end of file
diff --git a/src/debloat/debloat.csproj b/src/debloat/debloat.csproj
new file mode 100644
index 0000000..41f1d5a
--- /dev/null
+++ b/src/debloat/debloat.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Exe
+ net6.0
+
+
+