2014-03-14 14:13:41 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
using System ;
using System.Collections.Generic ;
using System.Text.RegularExpressions ;
using System.Diagnostics ;
using System.IO ;
using System.Linq ;
namespace UnrealBuildTool
{
class HTML5ToolChain : VCToolChain
{
// cache the location of SDK tools
static string EMCCPath ;
static string PythonPath ;
public override void RegisterToolChain ( )
{
// Make sure the SDK is installed
// look up installed SDK.
2014-04-28 14:10:06 -04:00
string BaseSDKPath = Environment . GetEnvironmentVariable ( "EMSCRIPTEN" ) ;
2014-03-14 14:13:41 -04:00
if ( ! String . IsNullOrEmpty ( BaseSDKPath ) )
{
BaseSDKPath = BaseSDKPath . Replace ( "\"" , "" ) ;
if ( ! String . IsNullOrEmpty ( BaseSDKPath ) )
{
EMCCPath = Path . Combine ( BaseSDKPath , "emcc" ) ;
// also figure out where python lives (if no envvar, assume it's in the path)
PythonPath = Environment . GetEnvironmentVariable ( "PYTHON" ) ;
2014-07-30 17:55:43 -04:00
string PythonExeName = Utils . IsRunningOnMono ? "python" : "python.exe" ;
2014-03-14 14:13:41 -04:00
if ( PythonPath = = null )
{
2014-07-30 17:55:43 -04:00
PythonPath = PythonExeName ;
2014-03-14 14:13:41 -04:00
}
2014-07-30 17:55:43 -04:00
else
{
if ( ! PythonPath . EndsWith ( PythonExeName ) )
{
PythonPath + = "/" + PythonExeName ;
}
}
2014-07-30 15:46:41 -04:00
EMCCPath = "\"" + EMCCPath + "\"" ;
2014-03-14 14:13:41 -04:00
// set some environment variable we'll need
//Environment.SetEnvironmentVariable("EMCC_DEBUG", "cache");
Environment . SetEnvironmentVariable ( "EMCC_CORES" , "8" ) ;
Environment . SetEnvironmentVariable ( "EMCC_FORCE_STDLIBS" , "1" ) ;
Environment . SetEnvironmentVariable ( "EMCC_OPTIMIZE_NORMALLY" , "1" ) ;
// finally register the toolchain that is now ready to go
Log . TraceVerbose ( " Registered for {0}" , CPPTargetPlatform . HTML5 . ToString ( ) ) ;
UEToolChain . RegisterPlatformToolChain ( CPPTargetPlatform . HTML5 , this ) ;
}
}
}
static string GetSharedArguments_Global ( CPPTargetConfiguration TargetConfiguration , string Architecture )
{
2014-04-23 17:30:27 -04:00
string Result = " " ;
2014-03-14 14:13:41 -04:00
2014-04-23 17:30:27 -04:00
if ( Architecture = = "-win32" )
{
2014-03-14 14:13:41 -04:00
return Result ;
}
2014-04-23 17:30:27 -04:00
// Result += " -funsigned-char";
// Result += " -fno-strict-aliasing";
Result + = " -fno-exceptions" ;
// Result += " -fno-short-enums";
2014-03-14 14:13:41 -04:00
2014-04-23 17:30:27 -04:00
Result + = " -Wno-unused-value" ; // appErrorf triggers this
Result + = " -Wno-switch" ; // many unhandled cases
Result + = " -Wno-tautological-constant-out-of-range-compare" ; // disables some warnings about comparisons from TCHAR being a char
// this hides the "warning : comparison of unsigned expression < 0 is always false" type warnings due to constant comparisons, which are possible with template arguments
Result + = " -Wno-tautological-compare" ;
2014-03-14 14:13:41 -04:00
2014-04-23 17:30:27 -04:00
// okay, in UE4, we'd fix the code for these, but in UE3, not worth it
Result + = " -Wno-logical-op-parentheses" ; // appErrorf triggers this
Result + = " -Wno-array-bounds" ; // some VectorLoads go past the end of the array, but it's okay in that case
2014-03-14 14:13:41 -04:00
Result + = " -Wno-invalid-offsetof" ; // too many warnings kills windows clang.
2014-04-23 17:30:27 -04:00
// JavsScript option overrides (see src/settings.js)
2014-03-14 14:13:41 -04:00
2014-04-23 17:30:27 -04:00
// we have to specify the full amount of memory with Asm.JS (1.5 G)
2014-03-14 14:13:41 -04:00
// I wonder if there's a per game way to change this.
2014-06-10 17:14:29 -04:00
int TotalMemory = 256 * 1024 * 1024 ;
2014-05-22 15:14:51 -04:00
Result + = " -s TOTAL_MEMORY=" + TotalMemory . ToString ( ) ;
2014-03-14 14:13:41 -04:00
2014-04-23 17:30:27 -04:00
// no need for exceptions
Result + = " -s DISABLE_EXCEPTION_CATCHING=1" ;
// enable checking for missing functions at link time as opposed to runtime
Result + = " -s WARN_ON_UNDEFINED_SYMBOLS=1" ;
// we want full ES2
Result + = " -s FULL_ES2=1 " ;
// don't need UTF8 string support, and it slows string ops down
Result + = " -s UTF_STRING_SUPPORT=0" ;
// export console command handler. Export main func too because default exports ( e.g Main ) are overridden if we use custom exported functions.
2014-07-14 10:54:28 -04:00
Result + = " -s EXPORTED_FUNCTIONS=\"['_main', '_resize_game']\" " ;
2014-03-14 14:13:41 -04:00
2014-04-23 17:30:27 -04:00
// NOTE: This may slow down the compiler's startup time!
{
2014-05-22 15:14:51 -04:00
Result + = " -s NO_EXIT_RUNTIME=1 --memory-init-file 1" ;
2014-04-23 17:30:27 -04:00
}
2014-03-14 14:13:41 -04:00
2014-04-23 17:30:27 -04:00
return Result ;
2014-03-14 14:13:41 -04:00
}
static string GetCLArguments_Global ( CPPEnvironment CompileEnvironment )
{
2014-06-09 11:12:01 -04:00
string Result = GetSharedArguments_Global ( CompileEnvironment . Config . Target . Configuration , CompileEnvironment . Config . Target . Architecture ) ;
2014-03-14 14:13:41 -04:00
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Architecture ! = "-win32" )
2014-03-14 14:13:41 -04:00
{
// do we want debug info?
/ * if ( CompileEnvironment . Config . bCreateDebugInfo )
{
Result + = " -g" ;
} * /
Result + = " -Wno-warn-absolute-paths " ;
2014-05-22 15:14:51 -04:00
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Debug )
2014-05-22 15:14:51 -04:00
{
Result + = " -O0" ;
}
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Debug | | CompileEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Development )
2014-05-22 15:14:51 -04:00
{
Result + = " -s GL_ASSERTIONS=1 " ;
}
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Development )
2014-05-22 15:14:51 -04:00
{
if ( UEBuildConfiguration . bCompileForSize )
{
Result + = " -Oz -s ASM_JS=1 -s OUTLINING_LIMIT=40000" ;
}
else
{
Result + = " -O2 -s ASM_JS=1 -s OUTLINING_LIMIT=110000" ;
}
}
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Shipping )
2014-05-22 15:14:51 -04:00
{
if ( UEBuildConfiguration . bCompileForSize )
{
Result + = " -Oz -s ASM_JS=1 -s OUTLINING_LIMIT=40000" ;
}
else
{
Result + = " -O3 -s ASM_JS=1 -s OUTLINING_LIMIT=110000" ;
}
}
2014-03-14 14:13:41 -04:00
}
return Result ;
}
static string GetCLArguments_CPP ( CPPEnvironment CompileEnvironment )
{
string Result = "" ;
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Architecture ! = "-win32" )
2014-03-14 14:13:41 -04:00
{
Result = " -std=c++11" ;
}
return Result ;
}
static string GetCLArguments_C ( string Architecture )
{
string Result = "" ;
return Result ;
}
static string GetLinkArguments ( LinkEnvironment LinkEnvironment )
{
2014-06-09 11:12:01 -04:00
string Result = GetSharedArguments_Global ( LinkEnvironment . Config . Target . Configuration , LinkEnvironment . Config . Target . Architecture ) ;
2014-03-14 14:13:41 -04:00
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Architecture ! = "-win32" )
2014-03-14 14:13:41 -04:00
{
// enable verbose mode
Result + = " -v" ;
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Debug )
2014-03-14 14:13:41 -04:00
{
// check for alignment/etc checking
//Result += " -s SAFE_HEAP=1";
//Result += " -s CHECK_HEAP_ALIGN=1";
//Result += " -s SAFE_DYNCALLS=1";
// enable assertions in non-Shipping/Release builds
Result + = " -s ASSERTIONS=1" ;
}
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Debug )
2014-05-22 15:14:51 -04:00
{
Result + = " -O0" ;
}
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Debug | | LinkEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Development )
2014-05-22 15:14:51 -04:00
{
Result + = " -s GL_ASSERTIONS=1 " ;
}
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Development )
2014-05-22 15:14:51 -04:00
{
2014-07-09 18:55:25 -04:00
Result + = " -O2 -s ASM_JS=1 -s OUTLINING_LIMIT=110000 -g2 " ;
2014-05-22 15:14:51 -04:00
}
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Shipping )
2014-05-22 15:14:51 -04:00
{
Result + = " -O3 -s ASM_JS=1 -s OUTLINING_LIMIT=40000" ;
}
2014-03-14 14:13:41 -04:00
Result + = " -s CASE_INSENSITIVE_FS=1 " ;
Result + = " --js-library Runtime/Core/Public/HTML5/HTML5DebugLogging.js " ;
string BaseSDKPath = Environment . GetEnvironmentVariable ( "EMSCRIPTEN" ) ;
Result + = " --js-library \"" + BaseSDKPath + "/Src/library_openal.js\" " ;
}
return Result ;
}
static string GetLibArguments ( LinkEnvironment LinkEnvironment )
{
string Result = "" ;
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Architecture = = "-win32" )
2014-03-14 14:13:41 -04:00
{
// Prevents the linker from displaying its logo for each invocation.
Result + = " /NOLOGO" ;
// Prompt the user before reporting internal errors to Microsoft.
Result + = " /errorReport:prompt" ;
// Win32 build
Result + = " /MACHINE:x86" ;
// Always CONSOLE because of main()
Result + = " /SUBSYSTEM:CONSOLE" ;
//
// Shipping & LTCG
//
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Configuration = = CPPTargetConfiguration . Shipping )
2014-03-14 14:13:41 -04:00
{
// Use link-time code generation.
Result + = " /ltcg" ;
}
return Result ;
}
return Result ;
}
public static void CompileOutputReceivedDataEventHandler ( Object Sender , DataReceivedEventArgs Line )
{
var Output = Line . Data ;
if ( Output = = null )
{
return ;
}
Output = Output . Replace ( "\\" , "/" ) ;
// Need to match following for clickable links
string RegexFilePath = @"^([\/A-Za-z0-9_\-\.]*)+\.(cpp|c|mm|m|hpp|h)" ;
string RegexFilePath2 = @"^([A-Z]:[\/A-Za-z0-9_\-\.]*)+\.(cpp|c|mm|m|hpp|h)" ;
string RegexLineNumber = @"\:\d+\:\d+\:" ;
string RegexDescription = @"(\serror:\s|\swarning:\s).*" ;
// Get Matches
string MatchFilePath = Regex . Match ( Output , RegexFilePath ) . Value ;
if ( MatchFilePath . Length = = 0 )
{
MatchFilePath = Regex . Match ( Output , RegexFilePath2 ) . Value ;
}
string MatchLineNumber = Regex . Match ( Output , RegexLineNumber ) . Value ;
string MatchDescription = Regex . Match ( Output , RegexDescription ) . Value ;
// If any of the above matches failed, do nothing
if ( MatchFilePath . Length = = 0 | |
MatchLineNumber . Length = = 0 | |
MatchDescription . Length = = 0 )
{
Log . TraceWarning ( Output ) ;
return ;
}
// Convert Path
string RegexStrippedPath = @"(Engine\/|[A-Za-z0-9_\-\.]*\/).*" ;
string ConvertedFilePath = Regex . Match ( MatchFilePath , RegexStrippedPath ) . Value ;
ConvertedFilePath = Path . GetFullPath ( /*"..\\..\\" +*/ ConvertedFilePath ) ;
// Extract Line + Column Number
string ConvertedLineNumber = Regex . Match ( MatchLineNumber , @"\d+" ) . Value ;
string ConvertedColumnNumber = Regex . Match ( MatchLineNumber , @"(?<=:\d+:)\d+" ) . Value ;
// Write output
string ConvertedExpression = " " + ConvertedFilePath + "(" + ConvertedLineNumber + "," + ConvertedColumnNumber + "):" + MatchDescription ;
Log . TraceInformation ( ConvertedExpression ) ; // To create clickable vs link
Log . TraceInformation ( Output ) ; // To preserve readable output log
}
2014-07-31 09:34:11 -04:00
public override CPPOutput CompileCPPFiles ( UEBuildTarget Target , CPPEnvironment CompileEnvironment , List < FileItem > SourceFiles , string ModuleName )
2014-03-14 14:13:41 -04:00
{
2014-06-09 11:12:01 -04:00
if ( CompileEnvironment . Config . Target . Architecture = = "-win32" )
2014-03-14 14:13:41 -04:00
{
2014-07-31 09:34:11 -04:00
return base . CompileCPPFiles ( Target , CompileEnvironment , SourceFiles , ModuleName ) ;
2014-03-14 14:13:41 -04:00
}
string Arguments = GetCLArguments_Global ( CompileEnvironment ) ;
string BaseSDKPath = Environment . GetEnvironmentVariable ( "EMSCRIPTEN" ) ;
CPPOutput Result = new CPPOutput ( ) ;
// Add include paths to the argument list.
foreach ( string IncludePath in CompileEnvironment . Config . IncludePaths )
{
Arguments + = string . Format ( " -I\"{0}\"" , IncludePath ) ;
}
foreach ( string IncludePath in CompileEnvironment . Config . SystemIncludePaths )
{
Arguments + = string . Format ( " -I\"{0}\"" , IncludePath ) ;
}
if ( ModuleName = = "Launch" )
Arguments + = string . Format ( " -I\"{0}\"" , BaseSDKPath + "/system/lib/libcxxabi/include" ) ;
// Add preprocessor definitions to the argument list.
foreach ( string Definition in CompileEnvironment . Config . Definitions )
{
Arguments + = string . Format ( " -D{0}" , Definition ) ;
}
// Create a compile action for each source file.
if ( ModuleName = = "Launch" )
SourceFiles . Add ( FileItem . GetItemByPath ( BaseSDKPath + "/system/lib/libcxxabi/src/cxa_demangle.cpp" ) ) ;
2014-07-31 09:34:11 -04:00
var BuildPlatform = UEBuildPlatform . GetBuildPlatformForCPPTargetPlatform ( CompileEnvironment . Config . Target . Platform ) ;
2014-03-14 14:13:41 -04:00
foreach ( FileItem SourceFile in SourceFiles )
{
Action CompileAction = new Action ( ActionType . Compile ) ;
bool bIsPlainCFile = Path . GetExtension ( SourceFile . AbsolutePath ) . ToUpperInvariant ( ) = = ".C" ;
// Add the C++ source file and its included files to the prerequisite item list.
CompileAction . PrerequisiteItems . Add ( SourceFile ) ;
{
2014-07-31 09:34:11 -04:00
var IncludedFileList = CPPEnvironment . FindAndCacheAllIncludedFiles ( Target , SourceFile , BuildPlatform , CompileEnvironment . GetIncludesPathsToSearch ( SourceFile ) , CompileEnvironment . IncludeFileSearchDictionary , bOnlyCachedDependencies : BuildConfiguration . bUseExperimentalFastDependencyScan ) ;
CompileAction . PrerequisiteItems . AddRange ( IncludedFileList ) ;
2014-03-14 14:13:41 -04:00
}
// Add the source file path to the command-line.
2014-04-28 14:10:06 -04:00
string FileArguments = string . Format ( " \"{0}\"" , SourceFile . AbsolutePath ) ;
2014-06-05 12:11:58 -04:00
var ObjectFileExtension = UEBuildPlatform . BuildPlatformDictionary [ UnrealTargetPlatform . HTML5 ] . GetBinaryExtension ( UEBuildBinaryType . Object ) ;
2014-03-14 14:13:41 -04:00
// Add the object file to the produced item list.
FileItem ObjectFile = FileItem . GetItemByPath (
Path . Combine (
CompileEnvironment . Config . OutputDirectory ,
2014-06-05 12:11:58 -04:00
Path . GetFileName ( SourceFile . AbsolutePath ) + ObjectFileExtension
2014-03-14 14:13:41 -04:00
)
) ;
CompileAction . ProducedItems . Add ( ObjectFile ) ;
FileArguments + = string . Format ( " -o \"{0}\"" , ObjectFile . AbsolutePath ) ;
// Add C or C++ specific compiler arguments.
if ( bIsPlainCFile )
{
2014-06-09 11:12:01 -04:00
FileArguments + = GetCLArguments_C ( CompileEnvironment . Config . Target . Architecture ) ;
2014-03-14 14:13:41 -04:00
}
else
{
FileArguments + = GetCLArguments_CPP ( CompileEnvironment ) ;
}
CompileAction . WorkingDirectory = Path . GetFullPath ( "." ) ;
CompileAction . CommandPath = PythonPath ;
2014-07-30 15:46:41 -04:00
2014-04-28 14:10:06 -04:00
CompileAction . CommandArguments = EMCCPath + Arguments + FileArguments + CompileEnvironment . Config . AdditionalArguments ;
2014-07-30 15:46:41 -04:00
2014-03-14 14:13:41 -04:00
System . Console . WriteLine ( CompileAction . CommandArguments ) ;
CompileAction . StatusDescription = Path . GetFileName ( SourceFile . AbsolutePath ) ;
CompileAction . StatusDetailedDescription = SourceFile . Description ;
CompileAction . OutputEventHandler = new DataReceivedEventHandler ( CompileOutputReceivedDataEventHandler ) ;
// Don't farm out creation of precomputed headers as it is the critical path task.
CompileAction . bCanExecuteRemotely = CompileEnvironment . Config . PrecompiledHeaderAction ! = PrecompiledHeaderAction . Create ;
// this is the final output of the compile step (a .abc file)
Result . ObjectFiles . Add ( ObjectFile ) ;
// VC++ always outputs the source file name being compiled, so we don't need to emit this ourselves
CompileAction . bShouldOutputStatusDescription = true ;
// Don't farm out creation of precompiled headers as it is the critical path task.
CompileAction . bCanExecuteRemotely =
CompileEnvironment . Config . PrecompiledHeaderAction ! = PrecompiledHeaderAction . Create | |
BuildConfiguration . bAllowRemotelyCompiledPCHs ;
}
return Result ;
}
2014-07-31 09:34:11 -04:00
public override CPPOutput CompileRCFiles ( UEBuildTarget Target , CPPEnvironment Environment , List < FileItem > RCFiles )
2014-03-14 14:13:41 -04:00
{
CPPOutput Result = new CPPOutput ( ) ;
2014-06-09 11:12:01 -04:00
if ( Environment . Config . Target . Architecture = = "-win32" )
2014-03-14 14:13:41 -04:00
{
2014-07-31 09:34:11 -04:00
return base . CompileRCFiles ( Target , Environment , RCFiles ) ;
2014-03-14 14:13:41 -04:00
}
return Result ;
}
/ * *
* Translates clang output warning / error messages into vs - clickable messages
*
* @param sender Sending object
* @param e Event arguments ( In this case , the line of string output )
* /
protected void RemoteOutputReceivedEventHandler ( object sender , DataReceivedEventArgs e )
{
var Output = e . Data ;
if ( Output = = null )
{
return ;
}
if ( Utils . IsRunningOnMono )
{
Log . TraceInformation ( Output ) ;
}
else
{
// Need to match following for clickable links
string RegexFilePath = @"^(\/[A-Za-z0-9_\-\.]*)+\.(cpp|c|mm|m|hpp|h)" ;
string RegexLineNumber = @"\:\d+\:\d+\:" ;
string RegexDescription = @"(\serror:\s|\swarning:\s).*" ;
// Get Matches
string MatchFilePath = Regex . Match ( Output , RegexFilePath ) . Value . Replace ( "Engine/Source/../../" , "" ) ;
string MatchLineNumber = Regex . Match ( Output , RegexLineNumber ) . Value ;
string MatchDescription = Regex . Match ( Output , RegexDescription ) . Value ;
// If any of the above matches failed, do nothing
if ( MatchFilePath . Length = = 0 | |
MatchLineNumber . Length = = 0 | |
MatchDescription . Length = = 0 )
{
Log . TraceInformation ( Output ) ;
return ;
}
// Convert Path
string RegexStrippedPath = @"\/Engine\/.*" ; //@"(Engine\/|[A-Za-z0-9_\-\.]*\/).*";
string ConvertedFilePath = Regex . Match ( MatchFilePath , RegexStrippedPath ) . Value ;
ConvertedFilePath = Path . GetFullPath ( "..\\.." + ConvertedFilePath ) ;
// Extract Line + Column Number
string ConvertedLineNumber = Regex . Match ( MatchLineNumber , @"\d+" ) . Value ;
string ConvertedColumnNumber = Regex . Match ( MatchLineNumber , @"(?<=:\d+:)\d+" ) . Value ;
// Write output
string ConvertedExpression = " " + ConvertedFilePath + "(" + ConvertedLineNumber + "," + ConvertedColumnNumber + "):" + MatchDescription ;
Log . TraceInformation ( ConvertedExpression ) ; // To create clickable vs link
// Log.TraceInformation(Output); // To preserve readable output log
}
}
public override FileItem LinkFiles ( LinkEnvironment LinkEnvironment , bool bBuildImportLibraryOnly )
{
2014-06-09 11:12:01 -04:00
if ( LinkEnvironment . Config . Target . Architecture = = "-win32" )
2014-03-14 14:13:41 -04:00
{
return base . LinkFiles ( LinkEnvironment , bBuildImportLibraryOnly ) ;
}
FileItem OutputFile ;
// Make the final javascript file
Action LinkAction = new Action ( ActionType . Link ) ;
LinkAction . bCanExecuteRemotely = false ;
LinkAction . WorkingDirectory = Path . GetFullPath ( "." ) ;
LinkAction . CommandPath = PythonPath ;
2014-04-28 14:10:06 -04:00
LinkAction . CommandArguments = EMCCPath ;
2014-03-14 14:13:41 -04:00
LinkAction . CommandArguments + = GetLinkArguments ( LinkEnvironment ) ;
// Add the input files to a response file, and pass the response file on the command-line.
foreach ( FileItem InputFile in LinkEnvironment . InputFiles )
{
System . Console . WriteLine ( "File {0} " , InputFile . AbsolutePath ) ;
2014-04-28 14:10:06 -04:00
LinkAction . CommandArguments + = string . Format ( " \"{0}\"" , InputFile . AbsolutePath ) ;
2014-03-14 14:13:41 -04:00
LinkAction . PrerequisiteItems . Add ( InputFile ) ;
}
foreach ( string InputFile in LinkEnvironment . Config . AdditionalLibraries )
{
2014-08-04 08:08:56 -04:00
FileItem Item = FileItem . GetItemByPath ( InputFile ) ;
if ( Item . AbsolutePath . Contains ( ".lib" ) )
continue ;
2014-03-14 14:13:41 -04:00
if ( Item ! = null )
{
2014-05-22 15:14:51 -04:00
if ( Item . ToString ( ) . Contains ( ".js" ) )
LinkAction . CommandArguments + = string . Format ( " --js-library \"{0}\"" , Item . AbsolutePath ) ;
else
LinkAction . CommandArguments + = string . Format ( " \"{0}\"" , Item . AbsolutePath ) ;
2014-03-14 14:13:41 -04:00
LinkAction . PrerequisiteItems . Add ( Item ) ;
}
}
// make the file we will create
OutputFile = FileItem . GetItemByPath ( LinkEnvironment . Config . OutputFilePath ) ;
LinkAction . ProducedItems . Add ( OutputFile ) ;
LinkAction . CommandArguments + = string . Format ( " -o \"{0}\"" , OutputFile . AbsolutePath ) ;
2014-04-28 14:10:06 -04:00
FileItem OutputBC = FileItem . GetItemByPath ( LinkEnvironment . Config . OutputFilePath . Replace ( ".js" , ".bc" ) . Replace ( ".html" , ".bc" ) ) ;
LinkAction . ProducedItems . Add ( OutputBC ) ;
LinkAction . CommandArguments + = string . Format ( " --save-bc \"{0}\"" , OutputBC . AbsolutePath ) ;
2014-03-14 14:13:41 -04:00
LinkAction . StatusDescription = Path . GetFileName ( OutputFile . AbsolutePath ) ;
LinkAction . OutputEventHandler = new DataReceivedEventHandler ( RemoteOutputReceivedEventHandler ) ;
return OutputFile ;
}
public override void CompileCSharpProject ( CSharpEnvironment CompileEnvironment , string ProjectFileName , string DestinationFile )
{
throw new BuildException ( "HTML5 cannot compile C# files" ) ;
}
2014-07-29 13:38:03 -04:00
public override void AddFilesToManifest ( ref FileManifest Manifest , UEBuildBinary Binary )
{
// we need to include the generated .mem file.
string MemFile = Binary . Config . OutputFilePath + ".mem" ;
// make sure we don't add mem files more than once.
Manifest . AddBinaryNames ( MemFile , null ) ;
}
2014-03-14 14:13:41 -04:00
} ;
}