Add **Web platform with Emscripten**
This commit is contained in:
@@ -35,6 +35,7 @@ namespace Flax.Build
|
||||
case TargetPlatform.Switch:
|
||||
case TargetPlatform.Mac:
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.Web:
|
||||
options.OutputFiles.Add(Path.Combine(path, string.Format("lib{0}.a", name)));
|
||||
break;
|
||||
default: throw new InvalidPlatformException(options.Platform.Target);
|
||||
|
||||
@@ -108,6 +108,7 @@ namespace Flax.Build
|
||||
case TargetPlatform.Switch: return "PLATFORM_SWITCH";
|
||||
case TargetPlatform.Mac: return "PLATFORM_MAC";
|
||||
case TargetPlatform.iOS: return "PLATFORM_IOS";
|
||||
case TargetPlatform.Web: return "PLATFORM_WEB";
|
||||
default: throw new InvalidPlatformException(platform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace Flax.Build
|
||||
/// <summary>
|
||||
/// Gets the default project format used by the given platform.
|
||||
/// </summary>
|
||||
public abstract Projects.ProjectFormat DefaultProjectFormat { get; }
|
||||
public virtual Projects.ProjectFormat DefaultProjectFormat => Projects.ProjectFormat.VisualStudioCode;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the toolchain for a given architecture.
|
||||
@@ -343,6 +343,7 @@ namespace Flax.Build
|
||||
case TargetPlatform.Switch: return targetArchitecture == TargetArchitecture.ARM64;
|
||||
case TargetPlatform.Mac: return targetArchitecture == TargetArchitecture.ARM64 || targetArchitecture == TargetArchitecture.x64;
|
||||
case TargetPlatform.iOS: return targetArchitecture == TargetArchitecture.ARM64;
|
||||
case TargetPlatform.Web: return targetArchitecture == TargetArchitecture.x86;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ namespace Flax.Build
|
||||
/// Running on iPhone.
|
||||
/// </summary>
|
||||
iOS = 11,
|
||||
|
||||
/// <summary>
|
||||
/// Running on Web.
|
||||
/// </summary>
|
||||
Web = 12,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -296,6 +296,8 @@ namespace Flax.Build
|
||||
|
||||
public static bool WithCSharp(NativeCpp.BuildOptions options)
|
||||
{
|
||||
if (options.Platform.Target == TargetPlatform.Web)
|
||||
return false; // TODO: implement .NET for WebAssembly
|
||||
return UseCSharp || options.Target.IsEditor;
|
||||
}
|
||||
|
||||
@@ -318,6 +320,8 @@ namespace Flax.Build
|
||||
case TargetPlatform.Linux:
|
||||
case TargetPlatform.Mac:
|
||||
return UseSDL;
|
||||
case TargetPlatform.Web:
|
||||
return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace Flax.Build
|
||||
TargetPlatform.Switch,
|
||||
TargetPlatform.Mac,
|
||||
TargetPlatform.iOS,
|
||||
TargetPlatform.Web,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -104,6 +104,7 @@ namespace Flax.Build.Platforms
|
||||
{
|
||||
case TargetPlatform.Linux: return HasRequiredSDKsInstalled;
|
||||
case TargetPlatform.Android: return AndroidSdk.Instance.IsValid && AndroidNdk.Instance.IsValid;
|
||||
case TargetPlatform.Web: return EmscriptenSdk.Instance.IsValid;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace Flax.Build.Platforms
|
||||
{
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.Mac: return HasRequiredSDKsInstalled;
|
||||
case TargetPlatform.Web: return EmscriptenSdk.Instance.IsValid;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ namespace Flax.Build.Platforms
|
||||
|
||||
// Language for the file
|
||||
args.Add("-x");
|
||||
if (Path.GetExtension(sourceFile).Equals(".c", StringComparison.OrdinalIgnoreCase))
|
||||
if (sourceFile.EndsWith(".c", StringComparison.OrdinalIgnoreCase))
|
||||
args.Add("c");
|
||||
else
|
||||
{
|
||||
|
||||
87
Source/Tools/Flax.Build/Platforms/Web/EmscriptenSdk.cs
Normal file
87
Source/Tools/Flax.Build/Platforms/Web/EmscriptenSdk.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Flax.Build.Platforms
|
||||
{
|
||||
/// <summary>
|
||||
/// The Emscripten SDK (https://emscripten.org/).
|
||||
/// </summary>
|
||||
/// <seealso cref="Sdk" />
|
||||
public sealed class EmscriptenSdk : Sdk
|
||||
{
|
||||
/// <summary>
|
||||
/// The singleton instance.
|
||||
/// </summary>
|
||||
public static readonly EmscriptenSdk Instance = new EmscriptenSdk();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TargetPlatform[] Platforms => new[]
|
||||
{
|
||||
TargetPlatform.Windows,
|
||||
TargetPlatform.Linux,
|
||||
TargetPlatform.Mac,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Full path to the current SDK folder with binaries, tools and sources (eg. '%EMSDK%\upstream').
|
||||
/// </summary>
|
||||
public string EmscriptenPath;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AndroidSdk"/> class.
|
||||
/// </summary>
|
||||
public EmscriptenSdk()
|
||||
{
|
||||
if (!Platforms.Contains(Platform.BuildTargetPlatform))
|
||||
return;
|
||||
|
||||
// Find Emscripten SDK folder path
|
||||
var sdkPath = Environment.GetEnvironmentVariable("EMSDK");
|
||||
if (string.IsNullOrEmpty(sdkPath))
|
||||
{
|
||||
Log.Warning("Missing Emscripten SDK. Cannot build for Web platform.");
|
||||
}
|
||||
else if (!Directory.Exists(sdkPath))
|
||||
{
|
||||
Log.Warning(string.Format("Specified Emscripten SDK folder in EMSDK env variable doesn't exist ({0})", sdkPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
RootPath = sdkPath;
|
||||
EmscriptenPath = Path.Combine(sdkPath, "upstream");
|
||||
var versionPath = Path.Combine(EmscriptenPath, "emscripten", "emscripten-version.txt");
|
||||
if (File.Exists(versionPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Read version
|
||||
var versionStr = File.ReadAllLines(versionPath)[0];
|
||||
versionStr = versionStr.Trim();
|
||||
if (versionStr.StartsWith('\"') && versionStr.EndsWith('\"'))
|
||||
versionStr = versionStr.Substring(1, versionStr.Length - 2);
|
||||
Version = new Version(versionStr);
|
||||
|
||||
var minVersion = new Version(4, 0);
|
||||
if (Version < minVersion)
|
||||
{
|
||||
Log.Error(string.Format("Unsupported Emscripten SDK version {0}. Minimum supported is {1}.", Version, minVersion));
|
||||
return;
|
||||
}
|
||||
Log.Info(string.Format("Found Emscripten SDK {0} at {1}", Version, RootPath));
|
||||
IsValid = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Failed to read Emscripten SDK version from file '{versionPath}'");
|
||||
Log.Exception(ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
Log.Warning($"Missing file {versionPath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
Source/Tools/Flax.Build/Platforms/Web/WebPlatform.cs
Normal file
68
Source/Tools/Flax.Build/Platforms/Web/WebPlatform.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
using Flax.Build.Projects;
|
||||
|
||||
namespace Flax.Build.Platforms
|
||||
{
|
||||
/// <summary>
|
||||
/// The build platform for Web with Emscripten.
|
||||
/// </summary>
|
||||
/// <seealso cref="Platform" />
|
||||
public sealed class WebPlatform : Platform, IProjectCustomizer
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override TargetPlatform Target => TargetPlatform.Web;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasRequiredSDKsInstalled { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasSharedLibrarySupport => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasModularBuildSupport => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool HasDynamicCodeExecutionSupport => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ExecutableFileExtension => ".html";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string SharedLibraryFileExtension => ".so";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string StaticLibraryFileExtension => ".a";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ProgramDatabaseFileExtension => string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Flax.Build.Platforms.WebPlatform"/> class.
|
||||
/// </summary>
|
||||
public WebPlatform()
|
||||
{
|
||||
HasRequiredSDKsInstalled = EmscriptenSdk.Instance.IsValid;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Toolchain CreateToolchain(TargetArchitecture architecture)
|
||||
{
|
||||
if (architecture != TargetArchitecture.x86)
|
||||
throw new InvalidArchitectureException(architecture, "Web is compiled into WebAssembly and doesn't have specific architecture but is mocked as x86.");
|
||||
return new WebToolchain(this, architecture);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
void IProjectCustomizer.GetSolutionArchitectureName(TargetArchitecture architecture, ref string name)
|
||||
{
|
||||
name = "Web";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
void IProjectCustomizer.GetProjectArchitectureName(Project project, Platform platform, TargetArchitecture architecture, ref string name)
|
||||
{
|
||||
name = "Win32";
|
||||
}
|
||||
}
|
||||
}
|
||||
302
Source/Tools/Flax.Build/Platforms/Web/WebToolchain.cs
Normal file
302
Source/Tools/Flax.Build/Platforms/Web/WebToolchain.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Flax.Build.Graph;
|
||||
using Flax.Build.NativeCpp;
|
||||
|
||||
namespace Flax.Build.Platforms
|
||||
{
|
||||
/// <summary>
|
||||
/// The build toolchain for Web with Emscripten.
|
||||
/// </summary>
|
||||
/// <seealso cref="Toolchain" />
|
||||
public sealed class WebToolchain : Toolchain
|
||||
{
|
||||
private string _sysrootPath;
|
||||
private string _compilerPath;
|
||||
private Version _compilerVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebToolchain"/> class.
|
||||
/// </summary>
|
||||
/// <param name="platform">The platform.</param>
|
||||
/// <param name="architecture">The target architecture.</param>
|
||||
public WebToolchain(WebPlatform platform, TargetArchitecture architecture)
|
||||
: base(platform, architecture)
|
||||
{
|
||||
var sdkPath = EmscriptenSdk.Instance.EmscriptenPath;
|
||||
|
||||
// Setup tools
|
||||
_compilerPath = Path.Combine(sdkPath, "emscripten", "emcc");
|
||||
var clangPath = Path.Combine(sdkPath, "bin", "clang++");
|
||||
if (Platform.BuildTargetPlatform == TargetPlatform.Windows)
|
||||
{
|
||||
_compilerPath += ".bat";
|
||||
clangPath += ".exe";
|
||||
}
|
||||
|
||||
// Determinate compiler version
|
||||
_compilerVersion = UnixToolchain.GetClangVersion(platform.Target, clangPath);
|
||||
|
||||
// Setup system paths
|
||||
SystemIncludePaths.Add(Path.Combine(sdkPath, "lib", "clang", _compilerVersion.Major.ToString(), "include"));
|
||||
SystemIncludePaths.Add(Path.Combine(sdkPath, "emscripten", "system", "include"));
|
||||
SystemIncludePaths.Add(Path.Combine(sdkPath, "emscripten", "system", "lib"));
|
||||
_sysrootPath = Path.Combine(sdkPath, "emscripten/cache/sysroot/include");
|
||||
}
|
||||
|
||||
public static string GetLibName(string path)
|
||||
{
|
||||
var libName = Path.GetFileNameWithoutExtension(path);
|
||||
if (libName.StartsWith("lib"))
|
||||
libName = libName.Substring(3);
|
||||
return libName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string DllExport => "__attribute__((__visibility__(\\\"default\\\")))";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string DllImport => "";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TargetCompiler Compiler => TargetCompiler.Clang;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string NativeCompilerPath => _compilerPath;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void LogInfo()
|
||||
{
|
||||
Log.Info("Clang version: " + _compilerVersion);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void SetupEnvironment(BuildOptions options)
|
||||
{
|
||||
base.SetupEnvironment(options);
|
||||
|
||||
options.CompileEnv.PreprocessorDefinitions.Add("PLATFORM_WEB");
|
||||
options.CompileEnv.PreprocessorDefinitions.Add("PLATFORM_UNIX");
|
||||
options.CompileEnv.PreprocessorDefinitions.Add("__EMSCRIPTEN__");
|
||||
options.CompileEnv.EnableExceptions = false;
|
||||
options.CompileEnv.CpuArchitecture = CpuArchitecture.None; // TODO: try SIMD support in Emscripten
|
||||
}
|
||||
|
||||
private void AddSharedArgs(List<string> args, bool debugInformation, bool optimization, FavorSizeOrSpeed favorSizeOrSpeed)
|
||||
{
|
||||
if (debugInformation)
|
||||
args.Add("-g2");
|
||||
else
|
||||
args.Add("-g0");
|
||||
|
||||
if (favorSizeOrSpeed == FavorSizeOrSpeed.SmallCode)
|
||||
args.Add("-Os");
|
||||
if (favorSizeOrSpeed == FavorSizeOrSpeed.FastCode)
|
||||
args.Add("-O3");
|
||||
else if (optimization)
|
||||
args.Add("-O2");
|
||||
else
|
||||
args.Add("-O0");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override CompileOutput CompileCppFiles(TaskGraph graph, BuildOptions options, List<string> sourceFiles, string outputPath)
|
||||
{
|
||||
var output = new CompileOutput();
|
||||
|
||||
// Setup arguments shared by all source files
|
||||
var commonArgs = new List<string>();
|
||||
commonArgs.AddRange(options.CompileEnv.CustomArgs);
|
||||
{
|
||||
commonArgs.Add("-c");
|
||||
|
||||
AddSharedArgs(commonArgs, options.CompileEnv.DebugInformation, options.CompileEnv.Optimization, options.CompileEnv.FavorSizeOrSpeed);
|
||||
}
|
||||
|
||||
// Add preprocessor definitions
|
||||
foreach (var definition in options.CompileEnv.PreprocessorDefinitions)
|
||||
{
|
||||
commonArgs.Add(string.Format("-D \"{0}\"", definition));
|
||||
}
|
||||
|
||||
// Add include paths
|
||||
foreach (var includePath in options.CompileEnv.IncludePaths)
|
||||
{
|
||||
if (SystemIncludePaths.Contains(includePath)) // TODO: fix SystemIncludePaths so this chack can be removed
|
||||
continue; // Skip system includes as those break compilation (need to fix sys root linking for emscripten)
|
||||
commonArgs.Add(string.Format("-I\"{0}\"", includePath.Replace('\\', '/')));
|
||||
}
|
||||
|
||||
// Hack for sysroot includes
|
||||
commonArgs.Add(string.Format("-I\"{0}\"", _sysrootPath.Replace('\\', '/')));
|
||||
|
||||
// Compile all C/C++ files
|
||||
var args = new List<string>();
|
||||
foreach (var sourceFile in sourceFiles)
|
||||
{
|
||||
var sourceFilename = Path.GetFileNameWithoutExtension(sourceFile);
|
||||
var task = graph.Add<CompileCppTask>();
|
||||
|
||||
// Use shared arguments
|
||||
args.Clear();
|
||||
args.AddRange(commonArgs);
|
||||
|
||||
// Language for the file
|
||||
args.Add("-x");
|
||||
if (sourceFile.EndsWith(".c", StringComparison.OrdinalIgnoreCase))
|
||||
args.Add("c");
|
||||
else
|
||||
{
|
||||
args.Add("c++");
|
||||
|
||||
// C++ version
|
||||
switch (options.CompileEnv.CppVersion)
|
||||
{
|
||||
case CppVersion.Cpp14:
|
||||
args.Add("-std=c++14");
|
||||
break;
|
||||
case CppVersion.Cpp17:
|
||||
case CppVersion.Latest:
|
||||
args.Add("-std=c++17");
|
||||
break;
|
||||
case CppVersion.Cpp20:
|
||||
args.Add("-std=c++20");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Object File Name
|
||||
var objFile = Path.Combine(outputPath, sourceFilename + ".o");
|
||||
args.Add(string.Format("-o \"{0}\"", objFile.Replace('\\', '/')));
|
||||
output.ObjectFiles.Add(objFile);
|
||||
task.ProducedFiles.Add(objFile);
|
||||
|
||||
// Source File Name
|
||||
args.Add("\"" + sourceFile.Replace('\\', '/') + "\"");
|
||||
|
||||
// Request included files to exist
|
||||
var includes = IncludesCache.FindAllIncludedFiles(sourceFile);
|
||||
task.PrerequisiteFiles.AddRange(includes);
|
||||
|
||||
// Compile
|
||||
task.WorkingDirectory = options.WorkingDirectory;
|
||||
task.CommandPath = _compilerPath;
|
||||
task.CommandArguments = string.Join(" ", args);
|
||||
task.PrerequisiteFiles.Add(sourceFile);
|
||||
task.InfoMessage = Path.GetFileName(sourceFile);
|
||||
task.Cost = task.PrerequisiteFiles.Count; // TODO: include source file size estimation to improve tasks sorting
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private Task CreateBinary(TaskGraph graph, BuildOptions options, string outputFilePath)
|
||||
{
|
||||
var task = graph.Add<LinkTask>();
|
||||
|
||||
// Setup arguments
|
||||
var args = new List<string>();
|
||||
args.AddRange(options.LinkEnv.CustomArgs);
|
||||
{
|
||||
args.Add(string.Format("-o \"{0}\"", outputFilePath.Replace('\\', '/')));
|
||||
|
||||
AddSharedArgs(args, options.LinkEnv.DebugInformation, options.LinkEnv.Optimization, options.CompileEnv.FavorSizeOrSpeed);
|
||||
}
|
||||
|
||||
args.Add("-Wl,--start-group");
|
||||
|
||||
// Input libraries
|
||||
var libraryPaths = new HashSet<string>();
|
||||
var dynamicLibExt = Platform.SharedLibraryFileExtension;
|
||||
foreach (var library in options.LinkEnv.InputLibraries.Concat(options.Libraries))
|
||||
{
|
||||
var dir = Path.GetDirectoryName(library);
|
||||
var ext = Path.GetExtension(library);
|
||||
if (library.StartsWith("--use-port="))
|
||||
{
|
||||
// Ports (https://emscripten.org/docs/compiling/Building-Projects.html#emscripten-ports)
|
||||
args.Add(library);
|
||||
}
|
||||
else if (string.IsNullOrEmpty(dir))
|
||||
{
|
||||
args.Add(string.Format("\"-l{0}\"", library));
|
||||
}
|
||||
else if (string.IsNullOrEmpty(ext))
|
||||
{
|
||||
// Skip executable
|
||||
}
|
||||
else if (ext == dynamicLibExt)
|
||||
{
|
||||
// Link against dynamic library
|
||||
task.PrerequisiteFiles.Add(library);
|
||||
libraryPaths.Add(dir);
|
||||
args.Add(string.Format("\"-l{0}\"", GetLibName(library)));
|
||||
}
|
||||
else
|
||||
{
|
||||
task.PrerequisiteFiles.Add(library);
|
||||
args.Add(string.Format("\"-l{0}\"", GetLibName(library)));
|
||||
}
|
||||
}
|
||||
|
||||
// Input files (link static libraries last)
|
||||
task.PrerequisiteFiles.AddRange(options.LinkEnv.InputFiles);
|
||||
foreach (var file in options.LinkEnv.InputFiles.Where(x => !x.EndsWith(".a")).Concat(options.LinkEnv.InputFiles.Where(x => x.EndsWith(".a"))))
|
||||
{
|
||||
args.Add(string.Format("\"{0}\"", file.Replace('\\', '/')));
|
||||
}
|
||||
|
||||
// Additional lib paths
|
||||
libraryPaths.AddRange(options.LinkEnv.LibraryPaths);
|
||||
foreach (var path in libraryPaths)
|
||||
{
|
||||
args.Add(string.Format("-L\"{0}\"", path.Replace('\\', '/')));
|
||||
}
|
||||
|
||||
args.Add("-Wl,--end-group");
|
||||
|
||||
// Use a response file (it can contain any commands that you would specify on the command line)
|
||||
bool useResponseFile = true;
|
||||
string responseFile = null;
|
||||
if (useResponseFile)
|
||||
{
|
||||
responseFile = Path.Combine(options.IntermediateFolder, Path.GetFileName(outputFilePath) + ".response");
|
||||
task.PrerequisiteFiles.Add(responseFile);
|
||||
Utilities.WriteFileIfChanged(responseFile, string.Join(Environment.NewLine, args));
|
||||
}
|
||||
|
||||
// Link
|
||||
task.WorkingDirectory = options.WorkingDirectory;
|
||||
task.CommandPath = _compilerPath;
|
||||
task.CommandArguments = useResponseFile ? string.Format("@\"{0}\"", responseFile) : string.Join(" ", args);
|
||||
task.InfoMessage = "Linking " + outputFilePath;
|
||||
task.Cost = task.PrerequisiteFiles.Count;
|
||||
task.ProducedFiles.Add(outputFilePath);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void LinkFiles(TaskGraph graph, BuildOptions options, string outputFilePath)
|
||||
{
|
||||
outputFilePath = Utilities.NormalizePath(outputFilePath);
|
||||
|
||||
Task linkTask;
|
||||
switch (options.LinkEnv.Output)
|
||||
{
|
||||
case LinkerOutput.Executable:
|
||||
case LinkerOutput.SharedLibrary:
|
||||
linkTask = CreateBinary(graph, options, outputFilePath);
|
||||
break;
|
||||
case LinkerOutput.StaticLibrary:
|
||||
case LinkerOutput.ImportLibrary:
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@ namespace Flax.Build.Platforms
|
||||
case TargetPlatform.Switch: return Sdk.HasValid("SwitchSdk");
|
||||
case TargetPlatform.XboxOne:
|
||||
case TargetPlatform.XboxScarlett: return GetPlatform(platform, true)?.HasRequiredSDKsInstalled ?? false;
|
||||
case TargetPlatform.Web: return EmscriptenSdk.Instance.IsValid;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user