2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
using System ;
using System.Collections.Generic ;
using System.Text.RegularExpressions ;
using System.Diagnostics ;
using System.IO ;
2014-09-22 11:23:43 -04:00
using System.Linq ;
2014-03-14 14:13:41 -04:00
namespace UnrealBuildTool
{
class HTML5ToolChain : VCToolChain
{
2015-02-20 04:41:01 -05:00
// Debug options -- TODO: add these to SDK/Project setup?
static bool bEnableTracing = false ;
2014-10-31 04:31:19 -04:00
2014-03-14 14:13:41 -04:00
// cache the location of SDK tools
public override void RegisterToolChain ( )
{
2015-07-04 18:45:54 -04:00
if ( HTML5SDKInfo . IsSDKInstalled ( ) )
{
2015-07-09 09:12:36 -04:00
// set some environment variable we'll need
//Environment.SetEnvironmentVariable("EMCC_DEBUG", "cache");
Environment . SetEnvironmentVariable ( "EMCC_CORES" , "8" ) ;
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 ) ;
2014-03-14 14:13:41 -04:00
}
}
2015-07-14 13:06:21 -04:00
2015-07-04 18:45:54 -04:00
public override void PreBuildSync ( )
{
2015-07-14 13:06:21 -04:00
Log . TraceInformation ( "Setting Emscripten SDK " ) ;
2015-07-04 18:45:54 -04:00
HTML5SDKInfo . SetupEmscriptenTemp ( ) ;
HTML5SDKInfo . SetUpEmscriptenConfigFile ( ) ;
2015-07-09 09:12:36 -04:00
// set some environment variable we'll need.
// Forces emcc to use our generated .emscripten config, not the one in the users home directory.
Environment . SetEnvironmentVariable ( "EM_CONFIG" , HTML5SDKInfo . DOT_EMSCRIPTEN ) ;
2015-07-09 15:31:44 -04:00
Environment . SetEnvironmentVariable ( "EM_CACHE" , HTML5SDKInfo . EMSCRIPTEN_CACHE ) ;
2015-07-04 18:45:54 -04:00
}
2015-05-12 08:03:21 -04:00
static string GetSharedArguments_Global ( CPPTargetConfiguration TargetConfiguration , string Architecture , bool bEnableShadowVariableWarning )
2014-03-14 14:13:41 -04:00
{
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.
2015-05-12 08:03:21 -04:00
if ( bEnableShadowVariableWarning )
2015-04-24 10:49:50 -04:00
{
2015-06-09 18:14:52 -04:00
Result + = " -Wshadow" + ( BuildConfiguration . bShadowVariableErrors ? "" : " -Wno-error=shadow" ) ;
2015-04-24 10:49:50 -04:00
}
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" ;
2015-01-08 17:38:47 -05:00
// we want full ES2
Result + = " -s FULL_ES2=1 " ;
2014-04-23 17:30:27 -04:00
// export console command handler. Export main func too because default exports ( e.g Main ) are overridden if we use custom exported functions.
2014-10-16 04:51:33 -04:00
Result + = " -s EXPORTED_FUNCTIONS=\"['_main', '_resize_game', '_on_fatal']\" " ;
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
2015-02-20 04:41:01 -05:00
if ( bEnableTracing )
{
Result + = " --tracing" ;
}
2014-04-23 17:30:27 -04:00
return Result ;
2014-03-14 14:13:41 -04:00
}
static string GetCLArguments_Global ( CPPEnvironment CompileEnvironment )
{
2015-05-12 08:03:21 -04:00
string Result = GetSharedArguments_Global ( CompileEnvironment . Config . Target . Configuration , CompileEnvironment . Config . Target . Architecture , CompileEnvironment . Config . bEnableShadowVariableWarning ) ;
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 " ;
2015-03-27 04:50:46 -04:00
Result + = " -Wno-reorder" ; // we disable constructor order warnings.
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 )
{
2015-05-12 08:03:21 -04:00
string Result = GetSharedArguments_Global ( LinkEnvironment . Config . Target . Configuration , LinkEnvironment . Config . Target . Architecture , false ) ;
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
{
2015-05-18 18:27:24 -04:00
Result + = " -O2 -s ASM_JS=1 -s OUTLINING_LIMIT=110000 " ;
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 " ;
2015-07-04 18:45:54 -04:00
}
2014-03-14 14:13:41 -04:00
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 ) ;
CPPOutput Result = new CPPOutput ( ) ;
// Add include paths to the argument list.
Experimental UnrealBuildTool makefile support
UnrealBuildTool 'Makefiles' allow for very fast iterative builds.
- New BuildConfiguration.xml setting added: "bUseExperimentalFastBuildIteration" (disabled by default)
- Turning this on causes Unreal Build Tool to emit 'UBT Makefiles' for targets when they're built the first time.
- Subsequent builds will load these Makefiles and begin outdatedness checking and build invocation very quickly.
- The caveat is that if source files are added or removed to the project, UBT will need to gather information about those in order for your build to complete successfully.
- Currently, you must run the project file generator after adding/removing source files to tell UBT to re-gather this information.
- Events that can invalidate the 'UBT Makefile':
- Adding/removing .cpp files
- Adding/removing .h files with UObjects
- Adding new UObject types to a file that didn't previously have any
- Changing global build settings (most settings in this file qualify.)
- Changed code that affects how Unreal Header Tool works
- You can force regeneration of the 'UBT Makefile' by passing the '-Gather' argument, or simply regenerating project files
- New command-line parameters added:
- "-Gather": Tells UBT to always perform the gather step (slower but will catch project structural changes)
- "-NoGather": Disables the gather step, unless UBT detects that it must be done. This is the default when bUseExperimentalFastBuildIteration is enabled
- "-GatherOnly": Runs the gather step and saves a UBTMakefile, but doesn't build anything
- "-Assemble": Tells UBT to also assemble build products. This always defaults to enabled
- "-NoAssemble": Tells UBT to skip the assemble step, whether we gathered build products or not
- "-AssembleOnly": Tells UBT to only assemble build products and not to gather, unless UBT determines it must
Other changes:
- UBT now keeps track of which targets it was building in an intermediate file, to help it invalidate cached includes in subsequent runs when the targets are different
- C++ includes are now stored in a class separate from the C++ compile enviroment (for easier serialization)
- The method that UBT uses to find the CoreUObject module timestamp was rewritten
- Various '@todo ubtmake' comments added to tag possible remaining Makefile tasks
- The 'FileItem' class had some member variable comments and code cleaned up, while making it serializable
- Cleaned up the comments and member variables in the "Action" class, while making it serializable
- Some UBT classes are now "serializable". This is because we need to store the data in UBTMakefiles.
- Removed support for Actions to tinker with Stdout and Stderror (was not used for anything)
- Moved PrecompileHeaderEnvironment class to the UEBuildModule.cs source file
- Plugin intermediate include directories are now selected on demand rather than cached early
- Toolchain code for gathering prerequisite headers is now shared in a single function (AddPrerequisiteSourceFile)
- Removed Action.StatusDetailedDescription, was not used for anything
- Removed UEBuildConfiguration.bExcludePlugins, was not used for anything
- Removed ECompilationResult.FailedDueToHeaderChange, was not used for anything
[CL 2254472 by Mike Fricker in Main branch]
2014-08-13 08:17:43 -04:00
foreach ( string IncludePath in CompileEnvironment . Config . CPPIncludeInfo . IncludePaths )
2014-03-14 14:13:41 -04:00
{
Arguments + = string . Format ( " -I\"{0}\"" , IncludePath ) ;
}
Experimental UnrealBuildTool makefile support
UnrealBuildTool 'Makefiles' allow for very fast iterative builds.
- New BuildConfiguration.xml setting added: "bUseExperimentalFastBuildIteration" (disabled by default)
- Turning this on causes Unreal Build Tool to emit 'UBT Makefiles' for targets when they're built the first time.
- Subsequent builds will load these Makefiles and begin outdatedness checking and build invocation very quickly.
- The caveat is that if source files are added or removed to the project, UBT will need to gather information about those in order for your build to complete successfully.
- Currently, you must run the project file generator after adding/removing source files to tell UBT to re-gather this information.
- Events that can invalidate the 'UBT Makefile':
- Adding/removing .cpp files
- Adding/removing .h files with UObjects
- Adding new UObject types to a file that didn't previously have any
- Changing global build settings (most settings in this file qualify.)
- Changed code that affects how Unreal Header Tool works
- You can force regeneration of the 'UBT Makefile' by passing the '-Gather' argument, or simply regenerating project files
- New command-line parameters added:
- "-Gather": Tells UBT to always perform the gather step (slower but will catch project structural changes)
- "-NoGather": Disables the gather step, unless UBT detects that it must be done. This is the default when bUseExperimentalFastBuildIteration is enabled
- "-GatherOnly": Runs the gather step and saves a UBTMakefile, but doesn't build anything
- "-Assemble": Tells UBT to also assemble build products. This always defaults to enabled
- "-NoAssemble": Tells UBT to skip the assemble step, whether we gathered build products or not
- "-AssembleOnly": Tells UBT to only assemble build products and not to gather, unless UBT determines it must
Other changes:
- UBT now keeps track of which targets it was building in an intermediate file, to help it invalidate cached includes in subsequent runs when the targets are different
- C++ includes are now stored in a class separate from the C++ compile enviroment (for easier serialization)
- The method that UBT uses to find the CoreUObject module timestamp was rewritten
- Various '@todo ubtmake' comments added to tag possible remaining Makefile tasks
- The 'FileItem' class had some member variable comments and code cleaned up, while making it serializable
- Cleaned up the comments and member variables in the "Action" class, while making it serializable
- Some UBT classes are now "serializable". This is because we need to store the data in UBTMakefiles.
- Removed support for Actions to tinker with Stdout and Stderror (was not used for anything)
- Moved PrecompileHeaderEnvironment class to the UEBuildModule.cs source file
- Plugin intermediate include directories are now selected on demand rather than cached early
- Toolchain code for gathering prerequisite headers is now shared in a single function (AddPrerequisiteSourceFile)
- Removed Action.StatusDetailedDescription, was not used for anything
- Removed UEBuildConfiguration.bExcludePlugins, was not used for anything
- Removed ECompilationResult.FailedDueToHeaderChange, was not used for anything
[CL 2254472 by Mike Fricker in Main branch]
2014-08-13 08:17:43 -04:00
foreach ( string IncludePath in CompileEnvironment . Config . CPPIncludeInfo . SystemIncludePaths )
2014-03-14 14:13:41 -04:00
{
Arguments + = string . Format ( " -I\"{0}\"" , IncludePath ) ;
}
2014-09-12 11:36:37 -04:00
2014-03-14 14:13:41 -04:00
// Add preprocessor definitions to the argument list.
foreach ( string Definition in CompileEnvironment . Config . Definitions )
{
Arguments + = string . Format ( " -D{0}" , Definition ) ;
}
2015-02-20 04:41:01 -05:00
if ( bEnableTracing )
{
Arguments + = string . Format ( " -D__EMSCRIPTEN_TRACING__" ) ;
}
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.
Experimental UnrealBuildTool makefile support
UnrealBuildTool 'Makefiles' allow for very fast iterative builds.
- New BuildConfiguration.xml setting added: "bUseExperimentalFastBuildIteration" (disabled by default)
- Turning this on causes Unreal Build Tool to emit 'UBT Makefiles' for targets when they're built the first time.
- Subsequent builds will load these Makefiles and begin outdatedness checking and build invocation very quickly.
- The caveat is that if source files are added or removed to the project, UBT will need to gather information about those in order for your build to complete successfully.
- Currently, you must run the project file generator after adding/removing source files to tell UBT to re-gather this information.
- Events that can invalidate the 'UBT Makefile':
- Adding/removing .cpp files
- Adding/removing .h files with UObjects
- Adding new UObject types to a file that didn't previously have any
- Changing global build settings (most settings in this file qualify.)
- Changed code that affects how Unreal Header Tool works
- You can force regeneration of the 'UBT Makefile' by passing the '-Gather' argument, or simply regenerating project files
- New command-line parameters added:
- "-Gather": Tells UBT to always perform the gather step (slower but will catch project structural changes)
- "-NoGather": Disables the gather step, unless UBT detects that it must be done. This is the default when bUseExperimentalFastBuildIteration is enabled
- "-GatherOnly": Runs the gather step and saves a UBTMakefile, but doesn't build anything
- "-Assemble": Tells UBT to also assemble build products. This always defaults to enabled
- "-NoAssemble": Tells UBT to skip the assemble step, whether we gathered build products or not
- "-AssembleOnly": Tells UBT to only assemble build products and not to gather, unless UBT determines it must
Other changes:
- UBT now keeps track of which targets it was building in an intermediate file, to help it invalidate cached includes in subsequent runs when the targets are different
- C++ includes are now stored in a class separate from the C++ compile enviroment (for easier serialization)
- The method that UBT uses to find the CoreUObject module timestamp was rewritten
- Various '@todo ubtmake' comments added to tag possible remaining Makefile tasks
- The 'FileItem' class had some member variable comments and code cleaned up, while making it serializable
- Cleaned up the comments and member variables in the "Action" class, while making it serializable
- Some UBT classes are now "serializable". This is because we need to store the data in UBTMakefiles.
- Removed support for Actions to tinker with Stdout and Stderror (was not used for anything)
- Moved PrecompileHeaderEnvironment class to the UEBuildModule.cs source file
- Plugin intermediate include directories are now selected on demand rather than cached early
- Toolchain code for gathering prerequisite headers is now shared in a single function (AddPrerequisiteSourceFile)
- Removed Action.StatusDetailedDescription, was not used for anything
- Removed UEBuildConfiguration.bExcludePlugins, was not used for anything
- Removed ECompilationResult.FailedDueToHeaderChange, was not used for anything
[CL 2254472 by Mike Fricker in Main branch]
2014-08-13 08:17:43 -04:00
AddPrerequisiteSourceFile ( Target , BuildPlatform , CompileEnvironment , SourceFile , CompileAction . PrerequisiteItems ) ;
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 ( "." ) ;
2015-07-04 18:45:54 -04:00
CompileAction . CommandPath = HTML5SDKInfo . Python ( ) ;
2014-07-30 15:46:41 -04:00
2015-07-04 18:45:54 -04:00
CompileAction . CommandArguments = HTML5SDKInfo . EmscriptenCompiler ( ) + " " + Arguments + FileArguments + CompileEnvironment . Config . AdditionalArguments ;
2014-07-30 15:46:41 -04:00
2015-02-20 04:41:01 -05:00
//System.Console.WriteLine(CompileAction.CommandArguments);
2014-03-14 14:13:41 -04:00
CompileAction . StatusDescription = Path . GetFileName ( SourceFile . AbsolutePath ) ;
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 ) ;
2015-06-09 15:17:07 -04:00
// ResponseFile lines.
List < string > ReponseLines = new List < string > ( ) ;
2014-03-14 14:13:41 -04:00
LinkAction . bCanExecuteRemotely = false ;
LinkAction . WorkingDirectory = Path . GetFullPath ( "." ) ;
2015-07-04 18:45:54 -04:00
LinkAction . CommandPath = HTML5SDKInfo . Python ( ) ;
LinkAction . CommandArguments = HTML5SDKInfo . EmscriptenCompiler ( ) ;
2015-06-09 15:17:07 -04:00
ReponseLines . Add ( GetLinkArguments ( LinkEnvironment ) ) ;
2014-03-14 14:13:41 -04:00
// Add the input files to a response file, and pass the response file on the command-line.
foreach ( FileItem InputFile in LinkEnvironment . InputFiles )
{
2015-02-20 04:41:01 -05:00
//System.Console.WriteLine("File {0} ", InputFile.AbsolutePath);
2015-06-09 15:17:07 -04:00
ReponseLines . Add ( string . Format ( " \"{0}\"" , InputFile . AbsolutePath ) ) ;
2014-03-14 14:13:41 -04:00
LinkAction . PrerequisiteItems . Add ( InputFile ) ;
}
2015-06-09 15:17:07 -04:00
2014-12-10 09:08:03 -05:00
if ( ! LinkEnvironment . Config . bIsBuildingLibrary )
{
2015-01-16 18:19:59 -05:00
// Make sure ThirdParty libs are at the end.
List < string > ThirdParty = ( from Lib in LinkEnvironment . Config . AdditionalLibraries
where Lib . Contains ( "ThirdParty" )
select Lib ) . ToList ( ) ;
2014-08-04 08:08:56 -04:00
2015-01-16 18:19:59 -05:00
LinkEnvironment . Config . AdditionalLibraries . RemoveAll ( Element = > Element . Contains ( "ThirdParty" ) ) ;
LinkEnvironment . Config . AdditionalLibraries . AddRange ( ThirdParty ) ;
2014-08-04 08:08:56 -04:00
2015-01-16 18:19:59 -05:00
foreach ( string InputFile in LinkEnvironment . Config . AdditionalLibraries )
{
FileItem Item = FileItem . GetItemByPath ( InputFile ) ;
if ( Item . AbsolutePath . Contains ( ".lib" ) )
continue ;
if ( Item ! = null )
{
2015-06-09 15:17:07 -04:00
if ( Item . ToString ( ) . Contains ( ".js" ) )
ReponseLines . Add ( string . Format ( " --js-library \"{0}\"" , Item . AbsolutePath ) ) ;
else
ReponseLines . Add ( string . Format ( " \"{0}\"" , Item . AbsolutePath ) ) ;
2015-07-04 18:45:54 -04:00
LinkAction . PrerequisiteItems . Add ( Item ) ;
}
}
2014-12-10 09:08:03 -05:00
}
2014-03-14 14:13:41 -04:00
// make the file we will create
2015-06-09 15:17:07 -04:00
2014-03-14 14:13:41 -04:00
OutputFile = FileItem . GetItemByPath ( LinkEnvironment . Config . OutputFilePath ) ;
LinkAction . ProducedItems . Add ( OutputFile ) ;
2015-06-09 15:17:07 -04:00
ReponseLines . Add ( 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 ) ;
2015-06-09 15:17:07 -04:00
ReponseLines . Add ( " --emit-symbol-map " + string . Format ( " --save-bc \"{0}\"" , OutputBC . AbsolutePath ) ) ;
2014-03-14 14:13:41 -04:00
LinkAction . StatusDescription = Path . GetFileName ( OutputFile . AbsolutePath ) ;
2015-06-09 15:17:07 -04:00
string ResponseFileName = GetResponseFileName ( LinkEnvironment , OutputFile ) ;
2015-07-04 18:45:54 -04:00
LinkAction . CommandArguments + = string . Format ( " @\"{0}\"" , ResponseFile . Create ( ResponseFileName , ReponseLines ) ) ;
2015-06-09 15:17:07 -04:00
2014-03-14 14:13:41 -04:00
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
2015-04-03 10:25:57 -04:00
public override void AddFilesToReceipt ( BuildReceipt Receipt , UEBuildBinary Binary )
2014-07-29 13:38:03 -04:00
{
2015-05-20 15:30:36 -04:00
// we need to include the generated .mem and .symbols file.
2015-03-21 19:35:46 -04:00
if ( Binary . Config . Type ! = UEBuildBinaryType . StaticLibrary )
{
2015-04-03 10:25:57 -04:00
Receipt . AddBuildProduct ( Binary . Config . OutputFilePath + ".mem" , BuildProductType . RequiredResource ) ;
2015-05-20 15:30:36 -04:00
Receipt . AddBuildProduct ( Binary . Config . OutputFilePath + ".symbols" , BuildProductType . RequiredResource ) ;
2015-03-21 19:35:46 -04:00
}
2014-07-29 13:38:03 -04:00
}
2014-12-02 14:58:59 -05:00
public override UnrealTargetPlatform GetPlatform ( )
{
return UnrealTargetPlatform . HTML5 ;
}
2014-03-14 14:13:41 -04:00
} ;
}