Files
2025-05-22 02:33:08 +03:00

250 lines
10 KiB
C#

using Actions;
using Actions.Library;
using Build;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using static System.Runtime.InteropServices.JavaScript.JSType;
class Application {
public static bool SkipBuildDeps = false;
static string GetCurrentFileDir([CallerFilePath]string callerFilePath = null) {
return Path.GetDirectoryName(callerFilePath);
}
static string GetProjectRootDir() {
return Path.GetDirectoryName(GetCurrentFileDir());
}
static string BuildZLib(string zlib, string installDir) {
var installPrefix = Path.Combine(installDir, "zlib");
if (!SkipBuildDeps) {
var buildDir = TempDirectory.New();
var cmake = Find.Executable("cmake");
var ninja = Find.Executable("ninja");
var configResult = cmake.Run($"-G \"Ninja\" -DCMAKE_INSTALL_PREFIX={installPrefix} -DCMAKE_BUILD_TYPE=RELEASE {zlib}", buildDir);
var buildResult = ninja.Run("", buildDir);
var installResult = ninja.Run("install", buildDir);
}
return installPrefix;
}
static string BuildOpenssl(string source, string installDir) {
var installPrefix = Path.Combine(installDir, "openssl").Replace("\\", "/");
if (!SkipBuildDeps) {
var tmpDir = TempDirectory.New();
var perl = Find.Executable("perl");
if (perl == null) {
throw new Exception("Perl not found but required for OpenSSL build");
}
var nasm = Find.Executable("nasm");
if (nasm == null) {
throw new Exception("Nasm not found but required for OpenSSL build");
}
var configFilePath = Path.Combine(source, "Configure").Replace("\\", "/");
var configureResult = perl.Run($"{configFilePath} VC-WIN64A enable-capieng --prefix={installPrefix} --openssldir={installPrefix}", tmpDir);
var nmake = Find.Executable("nmake");
var buildResult = nmake.Run("", tmpDir);
var installResult = nmake.Run("install", tmpDir);
}
return installPrefix;
}
static string BuildApr(string source, string installDir) {
var tmpDir = TempDirectory.New();
var cmake = Find.Executable("cmake");
var ninja = Find.Executable("ninja");
var installPrefix = Path.Combine(installDir, "apr").Replace("\\", "/");
if (!SkipBuildDeps) {
var configResult = cmake.Run($"-DCMAKE_INSTALL_PREFIX={installPrefix} -G \"Ninja\" -DAPR_INSTALL_PRIVATE_H=ON -DCMAKE_BUILD_TYPE=RELEASE -DAPR_BUILD_STATIC=ON {source}", tmpDir);
var buildResult = ninja.Run("", tmpDir);
var installResult = ninja.Run("install", tmpDir);
}
return installPrefix;
}
static string BuildAprUtil(string source, string expatLibDir, string installDir) {
var installPrefix = Path.Combine(installDir, "apr").Replace("\\", "/");
if (!SkipBuildDeps) {
var tmpDir = TempDirectory.New();
var cmake = Find.Executable("cmake");
var ninja = Find.Executable("ninja");
var expatLibPath = Path.Combine(expatLibDir, "Bin", "libexpat.lib").Replace("\\", "/");
var expatIncPath = Path.Combine(expatLibDir, "Source", "lib").Replace("\\", "/");
var opensslPath = Path.Combine(installDir, "openssl").Replace("\\", "/");
var configResult = cmake.Run($"-DCMAKE_INSTALL_PREFIX={installPrefix} -G \"Ninja\" -DAPR_INSTALL_PRIVATE_H=ON -DCMAKE_BUILD_TYPE=RELEASE -DEXPAT_LIBRARY={expatLibPath} -DEXPAT_INCLUDE_DIR={expatIncPath} -DAPU_HAVE_CRYPTO=ON -DOPENSSL_ROOT_DIR={opensslPath} {source}", tmpDir);
var buildResult = ninja.Run("", tmpDir);
var installResult = ninja.Run("install", tmpDir);
}
return installPrefix;
}
static string BuildSerf(string source, string installDir) {
var installPrefix = Path.Combine(installDir, "serf").Replace("\\", "/");
if (!SkipBuildDeps) {
var scons = Find.Executable("scons");
var libinstallPrefix = Path.Combine(installPrefix, "lib").Replace("\\", "/");
var aprPath = Path.Combine(installDir, "apr").Replace("\\", "/");
var aprUtilPath = Path.Combine(installDir, "apr").Replace("\\", "/");
var zlibPath = Path.Combine(installDir, "zlib").Replace("\\", "/");
var opensslPath = Path.Combine(installDir, "openssl").Replace("\\", "/");
//
scons.Run($"APR={aprPath} APU={aprUtilPath} ZLIB={zlibPath} OPENSSL={opensslPath} SOURCE_LAYOUT=0 TARGET_ARCH=X64 MSVC_VERSION=2022 PREFIX={installPrefix} LIBDIR={libinstallPrefix}", source);
scons.Run("install", source);
}
return installPrefix;
}
static void FixAprForSerf(string installDir) {
if (SkipBuildDeps) {
return;
}
var aprPath = Path.Combine(installDir, "apr");
var incPath = Path.Combine(aprPath, "include");
var fixPath = Path.Combine(incPath, "apr-1");
Directory.CreateDirectory(fixPath);
var files = Directory.GetFiles(incPath);
foreach (var file in files) {
var name = Path.GetFileName(file);
var destPath = Path.Combine(fixPath, name);
File.Copy(file, destPath, true);
}
}
static void PatchSerf(string serfSource) {
if (SkipBuildDeps) {
return;
}
var sconstructPath = Path.Combine(serfSource, "SConstruct");
string text = File.ReadAllText(sconstructPath);
text = text.Replace("$OPENSSL/include/openssl", "$OPENSSL/include");
File.WriteAllText(sconstructPath, text);
}
static void CopyLibraries(string srcBinlDir, string svnInstallDir) {
string svnBinDir = Path.Combine(svnInstallDir, "bin");
string[] srcFiles = Directory.GetFiles(srcBinlDir).Where(x=>x.EndsWith(".dll")).ToArray();
foreach(var file in srcFiles) {
var fileName = Path.GetFileName(file);
var dstPath = Path.Combine(svnBinDir, fileName);
File.Copy(file, dstPath, true);
}
}
static string BuildSubversion(string svnSource, string sqlSource, string aprInstallDir, string serfInstallDir, string zlibInstallDir, string opensslInstallDir, string expatDir, string svnInstallPrefix) {
var aprPath = aprInstallDir.Replace("\\", "/");
var serfPath = serfInstallDir.Replace("\\", "/");
var zlibPath = zlibInstallDir.Replace("\\", "/");
var opensslPath = opensslInstallDir.Replace("\\", "/");
string libPaths = $"{aprPath};{serfPath};{zlibPath}";
string expatBinDir = Path.Combine(expatDir,"Bin");
string expatIncDir = Path.Combine(expatDir, "Source/lib");
List<string> args = new List<string>();
args.Add("-G \"Ninja\"");
args.Add($"-DCMAKE_LIBRARY_PATH={libPaths}");
args.Add($"-DCMAKE_PREFIX_PATH={libPaths}");
args.Add($"-DPC_EXPAT_LIBRARY_DIRS={expatBinDir}");
args.Add($"-DPC_EXPAT_INCLUDE_DIRS={expatIncDir}");
args.Add($"-DSVN_SQLITE_USE_AMALGAMATION=ON");
args.Add($"-DSQLITE_AMALGAMATION_DIR={sqlSource}");
args.Add($"-DCMAKE_BUILD_TYPE=RELEASE");
args.Add($"-DSVN_ENABLE_RA_SERF=ON");
args.Add($"-DOPENSSL_ROOT_DIR={opensslPath}");
args.Add($"-DSVN_ENABLE_SVNXX=ON");
args.Add($"-DSVN_ENABLE_NLS=OFF");
args.Add($"-DZLIB_USE_STATIC_LIBS=ON");
args.Add($"-DCMAKE_INSTALL_PREFIX={svnInstallPrefix}");
args.Add($"{svnSource}");
var argsString = string.Join(" ", args);
var cmake = Find.Executable("cmake");
var ninja = Find.Executable("ninja");
var python = Find.Executable("python");
var genCmakeResult = python.Run("gen-make.py -t cmake", svnSource);
// python gen-make.py -t cmake
var tmpDir = TempDirectory.New();
var configResult = cmake.Run(argsString, tmpDir);
var buildResult = ninja.Run("", tmpDir);
var installResult = ninja.Run("install", tmpDir);
return svnInstallPrefix;
}
public static async Task<int> Main() {
SkipBuildDeps = false;
VisualStudio.SetupEnvironment(CpuArchitecture.x64);
var projectRootDir = GetProjectRootDir();
var depsSourceDirectory = Path.Combine(projectRootDir, "Downloads");
Directory.CreateDirectory(depsSourceDirectory);
var depsBuildDirectory = Path.Combine(projectRootDir, "BuildOutput");
Directory.CreateDirectory(depsBuildDirectory);
var svn = await Dependencies.GetSubversion(projectRootDir);
var zLib = await Dependencies.GetZLib(depsSourceDirectory);
var sqLite = await Dependencies.GetSqlite(depsSourceDirectory);
var apr = await Dependencies.GetApr(depsSourceDirectory);
var aprUtil = await Dependencies.GetAprUtil(depsSourceDirectory);
var serf = await Dependencies.GetSerf(depsSourceDirectory);
var openssl = await Dependencies.GetOpenssl(depsSourceDirectory);
var expat = await Dependencies.GetExpat(depsSourceDirectory);
var opensslInstallDir = BuildOpenssl(openssl, depsBuildDirectory);
var zlibInstallDir = BuildZLib(zLib, depsBuildDirectory);
var aprInstallDir = BuildApr(apr, depsBuildDirectory);
BuildAprUtil(aprUtil, expat, depsBuildDirectory);
FixAprForSerf(depsBuildDirectory);
PatchSerf(serf);
var serfInstallDir = BuildSerf(serf, depsBuildDirectory);
var svnInstallDir = BuildSubversion(svn, sqLite, aprInstallDir, serfInstallDir, zlibInstallDir, opensslInstallDir, expat, Path.Combine(depsBuildDirectory, "subversion"));
CopyLibraries(Path.Combine(aprInstallDir, "bin"), svnInstallDir);
CopyLibraries(Path.Combine(expat, "Bin"), svnInstallDir);
CopyLibraries(Path.Combine(opensslInstallDir, "bin"), svnInstallDir);
Console.WriteLine($"SVN install directory: {svnInstallDir}");
return 0;
}
}