Files
FlaxEngine/Source/Tools/Flax.Build/Deps/Dependencies/curl.cs
2023-02-27 23:00:04 +01:00

200 lines
10 KiB
C#

// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using Flax.Build;
namespace Flax.Deps.Dependencies
{
/// <summary>
/// libcurl is a free and easy-to-use client-side URL transfer library, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. libcurl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, Kerberos), file transfer resume, http proxy tunneling and more!
/// </summary>
/// <seealso cref="Flax.Deps.Dependency" />
class curl : Dependency
{
/// <inheritdoc />
public override TargetPlatform[] Platforms
{
get
{
switch (BuildPlatform)
{
case TargetPlatform.Windows:
return new[]
{
TargetPlatform.Windows,
};
case TargetPlatform.Linux:
return new[]
{
TargetPlatform.Linux,
};
case TargetPlatform.Mac:
return new[]
{
TargetPlatform.Mac,
};
default: return new TargetPlatform[0];
}
}
}
/// <inheritdoc />
public override void Build(BuildOptions options)
{
var root = options.IntermediateFolder;
var packagePath = Path.Combine(root, "package.zip");
var vcVersion = "VC14";
var configuration = "LIB Release - DLL Windows SSPI";
var binariesToCopyWin = new[]
{
"libcurl.lib",
"lib/libcurl.pdb",
};
var filesToKeep = new[]
{
"curl.Build.cs",
};
// Get the source
if (!File.Exists(packagePath))
Downloader.DownloadFileFromUrlToPath("https://curl.haxx.se/download/curl-7.64.1.zip", packagePath);
using (ZipArchive archive = ZipFile.Open(packagePath, ZipArchiveMode.Read))
{
var newRoot = Path.Combine(root, archive.Entries.First().FullName);
if (!Directory.Exists(newRoot))
archive.ExtractToDirectory(root);
root = newRoot;
}
foreach (var platform in options.Platforms)
{
switch (platform)
{
case TargetPlatform.Windows:
{
var vsSolutionPath = Path.Combine(root, "projects", "Windows", vcVersion, "curl-all.sln");
var vcxprojPath = Path.Combine(root, "projects", "Windows", vcVersion, "lib", "libcurl.vcxproj");
var vcxprojContents = File.ReadAllText(vcxprojPath);
vcxprojContents = vcxprojContents.Replace("<RuntimeLibrary>MultiThreaded</RuntimeLibrary>", "<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>");
vcxprojContents = vcxprojContents.Replace("<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>", "<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>");
vcxprojContents = vcxprojContents.Replace("<WholeProgramOptimization>true</WholeProgramOptimization>", "<WholeProgramOptimization>false</WholeProgramOptimization>");
vcxprojContents = vcxprojContents.Replace("<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>", "<DebugInformationFormat></DebugInformationFormat>");
File.WriteAllText(vcxprojPath, vcxprojContents);
{
// Build for Win64
Deploy.VCEnvironment.BuildSolution(vsSolutionPath, configuration, "x64");
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
foreach (var filename in binariesToCopyWin)
Utilities.FileCopy(Path.Combine(root, "build", "Win64", vcVersion, configuration, filename), Path.Combine(depsFolder, Path.GetFileName(filename)));
}
break;
}
case TargetPlatform.Linux:
{
// Build for Linux
var settings = new []
{
"--without-librtmp",
"--without-ssl",
"--with-gnutls",
"--disable-ipv6",
"--disable-manual",
"--disable-verbose",
"--disable-shared",
"--enable-static",
"-disable-ldap --disable-sspi --disable-ftp --disable-file --disable-dict --disable-telnet --disable-tftp --disable-rtsp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-smb",
};
var envVars = new Dictionary<string, string>
{
{ "CC", "clang-7" },
{ "CC_FOR_BUILD", "clang-7" },
};
var buildDir = Path.Combine(root, "build");
SetupDirectory(buildDir, true);
Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run(Path.Combine(root, "configure"), string.Join(" ", settings) + " --prefix=\"" + buildDir + "\"", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run("make", "install", null, root, Utilities.RunOptions.ThrowExceptionOnError);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
var filename = "libcurl.a";
Utilities.FileCopy(Path.Combine(buildDir, "lib", filename), Path.Combine(depsFolder, filename));
break;
}
case TargetPlatform.Mac:
{
// Build for Mac
var settings = new []
{
"--with-secure-transport",
"--without-librtmp",
"--disable-ipv6",
"--disable-manual",
"--disable-verbose",
"--disable-shared",
"--enable-static",
"-disable-ldap --disable-sspi --disable-ftp --disable-file --disable-dict --disable-telnet --disable-tftp --disable-rtsp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-smb",
};
foreach (var architecture in new []{ TargetArchitecture.x64, TargetArchitecture.ARM64 })
{
var arch = GetAppleArchName(architecture);
var archName = arch + "-apple-darwin19";
if (architecture == TargetArchitecture.ARM64)
archName = "arm-apple-darwin19"; // for configure
var compilerFlags = string.Format("-mmacosx-version-min={0} -arch {1}", Configuration.MacOSXMinVer, arch);
var envVars = new Dictionary<string, string>
{
{ "CC", "clang" },
{ "CXX", "clang" },
{ "CFLAGS", compilerFlags },
{ "CXXFLAGS", compilerFlags },
{ "CPPFLAGS", compilerFlags },
{ "ARCH", arch },
{ "SDK", "macosx" },
{ "DEPLOYMENT_TARGET", Configuration.MacOSXMinVer },
};
var buildDir = Path.Combine(root, "build");
SetupDirectory(buildDir, true);
Utilities.Run("chmod", "+x configure", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run("chmod", "+x install-sh", null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run(Path.Combine(root, "configure"), string.Join(" ", settings) + " --host=" + archName + " --prefix=\"" + buildDir + "\"", null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError);
Utilities.Run("make", "install", null, root, Utilities.RunOptions.ThrowExceptionOnError);
var depsFolder = GetThirdPartyFolder(options, platform, architecture);
var filename = "libcurl.a";
Utilities.FileCopy(Path.Combine(buildDir, "lib", filename), Path.Combine(depsFolder, filename));
}
break;
}
}
}
// Backup files
var srcIncludePath = Path.Combine(root, "include", "curl");
var dstIncludePath = Path.Combine(options.ThirdPartyFolder, "curl");
foreach (var filename in filesToKeep)
{
var src = Path.Combine(dstIncludePath, filename);
var dst = Path.Combine(options.IntermediateFolder, filename + ".tmp");
Utilities.FileCopy(src, dst);
}
// Setup headers directory
SetupDirectory(dstIncludePath, true);
// Deploy header files, license file and restore files
Directory.GetFiles(srcIncludePath, "Makefile*").ToList().ForEach(File.Delete);
Utilities.DirectoryCopy(srcIncludePath, dstIncludePath, true, true);
Utilities.FileCopy(Path.Combine(root, "COPYING"), Path.Combine(dstIncludePath, "curl License.txt"));
foreach (var filename in filesToKeep)
{
var src = Path.Combine(options.IntermediateFolder, filename + ".tmp");
var dst = Path.Combine(dstIncludePath, filename);
Utilities.FileCopy(src, dst);
}
}
}
}