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 args = new List(); 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 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; } }