Revert "New: Updated MediaInfo to 21.09, Sqlite to 3.32.1.0 and added support for mac osx arm64 arch. Deprecated osx x86."

This reverts commit 201004113e.
This commit is contained in:
Qstick 2021-12-19 20:27:43 -06:00 committed by Mark McDowall
parent c7919f80de
commit b819246655
26 changed files with 13578 additions and 595 deletions

View File

@ -12,11 +12,8 @@ sourceFolder='./src'
slnFile=$sourceFolder/Sonarr.sln slnFile=$sourceFolder/Sonarr.sln
updateSubFolder=Sonarr.Update updateSubFolder=Sonarr.Update
sqlitePackageDir="$HOME/.nuget/packages/system.data.sqlite.core.servarr/1.0.115.5-18"
nuget='tools/nuget/nuget.exe'; nuget='tools/nuget/nuget.exe';
vswhere='tools/vswhere/vswhere.exe'; vswhere='tools/vswhere/vswhere.exe';
macho='tools/macho/MachOConverter.exe';
. ./version.sh . ./version.sh
@ -138,9 +135,6 @@ Build()
CleanFolder $outputFolder false CleanFolder $outputFolder false
echo "Removing Sonarr.Update/sqlite3.dll"
rm $outputFolder/Sonarr.Update/sqlite3.dll
echo "Removing Mono.Posix.dll" echo "Removing Mono.Posix.dll"
rm $outputFolder/Mono.Posix.dll rm $outputFolder/Mono.Posix.dll
@ -240,7 +234,6 @@ PackageMono()
echo "Removing native windows binaries Sqlite, MediaInfo" echo "Removing native windows binaries Sqlite, MediaInfo"
rm -f $outputFolderLinux/sqlite3.* rm -f $outputFolderLinux/sqlite3.*
rm -f $outputFolderLinux/Sonarr.Update/sqlite3.*
rm -f $outputFolderLinux/MediaInfo.* rm -f $outputFolderLinux/MediaInfo.*
PatchMono $outputFolderLinux PatchMono $outputFolderLinux
@ -285,22 +278,17 @@ PackageMacOS()
chmod +x $outputFolderMacOS/Sonarr chmod +x $outputFolderMacOS/Sonarr
echo "Adding Sonarr.Update Launcher" echo "Adding Sonarr.Update Launcher"
CheckExitCode cp ./distribution/osx/Launcher/dist/Launcher $outputFolderMacOS/Sonarr.Update/ cp ./distribution/osx/Launcher/dist/Launcher $outputFolderMacOS/Sonarr.Update/
CheckExitCode mv $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe.bak mv $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe.bak
CheckExitCode mv $outputFolderMacOS/Sonarr.Update/Launcher $outputFolderMacOS/Sonarr.Update/Sonarr.Update mv $outputFolderMacOS/Sonarr.Update/Launcher $outputFolderMacOS/Sonarr.Update/Sonarr.Update
CheckExitCode mv $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe.bak $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe mv $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe.bak $outputFolderMacOS/Sonarr.Update/Sonarr.Update.exe
chmod +x $outputFolderMacOS/Sonarr.Update/Sonarr.Update chmod +x $outputFolderMacOS/Sonarr.Update/Sonarr.Update
echo "Adding sqlite dylib" echo "Adding sqlite dylibs"
CheckExitCode cp "$sqlitePackageDir/runtimes/osx-x64/native/net46"/*.config $outputFolderMacOS/ cp $sourceFolder/Libraries/Sqlite/*.dylib $outputFolderMacOS
if [ $runtime = "dotnet" ] ; then
CheckExitCode $macho merge $outputFolderMacOS "$sqlitePackageDir/runtimes/osx-x64/native/net46"/*.dylib "$sqlitePackageDir/runtimes/osx-arm64/native/net46"/*.dylib
else
CheckExitCode mono $macho merge $outputFolderMacOS "$sqlitePackageDir/runtimes/osx-x64/native/net46"/*.dylib "$sqlitePackageDir/runtimes/osx-arm64/native/net46"/*.dylib
fi
echo "Adding MediaInfo dylib" echo "Adding MediaInfo dylib"
CheckExitCode cp $sourceFolder/Libraries/MediaInfo/x64/*.dylib $outputFolderMacOS/ cp $sourceFolder/Libraries/MediaInfo/*.dylib $outputFolderMacOS
ProgressEnd 'Creating MacOS Package' ProgressEnd 'Creating MacOS Package'
} }
@ -309,37 +297,29 @@ PackageMacOSApp()
{ {
ProgressStart 'Creating macOS App Package' ProgressStart 'Creating macOS App Package'
outputFolderMacOSAppBase=$outputFolderMacOSApp/Sonarr.app/Contents/MacOS
outputFolderMacOSAppBin=$outputFolderMacOSAppBase/bin
rm -rf $outputFolderMacOSApp rm -rf $outputFolderMacOSApp
mkdir $outputFolderMacOSApp mkdir $outputFolderMacOSApp
cp -r ./distribution/osx/Sonarr.app $outputFolderMacOSApp cp -r ./distribution/osx/Sonarr.app $outputFolderMacOSApp
mkdir -p $outputFolderMacOSAppBase mkdir -p $outputFolderMacOSApp/Sonarr.app/Contents/MacOS
echo "Adding Sonarr Launcher" echo "Adding Sonarr Launcher"
CheckExitCode cp ./distribution/osx/Launcher/dist/Launcher $outputFolderMacOSAppBase/ cp ./distribution/osx/Launcher/dist/Launcher $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/
CheckExitCode mv $outputFolderMacOSAppBase/Launcher $outputFolderMacOSAppBase/Sonarr mv $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/Launcher $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/Sonarr
chmod +x $outputFolderMacOSAppBase/Sonarr chmod +x $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/Sonarr
echo "Copying Binaries" echo "Copying Binaries"
mkdir -p $outputFolderMacOSAppBin mkdir -p $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/bin
CheckExitCode cp -r $outputFolderLinux/* $outputFolderMacOSAppBin cp -r $outputFolderLinux/* $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/bin/
echo "Adding sqlite dylib"
if [ $runtime = "dotnet" ] ; then
CheckExitCode $macho merge $outputFolderMacOSAppBin "$sqlitePackageDir/runtimes/osx-x64/native/net46" "$sqlitePackageDir/runtimes/osx-arm64/native/net46"
else
CheckExitCode mono $macho merge $outputFolderMacOSAppBin "$sqlitePackageDir/runtimes/osx-x64/native/net46" "$sqlitePackageDir/runtimes/osx-arm64/native/net46"
fi
echo "Adding sqlite dylibs"
cp $sourceFolder/Libraries/Sqlite/*.dylib $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/bin/
echo "Adding MediaInfo dylib" echo "Adding MediaInfo dylib"
CheckExitCode cp $sourceFolder/Libraries/MediaInfo/x64/*.dylib $outputFolderMacOSAppBin/ cp $sourceFolder/Libraries/MediaInfo/*.dylib $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/bin/
echo "Removing Update Folder" echo "Removing Update Folder"
rm -r $outputFolderMacOSAppBin/Sonarr.Update rm -r $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/bin/Sonarr.Update
echo "# Do Not Edit\nPackageVersion=${BUILD_NUMBER}\nPackageAuthor=[Team Sonarr](https://sonarr.tv)\nReleaseVersion=${BUILD_NUMBER}\nUpdateMethod=$PackageUpdater\nBranch=${Branch:-master}" > $outputFolderMacOSAppBase/package_info echo "# Do Not Edit\nPackageVersion=${BUILD_NUMBER}\nPackageAuthor=[Team Sonarr](https://sonarr.tv)\nReleaseVersion=${BUILD_NUMBER}\nUpdateMethod=$PackageUpdater\nBranch=${Branch:-master}" > $outputFolderMacOSApp/Sonarr.app/Contents/MacOS/package_info
ProgressEnd 'Creating macOS App Package' ProgressEnd 'Creating macOS App Package'
} }

View File

@ -2,9 +2,6 @@
<!-- Common to all Sonarr Projects --> <!-- Common to all Sonarr Projects -->
<PropertyGroup> <PropertyGroup>
<SonarrRootDir>$(MSBuildThisFileDirectory)..\</SonarrRootDir> <SonarrRootDir>$(MSBuildThisFileDirectory)..\</SonarrRootDir>
<!-- Whether we want TargetFramework switching in Visual Studio -->
<TargetMultiple>false</TargetMultiple>
<!-- Specifies the type of output --> <!-- Specifies the type of output -->
<SonarrOutputType>Library</SonarrOutputType> <SonarrOutputType>Library</SonarrOutputType>
@ -22,34 +19,17 @@
<SonarrProject Condition="$(MSBuildProjectName.StartsWith('ServiceUninstall'))">true</SonarrProject> <SonarrProject Condition="$(MSBuildProjectName.StartsWith('ServiceUninstall'))">true</SonarrProject>
</PropertyGroup> </PropertyGroup>
<!-- Pick default RuntimeIdentifier for our compilation environment -->
<PropertyGroup Condition=" '$(TargetMultiple)'!='true' ">
<RuntimeIdentifiers></RuntimeIdentifiers>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<TargetFrameworks></TargetFrameworks>
<TargetFramework>net462</TargetFramework>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<Configuration Condition="'$(Configuration)'==''">Release</Configuration> <Configuration Condition="'$(Configuration)'==''">Release</Configuration>
<TargetFrameworkPath>$(TargetFramework)\</TargetFrameworkPath>
<TargetFrameworkPath Condition="'$(Platform)'!='x64'">$(TargetFrameworkPath)$(Platform)\</TargetFrameworkPath>
<TargetFrameworkPath>$(TargetFrameworkPath)$(Configuration)\</TargetFrameworkPath>
<!-- Centralize intermediate and default outputs --> <!-- Centralize intermediate and default outputs -->
<BaseIntermediateOutputPath>$(SonarrRootDir)_temp\obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath> <BaseIntermediateOutputPath>$(SonarrRootDir)_temp\obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
<IntermediateOutputPath>$(SonarrRootDir)_temp\obj\$(MSBuildProjectName)\$(TargetFrameworkPath)</IntermediateOutputPath> <IntermediateOutputPath>$(SonarrRootDir)_temp\obj\$(MSBuildProjectName)\$(Configuration)\</IntermediateOutputPath>
<OutputPath>$(SonarrRootDir)_temp\bin\$(TargetFrameworkPath)$(MSBuildProjectName)\</OutputPath> <OutputPath>$(SonarrRootDir)_temp\bin\$(Configuration)\$(MSBuildProjectName)\</OutputPath>
<!-- Flatten the 'real' output paths for backward compat -->
<OutputTargetFrameworkPath>$(TargetFrameworkPath)</OutputTargetFrameworkPath>
<OutputTargetFrameworkPath Condition=" '$(TargetMultiple)'!='true' "></OutputTargetFrameworkPath>
<!-- Output to _output and _tests respectively --> <!-- Output to _output and _tests respectively -->
<OutputPath Condition="'$(SonarrProject)'=='true'">$(SonarrRootDir)_output\$(OutputTargetFrameworkPath)</OutputPath> <OutputPath Condition="'$(SonarrProject)'=='true'">$(SonarrRootDir)_output\</OutputPath>
<OutputPath Condition="'$(SonarrOutputType)'=='Test'">$(SonarrRootDir)_tests\$(OutputTargetFrameworkPath)</OutputPath> <OutputPath Condition="'$(SonarrOutputType)'=='Test'">$(SonarrRootDir)_tests\</OutputPath>
<OutputPath Condition="'$(SonarrOutputType)'=='Update'">$(OutputPath)Sonarr.Update\</OutputPath> <OutputPath Condition="'$(SonarrOutputType)'=='Update'">$(SonarrRootDir)_output\Sonarr.Update\</OutputPath>
<!-- Paths relative to project file for better readability --> <!-- Paths relative to project file for better readability -->
<BaseIntermediateOutputPath>$([MSBuild]::MakeRelative('$(MSBuildProjectDirectory)', '$(BaseIntermediateOutputPath)'))</BaseIntermediateOutputPath> <BaseIntermediateOutputPath>$([MSBuild]::MakeRelative('$(MSBuildProjectDirectory)', '$(BaseIntermediateOutputPath)'))</BaseIntermediateOutputPath>
@ -93,7 +73,6 @@
<PropertyGroup> <PropertyGroup>
<!-- We don't want separate framework directories till we go dotnet core --> <!-- We don't want separate framework directories till we go dotnet core -->
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<!-- For now keep the NzbDrone namespace --> <!-- For now keep the NzbDrone namespace -->
<RootNamespace Condition="'$(SonarrProject)'=='true'">$(MSBuildProjectName.Replace('Sonarr','NzbDrone'))</RootNamespace> <RootNamespace Condition="'$(SonarrProject)'=='true'">$(MSBuildProjectName.Replace('Sonarr','NzbDrone'))</RootNamespace>

Binary file not shown.

View File

@ -1,3 +0,0 @@
File OS Arch Version
libmediainfo.0.dylib Mac x64,arm64 21.09

View File

@ -1,4 +0,0 @@
File OS Arch Version
libmediainfo.0.dylib Mac x64,arm64 21.09
MediaInfo.dll Win x64 21.09

View File

@ -1,4 +0,0 @@
File OS Arch Version
libmediainfo.0.dylib Mac x86,x64 21.03
MediaInfo.dll Win x86 21.09

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1 @@
libsqlite3.0.dylib

Binary file not shown.

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="Lidarr SQLite" value="https://pkgs.dev.azure.com/Servarr/Servarr/_packaging/SQLite/nuget/v3/index.json" />
</packageSources>
</configuration>

View File

@ -10,7 +10,6 @@
<PackageReference Include="NLog.Targets.Syslog" Version="6.0.3" /> <PackageReference Include="NLog.Targets.Syslog" Version="6.0.3" />
<PackageReference Include="Sentry" Version="1.2.0" /> <PackageReference Include="Sentry" Version="1.2.0" />
<PackageReference Include="SharpZipLib" Version="1.2.0" /> <PackageReference Include="SharpZipLib" Version="1.2.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -18,6 +17,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System.Configuration.Install" /> <Reference Include="System.Configuration.Install" />
<Reference Include="System.Data.SQLite">
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.ServiceProcess" /> <Reference Include="System.ServiceProcess" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -15,6 +15,9 @@
<Link>Files\1024.png</Link> <Link>Files\1024.png</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<Reference Include="System.Data.SQLite">
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference>
<None Update="Files\**\*.*"> <None Update="Files\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>

View File

@ -21,7 +21,10 @@
<ProjectReference Include="..\Marr.Data\Marr.Data.csproj" /> <ProjectReference Include="..\Marr.Data\Marr.Data.csproj" />
<ProjectReference Include="..\NzbDrone.Common\Sonarr.Common.csproj" /> <ProjectReference Include="..\NzbDrone.Common\Sonarr.Common.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System.Data.SQLite">
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Web" /> <Reference Include="System.Web" />
<Reference Include="System.Web.Extensions" /> <Reference Include="System.Web.Extensions" />
</ItemGroup> </ItemGroup>
@ -29,10 +32,10 @@
<EmbeddedResource Include="..\..\Logo\64.png"> <EmbeddedResource Include="..\..\Logo\64.png">
<Link>Resources\Logo\64.png</Link> <Link>Resources\Logo\64.png</Link>
</EmbeddedResource> </EmbeddedResource>
<None Include="..\Libraries\MediaInfo\$(Platform)\MediaInfo.dll" Condition="$(RuntimeIdentifier.StartsWith('win')) or '$(RuntimeIdentifier)'==''"> <None Include="..\Libraries\Sqlite\sqlite3.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="..\Libraries\MediaInfo\$(Platform)\libmediainfo.0.dylib" Condition="$(RuntimeIdentifier.StartsWith('osx'))"> <None Include="..\Libraries\MediaInfo\MediaInfo.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>

View File

@ -4,8 +4,4 @@
<TargetFramework>net462</TargetFramework> <TargetFramework>net462</TargetFramework>
<Platforms>x86</Platforms> <Platforms>x86</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<!-- Workaround to ensure sqlite3.dll is copied -->
<ProjectReference Include="..\NzbDrone.Common\Sonarr.Common.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -16,5 +16,8 @@
<ProjectReference Include="..\NzbDrone.SignalR\Sonarr.SignalR.csproj" /> <ProjectReference Include="..\NzbDrone.SignalR\Sonarr.SignalR.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System.Data.SQLite">
<HintPath>..\Libraries\Sqlite\System.Data.SQLite.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -53,7 +53,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sonarr.Common", "NzbDrone.C
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{1E6B3CBE-1578-41C1-9BF9-78D818740BE9}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{1E6B3CBE-1578-41C1-9BF9-78D818740BE9}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
NuGet.config = NuGet.config
.nuget\NuGet.exe = .nuget\NuGet.exe .nuget\NuGet.exe = .nuget\NuGet.exe
EndProjectSection EndProjectSection
EndProject EndProject

View File

@ -1,497 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace MachOConverter
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
PrintUsage();
return;
}
if (args[0] == "info" && args.Length >= 2)
{
for (var i = 1; i < args.Length; i++)
{
PrintInfo(args[i]);
}
}
else if (args[0] == "split" && args.Length >= 2)
{
for (var i = 1; i < args.Length; i++)
{
SplitFile(args[i]);
}
}
else if (args[0] == "merge" && args.Length >= 4)
{
var sources = args.Skip(2).ToList();
if (sources.Any(Directory.Exists))
MergeDir(args[1], args.Skip(2).ToList());
else
MergeFile(args[1], args.Skip(2).ToList());
}
else
{
PrintUsage();
}
}
static void PrintUsage()
{
var path = Path.GetFileName(Assembly.GetExecutingAssembly().Location);
Console.WriteLine($"Usage: {path} info [path]");
Console.WriteLine($" {path} split [source]");
Console.WriteLine($" {path} merge [target] [source1] [source2]");
}
static void PrintInfo(string path)
{
var file = new MachOFile(path);
}
static void SplitFile(string path)
{
var file = new MachOFile(path);
foreach (var entry in file.FatEntries)
{
var newPath = Path.ChangeExtension(path, "." + entry.cputype.ToString() + Path.GetExtension(path));
using (var src = new FileStream(path, FileMode.Open, FileAccess.Read))
using (var dst = new FileStream(newPath, FileMode.Create, FileAccess.Write))
{
src.Seek(entry.offset, SeekOrigin.Begin);
var remaining = (int)entry.size;
var buf = new byte[64 * 1024];
while (remaining != 0)
{
var size = Math.Min(remaining, buf.Length);
src.Read(buf, 0, size);
dst.Write(buf, 0, size);
remaining -= size;
}
}
Console.WriteLine($"Wrote {entry.cputype} to {newPath}");
}
}
static void MergeDir(string outPath, List<string> sources)
{
if (!Directory.Exists(outPath))
Directory.CreateDirectory(outPath);
var subdirs = sources.SelectMany(Directory.GetDirectories).Select(Path.GetFileName).Distinct().ToList();
var files = sources.SelectMany(Directory.GetFiles).Select(Path.GetFileName).Distinct().ToList();
foreach (var subdir in subdirs)
{
MergeDir(Path.Combine(outPath, subdir), sources.ConvertAll(v => Path.Combine(v, subdir)).Where(Directory.Exists).ToList());
}
foreach (var file in files)
{
MergeFile(Path.Combine(outPath, file), sources.ConvertAll(v => Path.Combine(v, file)).Where(File.Exists).ToList());
}
}
static void MergeFile(string outPath, List<string> sources)
{
if (Directory.Exists(outPath))
{
outPath = Path.Combine(outPath, Path.GetFileName(sources[0]));
}
if (!MachOFile.IsValidFile(sources[0]))
{
File.Copy(sources[0], outPath);
return;
}
var sourceItems = sources.ConvertAll(v => new MachOFile(v));
var outFile = new MachOFile(outPath, true);
sourceItems.ForEach(outFile.AppendFile);
outFile.Write();
}
}
class MachOFile
{
[Flags]
public enum MachOCpuType : uint
{
VAX = 1,
ROMP = 2,
NS32032 = 4,
NS32332 = 5,
MC680x0 = 6,
I386 = 7,
X86 = 7,
X86_64 = X86 | ABI64,
MIPS = 8,
NS32532 = 9,
HPPA = 11,
ARM = 12,
MC88000 = 13,
SPARC = 14,
I860 = 15, // big-endian
I860_LITTLE = 16, // little-endian
RS6000 = 17,
MC98000 = 18,
POWERPC = 18,
ABI64 = 0x1000000,
ABI64_32 = 0x2000000,
MASK = 0xff000000,
POWERPC64 = POWERPC | ABI64,
VEO = 255,
ARM64 = ARM | ABI64,
ARM64_32 = ARM | ABI64_32
}
public enum MachOCpuSubType : uint
{
}
public class MachOArchEntry
{
public MachOCpuType cputype;
public MachOCpuSubType cpusubtype;
public uint filetype;
public uint ncmds;
public uint sizeofcmds;
public uint flags;
public uint reserved;
}
public class MachOFatEntry
{
public MachOCpuType cputype;
public MachOCpuSubType cpusubtype;
public uint offset;
public uint size;
public uint align;
public string path;
public MachOFatEntry srcentry;
public MachOArchEntry archentry;
}
class BinaryReaderBigEndian : BinaryReader
{
public BinaryReaderBigEndian(Stream stream) : base(stream)
{
}
public new int ReadInt32()
{
var data = base.ReadBytes(4);
if (BitConverter.IsLittleEndian)
Array.Reverse(data);
return BitConverter.ToInt32(data, 0);
}
public new short ReadInt16()
{
var data = base.ReadBytes(2);
if (BitConverter.IsLittleEndian)
Array.Reverse(data);
return BitConverter.ToInt16(data, 0);
}
public new long ReadInt64()
{
var data = base.ReadBytes(8);
if (BitConverter.IsLittleEndian)
Array.Reverse(data);
return BitConverter.ToInt64(data, 0);
}
public new uint ReadUInt32()
{
var data = base.ReadBytes(4);
if (BitConverter.IsLittleEndian)
Array.Reverse(data);
return BitConverter.ToUInt32(data, 0);
}
}
class BinaryWriterBigEndian : BinaryWriter
{
public BinaryWriterBigEndian(Stream stream) : base(stream, Encoding.UTF8, true)
{
}
public override void Write(int value)
{
var data = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian)
Array.Reverse(data);
base.Write(data);
}
public override void Write(uint value)
{
var data = BitConverter.GetBytes(value);
if (BitConverter.IsLittleEndian)
Array.Reverse(data);
base.Write(data);
}
}
private string _path;
private int _size;
private MachOArchEntry _entry;
private List<MachOFatEntry> _fatEntries = new List<MachOFatEntry>();
public MachOArchEntry Entry => _entry;
public List<MachOFatEntry> FatEntries => _fatEntries;
public MachOFile(string path, bool create = false)
{
_path = path;
if (File.Exists(_path) && !create)
{
_size = (int)new FileInfo(_path).Length;
using (var stream = new FileStream(_path, FileMode.Open, FileAccess.Read))
using (var reader = new BinaryReaderBigEndian(stream))
{
ReadFile(reader);
}
}
}
public static bool IsValidFile(string path)
{
if (!File.Exists(path))
return false;
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
using (var reader = new BinaryReaderBigEndian(stream))
{
var magic = reader.ReadUInt32();
if (magic == 0xCAFEBABE || magic == 0xCEFAEDFE || magic == 0xCFFAEDFE)
{
return true;
}
return false;
}
}
private void ReadFile(BinaryReaderBigEndian reader)
{
var magic = reader.ReadUInt32();
if (magic == 0xCAFEBABE)
{
ReadFatFile(reader);
foreach (var entry in _fatEntries)
{
Console.WriteLine($"Details for {entry.cputype}");
reader.BaseStream.Seek(entry.offset, SeekOrigin.Begin);
ReadFile(reader);
entry.path = _path;
entry.archentry = _entry;
_entry = null;
}
}
else if (magic == 0xCEFAEDFE)
{
ReadFileArch32(reader);
}
else if (magic == 0xCFFAEDFE)
{
ReadFileArch64(reader);
}
else
{
throw new ApplicationException($"File {_path} contains unknown Mach-O header");
}
}
private void ReadFileArch32(BinaryReader reader)
{
_entry = new MachOArchEntry
{
cputype = (MachOCpuType)reader.ReadUInt32(),
cpusubtype = (MachOCpuSubType)reader.ReadUInt32(),
filetype = reader.ReadUInt32(),
ncmds = reader.ReadUInt32(),
sizeofcmds = reader.ReadUInt32(),
flags = reader.ReadUInt32()
};
Console.WriteLine($"Found {_entry.cputype} filetype {_entry.filetype} flags {_entry.flags}");
}
private void ReadFileArch64(BinaryReader reader)
{
_entry = new MachOArchEntry
{
cputype = (MachOCpuType)reader.ReadUInt32(),
cpusubtype = (MachOCpuSubType)reader.ReadUInt32(),
filetype = reader.ReadUInt32(),
ncmds = reader.ReadUInt32(),
sizeofcmds = reader.ReadUInt32(),
flags = reader.ReadUInt32(),
reserved = reader.ReadUInt32()
};
Console.WriteLine($"Found {_entry.cputype} filetype {_entry.filetype} flags {_entry.flags}");
}
private void ReadFatFile(BinaryReaderBigEndian reader)
{
var numArchs = reader.ReadUInt32();
Console.WriteLine($"Found Mach-O Universal with {numArchs} items");
for (var i = 0; i < numArchs; i++)
{
var entry = new MachOFatEntry
{
cputype = (MachOCpuType)reader.ReadUInt32(),
cpusubtype = (MachOCpuSubType)reader.ReadUInt32(),
offset = reader.ReadUInt32(),
size = reader.ReadUInt32(),
align = reader.ReadUInt32()
};
Console.WriteLine($" - {entry.cputype} at offset {entry.offset} size {entry.size}");
_fatEntries.Add(entry);
}
}
static int Align(int offset, int align)
{
offset += (1 << align) - 1;
offset -= offset % (1 << align);
return offset;
}
public void Write()
{
var align = 14;
var offset = Align(4 + FatEntries.Count * 5 * 4, align);
// Determine offsets
foreach (var entry in FatEntries)
{
entry.offset = (uint)offset;
entry.align = (uint)align;
offset = Align(offset + (int)entry.size, align);
}
if (FatEntries.Count == 0)
{
}
else if (FatEntries.Count == 1)
{
Console.WriteLine($"Writing {_path} {FatEntries[0].cputype} from {FatEntries[0].srcentry.path}");
File.Copy(FatEntries[0].srcentry.path, _path);
}
else
{
Console.WriteLine($"Writing {_path}:");
using (var dst = new FileStream(_path, FileMode.Create, FileAccess.Write))
{
// Write Header
using (var writer = new BinaryWriterBigEndian(dst))
{
writer.Write(0xCAFEBABE);
writer.Write(FatEntries.Count);
foreach (var entry in FatEntries)
{
writer.Write((uint)entry.cputype);
writer.Write((uint)entry.cpusubtype);
writer.Write(entry.offset);
writer.Write(entry.size);
writer.Write(entry.align);
}
}
foreach (var entry in FatEntries)
{
Console.WriteLine($" - {entry.cputype} from {entry.srcentry.path}");
using (var src = new FileStream(entry.srcentry.path, FileMode.Open, FileAccess.Read))
{
dst.Seek(entry.offset, SeekOrigin.Begin);
src.Seek(entry.srcentry.offset, SeekOrigin.Begin);
var remaining = (int)entry.size;
var buf = new byte[64 * 1024];
while (remaining != 0)
{
var size = Math.Min(remaining, buf.Length);
src.Read(buf, 0, size);
dst.Write(buf, 0, size);
remaining -= size;
}
}
}
}
}
}
public void AppendEntry(MachOFatEntry entry)
{
if (!FatEntries.Any(v => v.cputype == entry.cputype))
{
FatEntries.Add(new MachOFatEntry()
{
cputype = entry.cputype,
cpusubtype = entry.cpusubtype,
offset = 0,
size = entry.size,
align = entry.align,
srcentry = entry,
archentry = entry.archentry
});
}
}
public void AppendFile(MachOFile file)
{
if (file.Entry != null)
{
AppendEntry(new MachOFatEntry
{
cputype = file.Entry.cputype,
cpusubtype = file.Entry.cpusubtype,
offset = 0,
size = (uint)file._size,
align = 0,
path = file._path,
archentry = file.Entry
});
}
else
{
file.FatEntries.ForEach(AppendEntry);
}
}
}
}

View File

@ -1,8 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net462</TargetFramework>
</PropertyGroup>
</Project>

Binary file not shown.