Mac support progress

This commit is contained in:
Wojtek Figat
2021-12-29 19:43:53 +01:00
parent 0dbbdc9149
commit e361ab811a
15 changed files with 465 additions and 63 deletions

View File

@@ -47,7 +47,7 @@ namespace Flax.Build
public override string GetOutputFilePath(BuildOptions options, TargetOutputType? outputType)
{
// If building engine executable for platform doesn't support referencing it when linking game shared libraries
if (UseSymbolsExports && (outputType ?? OutputType) == TargetOutputType.Executable && !options.Platform.HasExecutableFileReferenceSupport)
if (outputType == null && UseSymbolsExports && OutputType == TargetOutputType.Executable && !options.Platform.HasExecutableFileReferenceSupport)
{
// Build into shared library
outputType = TargetOutputType.Library;

View File

@@ -29,6 +29,7 @@ namespace Flax.Deps.Dependencies
TargetPlatform.PS4,
TargetPlatform.PS5,
TargetPlatform.Switch,
TargetPlatform.Mac,
};
default: return new TargetPlatform[0];
}
@@ -62,6 +63,7 @@ namespace Flax.Deps.Dependencies
{
case TargetPlatform.Windows:
case TargetPlatform.Linux:
case TargetPlatform.Mac:
{
foreach (var file in outputFileNames)
{

View File

@@ -41,6 +41,11 @@ namespace Flax.Deps.Dependencies
{
TargetPlatform.Linux,
};
case TargetPlatform.Mac:
return new[]
{
TargetPlatform.Mac,
};
default: return new TargetPlatform[0];
}
}
@@ -104,6 +109,7 @@ namespace Flax.Deps.Dependencies
string buildPlatform;
bool suppressBitsPostfix = false;
string binariesPrefix = string.Empty;
var envVars = new Dictionary<string, string>();
switch (architecture)
{
case TargetArchitecture.x86:
@@ -180,11 +186,15 @@ namespace Flax.Deps.Dependencies
suppressBitsPostfix = true;
binariesPrefix = "lib";
break;
case TargetPlatform.Mac:
binariesSubDir = "mac.x86_64";
binariesPrefix = "lib";
envVars.Add("MACOSX_DEPLOYMENT_TARGET", Configuration.MacOSXMinVer);
break;
default: throw new InvalidPlatformException(targetPlatform);
}
// Setup build environment variables for PhysX build system
var envVars = new Dictionary<string, string>();
switch (BuildPlatform)
{
case TargetPlatform.Windows:
@@ -197,11 +207,11 @@ namespace Flax.Deps.Dependencies
break;
}
case TargetPlatform.Linux:
{
envVars.Add("CC", "clang-7");
envVars.Add("CC_FOR_BUILD", "clang-7");
break;
}
case TargetPlatform.Mac:
break;
default: throw new InvalidPlatformException(BuildPlatform);
}
if (AndroidNdk.Instance.IsValid)
@@ -276,6 +286,9 @@ namespace Flax.Deps.Dependencies
case TargetPlatform.Linux:
Utilities.Run("make", null, null, Path.Combine(projectGenDir, "compiler", "linux-" + configuration), Utilities.RunOptions.None);
break;
case TargetPlatform.Mac:
Utilities.Run("xcodebuild", "-project PhysXSDK.xcodeproj -alltargets -configuration " + configuration, null, Path.Combine(projectGenDir, "compiler", preset), Utilities.RunOptions.None);
break;
default: throw new InvalidPlatformException(BuildPlatform);
}
@@ -291,6 +304,16 @@ namespace Flax.Deps.Dependencies
var filenamePdb = Path.ChangeExtension(filename, "pdb");
if (File.Exists(Path.Combine(srcBinaries, filenamePdb)))
Utilities.FileCopy(Path.Combine(srcBinaries, filenamePdb), Path.Combine(dstBinaries, filenamePdb));
// Strip debug symbols to reduce binaries size
switch (targetPlatform)
{
case TargetPlatform.Linux:
case TargetPlatform.Mac:
case TargetPlatform.Android:
Utilities.Run("strip", "\"" + filename + "\"", null, dstBinaries, Utilities.RunOptions.None);
break;
}
}
srcBinaries = Path.Combine(root, "physx", "compiler", preset, "sdk_source_bin", configuration);
var additionalPhysXLibs = new[]
@@ -318,13 +341,16 @@ namespace Flax.Deps.Dependencies
root = options.IntermediateFolder;
projectGenDir = Path.Combine(root, "physx");
solutionFilesRoot = Path.Combine(root, "physx", "compiler");
if (BuildPlatform == TargetPlatform.Windows)
switch (BuildPlatform)
{
case TargetPlatform.Windows:
projectGenPath = Path.Combine(projectGenDir, "generate_projects.bat");
}
else if (BuildPlatform == TargetPlatform.Linux)
{
break;
case TargetPlatform.Linux:
case TargetPlatform.Mac:
projectGenPath = Path.Combine(projectGenDir, "generate_projects.sh");
break;
default: throw new InvalidPlatformException(BuildPlatform);
}
// Get the source
@@ -382,6 +408,11 @@ namespace Flax.Deps.Dependencies
Build(options, "switch64", platform, TargetArchitecture.ARM64);
break;
}
case TargetPlatform.Mac:
{
Build(options, "mac64", platform, TargetArchitecture.x64);
break;
}
}
}

View File

@@ -39,6 +39,11 @@ namespace Flax.Deps.Dependencies
{
TargetPlatform.Linux,
};
case TargetPlatform.Mac:
return new[]
{
TargetPlatform.Mac,
};
default: return new TargetPlatform[0];
}
}
@@ -63,10 +68,12 @@ namespace Flax.Deps.Dependencies
};
// Get the source
Downloader.DownloadFileFromUrlToPath("https://sourceforge.net/projects/freetype/files/freetype2/2.10.0/ft2100.zip/download", packagePath);
if (!File.Exists(packagePath))
Downloader.DownloadFileFromUrlToPath("https://sourceforge.net/projects/freetype/files/freetype2/2.10.0/ft2100.zip/download", packagePath);
using (ZipArchive archive = ZipFile.Open(packagePath, ZipArchiveMode.Read))
{
archive.ExtractToDirectory(root);
if (!Directory.Exists(root))
archive.ExtractToDirectory(root);
root = Path.Combine(root, archive.Entries.First().FullName);
}
@@ -238,6 +245,17 @@ namespace Flax.Deps.Dependencies
Utilities.FileCopy(Path.Combine(buildDir, libraryFileName), Path.Combine(depsFolder, libraryFileName));
break;
}
case TargetPlatform.Mac:
{
// Build for Mac
var buildDir = Path.Combine(root, "build");
SetupDirectory(buildDir, true);
RunCmake(buildDir, platform, TargetArchitecture.x64, ".. -DCMAKE_BUILD_TYPE=Release");
Utilities.Run("cmake", "--build .", null, buildDir, Utilities.RunOptions.None);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
Utilities.FileCopy(Path.Combine(buildDir, libraryFileName), Path.Combine(depsFolder, libraryFileName));
break;
}
}
}

View File

@@ -38,6 +38,11 @@ namespace Flax.Deps.Dependencies
{
TargetPlatform.Linux,
};
case TargetPlatform.Mac:
return new[]
{
TargetPlatform.Mac,
};
default: return new TargetPlatform[0];
}
}
@@ -191,7 +196,7 @@ namespace Flax.Deps.Dependencies
// Build for Android
SetupDirectory(buildDir, true);
RunCmake(buildDir, TargetPlatform.Android, TargetArchitecture.ARM64, ".. -DCMAKE_BUILD_TYPE=Release");
RunCmake(buildDir, platform, TargetArchitecture.ARM64, ".. -DCMAKE_BUILD_TYPE=Release");
Utilities.Run("cmake", "--build .", null, buildDir, Utilities.RunOptions.None);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.ARM64);
Utilities.FileCopy(Path.Combine(buildDir, libraryFileName), Path.Combine(depsFolder, libraryFileName));
@@ -211,6 +216,18 @@ namespace Flax.Deps.Dependencies
Utilities.FileCopy(Path.Combine(buildDir, libraryFileName), Path.Combine(depsFolder, libraryFileName));
break;
}
case TargetPlatform.Mac:
{
var buildDir = Path.Combine(root, "build");
// Build for Mac
SetupDirectory(buildDir, true);
RunCmake(buildDir, platform, TargetArchitecture.x64, ".. -DCMAKE_BUILD_TYPE=Release");
Utilities.Run("cmake", "--build .", null, buildDir, Utilities.RunOptions.None);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
Utilities.FileCopy(Path.Combine(buildDir, libraryFileName), Path.Combine(depsFolder, libraryFileName));
break;
}
}
}

View File

@@ -39,6 +39,11 @@ namespace Flax.Deps.Dependencies
{
TargetPlatform.Linux,
};
case TargetPlatform.Mac:
return new[]
{
TargetPlatform.Mac,
};
default: return new TargetPlatform[0];
}
}
@@ -283,12 +288,12 @@ namespace Flax.Deps.Dependencies
Utilities.Run(Path.Combine(root, "autogen.sh"), null, null, root, Utilities.RunOptions.Default, envVars);
// Build for Linux
var toolchain = UnixToolchain.GetToolchainName(TargetPlatform.Linux, TargetArchitecture.x64);
var toolchain = UnixToolchain.GetToolchainName(platform, TargetArchitecture.x64);
Utilities.Run(Path.Combine(root, "configure"), string.Format("--host={0}", toolchain), null, root, Utilities.RunOptions.Default, envVars);
SetupDirectory(buildDir, true);
Utilities.Run("cmake", "-G \"Unix Makefiles\" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_BUILD_TYPE=Release ..", null, buildDir, Utilities.RunOptions.None, envVars);
Utilities.Run("cmake", "--build .", null, buildDir, Utilities.RunOptions.None, envVars);
var depsFolder = GetThirdPartyFolder(options, TargetPlatform.Linux, TargetArchitecture.x64);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
foreach (var file in binariesToCopyUnix)
Utilities.FileCopy(Path.Combine(buildDir, file.SrcFolder, file.Filename), Path.Combine(depsFolder, file.Filename));
break;
@@ -321,12 +326,12 @@ namespace Flax.Deps.Dependencies
// Build for Android
SetupDirectory(oggBuildDir, true);
RunCmake(oggBuildDir, TargetPlatform.Android, TargetArchitecture.ARM64, ".. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=\"../install\"");
RunCmake(oggBuildDir, platform, TargetArchitecture.ARM64, ".. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=\"../install\"");
Utilities.Run("cmake", "--build . --target install", null, oggBuildDir, Utilities.RunOptions.None);
SetupDirectory(buildDir, true);
RunCmake(buildDir, TargetPlatform.Android, TargetArchitecture.ARM64, string.Format(".. -DCMAKE_BUILD_TYPE=Release -DOGG_INCLUDE_DIR=\"{0}/install/include\" -DOGG_LIBRARY=\"{0}/install/lib\"", oggRoot));
RunCmake(buildDir, platform, TargetArchitecture.ARM64, string.Format(".. -DCMAKE_BUILD_TYPE=Release -DOGG_INCLUDE_DIR=\"{0}/install/include\" -DOGG_LIBRARY=\"{0}/install/lib\"", oggRoot));
Utilities.Run("cmake", "--build .", null, buildDir, Utilities.RunOptions.None);
var depsFolder = GetThirdPartyFolder(options, TargetPlatform.Android, TargetArchitecture.ARM64);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.ARM64);
foreach (var file in binariesToCopyUnix)
Utilities.FileCopy(Path.Combine(buildDir, file.SrcFolder, file.Filename), Path.Combine(depsFolder, file.Filename));
break;
@@ -358,6 +363,29 @@ namespace Flax.Deps.Dependencies
Utilities.FileCopy(Path.Combine(buildDir, file.SrcFolder, file.Filename), Path.Combine(depsFolder, file.Filename));
break;
}
case TargetPlatform.Mac:
{
var oggRoot = Path.Combine(root, "ogg");
var oggBuildDir = Path.Combine(oggRoot, "build");
var buildDir = Path.Combine(root, "build");
// Get the source
CloneGitRepoFast(root, "https://github.com/xiph/vorbis.git");
CloneGitRepo(oggRoot, "https://github.com/xiph/ogg.git");
GitCheckout(oggRoot, "master", "4380566a44b8d5e85ad511c9c17eb04197863ec5");
// Build for Android
SetupDirectory(oggBuildDir, true);
RunCmake(oggBuildDir, platform, TargetArchitecture.x64, ".. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=\"../install\"");
Utilities.Run("cmake", "--build . --target install", null, oggBuildDir, Utilities.RunOptions.None);
SetupDirectory(buildDir, true);
RunCmake(buildDir, platform, TargetArchitecture.x64, string.Format(".. -DCMAKE_BUILD_TYPE=Release -DOGG_INCLUDE_DIR=\"{0}/install/include\" -DOGG_LIBRARY=\"{0}/install/lib\"", oggRoot));
Utilities.Run("cmake", "--build .", null, buildDir, Utilities.RunOptions.None);
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
foreach (var file in binariesToCopyUnix)
Utilities.FileCopy(Path.Combine(buildDir, file.SrcFolder, file.Filename), Path.Combine(depsFolder, file.Filename));
break;
}
}
}

View File

@@ -239,7 +239,6 @@ namespace Flax.Deps
case TargetPlatform.Linux:
case TargetPlatform.PS4:
case TargetPlatform.PS5:
case TargetPlatform.Mac:
{
cmdLine = "CMakeLists.txt";
break;
@@ -257,6 +256,11 @@ namespace Flax.Deps
cmdLine = string.Format("-DCMAKE_TOOLCHAIN_FILE=\"{0}/build/cmake/android.toolchain.cmake\" -DANDROID_NDK=\"{0}\" -DANDROID_STL=c++_shared -DANDROID_ABI={1} -DANDROID_PLATFORM=android-{2} -G \"MinGW Makefiles\" -DCMAKE_MAKE_PROGRAM=\"{0}/prebuilt/{3}/bin/make.exe\"", ndk, abi, Configuration.AndroidPlatformApi, hostName);
break;
}
case TargetPlatform.Mac:
{
cmdLine = string.Format("CMakeLists.txt -DCMAKE_OSX_DEPLOYMENT_TARGET=\"{0}\"", Configuration.MacOSXMinVer);
break;
}
default: throw new InvalidPlatformException(platform);
}

View File

@@ -61,6 +61,8 @@ namespace Flax.Deps
public static FileInfo DownloadFileFromUrlToPath(string url, string path)
{
Log.Verbose(string.Format("Downloading {0} to {1}", url, path));
if (File.Exists(path))
File.Delete(path);
if (url.StartsWith(GoogleDriveDomain) || url.StartsWith(GoogleDriveDomain2))
return DownloadGoogleDriveFileFromUrlToPath(url, path);

View File

@@ -6,6 +6,18 @@ using System.Collections.Generic;
using Flax.Build.Graph;
using Flax.Build.NativeCpp;
namespace Flax.Build
{
partial class Configuration
{
/// <summary>
/// Specifies the minimum Mac OSX version to use (eg. 10.14).
/// </summary>
[CommandLine("macOSXMinVer", "<version>", "Specifies the minimum Mac OSX version to use (eg. 10.14).")]
public static string MacOSXMinVer = "10.14";
}
}
namespace Flax.Build.Platforms
{
/// <summary>
@@ -14,8 +26,6 @@ namespace Flax.Build.Platforms
/// <seealso cref="UnixToolchain" />
public sealed class MacToolchain : UnixToolchain
{
private string MinMacOSXVer = "10.14";
public string ToolchainPath;
public string SdkPath;
public string LinkerPath;
@@ -95,6 +105,14 @@ namespace Flax.Build.Platforms
base.SetupEnvironment(options);
options.CompileEnv.PreprocessorDefinitions.Add("PLATFORM_MAC");
options.LinkEnv.InputLibraries.Add("z");
options.LinkEnv.InputLibraries.Add("bz2");
options.LinkEnv.InputLibraries.Add("CoreFoundation.framework");
options.LinkEnv.InputLibraries.Add("CoreGraphics.framework");
options.LinkEnv.InputLibraries.Add("SystemConfiguration.framework");
options.LinkEnv.InputLibraries.Add("IOKit.framework");
}
/// <inheritdoc />
@@ -113,15 +131,26 @@ namespace Flax.Build.Platforms
commonArgs.Add("c++");
commonArgs.Add("-std=c++14");
commonArgs.Add("-stdlib=libc++");
commonArgs.Add("-mmacosx-version-min=" + MinMacOSXVer);
AddArgsCommon(options, commonArgs);
switch (Architecture)
{
case TargetArchitecture.x64:
commonArgs.Add("-msse2");
break;
}
commonArgs.Add("-Wdelete-non-virtual-dtor");
commonArgs.Add("-fno-math-errno");
commonArgs.Add("-fasm-blocks");
commonArgs.Add("-fpascal-strings");
commonArgs.Add("-fdiagnostics-format=msvc");
commonArgs.Add("-Wno-absolute-value");
commonArgs.Add("-Wno-nullability-completeness");
commonArgs.Add("-Wno-undef-prefix");
commonArgs.Add("-Wno-expansion-to-defined");
commonArgs.Add("-Wno-non-virtual-dtor");
// Hide all symbols by default
commonArgs.Add("-fvisibility-inlines-hidden");
@@ -222,7 +251,7 @@ namespace Flax.Build.Platforms
var args = new List<string>();
{
args.Add(string.Format("-o \"{0}\"", outputFilePath));
args.Add("-mmacosx-version-min=" + MinMacOSXVer);
AddArgsCommon(options, args);
if (!options.LinkEnv.DebugInformation)
args.Add("-Wl,--strip-debug");
@@ -230,12 +259,15 @@ namespace Flax.Build.Platforms
switch (linkEnvironment.Output)
{
case LinkerOutput.Executable:
args.Add("-dead_strip");
break;
case LinkerOutput.SharedLibrary:
args.Add("-dynamiclib");
args.Add("-dead_strip");
break;
case LinkerOutput.StaticLibrary:
case LinkerOutput.ImportLibrary:
args.Add("-static");
break;
default: throw new ArgumentOutOfRangeException();
}
@@ -247,7 +279,11 @@ namespace Flax.Build.Platforms
{
var dir = Path.GetDirectoryName(library);
var ext = Path.GetExtension(library);
if (string.IsNullOrEmpty(dir))
if (ext == ".framework")
{
args.Add(string.Format("-framework {0}", library.Substring(0, library.Length - ext.Length)));
}
else if (string.IsNullOrEmpty(dir))
{
args.Add(string.Format("\"-l{0}\"", library));
}
@@ -260,12 +296,13 @@ namespace Flax.Build.Platforms
// Link against dynamic library
task.PrerequisiteFiles.Add(library);
libraryPaths.Add(dir);
args.Add(string.Format("\"-l{0}\"", UnixToolchain.GetLibName(library)));
//args.Add(string.Format("\"-l{0}\"", GetLibName(library)));
args.Add(string.Format("\"{0}\"", library));
}
else
{
task.PrerequisiteFiles.Add(library);
args.Add(string.Format("\"{0}\"", UnixToolchain.GetLibName(library)));
args.Add(string.Format("\"{0}\"", GetLibName(library)));
}
}
foreach (var library in options.Libraries)
@@ -285,12 +322,13 @@ namespace Flax.Build.Platforms
// Link against dynamic library
task.PrerequisiteFiles.Add(library);
libraryPaths.Add(dir);
args.Add(string.Format("\"-l{0}\"", UnixToolchain.GetLibName(library)));
//args.Add(string.Format("\"-l{0}\"", GetLibName(library)));
args.Add(string.Format("\"{0}\"", library));
}
else
{
task.PrerequisiteFiles.Add(library);
args.Add(string.Format("\"{0}\"", UnixToolchain.GetLibName(library)));
args.Add(string.Format("\"{0}\"", GetLibName(library)));
}
}
@@ -336,6 +374,36 @@ namespace Flax.Build.Platforms
task.InfoMessage = "Linking " + outputFilePath;
task.Cost = task.PrerequisiteFiles.Count;
task.ProducedFiles.Add(outputFilePath);
if (!options.LinkEnv.DebugInformation)
{
// Strip debug symbols
var stripTask = graph.Add<Task>();
stripTask.ProducedFiles.Add(outputFilePath);
stripTask.WorkingDirectory = options.WorkingDirectory;
stripTask.CommandPath = "strip";
stripTask.CommandArguments = string.Format("\"{0}\" -S", outputFilePath);
stripTask.InfoMessage = "Striping " + outputFilePath;
stripTask.Cost = 1;
stripTask.DisableCache = true;
stripTask.DependentTasks = new HashSet<Task>();
stripTask.DependentTasks.Add(task);
}
}
private void AddArgsCommon(BuildOptions options, List<string> args)
{
args.Add("-mmacosx-version-min=" + Configuration.MacOSXMinVer);
args.Add("-isysroot \"" + SdkPath + "\"");
switch (Architecture)
{
case TargetArchitecture.x64:
args.Add("-arch x86_64");
break;
case TargetArchitecture.ARM64:
args.Add("-arch arm64");
break;
}
}
}
}

View File

@@ -304,7 +304,7 @@ namespace Flax.Build.Projects.VisualStudioCode
var target = configuration.Target;
var outputType = project.OutputType ?? target.OutputType;
var outputTargetFilePath = target.GetOutputFilePath(configuration.TargetBuildOptions, project.OutputType);
var outputTargetFilePath = target.GetOutputFilePath(configuration.TargetBuildOptions, TargetOutputType.Executable);
json.BeginObject();
{
@@ -387,6 +387,31 @@ namespace Flax.Build.Projects.VisualStudioCode
json.EndArray();
}
break;
case TargetPlatform.Mac:
if (configuration.Platform == TargetPlatform.Mac && (outputType != TargetOutputType.Executable || project.Name == "Flax") && configuration.Name.StartsWith("Editor."))
{
json.AddField("program", Path.Combine(Globals.EngineRoot, "Binaries", "Editor", "Mac", configuration.ConfigurationName, "FlaxEditor"));
}
else
{
json.AddField("program", outputTargetFilePath);
}
if (configuration.Platform == TargetPlatform.Mac)
{
json.AddField("MIMode", "lldb");
json.BeginArray("args");
{
json.AddUnnamedField("--std");
if (outputType != TargetOutputType.Executable && configuration.Name.StartsWith("Editor."))
{
json.AddUnnamedField("--project");
json.AddUnnamedField(buildToolWorkspace);
json.AddUnnamedField("--skipCompile");
}
}
json.EndArray();
}
break;
}
switch (configuration.Platform)
{

View File

@@ -319,7 +319,10 @@ namespace Flax.Build
/// <returns>The exit code of the program.</returns>
public static int Run(string app, string commandLine = null, string input = null, string workspace = null, RunOptions options = RunOptions.Default, Dictionary<string, string> envVars = null)
{
// Check if the application exists, including the PATH directories.
if (string.IsNullOrEmpty(app))
throw new ArgumentNullException(nameof(app), "Missing app to run.");
// Check if the application exists, including the PATH directories
if (options.HasFlag(RunOptions.AppMustExist) && !File.Exists(app))
{
bool existsInPath = false;