2016-01-07 08:17:16 -05:00
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2014-04-23 18:32:52 -04:00
# include "DesktopPlatformPrivatePCH.h"
# include "DesktopPlatformBase.h"
2014-05-06 10:27:35 -04:00
# include "UProjectInfo.h"
2014-05-13 18:23:53 -04:00
# include "EngineVersion.h"
# include "ModuleManager.h"
2014-09-25 18:48:22 -04:00
# include "Json.h"
2014-05-13 18:23:53 -04:00
# define LOCTEXT_NAMESPACE "DesktopPlatform"
2014-04-23 18:32:52 -04:00
2014-09-25 18:48:22 -04:00
2014-05-14 15:20:39 -04:00
FDesktopPlatformBase : : FDesktopPlatformBase ( )
{
LauncherInstallationTimestamp = FDateTime : : MinValue ( ) ;
}
2014-06-04 19:07:11 -04:00
FString FDesktopPlatformBase : : GetEngineDescription ( const FString & Identifier )
{
// Official release versions just have a version number
if ( IsStockEngineRelease ( Identifier ) )
{
return Identifier ;
}
// Otherwise get the path
FString RootDir ;
if ( ! GetEngineRootDirFromIdentifier ( Identifier , RootDir ) )
{
return FString ( ) ;
}
// Convert it to a platform directory
FString PlatformRootDir = RootDir ;
FPaths : : MakePlatformFilename ( PlatformRootDir ) ;
// Perforce build
if ( IsSourceDistribution ( RootDir ) )
{
return FString : : Printf ( TEXT ( " Source build at %s " ) , * PlatformRootDir ) ;
}
else
{
return FString : : Printf ( TEXT ( " Binary build at %s " ) , * PlatformRootDir ) ;
}
}
2014-04-23 18:32:52 -04:00
FString FDesktopPlatformBase : : GetCurrentEngineIdentifier ( )
{
2014-05-13 18:23:53 -04:00
if ( CurrentEngineIdentifier . Len ( ) = = 0 & & ! GetEngineIdentifierFromRootDir ( FPlatformMisc : : RootDir ( ) , CurrentEngineIdentifier ) )
{
CurrentEngineIdentifier . Empty ( ) ;
}
return CurrentEngineIdentifier ;
2014-04-23 18:32:52 -04:00
}
2014-04-23 18:46:48 -04:00
void FDesktopPlatformBase : : EnumerateLauncherEngineInstallations ( TMap < FString , FString > & OutInstallations )
{
2014-05-14 15:20:39 -04:00
// Cache the launcher install list if necessary
ReadLauncherInstallationList ( ) ;
// We've got a list of launcher installations. Filter it by the engine installations.
for ( TMap < FString , FString > : : TConstIterator Iter ( LauncherInstallationList ) ; Iter ; + + Iter )
2014-05-08 08:20:34 -04:00
{
2014-05-14 15:20:39 -04:00
FString AppName = Iter . Key ( ) ;
if ( AppName . RemoveFromStart ( TEXT ( " UE_ " ) , ESearchCase : : CaseSensitive ) )
2014-05-08 08:20:34 -04:00
{
2014-05-14 15:20:39 -04:00
OutInstallations . Add ( AppName , Iter . Value ( ) ) ;
2014-05-08 08:20:34 -04:00
}
}
2014-04-23 18:46:48 -04:00
}
2014-05-13 19:34:00 -04:00
void FDesktopPlatformBase : : EnumerateLauncherSampleInstallations ( TArray < FString > & OutInstallations )
{
2014-05-14 15:20:39 -04:00
// Cache the launcher install list if necessary
ReadLauncherInstallationList ( ) ;
// We've got a list of launcher installations. Filter it by the engine installations.
for ( TMap < FString , FString > : : TConstIterator Iter ( LauncherInstallationList ) ; Iter ; + + Iter )
2014-05-13 19:34:00 -04:00
{
2014-05-14 15:20:39 -04:00
FString AppName = Iter . Key ( ) ;
if ( ! AppName . StartsWith ( TEXT ( " UE_ " ) , ESearchCase : : CaseSensitive ) )
2014-05-13 19:34:00 -04:00
{
2014-05-14 15:20:39 -04:00
OutInstallations . Add ( Iter . Value ( ) ) ;
2014-05-13 19:34:00 -04:00
}
}
}
2014-06-04 18:06:57 -04:00
void FDesktopPlatformBase : : EnumerateLauncherSampleProjects ( TArray < FString > & OutFileNames )
{
// Enumerate all the sample installation directories
TArray < FString > LauncherSampleDirectories ;
EnumerateLauncherSampleInstallations ( LauncherSampleDirectories ) ;
// Find all the project files within them
for ( int32 Idx = 0 ; Idx < LauncherSampleDirectories . Num ( ) ; Idx + + )
{
TArray < FString > FileNames ;
IFileManager : : Get ( ) . FindFiles ( FileNames , * ( LauncherSampleDirectories [ Idx ] / TEXT ( " *.uproject " ) ) , true , false ) ;
OutFileNames . Append ( FileNames ) ;
}
}
2014-04-23 18:32:52 -04:00
bool FDesktopPlatformBase : : GetEngineRootDirFromIdentifier ( const FString & Identifier , FString & OutRootDir )
{
// Get all the installations
TMap < FString , FString > Installations ;
EnumerateEngineInstallations ( Installations ) ;
// Find the one with the right identifier
for ( TMap < FString , FString > : : TConstIterator Iter ( Installations ) ; Iter ; + + Iter )
{
if ( Iter - > Key = = Identifier )
{
OutRootDir = Iter - > Value ;
return true ;
}
}
return false ;
}
bool FDesktopPlatformBase : : GetEngineIdentifierFromRootDir ( const FString & RootDir , FString & OutIdentifier )
{
// Get all the installations
TMap < FString , FString > Installations ;
EnumerateEngineInstallations ( Installations ) ;
// Normalize the root directory
FString NormalizedRootDir = RootDir ;
2015-01-09 08:11:29 -05:00
FPaths : : CollapseRelativeDirectories ( NormalizedRootDir ) ;
2014-04-23 18:32:52 -04:00
FPaths : : NormalizeDirectoryName ( NormalizedRootDir ) ;
// Find the label for the given directory
for ( TMap < FString , FString > : : TConstIterator Iter ( Installations ) ; Iter ; + + Iter )
{
if ( Iter - > Value = = NormalizedRootDir )
{
OutIdentifier = Iter - > Key ;
return true ;
}
}
2014-05-06 10:27:35 -04:00
// Otherwise just try to add it
return RegisterEngineInstallation ( RootDir , OutIdentifier ) ;
2014-04-23 18:32:52 -04:00
}
2014-04-23 18:46:48 -04:00
bool FDesktopPlatformBase : : GetDefaultEngineIdentifier ( FString & OutId )
{
TMap < FString , FString > Installations ;
EnumerateEngineInstallations ( Installations ) ;
bool bRes = false ;
if ( Installations . Num ( ) > 0 )
{
// Default to the first install
TMap < FString , FString > : : TConstIterator Iter ( Installations ) ;
OutId = Iter . Key ( ) ;
+ + Iter ;
// Try to find the most preferred install
for ( ; Iter ; + + Iter )
{
if ( IsPreferredEngineIdentifier ( Iter . Key ( ) , OutId ) )
{
OutId = Iter . Key ( ) ;
}
}
}
return bRes ;
}
bool FDesktopPlatformBase : : GetDefaultEngineRootDir ( FString & OutDirName )
{
FString Identifier ;
return GetDefaultEngineIdentifier ( Identifier ) & & GetEngineRootDirFromIdentifier ( Identifier , OutDirName ) ;
}
bool FDesktopPlatformBase : : IsPreferredEngineIdentifier ( const FString & Identifier , const FString & OtherIdentifier )
{
int32 Version = ParseReleaseVersion ( Identifier ) ;
int32 OtherVersion = ParseReleaseVersion ( OtherIdentifier ) ;
if ( Version ! = OtherVersion )
{
return Version > OtherVersion ;
}
else
{
return Identifier > OtherIdentifier ;
}
}
2015-07-10 15:21:32 -04:00
bool FDesktopPlatformBase : : TryGetEngineVersion ( const FString & RootDir , FEngineVersion & OutVersion )
{
// Read the file to a string
FString VersionText ;
if ( FFileHelper : : LoadFileToString ( VersionText , * ( RootDir / TEXT ( " Engine/Build/Build.version " ) ) ) )
{
// Deserialize a JSON object from the string
TSharedPtr < FJsonObject > Object ;
TSharedRef < TJsonReader < > > Reader = TJsonReaderFactory < > : : Create ( VersionText ) ;
if ( FJsonSerializer : : Deserialize ( Reader , Object ) & & Object . IsValid ( ) )
{
int32 MajorVersion = 0 ;
int32 MinorVersion = 0 ;
int32 PatchVersion = 0 ;
if ( Object - > TryGetNumberField ( TEXT ( " MajorVersion " ) , MajorVersion ) & & Object - > TryGetNumberField ( TEXT ( " MinorVersion " ) , MinorVersion ) & & Object - > TryGetNumberField ( TEXT ( " PatchVersion " ) , PatchVersion ) )
{
int32 Changelist = 0 ;
if ( ! Object - > TryGetNumberField ( TEXT ( " Changelist " ) , Changelist ) )
{
Changelist = 0 ;
}
int32 IsLicenseeVersion = 0 ;
if ( ! Object - > TryGetNumberField ( TEXT ( " IsLicenseeVersion " ) , IsLicenseeVersion ) )
{
IsLicenseeVersion = 0 ;
}
FString BranchName ;
if ( ! Object - > TryGetStringField ( TEXT ( " BranchName " ) , BranchName ) )
{
BranchName = FString ( ) ;
}
int EncodedChangelist = ( IsLicenseeVersion = = 0 ) ? Changelist : FEngineVersionBase : : EncodeLicenseeChangelist ( Changelist ) ;
OutVersion = FEngineVersion ( MajorVersion , MinorVersion , PatchVersion , EncodedChangelist , BranchName ) ;
return true ;
}
}
}
// Try to read the version file
FString VersionHeader ;
if ( FFileHelper : : LoadFileToString ( VersionHeader , * ( RootDir / TEXT ( " Engine/Source/Runtime/Launch/Resources/Version.h " ) ) ) )
{
int32 MajorVersion = - 1 ;
int32 MinorVersion = - 1 ;
int32 PatchVersion = - 1 ;
int32 Changelist = 0 ;
int32 IsLicenseeVersion = 0 ;
FString BranchName ;
// Scan the file for version defines
const TCHAR * TextPos = * VersionHeader ;
while ( * TextPos )
{
// Skip over any newlines
while ( FChar : : IsWhitespace ( * TextPos ) )
{
TextPos + + ;
}
// Buffer up a line of tokens
TArray < FString > Tokens ;
while ( * TextPos ! = ' \n ' & & * TextPos ! = 0 )
{
if ( * TextPos = = ' ' | | * TextPos = = ' \t ' | | * TextPos = = ' \r ' )
{
// Skip over whitespace
TextPos + + ;
}
else if ( FChar : : IsIdentifier ( * TextPos ) )
{
// Parse an identifier. Exact C rules for an identifier don't really matter; we just need alphanumeric sequences.
const TCHAR * TokenStart = TextPos + + ;
while ( FChar : : IsIdentifier ( * TextPos ) ) TextPos + + ;
Tokens . Add ( FString ( TextPos - TokenStart , TokenStart ) ) ;
}
else if ( * TextPos = = ' \" ' )
{
// Parse a string
const TCHAR * TokenStart = TextPos + + ;
while ( * TextPos ! = 0 & & ( TextPos = = TokenStart + 1 | | * ( TextPos - 1 ) ! = ' \" ' ) ) TextPos + + ;
Tokens . Add ( FString ( TextPos - TokenStart , TokenStart ) ) ;
}
else if ( * TextPos = = ' / ' & & * ( TextPos + 1 ) = = ' / ' )
{
// Skip a C++ style comment
TextPos + = 2 ;
while ( * TextPos ! = ' \n ' & & * TextPos ! = 0 ) TextPos + + ;
}
else if ( * TextPos = = ' / ' & & * ( TextPos + 1 ) = = ' * ' & & * ( TextPos + 2 ) ! = 0 & & * ( TextPos + 3 ) ! = 0 )
{
// Skip a C-style comment
TextPos + = 4 ;
while ( * TextPos ! = 0 & & ( * ( TextPos - 2 ) ! = ' * ' | | * ( TextPos - 1 ) ! = ' / ' ) ) TextPos + + ;
}
else
{
// Take a single symbol character
Tokens . Add ( FString ( 1 , TextPos ) ) ;
TextPos + + ;
}
}
// Check if it matches any version defines
if ( Tokens . Num ( ) > = 4 & & Tokens [ 0 ] = = " # " & & Tokens [ 1 ] = = " define " )
{
if ( FChar : : IsDigit ( Tokens [ 3 ] [ 0 ] ) )
{
if ( Tokens [ 2 ] = = " ENGINE_MAJOR_VERSION " )
{
MajorVersion = FCString : : Atoi ( * Tokens [ 3 ] ) ;
}
else if ( Tokens [ 2 ] = = " ENGINE_MINOR_VERSION " )
{
MinorVersion = FCString : : Atoi ( * Tokens [ 3 ] ) ;
}
else if ( Tokens [ 2 ] = = " ENGINE_PATCH_VERSION " )
{
PatchVersion = FCString : : Atoi ( * Tokens [ 3 ] ) ;
}
2015-07-18 16:57:53 -04:00
else if ( Tokens [ 2 ] = = " BUILT_FROM_CHANGELIST " )
2015-07-10 15:21:32 -04:00
{
Changelist = FCString : : Atoi ( * Tokens [ 3 ] ) ;
}
else if ( Tokens [ 2 ] = = " ENGINE_IS_LICENSEE_VERSION " )
{
IsLicenseeVersion = FCString : : Atoi ( * Tokens [ 3 ] ) ;
}
}
else if ( Tokens [ 3 ] . StartsWith ( " \" " ) & & Tokens [ 3 ] . EndsWith ( " \" " ) )
{
if ( Tokens [ 2 ] = = " BRANCH_NAME " )
{
BranchName = Tokens [ 3 ] . TrimQuotes ( ) ;
}
}
}
}
// If we have everything we need, fill in the version struct
if ( MajorVersion ! = - 1 & & MinorVersion ! = - 1 & & PatchVersion ! = - 1 )
{
int EncodedChangelist = ( IsLicenseeVersion = = 0 ) ? Changelist : FEngineVersionBase : : EncodeLicenseeChangelist ( Changelist ) ;
OutVersion = FEngineVersion ( MajorVersion , MinorVersion , PatchVersion , EncodedChangelist , BranchName ) ;
return true ;
}
}
return false ;
}
2014-05-13 18:23:53 -04:00
bool FDesktopPlatformBase : : IsStockEngineRelease ( const FString & Identifier )
{
2014-08-27 15:29:01 -04:00
FGuid Guid ;
return ! FGuid : : Parse ( Identifier , Guid ) ;
2014-05-13 18:23:53 -04:00
}
2015-04-17 06:35:39 -04:00
bool FDesktopPlatformBase : : TryParseStockEngineVersion ( const FString & Identifier , FEngineVersion & OutVersion )
{
TCHAR * End ;
uint64 Major = FCString : : Strtoui64 ( * Identifier , & End , 10 ) ;
if ( Major > MAX_uint16 | | * ( End + + ) ! = ' . ' )
{
return false ;
}
uint64 Minor = FCString : : Strtoui64 ( End , & End , 10 ) ;
if ( Minor > MAX_uint16 | | * End ! = 0 )
{
return false ;
}
OutVersion = FEngineVersion ( Major , Minor , 0 , 0 , TEXT ( " " ) ) ;
return true ;
}
2014-04-23 18:46:48 -04:00
bool FDesktopPlatformBase : : IsSourceDistribution ( const FString & EngineRootDir )
{
// Check for the existence of a SourceBuild.txt file
2014-04-23 18:59:02 -04:00
FString SourceBuildPath = EngineRootDir / TEXT ( " Engine/Build/SourceDistribution.txt " ) ;
2014-04-23 18:46:48 -04:00
return ( IFileManager : : Get ( ) . FileSize ( * SourceBuildPath ) > = 0 ) ;
}
bool FDesktopPlatformBase : : IsPerforceBuild ( const FString & EngineRootDir )
{
// Check for the existence of a SourceBuild.txt file
2014-04-23 18:59:02 -04:00
FString PerforceBuildPath = EngineRootDir / TEXT ( " Engine/Build/PerforceBuild.txt " ) ;
2014-04-23 18:46:48 -04:00
return ( IFileManager : : Get ( ) . FileSize ( * PerforceBuildPath ) > = 0 ) ;
}
bool FDesktopPlatformBase : : IsValidRootDirectory ( const FString & RootDir )
{
2014-08-01 11:32:55 -04:00
// Check that there's an Engine\Binaries directory underneath the root
2014-04-23 18:46:48 -04:00
FString EngineBinariesDirName = RootDir / TEXT ( " Engine/Binaries " ) ;
FPaths : : NormalizeDirectoryName ( EngineBinariesDirName ) ;
2014-08-01 11:32:55 -04:00
if ( ! IFileManager : : Get ( ) . DirectoryExists ( * EngineBinariesDirName ) )
{
return false ;
}
// Also check there's an Engine\Build directory. This will filter out anything that has an engine-like directory structure but doesn't allow building code projects - like the launcher.
FString EngineBuildDirName = RootDir / TEXT ( " Engine/Build " ) ;
FPaths : : NormalizeDirectoryName ( EngineBuildDirName ) ;
if ( ! IFileManager : : Get ( ) . DirectoryExists ( * EngineBuildDirName ) )
{
return false ;
}
// Otherwise it's valid
return true ;
2014-04-23 18:46:48 -04:00
}
2014-05-06 10:27:35 -04:00
bool FDesktopPlatformBase : : SetEngineIdentifierForProject ( const FString & ProjectFileName , const FString & InIdentifier )
2014-04-23 18:46:48 -04:00
{
2014-05-06 10:27:35 -04:00
// Load the project file
2014-04-23 18:46:48 -04:00
TSharedPtr < FJsonObject > ProjectFile = LoadProjectFile ( ProjectFileName ) ;
if ( ! ProjectFile . IsValid ( ) )
{
return false ;
}
2014-05-06 10:27:35 -04:00
// Check if the project is a non-foreign project of the given engine installation. If so, blank the identifier
// string to allow portability between source control databases. GetEngineIdentifierForProject will translate
// the association back into a local identifier on other machines or syncs.
FString Identifier = InIdentifier ;
if ( Identifier . Len ( ) > 0 )
{
FString RootDir ;
if ( GetEngineRootDirFromIdentifier ( Identifier , RootDir ) )
{
2014-05-13 18:23:53 -04:00
const FUProjectDictionary & Dictionary = GetCachedProjectDictionary ( RootDir ) ;
2014-05-06 10:27:35 -04:00
if ( ! Dictionary . IsForeignProject ( ProjectFileName ) )
{
Identifier . Empty ( ) ;
}
}
}
// Set the association on the project and save it
2014-04-23 18:46:48 -04:00
ProjectFile - > SetStringField ( TEXT ( " EngineAssociation " ) , Identifier ) ;
return SaveProjectFile ( ProjectFileName , ProjectFile ) ;
}
2015-01-09 08:11:29 -05:00
bool FDesktopPlatformBase : : GetEngineIdentifierForProject ( const FString & ProjectFileName , FString & OutIdentifier )
2014-04-23 18:46:48 -04:00
{
2014-06-10 10:27:47 -04:00
OutIdentifier . Empty ( ) ;
2014-05-06 10:27:35 -04:00
// Load the project file
2014-04-23 18:46:48 -04:00
TSharedPtr < FJsonObject > ProjectFile = LoadProjectFile ( ProjectFileName ) ;
if ( ! ProjectFile . IsValid ( ) )
{
return false ;
}
2014-06-10 10:27:47 -04:00
// Try to read the identifier from it
TSharedPtr < FJsonValue > Value = ProjectFile - > TryGetField ( TEXT ( " EngineAssociation " ) ) ;
if ( Value . IsValid ( ) & & Value - > Type = = EJson : : String )
2014-05-06 10:27:35 -04:00
{
2014-06-10 10:27:47 -04:00
OutIdentifier = Value - > AsString ( ) ;
if ( OutIdentifier . Len ( ) > 0 )
{
2015-01-09 08:11:29 -05:00
// If it's a path, convert it into an engine identifier
if ( OutIdentifier . Contains ( TEXT ( " / " ) ) | | OutIdentifier . Contains ( " \\ " ) )
{
FString EngineRootDir = FPaths : : ConvertRelativePathToFull ( FPaths : : GetPath ( ProjectFileName ) , OutIdentifier ) ;
if ( ! GetEngineIdentifierFromRootDir ( EngineRootDir , OutIdentifier ) )
{
return false ;
}
}
2014-06-10 10:27:47 -04:00
return true ;
}
2014-05-06 10:27:35 -04:00
}
2014-05-15 13:07:56 -04:00
// Otherwise scan up through the directory hierarchy to find an installation
2014-05-06 10:27:35 -04:00
FString ParentDir = FPaths : : GetPath ( ProjectFileName ) ;
FPaths : : NormalizeDirectoryName ( ParentDir ) ;
2014-05-15 13:07:56 -04:00
// Keep going until we reach the root
2014-05-06 10:27:35 -04:00
int32 SeparatorIdx ;
while ( ParentDir . FindLastChar ( TEXT ( ' / ' ) , SeparatorIdx ) )
{
ParentDir . RemoveAt ( SeparatorIdx , ParentDir . Len ( ) - SeparatorIdx ) ;
2014-05-15 13:07:56 -04:00
if ( IsValidRootDirectory ( ParentDir ) & & GetEngineIdentifierFromRootDir ( ParentDir , OutIdentifier ) )
2014-05-06 10:27:35 -04:00
{
return true ;
}
}
2014-05-13 18:23:53 -04:00
// Otherwise check the engine version string for 4.0, in case this project existed before the engine association stuff went in
FString EngineVersionString = ProjectFile - > GetStringField ( TEXT ( " EngineVersion " ) ) ;
if ( EngineVersionString . Len ( ) > 0 )
{
FEngineVersion EngineVersion ;
2015-06-26 09:25:56 -04:00
if ( FEngineVersion : : Parse ( EngineVersionString , EngineVersion ) & & EngineVersion . HasChangelist ( ) & & EngineVersion . ToString ( EVersionComponent : : Minor ) = = TEXT ( " 4.0 " ) )
2014-05-13 18:23:53 -04:00
{
OutIdentifier = TEXT ( " 4.0 " ) ;
return true ;
}
}
2014-05-06 10:27:35 -04:00
return false ;
2014-04-23 18:46:48 -04:00
}
2014-06-18 13:42:01 -04:00
bool FDesktopPlatformBase : : OpenProject ( const FString & ProjectFileName )
{
FPlatformProcess : : LaunchFileInDefaultExternalApplication ( * ProjectFileName ) ;
return true ;
}
2014-07-22 15:58:02 -04:00
bool FDesktopPlatformBase : : CleanGameProject ( const FString & ProjectDir , FString & OutFailPath , FFeedbackContext * Warn )
2014-05-14 19:11:30 -04:00
{
// Begin a task
Warn - > BeginSlowTask ( LOCTEXT ( " CleaningProject " , " Removing stale build products... " ) , true ) ;
// Enumerate all the files
TArray < FString > FileNames ;
2014-05-29 17:45:17 -04:00
TArray < FString > DirectoryNames ;
GetProjectBuildProducts ( ProjectDir , FileNames , DirectoryNames ) ;
2014-05-14 19:11:30 -04:00
// Remove all the files
for ( int32 Idx = 0 ; Idx < FileNames . Num ( ) ; Idx + + )
{
// Remove the file
if ( ! IFileManager : : Get ( ) . Delete ( * FileNames [ Idx ] ) )
{
2014-07-22 15:58:02 -04:00
OutFailPath = FileNames [ Idx ] ;
Warn - > EndSlowTask ( ) ;
2014-05-14 19:11:30 -04:00
return false ;
}
2014-05-29 17:45:17 -04:00
// Update the progress
Warn - > UpdateProgress ( Idx , FileNames . Num ( ) + DirectoryNames . Num ( ) ) ;
}
// Remove all the directories
for ( int32 Idx = 0 ; Idx < DirectoryNames . Num ( ) ; Idx + + )
{
// Remove the directory
if ( ! IFileManager : : Get ( ) . DeleteDirectory ( * DirectoryNames [ Idx ] , false , true ) )
2014-05-14 19:11:30 -04:00
{
2014-07-22 15:58:02 -04:00
OutFailPath = DirectoryNames [ Idx ] ;
Warn - > EndSlowTask ( ) ;
2014-05-29 17:45:17 -04:00
return false ;
2014-05-14 19:11:30 -04:00
}
// Update the progress
2014-05-29 17:45:17 -04:00
Warn - > UpdateProgress ( Idx + FileNames . Num ( ) , FileNames . Num ( ) + DirectoryNames . Num ( ) ) ;
2014-05-14 19:11:30 -04:00
}
// End the task
Warn - > EndSlowTask ( ) ;
return true ;
}
2014-05-13 18:23:53 -04:00
bool FDesktopPlatformBase : : CompileGameProject ( const FString & RootDir , const FString & ProjectFileName , FFeedbackContext * Warn )
{
2014-10-06 10:59:41 -04:00
// Get the project directory
FString ProjectDir = FPaths : : GetPath ( ProjectFileName ) ;
// Get the target name. By default it'll be the same as the project name, but that might not be the case if the project was renamed.
FString TargetName = FPaths : : GetBaseFilename ( ProjectFileName ) ;
if ( ! FPaths : : FileExists ( ProjectDir / FString : : Printf ( TEXT ( " Source/%sEditor.Target.cs " ) , * TargetName ) ) )
{
// Find all the target files
TArray < FString > TargetFiles ;
IFileManager : : Get ( ) . FindFilesRecursive ( TargetFiles , * ( ProjectDir / TEXT ( " Source " ) ) , TEXT ( " *.target.cs " ) , true , false , false ) ;
// Try to find a target that's clearly meant to be the editor. If there isn't one, let UBT fail with a sensible message without trying to do anything else smart.
for ( const FString TargetFile : TargetFiles )
{
if ( TargetFile . EndsWith ( " Editor.Target.cs " ) )
{
TargetName = FPaths : : GetBaseFilename ( FPaths : : GetBaseFilename ( TargetFile ) ) ;
break ;
}
}
}
// Build the argument list
FString Arguments = FString : : Printf ( TEXT ( " %s %s %s " ) , * TargetName , FModuleManager : : Get ( ) . GetUBTConfiguration ( ) , FPlatformMisc : : GetUBTPlatform ( ) ) ;
2014-05-13 18:23:53 -04:00
// Append the project name if it's a foreign project
if ( ! ProjectFileName . IsEmpty ( ) )
{
FUProjectDictionary ProjectDictionary ( RootDir ) ;
if ( ProjectDictionary . IsForeignProject ( ProjectFileName ) )
{
Arguments + = FString : : Printf ( TEXT ( " -project= \" %s \" " ) , * IFileManager : : Get ( ) . ConvertToAbsolutePathForExternalAppForRead ( * ProjectFileName ) ) ;
}
}
// Append any other options
2015-09-15 11:39:18 -04:00
Arguments + = " -editorrecompile -progress -noubtmakefiles -NoHotReloadFromIDE " ;
2014-05-13 18:23:53 -04:00
// Run UBT
return RunUnrealBuildTool ( LOCTEXT ( " CompilingProject " , " Compiling project... " ) , RootDir , Arguments , Warn ) ;
}
bool FDesktopPlatformBase : : GenerateProjectFiles ( const FString & RootDir , const FString & ProjectFileName , FFeedbackContext * Warn )
{
# if PLATFORM_MAC
2015-02-16 07:53:59 -05:00
FString Arguments = TEXT ( " -xcodeprojectfile " ) ;
2014-07-30 23:26:47 -04:00
# elif PLATFORM_LINUX
2015-07-14 18:17:55 -04:00
FString Arguments = TEXT ( " -makefile -kdevelopfile -qmakefile -cmakefile -codelitefile " ) ;
2014-05-13 18:23:53 -04:00
# else
2015-02-16 07:53:59 -05:00
FString Arguments = TEXT ( " -projectfiles " ) ;
2014-05-13 18:23:53 -04:00
# endif
2015-04-30 13:15:34 -04:00
2014-12-10 11:58:11 -05:00
// Build the arguments to pass to UBT. If it's a non-foreign project, just build full project files.
if ( ! ProjectFileName . IsEmpty ( ) & & GetCachedProjectDictionary ( RootDir ) . IsForeignProject ( ProjectFileName ) )
2014-05-13 18:23:53 -04:00
{
// Figure out whether it's a foreign project
2014-05-14 14:53:19 -04:00
const FUProjectDictionary & ProjectDictionary = GetCachedProjectDictionary ( RootDir ) ;
2014-05-13 18:23:53 -04:00
if ( ProjectDictionary . IsForeignProject ( ProjectFileName ) )
{
Arguments + = FString : : Printf ( TEXT ( " -project= \" %s \" " ) , * IFileManager : : Get ( ) . ConvertToAbsolutePathForExternalAppForRead ( * ProjectFileName ) ) ;
2014-05-19 13:08:08 -04:00
// Always include game source
2015-02-16 07:53:59 -05:00
Arguments + = TEXT ( " -game " ) ;
2014-05-13 18:23:53 -04:00
2014-05-19 13:08:08 -04:00
// Determine whether or not to include engine source
2015-12-04 09:32:58 -05:00
if ( IsSourceDistribution ( RootDir ) )
2014-05-19 13:08:08 -04:00
{
2015-02-16 07:53:59 -05:00
Arguments + = TEXT ( " -engine " ) ;
2014-05-19 13:08:08 -04:00
}
2016-02-03 15:40:40 -05:00
else
{
// If this is used within UnrealVersionSelector then we still need to pass
// -rocket to deal with old versions that don't use Rocket.txt file
Arguments + = TEXT ( " -rocket " ) ;
}
2014-05-13 18:23:53 -04:00
}
}
2015-02-16 07:53:59 -05:00
Arguments + = TEXT ( " -progress " ) ;
2014-05-13 18:23:53 -04:00
2014-10-30 17:07:40 -04:00
// Compile UnrealBuildTool if it doesn't exist. This can happen if we're just copying source from somewhere.
bool bRes = true ;
2014-05-13 18:23:53 -04:00
Warn - > BeginSlowTask ( LOCTEXT ( " GeneratingProjectFiles " , " Generating project files... " ) , true , true ) ;
2015-01-29 16:15:16 -05:00
if ( ! FPaths : : FileExists ( GetUnrealBuildToolExecutableFilename ( RootDir ) ) )
2014-10-30 17:07:40 -04:00
{
Warn - > StatusUpdate ( 0 , 1 , LOCTEXT ( " BuildingUBT " , " Building UnrealBuildTool... " ) ) ;
2015-01-29 16:15:16 -05:00
bRes = BuildUnrealBuildTool ( RootDir , * Warn ) ;
2014-10-30 17:07:40 -04:00
}
if ( bRes )
{
2015-01-29 16:15:16 -05:00
Warn - > StatusUpdate ( 0 , 1 , LOCTEXT ( " GeneratingProjectFiles " , " Generating project files... " ) ) ;
2014-10-30 17:07:40 -04:00
bRes = RunUnrealBuildTool ( LOCTEXT ( " GeneratingProjectFiles " , " Generating project files... " ) , RootDir , Arguments , Warn ) ;
}
2014-05-13 18:23:53 -04:00
Warn - > EndSlowTask ( ) ;
return bRes ;
}
2015-03-17 09:34:18 -04:00
bool FDesktopPlatformBase : : InvalidateMakefiles ( const FString & RootDir , const FString & ProjectFileName , FFeedbackContext * Warn )
2015-02-16 07:53:59 -05:00
{
// Composes the target, platform, and config (eg, "QAGame Win64 Development")
FString Arguments = FString : : Printf ( TEXT ( " %s %s %s " ) , FApp : : GetGameName ( ) , FPlatformMisc : : GetUBTPlatform ( ) , FModuleManager : : GetUBTConfiguration ( ) ) ;
// -editorrecompile tells UBT to work out the editor target name from the game target name we provided (eg, converting "QAGame" to "QAGameEditor")
Arguments + = TEXT ( " -editorrecompile " ) ;
// Build the arguments to pass to UBT. If it's a non-foreign project, just build full project files.
if ( ! ProjectFileName . IsEmpty ( ) & & GetCachedProjectDictionary ( RootDir ) . IsForeignProject ( ProjectFileName ) )
{
// Figure out whether it's a foreign project
const FUProjectDictionary & ProjectDictionary = GetCachedProjectDictionary ( RootDir ) ;
if ( ProjectDictionary . IsForeignProject ( ProjectFileName ) )
{
Arguments + = FString : : Printf ( TEXT ( " \" %s \" " ) , * IFileManager : : Get ( ) . ConvertToAbsolutePathForExternalAppForRead ( * ProjectFileName ) ) ;
}
}
2015-03-17 09:34:18 -04:00
// -invalidatemakefilesonly tells UBT to invalidate its UBT makefiles without building
Arguments + = TEXT ( " -invalidatemakefilesonly " ) ;
2015-02-16 07:53:59 -05:00
// Compile UnrealBuildTool if it doesn't exist. This can happen if we're just copying source from somewhere.
bool bRes = true ;
2015-03-17 09:34:18 -04:00
Warn - > BeginSlowTask ( LOCTEXT ( " InvalidateMakefiles " , " Invalidating makefiles... " ) , true , true ) ;
2015-02-16 07:53:59 -05:00
if ( ! FPaths : : FileExists ( GetUnrealBuildToolExecutableFilename ( RootDir ) ) )
{
Warn - > StatusUpdate ( 0 , 1 , LOCTEXT ( " BuildingUBT " , " Building UnrealBuildTool... " ) ) ;
bRes = BuildUnrealBuildTool ( RootDir , * Warn ) ;
}
if ( bRes )
{
2015-03-17 09:34:18 -04:00
Warn - > StatusUpdate ( 0 , 1 , LOCTEXT ( " InvalidateMakefiles " , " Invalidating makefiles... " ) ) ;
bRes = RunUnrealBuildTool ( LOCTEXT ( " InvalidateMakefiles " , " Invalidating makefiles... " ) , RootDir , Arguments , Warn ) ;
2015-02-16 07:53:59 -05:00
}
Warn - > EndSlowTask ( ) ;
return bRes ;
}
2014-09-05 13:31:22 -04:00
bool FDesktopPlatformBase : : IsUnrealBuildToolAvailable ( )
{
Copying //UE4/Dev-Build to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2864843 on 2016/02/12 by Ben.Marsh
Add individual 'status', 'outcome', and 'error_code' fields to parsed jobsteps. Should fix grid view not being able to display 'pending' icons.
Change 2865161 on 2016/02/12 by Ben.Marsh
Stop storing a reference to UEBuildTarget from UEBuildModule. It creates an awkward cyclic data dependency, and makes it easy for people to write lazy code that just reaches into the internal state of the build.
Change 2865643 on 2016/02/12 by Ben.Marsh
Rename UEBuildModuleType to UHTModuleType, and move implementation into ExternalExecution.
Change 2874408 on 2016/02/19 by Ben.Marsh
Automatically sort nodes in the dashboard grid view by a weight derived from the node's order in the build graph, summed across all the jobs in which it was present.
Change 2879572 on 2016/02/24 by Ben.Marsh
Allow spoofing a Git merge from a given commit, using a changelist description containing the tag "git merge <branch> <changelist>", where <branch> is the name of a branch on Git (eg. master, 4.11, etc..), and <changelist> is the changelist being merged in.
Change 2883216 on 2016/02/26 by Ben.Marsh
Prevent Jira tickets being incorrectly updated with 'Main CL' fields which are after the 'Fix CL' fields.
Change 2883755 on 2016/02/26 by Ben.Marsh
Fix solution files having a Shipping configuration, even when -NoShippingConfigs is passed on the command line.
Change 2886223 on 2016/02/29 by Ben.Marsh
Ignore SignTool errors - we can recover from them.
Change 2887414 on 2016/03/01 by Ben.Marsh
Dump all the *.crash files produced while running commandlets, to make it easier to diagnose build system crashes cooking on Mac.
Change 2888235 on 2016/03/01 by Ben.Marsh
Add overloads for methods in FileFilter which take FileReference and DirectoryReference objects.
Change 2889602 on 2016/03/02 by Ben.Marsh
Treat shaders as code in UGS. Don't sync them as part of content-only syncs, and don't allow syncing past them without updated binaries.
Change 2889610 on 2016/03/02 by Ben.Marsh
Fix setting for using incremental builds not being saved. Also hide command to do incremental builds if the 'use incremental builds' option is not checked.
Change 2891866 on 2016/03/03 by Matthew.Griffin
Removed Rocket specific batch files and made sure installed build won't try to include them
Removed last use of RocketGenerateProjectFiles.sh by using UBT directly instead
Change 2893349 on 2016/03/03 by Ben.Marsh
Add derived ReplicatedBranch to support mirroring the VR editor branch to GitHub.
Change 2894703 on 2016/03/04 by Ben.Marsh
Include *.usf when looking for the last code changelist. Also update version to 1.68.
Change 2897991 on 2016/03/07 by Ben.Marsh
Copy the changelist number to the clipboard when the user presses Ctrl-C. Update version number to 1.69.
Change 2898005 on 2016/03/07 by Ben.Marsh
Minor changes to support BuildGraph:
* UE4Build now has a static function that can update version files.
* Adding FileReference/DirectoryReference methods to FileFilter and CommandUtils.
* FileFilter treats any pattern containing a slash as implictly starting from the root directory, unless it begins with "...".
Change 2898095 on 2016/03/07 by Ben.Marsh
UAT - Don't retry builds if we're using local executor; we don't encounter failures due to timeouts.
Change 2898248 on 2016/03/07 by Ben.Marsh
UBT - Add the standard game include paths back in to plugin modules. Existing game code relies on this.
Change 2898615 on 2016/03/08 by Matthew.Griffin
Removed last uses of RunningRocket function
All seemed to be overly cautious about people using an Installed build to do non standard things, don't see any ill effects in the most common circumstances.
Change 2898681 on 2016/03/08 by Matthew.Griffin
Removed Automation.RunningRocket function as there are no more uses
Changed the majority of comments referencing Rocket mode that are now either about the engine being installed or from the Launcher etc.
#lockdown Nick.Penwarden
[CL 2898813 by Matthew Griffin in Main branch]
2016-03-08 09:00:48 -05:00
// If using installed build and the unreal build tool executable exists, then UBT is available. Otherwise check it can be built.
2014-09-05 13:31:22 -04:00
if ( FApp : : IsEngineInstalled ( ) )
{
2015-01-29 16:15:16 -05:00
return FPaths : : FileExists ( GetUnrealBuildToolExecutableFilename ( FPaths : : RootDir ( ) ) ) ;
2014-09-05 13:31:22 -04:00
}
else
{
2015-01-29 16:15:16 -05:00
return FPaths : : FileExists ( GetUnrealBuildToolProjectFileName ( FPaths : : RootDir ( ) ) ) ;
2014-09-05 13:31:22 -04:00
}
}
bool FDesktopPlatformBase : : InvokeUnrealBuildToolSync ( const FString & InCmdLineParams , FOutputDevice & Ar , bool bSkipBuildUBT , int32 & OutReturnCode , FString & OutProcOutput )
{
2015-03-09 11:45:35 -04:00
void * PipeRead = nullptr ;
void * PipeWrite = nullptr ;
2014-09-05 13:31:22 -04:00
verify ( FPlatformProcess : : CreatePipe ( PipeRead , PipeWrite ) ) ;
bool bInvoked = false ;
FProcHandle ProcHandle = InvokeUnrealBuildToolAsync ( InCmdLineParams , Ar , PipeRead , PipeWrite , bSkipBuildUBT ) ;
if ( ProcHandle . IsValid ( ) )
{
// rather than waiting, we must flush the read pipe or UBT will stall if it writes out a ton of text to the console.
while ( FPlatformProcess : : IsProcRunning ( ProcHandle ) )
{
OutProcOutput + = FPlatformProcess : : ReadPipe ( PipeRead ) ;
FPlatformProcess : : Sleep ( 0.1f ) ;
}
bInvoked = true ;
bool bGotReturnCode = FPlatformProcess : : GetProcReturnCode ( ProcHandle , & OutReturnCode ) ;
check ( bGotReturnCode ) ;
}
else
{
bInvoked = false ;
OutReturnCode = - 1 ;
OutProcOutput = TEXT ( " " ) ;
}
FPlatformProcess : : ClosePipe ( PipeRead , PipeWrite ) ;
return bInvoked ;
}
FProcHandle FDesktopPlatformBase : : InvokeUnrealBuildToolAsync ( const FString & InCmdLineParams , FOutputDevice & Ar , void * & OutReadPipe , void * & OutWritePipe , bool bSkipBuildUBT )
{
FString CmdLineParams = InCmdLineParams ;
Copying //UE4/Release-Staging-4.11 to //UE4/Main (Source: //UE4/Release-Staging-4.11 @ 2941426, //UE4/Release-4.11 @ 2927265)
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2910079 on 2016/03/15 by Taizyd.Korambayil
#jira UE-28293 Reworded some Sentences
Change 2910157 on 2016/03/15 by Taizyd.Korambayil
#jira UE-28240 Rebuilt Lighting for Sanctuary
Change 2910317 on 2016/03/15 by Ben.Marsh
Fix crash trying to print out a message explaining that you need to install the Visual Studio 2015 toolchain, if the Visual Studio 2015 toolchain is not installed!
Change 2910425 on 2016/03/15 by Ori.Cohen
Fix crash and incorrect behavior when setting physical material on a welded body.
#JIRA UE-28399
#rb Marc.Audy
Change 2910525 on 2016/03/15 by Ori.Cohen
Fix player capsule not spawning at the right place due to float precision issues.
#JIRA UE-28438
#rb Zak.Middleton
Change 2910595 on 2016/03/15 by Chris.Babcock
Fixed issue with missing event location paired with IE_Pressed if IE_DoubleClick generated
#jira UE-28051
#ue4
#codereview Marc.Audy
Change 2911442 on 2016/03/16 by Andrew.Rodham
Sequencer: Fixed frame grabbers where hardware mapped surfaces to memory of a different stride
#jira UE-28434
Change 2911596 on 2016/03/16 by andrew.porter
Test content for blueprint vertex painting
#jira UE-24473
Change 2911860 on 2016/03/16 by Jamie.Dale
Allowed SViewport to (once again) be able to use non-pre-multiplied alpha blending
SViewport now has an PreMultipliedAlpha argument (default true), which can control whether to use pre-multiplied alpha when blending is enabled (blending is disabled by default). Note: This is a change in behavior from 4.10, as non-pre-multiplied alpha blending used to be the default, but pre-multiplied alpha blending better supports the pipeline used through Slate.
This change also cleans up the use of bool parameters in the FSlateDrawElement::MakeX functions to control the render behavior, instead favoring use of advanced ESlateDrawEffect flags.
API Breaking Changes
- FSlateDrawElement::MakeGradient no longer takes a bInGammaCorrect bool, instead pass ESlateDrawEffect::NoGamma as part of InDrawEffects to disable gamma correction.
- FSlateDrawElement::MakeViewport no longer takes a bInGammaCorrect bool, instead pass ESlateDrawEffect::NoGamma as part of InDrawEffects to disable gamma correction.
- FSlateDrawElement::MakeViewport no longer takes a bInAllowBlending bool, instead pass ESlateDrawEffect::NoBlending as part of InDrawEffects to disable blending.
#jira UE-26797
Change 2912345 on 2016/03/16 by Olaf.Piesche
Removing the check that causes UE-28441, duplicating beam type data module from highest LOD in Cascade causes crash. The beam data module is the only one that explicitly checks to make sure it's always shared across LOD levels; there's no obvious reasons why duplicating beam data modules shouldn't be possible.
#codereview simon.tovey
#jira UE-28441
Change 2912526 on 2016/03/16 by Steve.Robb
Fix uninitialized variables.
#codereview robert.manuszewski
#jira UE-28391
Change 2913114 on 2016/03/17 by Steve.Robb
Fixed some private properties which caused UHT errors.
#codereview robert.manuszewski
#jira UE-28059
Change 2913295 on 2016/03/17 by Richard.TalbotWatkin
Replicated from Dev-Editor CL 2913224
Disallow assets from being deleted if PIE is active. This prevents various troubles which can occur when PIE is referencing asset objects.
#jira UE-12387 - [CrashReport] Crash when deleting assets needed for template
#RB Nick.Darnell, Frank.Fella
Change 2913310 on 2016/03/17 by Nick.Shin
merging from //UE4/Dev-Platform to //UE4/Release-4.11
--- original commit CL: #2913300 message ---
corrected VS 2015 websocket lib to look at the right offset
it is currently a high risk change to just update the libwebsocket wholesale for release-4.11.
this change is the most minimum invasive change with a lot of deep analysis (details will be put in jira: # UEPLAT-1221).
this fix will also be pushed up to release-4.11
#jira UE-22166 - HTML5 Cook on the fly will launch and then close browser
#jira UE-22513 - HTTP Network File System crashes randomly.
#jira UE-28003 - Fail to QuickLaunch HTML5 through UnrealFrontEnd
Change 2913593 on 2016/03/17 by Mark.Satterthwaite
For non-debug builds silence the warning about no deth/stencil when shader writes to depth in MetalRHI - the RHI implementation will create a temporary D/S buffer to cope but really this needs to be properly addressed elsewhere.
#jira UE-28491
Change 2913655 on 2016/03/17 by Taizyd.Korambayil
#jira UE-28492 Rebuilt Lighting For the Samples Listed
Change 2914025 on 2016/03/17 by Olaf.Piesche
Make sure ST primitives are added to NST draw list if in shader complexity mode
#codereview simon.tovey
#jira UE-28471
Change 2914027 on 2016/03/17 by Nick.Shin
[CL 2941462 by Ben Marsh in Main branch]
2016-04-12 17:04:39 -04:00
# if PLATFORM_WINDOWS
# if _MSC_VER >= 1900
CmdLineParams + = TEXT ( " -2015 " ) ;
# elif _MSC_VER >= 1800
CmdLineParams + = TEXT ( " -2013 " ) ;
# else
CmdLineParams + = TEXT ( " -2012 " ) ;
# endif
# endif // PLATFORM_WINDOWS
2014-09-05 13:31:22 -04:00
// UnrealBuildTool is currently always located in the Binaries/DotNET folder
2015-01-29 16:15:16 -05:00
FString ExecutableFileName = GetUnrealBuildToolExecutableFilename ( FPaths : : RootDir ( ) ) ;
2014-09-05 13:31:22 -04:00
Copying //UE4/Dev-Build to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2864843 on 2016/02/12 by Ben.Marsh
Add individual 'status', 'outcome', and 'error_code' fields to parsed jobsteps. Should fix grid view not being able to display 'pending' icons.
Change 2865161 on 2016/02/12 by Ben.Marsh
Stop storing a reference to UEBuildTarget from UEBuildModule. It creates an awkward cyclic data dependency, and makes it easy for people to write lazy code that just reaches into the internal state of the build.
Change 2865643 on 2016/02/12 by Ben.Marsh
Rename UEBuildModuleType to UHTModuleType, and move implementation into ExternalExecution.
Change 2874408 on 2016/02/19 by Ben.Marsh
Automatically sort nodes in the dashboard grid view by a weight derived from the node's order in the build graph, summed across all the jobs in which it was present.
Change 2879572 on 2016/02/24 by Ben.Marsh
Allow spoofing a Git merge from a given commit, using a changelist description containing the tag "git merge <branch> <changelist>", where <branch> is the name of a branch on Git (eg. master, 4.11, etc..), and <changelist> is the changelist being merged in.
Change 2883216 on 2016/02/26 by Ben.Marsh
Prevent Jira tickets being incorrectly updated with 'Main CL' fields which are after the 'Fix CL' fields.
Change 2883755 on 2016/02/26 by Ben.Marsh
Fix solution files having a Shipping configuration, even when -NoShippingConfigs is passed on the command line.
Change 2886223 on 2016/02/29 by Ben.Marsh
Ignore SignTool errors - we can recover from them.
Change 2887414 on 2016/03/01 by Ben.Marsh
Dump all the *.crash files produced while running commandlets, to make it easier to diagnose build system crashes cooking on Mac.
Change 2888235 on 2016/03/01 by Ben.Marsh
Add overloads for methods in FileFilter which take FileReference and DirectoryReference objects.
Change 2889602 on 2016/03/02 by Ben.Marsh
Treat shaders as code in UGS. Don't sync them as part of content-only syncs, and don't allow syncing past them without updated binaries.
Change 2889610 on 2016/03/02 by Ben.Marsh
Fix setting for using incremental builds not being saved. Also hide command to do incremental builds if the 'use incremental builds' option is not checked.
Change 2891866 on 2016/03/03 by Matthew.Griffin
Removed Rocket specific batch files and made sure installed build won't try to include them
Removed last use of RocketGenerateProjectFiles.sh by using UBT directly instead
Change 2893349 on 2016/03/03 by Ben.Marsh
Add derived ReplicatedBranch to support mirroring the VR editor branch to GitHub.
Change 2894703 on 2016/03/04 by Ben.Marsh
Include *.usf when looking for the last code changelist. Also update version to 1.68.
Change 2897991 on 2016/03/07 by Ben.Marsh
Copy the changelist number to the clipboard when the user presses Ctrl-C. Update version number to 1.69.
Change 2898005 on 2016/03/07 by Ben.Marsh
Minor changes to support BuildGraph:
* UE4Build now has a static function that can update version files.
* Adding FileReference/DirectoryReference methods to FileFilter and CommandUtils.
* FileFilter treats any pattern containing a slash as implictly starting from the root directory, unless it begins with "...".
Change 2898095 on 2016/03/07 by Ben.Marsh
UAT - Don't retry builds if we're using local executor; we don't encounter failures due to timeouts.
Change 2898248 on 2016/03/07 by Ben.Marsh
UBT - Add the standard game include paths back in to plugin modules. Existing game code relies on this.
Change 2898615 on 2016/03/08 by Matthew.Griffin
Removed last uses of RunningRocket function
All seemed to be overly cautious about people using an Installed build to do non standard things, don't see any ill effects in the most common circumstances.
Change 2898681 on 2016/03/08 by Matthew.Griffin
Removed Automation.RunningRocket function as there are no more uses
Changed the majority of comments referencing Rocket mode that are now either about the engine being installed or from the Launcher etc.
#lockdown Nick.Penwarden
[CL 2898813 by Matthew Griffin in Main branch]
2016-03-08 09:00:48 -05:00
// Installed builds never build UBT, UnrealBuildTool should already exist
2014-09-05 13:31:22 -04:00
bool bSkipBuild = FApp : : IsEngineInstalled ( ) | | bSkipBuildUBT ;
if ( ! bSkipBuild )
{
Copying //UE4/Dev-Build to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2864843 on 2016/02/12 by Ben.Marsh
Add individual 'status', 'outcome', and 'error_code' fields to parsed jobsteps. Should fix grid view not being able to display 'pending' icons.
Change 2865161 on 2016/02/12 by Ben.Marsh
Stop storing a reference to UEBuildTarget from UEBuildModule. It creates an awkward cyclic data dependency, and makes it easy for people to write lazy code that just reaches into the internal state of the build.
Change 2865643 on 2016/02/12 by Ben.Marsh
Rename UEBuildModuleType to UHTModuleType, and move implementation into ExternalExecution.
Change 2874408 on 2016/02/19 by Ben.Marsh
Automatically sort nodes in the dashboard grid view by a weight derived from the node's order in the build graph, summed across all the jobs in which it was present.
Change 2879572 on 2016/02/24 by Ben.Marsh
Allow spoofing a Git merge from a given commit, using a changelist description containing the tag "git merge <branch> <changelist>", where <branch> is the name of a branch on Git (eg. master, 4.11, etc..), and <changelist> is the changelist being merged in.
Change 2883216 on 2016/02/26 by Ben.Marsh
Prevent Jira tickets being incorrectly updated with 'Main CL' fields which are after the 'Fix CL' fields.
Change 2883755 on 2016/02/26 by Ben.Marsh
Fix solution files having a Shipping configuration, even when -NoShippingConfigs is passed on the command line.
Change 2886223 on 2016/02/29 by Ben.Marsh
Ignore SignTool errors - we can recover from them.
Change 2887414 on 2016/03/01 by Ben.Marsh
Dump all the *.crash files produced while running commandlets, to make it easier to diagnose build system crashes cooking on Mac.
Change 2888235 on 2016/03/01 by Ben.Marsh
Add overloads for methods in FileFilter which take FileReference and DirectoryReference objects.
Change 2889602 on 2016/03/02 by Ben.Marsh
Treat shaders as code in UGS. Don't sync them as part of content-only syncs, and don't allow syncing past them without updated binaries.
Change 2889610 on 2016/03/02 by Ben.Marsh
Fix setting for using incremental builds not being saved. Also hide command to do incremental builds if the 'use incremental builds' option is not checked.
Change 2891866 on 2016/03/03 by Matthew.Griffin
Removed Rocket specific batch files and made sure installed build won't try to include them
Removed last use of RocketGenerateProjectFiles.sh by using UBT directly instead
Change 2893349 on 2016/03/03 by Ben.Marsh
Add derived ReplicatedBranch to support mirroring the VR editor branch to GitHub.
Change 2894703 on 2016/03/04 by Ben.Marsh
Include *.usf when looking for the last code changelist. Also update version to 1.68.
Change 2897991 on 2016/03/07 by Ben.Marsh
Copy the changelist number to the clipboard when the user presses Ctrl-C. Update version number to 1.69.
Change 2898005 on 2016/03/07 by Ben.Marsh
Minor changes to support BuildGraph:
* UE4Build now has a static function that can update version files.
* Adding FileReference/DirectoryReference methods to FileFilter and CommandUtils.
* FileFilter treats any pattern containing a slash as implictly starting from the root directory, unless it begins with "...".
Change 2898095 on 2016/03/07 by Ben.Marsh
UAT - Don't retry builds if we're using local executor; we don't encounter failures due to timeouts.
Change 2898248 on 2016/03/07 by Ben.Marsh
UBT - Add the standard game include paths back in to plugin modules. Existing game code relies on this.
Change 2898615 on 2016/03/08 by Matthew.Griffin
Removed last uses of RunningRocket function
All seemed to be overly cautious about people using an Installed build to do non standard things, don't see any ill effects in the most common circumstances.
Change 2898681 on 2016/03/08 by Matthew.Griffin
Removed Automation.RunningRocket function as there are no more uses
Changed the majority of comments referencing Rocket mode that are now either about the engine being installed or from the Launcher etc.
#lockdown Nick.Penwarden
[CL 2898813 by Matthew Griffin in Main branch]
2016-03-08 09:00:48 -05:00
// When not using an installed build, we should attempt to build UBT to make sure it is up to date
2014-09-05 13:31:22 -04:00
// Only do this if we have not already successfully done it once during this session.
static bool bSuccessfullyBuiltUBTOnce = false ;
if ( ! bSuccessfullyBuiltUBTOnce )
{
Ar . Log ( TEXT ( " Building UnrealBuildTool... " ) ) ;
2015-01-29 16:15:16 -05:00
if ( BuildUnrealBuildTool ( FPaths : : RootDir ( ) , Ar ) )
2014-09-05 13:31:22 -04:00
{
bSuccessfullyBuiltUBTOnce = true ;
}
else
{
// Failed to build UBT
Ar . Log ( TEXT ( " Failed to build UnrealBuildTool. " ) ) ;
return FProcHandle ( ) ;
}
}
}
2014-11-04 16:37:36 -05:00
# if PLATFORM_LINUX
CmdLineParams + = ( " -progress " ) ;
# endif // PLATFORM_LINUX
2014-09-05 13:31:22 -04:00
Ar . Logf ( TEXT ( " Launching UnrealBuildTool... [%s %s] " ) , * ExecutableFileName , * CmdLineParams ) ;
# if PLATFORM_MAC
// On Mac we launch UBT with Mono
FString ScriptPath = FPaths : : ConvertRelativePathToFull ( FPaths : : EngineDir ( ) / TEXT ( " Build/BatchFiles/Mac/RunMono.sh " ) ) ;
CmdLineParams = FString : : Printf ( TEXT ( " \" %s \" \" %s \" %s " ) , * ScriptPath , * ExecutableFileName , * CmdLineParams ) ;
ExecutableFileName = TEXT ( " /bin/sh " ) ;
2014-11-04 16:37:36 -05:00
# elif PLATFORM_LINUX
// Real men run Linux (with Mono??)
FString ScriptPath = FPaths : : ConvertRelativePathToFull ( FPaths : : EngineDir ( ) / TEXT ( " Build/BatchFiles/Linux/RunMono.sh " ) ) ;
CmdLineParams = FString : : Printf ( TEXT ( " \" %s \" \" %s \" %s " ) , * ScriptPath , * ExecutableFileName , * CmdLineParams ) ;
ExecutableFileName = TEXT ( " /bin/bash " ) ;
2014-09-05 13:31:22 -04:00
# endif
// Run UnrealBuildTool
const bool bLaunchDetached = false ;
const bool bLaunchHidden = true ;
const bool bLaunchReallyHidden = bLaunchHidden ;
FProcHandle ProcHandle = FPlatformProcess : : CreateProc ( * ExecutableFileName , * CmdLineParams , bLaunchDetached , bLaunchHidden , bLaunchReallyHidden , NULL , 0 , NULL , OutWritePipe ) ;
if ( ! ProcHandle . IsValid ( ) )
{
Ar . Logf ( TEXT ( " Failed to launch Unreal Build Tool. (%s) " ) , * ExecutableFileName ) ;
}
return ProcHandle ;
}
2014-08-29 15:31:27 -04:00
bool FDesktopPlatformBase : : GetSolutionPath ( FString & OutSolutionPath )
{
// Get the platform-specific suffix for solution files
# if PLATFORM_MAC
2015-12-10 16:56:55 -05:00
const TCHAR * Suffix = TEXT ( " .xcworkspace/contents.xcworkspacedata " ) ;
2014-08-29 15:31:27 -04:00
# elif PLATFORM_LINUX
2015-07-14 18:17:55 -04:00
const TCHAR * Suffix = TEXT ( " .workspace " ) ; // FIXME: Should depend on PreferredAccessor setting
2014-08-29 15:31:27 -04:00
# else
const TCHAR * Suffix = TEXT ( " .sln " ) ;
# endif
// When using game specific uproject files, the solution is named after the game and in the uproject folder
if ( FPaths : : IsProjectFilePathSet ( ) )
{
FString SolutionPath = FPaths : : GameDir ( ) / FPaths : : GetBaseFilename ( FPaths : : GetProjectFilePath ( ) ) + Suffix ;
if ( FPaths : : FileExists ( SolutionPath ) )
{
OutSolutionPath = SolutionPath ;
return true ;
}
}
// Otherwise, it is simply titled UE4.sln
FString DefaultSolutionPath = FPaths : : RootDir ( ) / FString ( TEXT ( " UE4 " ) ) + Suffix ;
if ( FPaths : : FileExists ( DefaultSolutionPath ) )
{
OutSolutionPath = DefaultSolutionPath ;
return true ;
}
return false ;
}
2015-06-10 11:14:19 -04:00
FString FDesktopPlatformBase : : GetDefaultProjectCreationPath ( )
2014-06-04 18:06:57 -04:00
{
// My Documents
const FString DefaultProjectSubFolder = TEXT ( " Unreal Projects " ) ;
return FString ( FPlatformProcess : : UserDir ( ) ) + DefaultProjectSubFolder ;
}
2014-05-14 15:20:39 -04:00
void FDesktopPlatformBase : : ReadLauncherInstallationList ( )
2014-05-08 08:20:34 -04:00
{
2015-06-19 14:22:08 -04:00
FString InstalledListFile = FString ( FPlatformProcess : : ApplicationSettingsDir ( ) ) / TEXT ( " UnrealEngineLauncher/LauncherInstalled.dat " ) ;
2015-06-19 10:12:02 -04:00
2014-05-14 15:20:39 -04:00
// If the file does not exist, manually check for the 4.0 or 4.1 manifest
FDateTime NewListTimestamp = IFileManager : : Get ( ) . GetTimeStamp ( * InstalledListFile ) ;
if ( NewListTimestamp = = FDateTime : : MinValue ( ) )
2014-05-08 08:20:34 -04:00
{
2014-05-14 15:20:39 -04:00
if ( LauncherInstallationList . Num ( ) = = 0 )
2014-05-08 08:20:34 -04:00
{
2014-05-14 15:20:39 -04:00
CheckForLauncherEngineInstallation ( TEXT ( " 40003 " ) , TEXT ( " UE_4.0 " ) , LauncherInstallationList ) ;
CheckForLauncherEngineInstallation ( TEXT ( " 1040003 " ) , TEXT ( " UE_4.1 " ) , LauncherInstallationList ) ;
}
}
else if ( NewListTimestamp ! = LauncherInstallationTimestamp )
{
// Read the installation manifest
FString InstalledText ;
if ( FFileHelper : : LoadFileToString ( InstalledText , * InstalledListFile ) )
{
// Deserialize the object
TSharedPtr < FJsonObject > RootObject ;
TSharedRef < TJsonReader < > > Reader = TJsonReaderFactory < > : : Create ( InstalledText ) ;
if ( FJsonSerializer : : Deserialize ( Reader , RootObject ) & & RootObject . IsValid ( ) )
{
// Parse the list of installations
TArray < TSharedPtr < FJsonValue > > InstallationList = RootObject - > GetArrayField ( TEXT ( " InstallationList " ) ) ;
for ( int32 Idx = 0 ; Idx < InstallationList . Num ( ) ; Idx + + )
{
TSharedPtr < FJsonObject > InstallationItem = InstallationList [ Idx ] - > AsObject ( ) ;
FString AppName = InstallationItem - > GetStringField ( TEXT ( " AppName " ) ) ;
FString InstallLocation = InstallationItem - > GetStringField ( TEXT ( " InstallLocation " ) ) ;
if ( AppName . Len ( ) > 0 & & InstallLocation . Len ( ) > 0 )
{
FPaths : : NormalizeDirectoryName ( InstallLocation ) ;
LauncherInstallationList . Add ( AppName , InstallLocation ) ;
}
}
}
LauncherInstallationTimestamp = NewListTimestamp ;
2014-05-08 08:20:34 -04:00
}
}
}
2014-04-23 18:46:48 -04:00
void FDesktopPlatformBase : : CheckForLauncherEngineInstallation ( const FString & AppId , const FString & Identifier , TMap < FString , FString > & OutInstallations )
{
FString ManifestText ;
2015-06-19 14:22:08 -04:00
FString ManifestFileName = FString ( FPlatformProcess : : ApplicationSettingsDir ( ) ) / FString : : Printf ( TEXT ( " UnrealEngineLauncher/Data/Manifests/%s.manifest " ) , * AppId ) ;
2015-06-19 13:26:10 -04:00
2014-04-23 18:46:48 -04:00
if ( FFileHelper : : LoadFileToString ( ManifestText , * ManifestFileName ) )
{
TSharedPtr < FJsonObject > RootObject ;
TSharedRef < TJsonReader < > > Reader = TJsonReaderFactory < > : : Create ( ManifestText ) ;
if ( FJsonSerializer : : Deserialize ( Reader , RootObject ) & & RootObject . IsValid ( ) )
{
TSharedPtr < FJsonObject > CustomFieldsObject = RootObject - > GetObjectField ( TEXT ( " CustomFields " ) ) ;
if ( CustomFieldsObject . IsValid ( ) )
{
FString InstallLocation = CustomFieldsObject - > GetStringField ( " InstallLocation " ) ;
if ( InstallLocation . Len ( ) > 0 )
{
OutInstallations . Add ( Identifier , InstallLocation ) ;
}
}
}
}
}
int32 FDesktopPlatformBase : : ParseReleaseVersion ( const FString & Version )
{
TCHAR * End ;
uint64 Major = FCString : : Strtoui64 ( * Version , & End , 10 ) ;
if ( Major > = MAX_int16 | | * ( End + + ) ! = ' . ' )
{
return INDEX_NONE ;
}
uint64 Minor = FCString : : Strtoui64 ( End , & End , 10 ) ;
if ( Minor > = MAX_int16 | | * End ! = 0 )
{
return INDEX_NONE ;
}
return ( Major < < 16 ) + Minor ;
}
TSharedPtr < FJsonObject > FDesktopPlatformBase : : LoadProjectFile ( const FString & FileName )
{
FString FileContents ;
if ( ! FFileHelper : : LoadFileToString ( FileContents , * FileName ) )
{
return TSharedPtr < FJsonObject > ( NULL ) ;
}
TSharedPtr < FJsonObject > JsonObject ;
TSharedRef < TJsonReader < > > Reader = TJsonReaderFactory < > : : Create ( FileContents ) ;
if ( ! FJsonSerializer : : Deserialize ( Reader , JsonObject ) | | ! JsonObject . IsValid ( ) )
{
return TSharedPtr < FJsonObject > ( NULL ) ;
}
return JsonObject ;
}
bool FDesktopPlatformBase : : SaveProjectFile ( const FString & FileName , TSharedPtr < FJsonObject > Object )
{
FString FileContents ;
TSharedRef < TJsonWriter < > > Writer = TJsonWriterFactory < > : : Create ( & FileContents ) ;
if ( ! FJsonSerializer : : Serialize ( Object . ToSharedRef ( ) , Writer ) )
{
return false ;
}
if ( ! FFileHelper : : SaveStringToFile ( FileContents , * FileName ) )
{
return false ;
}
return true ;
}
2014-05-13 18:23:53 -04:00
const FUProjectDictionary & FDesktopPlatformBase : : GetCachedProjectDictionary ( const FString & RootDir )
{
FString NormalizedRootDir = RootDir ;
FPaths : : NormalizeDirectoryName ( NormalizedRootDir ) ;
FUProjectDictionary * Dictionary = CachedProjectDictionaries . Find ( NormalizedRootDir ) ;
if ( Dictionary = = NULL )
{
Dictionary = & CachedProjectDictionaries . Add ( RootDir , FUProjectDictionary ( RootDir ) ) ;
}
return * Dictionary ;
}
2014-05-29 17:45:17 -04:00
void FDesktopPlatformBase : : GetProjectBuildProducts ( const FString & ProjectDir , TArray < FString > & OutFileNames , TArray < FString > & OutDirectoryNames )
2014-05-14 19:11:30 -04:00
{
FString NormalizedProjectDir = ProjectDir ;
FPaths : : NormalizeDirectoryName ( NormalizedProjectDir ) ;
// Find all the build roots
TArray < FString > BuildRootDirectories ;
BuildRootDirectories . Add ( NormalizedProjectDir ) ;
// Add all the plugin directories
TArray < FString > PluginFileNames ;
IFileManager : : Get ( ) . FindFilesRecursive ( PluginFileNames , * ( NormalizedProjectDir / TEXT ( " Plugins " ) ) , TEXT ( " *.uplugin " ) , true , false ) ;
for ( int32 Idx = 0 ; Idx < PluginFileNames . Num ( ) ; Idx + + )
{
BuildRootDirectories . Add ( FPaths : : GetPath ( PluginFileNames [ Idx ] ) ) ;
}
2014-05-29 17:45:17 -04:00
// Add all the intermediate directories
for ( int32 Idx = 0 ; Idx < BuildRootDirectories . Num ( ) ; Idx + + )
2014-05-14 19:11:30 -04:00
{
2014-05-29 17:45:17 -04:00
OutDirectoryNames . Add ( BuildRootDirectories [ Idx ] / TEXT ( " Intermediate " ) ) ;
2014-05-14 19:11:30 -04:00
}
2014-05-29 17:45:17 -04:00
// Add the files in the cleaned directories to the output list
for ( int32 Idx = 0 ; Idx < OutDirectoryNames . Num ( ) ; Idx + + )
2014-05-14 19:11:30 -04:00
{
2014-05-29 17:45:17 -04:00
IFileManager : : Get ( ) . FindFilesRecursive ( OutFileNames , * OutDirectoryNames [ Idx ] , TEXT ( " * " ) , true , false , false ) ;
2014-05-14 19:11:30 -04:00
}
}
2015-04-20 14:30:09 -04:00
FString FDesktopPlatformBase : : GetEngineSavedConfigDirectory ( const FString & Identifier )
2014-06-04 18:06:57 -04:00
{
// Get the engine root directory
FString RootDir ;
2015-04-20 14:30:09 -04:00
if ( ! GetEngineRootDirFromIdentifier ( Identifier , RootDir ) )
2014-06-04 18:06:57 -04:00
{
2015-04-20 14:30:09 -04:00
return FString ( ) ;
2014-06-04 18:06:57 -04:00
}
// Get the path to the game agnostic settings
FString UserDir ;
2015-04-20 14:30:09 -04:00
if ( IsStockEngineRelease ( Identifier ) )
2014-06-04 18:06:57 -04:00
{
2015-06-12 12:01:23 -04:00
UserDir = FPaths : : Combine ( FPlatformProcess : : UserSettingsDir ( ) , * FApp : : GetEpicProductIdentifier ( ) , * Identifier ) ;
2014-06-04 18:06:57 -04:00
}
else
{
UserDir = FPaths : : Combine ( * RootDir , TEXT ( " Engine " ) ) ;
}
// Get the game agnostic config dir
2015-04-20 14:30:09 -04:00
return UserDir / TEXT ( " Saved/Config " ) / ANSI_TO_TCHAR ( FPlatformProperties : : PlatformName ( ) ) ;
}
bool FDesktopPlatformBase : : EnumerateProjectsKnownByEngine ( const FString & Identifier , bool bIncludeNativeProjects , TArray < FString > & OutProjectFileNames )
{
// Get the engine root directory
FString RootDir ;
if ( ! GetEngineRootDirFromIdentifier ( Identifier , RootDir ) )
{
return false ;
}
FString GameAgnosticConfigDir = GetEngineSavedConfigDirectory ( Identifier ) ;
if ( GameAgnosticConfigDir . Len ( ) = = 0 )
{
return false ;
}
2014-06-04 18:06:57 -04:00
// Find all the created project directories. Start with the default project creation path.
TArray < FString > SearchDirectories ;
SearchDirectories . AddUnique ( GetDefaultProjectCreationPath ( ) ) ;
// Load the config file
FConfigFile GameAgnosticConfig ;
2015-04-20 10:12:55 -04:00
FConfigCacheIni : : LoadExternalIniFile ( GameAgnosticConfig , TEXT ( " EditorSettings " ) , NULL , * GameAgnosticConfigDir , false ) ;
2014-06-04 18:06:57 -04:00
// Find the editor game-agnostic settings
2015-04-20 10:12:55 -04:00
FConfigSection * Section = GameAgnosticConfig . Find ( TEXT ( " /Script/UnrealEd.EditorSettings " ) ) ;
2015-06-19 09:54:12 -04:00
if ( Section = = NULL )
{
FConfigCacheIni : : LoadExternalIniFile ( GameAgnosticConfig , TEXT ( " EditorGameAgnostic " ) , NULL , * GameAgnosticConfigDir , false ) ;
Section = GameAgnosticConfig . Find ( TEXT ( " /Script/UnrealEd.EditorGameAgnosticSettings " ) ) ;
}
2014-06-04 18:06:57 -04:00
if ( Section ! = NULL )
{
// Add in every path that the user has ever created a project file. This is to catch new projects showing up in the user's project folders
TArray < FString > AdditionalDirectories ;
Section - > MultiFind ( TEXT ( " CreatedProjectPaths " ) , AdditionalDirectories ) ;
for ( int Idx = 0 ; Idx < AdditionalDirectories . Num ( ) ; Idx + + )
{
FPaths : : NormalizeDirectoryName ( AdditionalDirectories [ Idx ] ) ;
SearchDirectories . AddUnique ( AdditionalDirectories [ Idx ] ) ;
}
// Also add in all the recently opened projects
TArray < FString > RecentlyOpenedFiles ;
Section - > MultiFind ( TEXT ( " RecentlyOpenedProjectFiles " ) , RecentlyOpenedFiles ) ;
for ( int Idx = 0 ; Idx < RecentlyOpenedFiles . Num ( ) ; Idx + + )
{
FPaths : : NormalizeFilename ( RecentlyOpenedFiles [ Idx ] ) ;
OutProjectFileNames . AddUnique ( RecentlyOpenedFiles [ Idx ] ) ;
}
}
// Find all the other projects that are in the search directories
for ( int Idx = 0 ; Idx < SearchDirectories . Num ( ) ; Idx + + )
{
TArray < FString > ProjectFolders ;
IFileManager : : Get ( ) . FindFiles ( ProjectFolders , * ( SearchDirectories [ Idx ] / TEXT ( " * " ) ) , false , true ) ;
for ( int32 FolderIdx = 0 ; FolderIdx < ProjectFolders . Num ( ) ; FolderIdx + + )
{
TArray < FString > ProjectFiles ;
2014-06-05 16:39:57 -04:00
IFileManager : : Get ( ) . FindFiles ( ProjectFiles , * ( SearchDirectories [ Idx ] / ProjectFolders [ FolderIdx ] / TEXT ( " *.uproject " ) ) , true , false ) ;
2014-06-04 18:06:57 -04:00
for ( int32 FileIdx = 0 ; FileIdx < ProjectFiles . Num ( ) ; FileIdx + + )
{
2014-06-05 16:39:57 -04:00
OutProjectFileNames . AddUnique ( SearchDirectories [ Idx ] / ProjectFolders [ FolderIdx ] / ProjectFiles [ FileIdx ] ) ;
2014-06-04 18:06:57 -04:00
}
}
}
// Find all the native projects, and either add or remove them from the list depending on whether we want native projects
const FUProjectDictionary & Dictionary = GetCachedProjectDictionary ( RootDir ) ;
if ( bIncludeNativeProjects )
{
TArray < FString > NativeProjectPaths = Dictionary . GetProjectPaths ( ) ;
for ( int Idx = 0 ; Idx < NativeProjectPaths . Num ( ) ; Idx + + )
{
if ( ! NativeProjectPaths [ Idx ] . Contains ( TEXT ( " /Templates/ " ) ) )
{
OutProjectFileNames . AddUnique ( NativeProjectPaths [ Idx ] ) ;
}
}
}
else
{
TArray < FString > NativeProjectPaths = Dictionary . GetProjectPaths ( ) ;
for ( int Idx = 0 ; Idx < NativeProjectPaths . Num ( ) ; Idx + + )
{
OutProjectFileNames . Remove ( NativeProjectPaths [ Idx ] ) ;
}
}
return true ;
}
2015-01-29 16:15:16 -05:00
bool FDesktopPlatformBase : : BuildUnrealBuildTool ( const FString & RootDir , FOutputDevice & Ar )
2014-09-05 13:31:22 -04:00
{
2015-01-29 16:15:16 -05:00
Ar . Logf ( TEXT ( " Building UnrealBuildTool in %s... " ) , * RootDir ) ;
2014-09-05 13:31:22 -04:00
2015-01-29 16:15:16 -05:00
// Check the project file exists
FString CsProjLocation = GetUnrealBuildToolProjectFileName ( RootDir ) ;
if ( ! FPaths : : FileExists ( CsProjLocation ) )
{
Ar . Logf ( TEXT ( " Project file not found at %s " ) , * CsProjLocation ) ;
return false ;
}
2014-09-05 13:31:22 -04:00
FString CompilerExecutableFilename ;
FString CmdLineParams ;
2015-03-17 18:47:43 -04:00
if ( PLATFORM_WINDOWS )
2014-09-05 13:31:22 -04:00
{
2015-03-17 18:47:43 -04:00
// To build UBT for windows, we must assemble a batch file that first registers the environment variable necessary to run msbuild then run it
// This can not be done in a single invocation of CMD.exe because the environment variables do not transfer between subsequent commands when using the "&" syntax
// devenv.exe can be used to build as well but it takes several seconds to start up so it is not desirable
// First determine the appropriate vcvars batch file to launch
FString VCVarsBat ;
# if PLATFORM_WINDOWS
2015-12-10 16:56:55 -05:00
# if _MSC_VER >= 1900
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3125471)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3105904 on 2016/08/30 by Ben.Marsh
PR #2691: Copy .map-file to staging & cleanup (Contributed by projectgheist)
Change 3105974 on 2016/08/30 by Ben.Marsh
PR #2748: [Bug-Fix] UGS - Ensure older events do not trample newer ones (Contributed by paulevans)
Change 3106035 on 2016/08/30 by Ben.Marsh
PR #2746: [Bug-Fix] UGS - Starting build colour was the same as disabled (Contributed by paulevans)
Change 3106172 on 2016/08/30 by Ben.Marsh
UAT: Do not default to submitting build products from BuildCookRun unless -submit is explicitly specified on the command line.
#codreview Maciej.Mroz
Change 3107642 on 2016/08/31 by Matthew.Griffin
More Monolithic editor fixes
Fixed IMPLEMENT_MODULE macros with incorrect module name
Wrapped some usages of GIsHotReload in WITH_HOT_RELOAD
Fixed NiagaraConstants so that they can be used in multiple modules
Change 3107808 on 2016/08/31 by Matthew.Griffin
Added Node to Compile UAT on Mac to catch any Mono failures which will run as part of monolithics aggregate
Change 3111527 on 2016/09/02 by Matthew.Griffin
Duplicating CL#3111524 from Release-4.13 stream
Including Documentation/Extras in installed build
Change 3117683 on 2016/09/08 by Ben.Marsh
PR #2771: Fix compilation of C# projects on case-sensitive OSes (Contributed by slonopotamus)
Change 3119707 on 2016/09/09 by Ben.Marsh
UBT: Add more explicit methods for querying Visual C++ and Visual Studio installation directories. Now uses the same logic in the Visual Studio batch files.
Change 3120824 on 2016/09/12 by Ben.Marsh
UnrealGameSync: Add a project-wide option which can disable using the last code changelist for version files, and use the sync changelist instead. ("VersionToLastCodeChange" in the "[Options]" section). Update version to 1.80.
Change 3120996 on 2016/09/12 by Ben.Marsh
Core: Fix lines of output text from FMonitoredProcess being truncated at 512 characters, due to pipe buffer size. Accumulate incomplete lines and merge them together again instead. Also remove CR-LF pairs if they occur at the end of a line.
#jira UE-35659
Change 3121353 on 2016/09/12 by Ben.Marsh
Core: Manually enumerate and load dependent DLLs for modules by the editor, to work around limitations in the number of search paths checked by the Windows loader. We previously temporarily modified the PATH environment variable to provide this functionality, but are close to the OS limit for length of that string. This method should not have any such restrictions (though it will not work for circular dependencies).
Change 3121996 on 2016/09/12 by Ben.Marsh
Add support for Visual Studio 2017 (aka "15"; assuming consistent naming with other versions until final name is announced).
* Compiler, STL implementation and CRT are binary compatible with VS2015 (see https://blogs.msdn.microsoft.com/vcblog/2016/08/24/c1417-features-and-stl-fixes-in-vs-15-preview-4/), so no new third-party libraries needed so far. WindowsPlatform.GetVisualStudioCompilerVersionName() returns "2015" as a result.
* Default compiler for compiling and generating project files is still VS 2015 for now. Pass -2017 on the command line to GenerateProjectFiles.bat to generate VS2017 projects. Projects generated for VS2017 will use the 2017 compiler by default.
* Visual Studio source code accessor can talk to VS 2017 instances.
* Added a VS2017 configuration for UnrealVS, and added precompiled vsix package.
* Switched GetVSComnTools to check the SOFTWARE\Microsoft\VisualStudio\SxS\VS7 registry key rather than the individual product install registry key. "15" doesn't seem to have it's own "InstallDir" key, but this system seems to work for all versions of Visual Studio (including previous releases of VS Express).
* Removed ATL dependency from VisualStudioSourceCodeAccessor. It's not installed with VS by default any more, and is only used for a couple of smart pointer classes.
Tested running the editor and packaging TP_Flying for Win64. Packaging from the editor still defaults to using the 2015 compiler, so ConfigureToolchain() needs to be overriden from the .target.cs file if multiple Visual Studio versions are installed.
Change 3123144 on 2016/09/13 by Ben.Marsh
BuildGraph: Fix exception due to mismatched argument lists.
Change 3123160 on 2016/09/13 by Ben.Marsh
Linux: Make PLATFORM_SUPPORTS_JEMALLOC a globally defined macro rather than just defined by the jemalloc module. Core supplies a default value for this macro which is inconsistent unless your module has an explicit dependency on jemalloc.
Change 3123211 on 2016/09/13 by Ben.Marsh
UBT: Fix exception writing a version manifest if the output directory does not exist.
Change 3125300 on 2016/09/14 by Ben.Marsh
UnrealVS: Few fixes to single-file compile command.
* All documents are now saved before compile starts.
* Now gives a useful error when trying to compile non-cpp files, rather than falling back to the invalid default command handler.
* Trying to do a single-file compile while an existing build is running now prompts to stop it, rather than falling back to the default command handler (which gives a "Invalid command" message for makefile projects)
Change 3125437 on 2016/09/14 by Ben.Marsh
UnrealVS: Update version number to 1.43 in order to prevent installer from bailing unless existing version is uninstalled first.
[CL 3126342 by Ben Marsh in Main branch]
2016-09-15 08:33:13 -04:00
# if _MSC_FULL_VER >= 190024406
FPlatformMisc : : GetVSComnTools ( 15 , VCVarsBat ) ;
# else
FPlatformMisc : : GetVSComnTools ( 14 , VCVarsBat ) ;
# endif
2016-03-10 04:38:13 -05:00
# elif _MSC_VER >= 1800
FPlatformMisc : : GetVSComnTools ( 12 , VCVarsBat ) ;
2015-03-17 18:47:43 -04:00
# else
2016-03-07 20:55:29 -05:00
# error "Unsupported Visual Studio version."
2015-03-17 18:47:43 -04:00
# endif
# endif // PLATFORM_WINDOWS
VCVarsBat = FPaths : : Combine ( * VCVarsBat , L " ../../VC/bin/x86_amd64/vcvarsx86_amd64.bat " ) ;
// Check to make sure we found one.
if ( VCVarsBat . IsEmpty ( ) | | ! FPaths : : FileExists ( VCVarsBat ) )
{
Ar . Logf ( TEXT ( " Couldn't find %s; skipping. " ) , * VCVarsBat ) ;
return false ;
}
// Now make a batch file in the intermediate directory to invoke the vcvars batch then msbuild
FString BuildBatchFile = RootDir / TEXT ( " Engine/Intermediate/Build/UnrealBuildTool/BuildUBT.bat " ) ;
BuildBatchFile . ReplaceInline ( TEXT ( " / " ) , TEXT ( " \\ " ) ) ;
FString BatchFileContents ;
BatchFileContents = FString : : Printf ( TEXT ( " call \" %s \" " ) LINE_TERMINATOR , * VCVarsBat ) ;
BatchFileContents + = FString : : Printf ( TEXT ( " msbuild /nologo /verbosity:quiet \" %s \" /property:Configuration=Development /property:Platform=AnyCPU " ) , * CsProjLocation ) ;
FFileHelper : : SaveStringToFile ( BatchFileContents , * BuildBatchFile ) ;
TCHAR CmdExePath [ MAX_PATH ] ;
FPlatformMisc : : GetEnvironmentVariable ( TEXT ( " ComSpec " ) , CmdExePath , ARRAY_COUNT ( CmdExePath ) ) ;
CompilerExecutableFilename = CmdExePath ;
CmdLineParams = FString : : Printf ( TEXT ( " /c \" %s \" " ) , * BuildBatchFile ) ;
}
else if ( PLATFORM_MAC )
{
FString ScriptPath = FPaths : : ConvertRelativePathToFull ( RootDir / TEXT ( " Engine/Build/BatchFiles/Mac/RunXBuild.sh " ) ) ;
CompilerExecutableFilename = TEXT ( " /bin/sh " ) ;
CmdLineParams = FString : : Printf ( TEXT ( " \" %s \" /property:Configuration=Development %s " ) , * ScriptPath , * CsProjLocation ) ;
}
else if ( PLATFORM_LINUX )
{
FString ScriptPath = FPaths : : ConvertRelativePathToFull ( RootDir / TEXT ( " Engine/Build/BatchFiles/Linux/RunXBuild.sh " ) ) ;
CompilerExecutableFilename = TEXT ( " /bin/bash " ) ;
CmdLineParams = FString : : Printf ( TEXT ( " \" %s \" /property:Configuration=Development /property:TargetFrameworkVersion=v4.0 %s " ) , * ScriptPath , * CsProjLocation ) ;
}
else
{
Ar . Log ( TEXT ( " Unknown platform, unable to build UnrealBuildTool. " ) ) ;
2015-01-29 16:15:16 -05:00
return false ;
2014-09-05 13:31:22 -04:00
}
2015-01-29 16:15:16 -05:00
// Spawn the compiler
Ar . Logf ( TEXT ( " Running: %s %s " ) , * CompilerExecutableFilename , * CmdLineParams ) ;
2014-09-11 16:10:11 -04:00
const bool bLaunchDetached = false ;
const bool bLaunchHidden = true ;
const bool bLaunchReallyHidden = bLaunchHidden ;
FProcHandle ProcHandle = FPlatformProcess : : CreateProc ( * CompilerExecutableFilename , * CmdLineParams , bLaunchDetached , bLaunchHidden , bLaunchReallyHidden , NULL , 0 , NULL , NULL ) ;
2015-01-29 16:15:16 -05:00
if ( ! ProcHandle . IsValid ( ) )
2014-09-11 16:10:11 -04:00
{
2015-01-29 16:15:16 -05:00
Ar . Log ( TEXT ( " Failed to start process. " ) ) ;
return false ;
2014-09-11 16:10:11 -04:00
}
2015-01-29 16:15:16 -05:00
FPlatformProcess : : WaitForProc ( ProcHandle ) ;
2015-03-12 00:06:15 -04:00
FPlatformProcess : : CloseProc ( ProcHandle ) ;
2014-09-11 16:10:11 -04:00
// If the executable appeared where we expect it, then we were successful
2015-01-29 16:15:16 -05:00
FString UnrealBuildToolExePath = GetUnrealBuildToolExecutableFilename ( RootDir ) ;
if ( ! FPaths : : FileExists ( UnrealBuildToolExePath ) )
{
Ar . Logf ( TEXT ( " Missing %s after build " ) , * UnrealBuildToolExePath ) ;
return false ;
}
return true ;
}
FString FDesktopPlatformBase : : GetUnrealBuildToolProjectFileName ( const FString & RootDir ) const
{
return FPaths : : ConvertRelativePathToFull ( RootDir / TEXT ( " Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.csproj " ) ) ;
}
FString FDesktopPlatformBase : : GetUnrealBuildToolExecutableFilename ( const FString & RootDir ) const
{
return FPaths : : ConvertRelativePathToFull ( RootDir / TEXT ( " Engine/Binaries/DotNET/UnrealBuildTool.exe " ) ) ;
2014-09-05 13:31:22 -04:00
}
2014-05-13 18:23:53 -04:00
# undef LOCTEXT_NAMESPACE