2016-12-08 08:52:44 -05:00
|
|
|
|
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
2016-01-11 10:12:46 -05:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Xml;
|
|
|
|
|
|
|
|
|
|
|
|
namespace AutomationTool
|
|
|
|
|
|
{
|
|
|
|
|
|
static class ParallelExecutor
|
|
|
|
|
|
{
|
|
|
|
|
|
[DebuggerDisplay("{Caption}")]
|
|
|
|
|
|
class BuildAction
|
|
|
|
|
|
{
|
|
|
|
|
|
public int SortIndex = -1;
|
|
|
|
|
|
|
|
|
|
|
|
public string Caption;
|
|
|
|
|
|
public string GroupPrefix;
|
|
|
|
|
|
public string OutputPrefix;
|
|
|
|
|
|
public string ToolPath;
|
|
|
|
|
|
public string ToolArguments;
|
|
|
|
|
|
public string WorkingDirectory;
|
|
|
|
|
|
public bool bSkipIfProjectFailed;
|
|
|
|
|
|
|
|
|
|
|
|
public List<BuildAction> Dependants = new List<BuildAction>();
|
|
|
|
|
|
public List<BuildAction> Dependencies = new List<BuildAction>();
|
|
|
|
|
|
|
|
|
|
|
|
public int TotalDependants;
|
|
|
|
|
|
public int MissingDependencyCount;
|
|
|
|
|
|
|
|
|
|
|
|
public IReadOnlyDictionary<string, string> Environment;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class BuildActionExecutor
|
|
|
|
|
|
{
|
|
|
|
|
|
public BuildAction Action;
|
|
|
|
|
|
public List<string> LogLines = new List<string>();
|
|
|
|
|
|
public int ExitCode = -1;
|
|
|
|
|
|
|
|
|
|
|
|
private ManualResetEvent CompletedEvent;
|
|
|
|
|
|
private List<BuildActionExecutor> CompletedActions;
|
|
|
|
|
|
|
|
|
|
|
|
public BuildActionExecutor(BuildAction InAction, ManualResetEvent InCompletedEvent, List<BuildActionExecutor> InCompletedActions)
|
|
|
|
|
|
{
|
|
|
|
|
|
Action = InAction;
|
|
|
|
|
|
CompletedEvent = InCompletedEvent;
|
|
|
|
|
|
CompletedActions = InCompletedActions;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Run()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!String.IsNullOrEmpty(Action.OutputPrefix))
|
|
|
|
|
|
{
|
|
|
|
|
|
LogLines.Add(Action.OutputPrefix);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
using(ManagedProcess Process = new ManagedProcess(Action.ToolPath, Action.ToolArguments, Action.WorkingDirectory, Action.Environment, null, ManagedProcessPriority.BelowNormal))
|
|
|
|
|
|
{
|
|
|
|
|
|
LogLines.AddRange(Process.ReadAllLines());
|
|
|
|
|
|
ExitCode = Process.ExitCode;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lock(CompletedActions)
|
|
|
|
|
|
{
|
|
|
|
|
|
CompletedActions.Add(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CompletedEvent.Set();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3209340 on 2016/11/23 by Ben.Marsh
Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h.
Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms.
* Every header now includes everything it needs to compile.
* There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first.
* There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h.
* Every .cpp file includes its matching .h file first.
* This helps validate that each header is including everything it needs to compile.
* No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more.
* You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there.
* There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible.
* No engine code explicitly includes a precompiled header any more.
* We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies.
* PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files.
Tool used to generate this transform is at Engine\Source\Programs\IncludeTool.
[CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
|
|
|
|
public static int Execute(string ActionsFileName, bool bStopOnErrors)
|
2016-01-11 10:12:46 -05:00
|
|
|
|
{
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3209340 on 2016/11/23 by Ben.Marsh
Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h.
Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms.
* Every header now includes everything it needs to compile.
* There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first.
* There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h.
* Every .cpp file includes its matching .h file first.
* This helps validate that each header is including everything it needs to compile.
* No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more.
* You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there.
* There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible.
* No engine code explicitly includes a precompiled header any more.
* We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies.
* PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files.
Tool used to generate this transform is at Engine\Source\Programs\IncludeTool.
[CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
|
|
|
|
return Execute(ActionsFileName, Environment.ProcessorCount, bStopOnErrors);
|
2016-01-11 10:12:46 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3209340 on 2016/11/23 by Ben.Marsh
Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h.
Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms.
* Every header now includes everything it needs to compile.
* There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first.
* There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h.
* Every .cpp file includes its matching .h file first.
* This helps validate that each header is including everything it needs to compile.
* No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more.
* You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there.
* There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible.
* No engine code explicitly includes a precompiled header any more.
* We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies.
* PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files.
Tool used to generate this transform is at Engine\Source\Programs\IncludeTool.
[CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
|
|
|
|
public static int Execute(string ActionsFileName, int MaxProcesses, bool bStopOnErrors)
|
2016-01-11 10:12:46 -05:00
|
|
|
|
{
|
|
|
|
|
|
List<BuildAction> Actions = ReadActions(ActionsFileName);
|
|
|
|
|
|
|
|
|
|
|
|
CommandUtils.Log("Building with {0} {1}...", MaxProcesses, (MaxProcesses == 1)? "process" : "processes");
|
|
|
|
|
|
|
|
|
|
|
|
// Create the list of things to process
|
|
|
|
|
|
List<BuildAction> QueuedActions = new List<BuildAction>();
|
|
|
|
|
|
foreach(BuildAction Action in Actions)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(Action.MissingDependencyCount == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
QueuedActions.Add(Action);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Create a job object for all the child processes
|
|
|
|
|
|
int ExitCode = 0;
|
|
|
|
|
|
string CurrentPrefix = "";
|
|
|
|
|
|
Dictionary<BuildActionExecutor, Thread> ExecutingActions = new Dictionary<BuildActionExecutor,Thread>();
|
|
|
|
|
|
List<BuildActionExecutor> CompletedActions = new List<BuildActionExecutor>();
|
|
|
|
|
|
|
|
|
|
|
|
using(ManualResetEvent CompletedEvent = new ManualResetEvent(false))
|
|
|
|
|
|
{
|
|
|
|
|
|
while(QueuedActions.Count > 0 || ExecutingActions.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Sort the actions by the number of things dependent on them
|
|
|
|
|
|
QueuedActions.Sort((A, B) => (A.TotalDependants == B.TotalDependants)? (B.SortIndex - A.SortIndex) : (B.TotalDependants - A.TotalDependants));
|
|
|
|
|
|
|
|
|
|
|
|
// Create threads up to the maximum number of actions
|
|
|
|
|
|
while(ExecutingActions.Count < MaxProcesses && QueuedActions.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
BuildAction Action = QueuedActions[QueuedActions.Count - 1];
|
|
|
|
|
|
QueuedActions.RemoveAt(QueuedActions.Count - 1);
|
|
|
|
|
|
|
|
|
|
|
|
BuildActionExecutor ExecutingAction = new BuildActionExecutor(Action, CompletedEvent, CompletedActions);
|
|
|
|
|
|
|
|
|
|
|
|
Thread ExecutingThread = new Thread(() => { ExecutingAction.Run(); });
|
|
|
|
|
|
ExecutingThread.Name = String.Format("Build:{0}", Action.Caption);
|
|
|
|
|
|
ExecutingThread.Start();
|
|
|
|
|
|
|
|
|
|
|
|
ExecutingActions.Add(ExecutingAction, ExecutingThread);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for something to finish
|
|
|
|
|
|
CompletedEvent.WaitOne();
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for something to finish and flush it to the log
|
|
|
|
|
|
lock(CompletedActions)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach(BuildActionExecutor CompletedAction in CompletedActions)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Join the thread
|
|
|
|
|
|
Thread CompletedThread = ExecutingActions[CompletedAction];
|
|
|
|
|
|
CompletedThread.Join();
|
|
|
|
|
|
ExecutingActions.Remove(CompletedAction);
|
|
|
|
|
|
|
|
|
|
|
|
// Write it to the log
|
|
|
|
|
|
if(CompletedAction.LogLines.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(CurrentPrefix != CompletedAction.Action.GroupPrefix)
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentPrefix = CompletedAction.Action.GroupPrefix;
|
|
|
|
|
|
CommandUtils.Log(CurrentPrefix);
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach(string LogLine in CompletedAction.LogLines)
|
|
|
|
|
|
{
|
|
|
|
|
|
CommandUtils.Log(LogLine);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Check the exit code
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
if(CompletedAction.ExitCode == 0)
|
2016-01-11 10:12:46 -05:00
|
|
|
|
{
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
// Mark all the dependents as done
|
|
|
|
|
|
foreach(BuildAction DependantAction in CompletedAction.Action.Dependants)
|
2016-01-11 10:12:46 -05:00
|
|
|
|
{
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
if(--DependantAction.MissingDependencyCount == 0)
|
2016-01-11 10:12:46 -05:00
|
|
|
|
{
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
QueuedActions.Add(DependantAction);
|
2016-01-11 10:12:46 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
else
|
2016-01-11 10:12:46 -05:00
|
|
|
|
{
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
// Update the exit code if it's not already set
|
|
|
|
|
|
if(ExitCode == 0)
|
2016-01-11 10:12:46 -05:00
|
|
|
|
{
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
ExitCode = CompletedAction.ExitCode;
|
2016-01-11 10:12:46 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
CompletedActions.Clear();
|
|
|
|
|
|
}
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
|
|
|
|
|
|
// If we've already got a non-zero exit code, clear out the list of queued actions so nothing else will run
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3209340 on 2016/11/23 by Ben.Marsh
Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h.
Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms.
* Every header now includes everything it needs to compile.
* There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first.
* There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h.
* Every .cpp file includes its matching .h file first.
* This helps validate that each header is including everything it needs to compile.
* No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more.
* You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there.
* There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible.
* No engine code explicitly includes a precompiled header any more.
* We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies.
* PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files.
Tool used to generate this transform is at Engine\Source\Programs\IncludeTool.
[CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
|
|
|
|
if(ExitCode != 0 && bStopOnErrors)
|
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3075869)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3059740 on 2016/07/21 by Ben.Marsh
Format license violations on separate lines rather than as a single multi-line string, so they can be parsed out correctly by the EC log parser.
Change 3063115 on 2016/07/25 by Ben.Marsh
Add missing projects to Mono AutomationTool solution.
Change 3067125 on 2016/07/27 by Ben.Marsh
Clean up and document the engine versioning system.
* Version.h has a summary of all the different versioning concepts in UE4, as well as an explanation of what all the macros do.
* VersionLocked.h has been removed. ENGINE_NET_VERSION and ENGINE_REPLAY_VERSION can be overriden directly in Version.h if necessary.
* Added explicit macros for ENGINE_CURRENT_CL_VERSION And ENGINE_COMPATIBLE_CL_VERSION. The MODULE_API_VERSION macro is now defined to be the same as ENGINE_COMPATIBLE_CL_VERSION.
* Build/Build.version now includes the compatible CL version, so it can be determined without having to parse header files inside MacToolChain.cs.
* UpdateLocalVersion UAT command now exposes a -CompatibleCL=... argument to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* SetVersion BuildGraph task now has a CompatibleChange="" attribute to update ENGINE_COMPATIBLE_CL_VERSION and the CompatibleChange property in Build.version.
* VersionFileUpdater now makes an effort to parse tokens matching the macros it's going to overwrite, rather than requiring exact matches in whitespace in Version.h.
* Running UpdateLocalVersion now syncs files to revision 0 before writing if P4 is enabled, similarly to UGS, or fails if they are not writable.
Change 3067242 on 2016/07/27 by Ben.Marsh
Fix UGS showing a build failure/warning dialog immediately if you submit while the build is yellow/red. Now ignores builds before your last submitted CL.
Change 3068116 on 2016/07/28 by Ben.Marsh
Add a small Windows utility to terminate all running processes under a given root directory, and run it before and after every sync. Mean to fix instances where zombie editor processes do not terminate correctly and cause subsequent syncs to fail.
Change 3068246 on 2016/07/28 by Ben.Marsh
UGS: Improvements to 'Clean Workspace' dialog - empty folders are now set to be deleted by default, and added a context menu to select all/none/empty/default for a subtree, as well as to open Windows explorer at that location.
Change 3068573 on 2016/07/28 by Ben.Marsh
Attempt to fix AppDomain unload errors; suspect caused by delay to terminate child processes when managed exception is thrown on child threads. Now waits for the currently running threads to finish executing before quitting.
Change 3068575 on 2016/07/28 by Ben.Marsh
Respect the -noxge command-line argument when compiling UHT.
Change 3068665 on 2016/07/28 by Ben.Marsh
Delete any DLLs in output folders which share names with build products. The Windows loader reads DLLs from the first location it finds a file with a matching name, so we need to ensure that it doesn't load stale DLLs when output directories are changed (moving a module into a plugin, for example).
Change 3073316 on 2016/08/02 by Ben.Marsh
CoreUObject: Replace header guards with #pragma once directives.
Change 3073325 on 2016/08/02 by Ben.Marsh
CoreUObject: Manually untangle a few circular includes around ObjectBase.h and Class.h to allow making them into IWYU-style headers.
Change 3074391 on 2016/08/02 by Ben.Marsh
GitHub #2646: Always allow programs to build as part of non-game solution configurations.
Change 3075123 on 2016/08/03 by Richard.Fawcett
Ensure that zip files created outside of Ionic Zip can be unzipped with CommandUtils.UnzipFiles
Zip files created with 7-zip, WinRAR, and Windows Explorer all contain entities for directories, not just the files in them. Code in CommandUtils.UnzipFiles made the assumption that all entities in the zip file were files, and an exception was being thrown on encountering a directory.
Change 3075848 on 2016/08/03 by Ben.Marsh
UBT: Fix a few cases where it's possible to construct a non-canonical DirectoryReference - root directories on Windows must always have a terminating slash, but any other directories must note. DirectoryInfo and Path.GetFullPath() do not enforce this requirement.
Change 3075850 on 2016/08/03 by Ben.Marsh
UBT: Fix UHT failures when running with -nopch.
Change 3077058 by Ben.Marsh
UHT: Remove the auto-generated ObjectBase.h include from generated header files. Was originally added to allow doxygen to parse headers more easily, but was switched to parsing the file only as part of parent files instead.
[CL 3077308 by Ben Marsh in Main branch]
2016-08-04 10:41:07 -04:00
|
|
|
|
{
|
|
|
|
|
|
QueuedActions.Clear();
|
|
|
|
|
|
}
|
2016-01-11 10:12:46 -05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return ExitCode;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static List<BuildAction> ReadActions(string InputPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
XmlDocument File = new XmlDocument();
|
|
|
|
|
|
File.Load(InputPath);
|
|
|
|
|
|
|
|
|
|
|
|
XmlNode RootNode = File.FirstChild;
|
|
|
|
|
|
if(RootNode == null || RootNode.Name != "BuildSet")
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("Incorrect node at root of graph; expected 'BuildSet'");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
XmlNode EnvironmentsNode = RootNode.SelectSingleNode("Environments");
|
|
|
|
|
|
if(EnvironmentsNode == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("Missing Environments node under root in XML document");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get the current environment variables
|
|
|
|
|
|
Dictionary<string, string> CurrentEnvironment = new Dictionary<string,string>(StringComparer.InvariantCultureIgnoreCase);
|
|
|
|
|
|
foreach(System.Collections.DictionaryEntry Entry in Environment.GetEnvironmentVariables())
|
|
|
|
|
|
{
|
|
|
|
|
|
CurrentEnvironment[Entry.Key.ToString()] = Entry.Value.ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Read the tool environment
|
|
|
|
|
|
Dictionary<string, XmlNode> NameToTool = new Dictionary<string,XmlNode>();
|
|
|
|
|
|
Dictionary<string, IReadOnlyDictionary<string, string>> NameToEnvironment = new Dictionary<string,IReadOnlyDictionary<string, string>>();
|
|
|
|
|
|
for(XmlNode EnvironmentNode = EnvironmentsNode.FirstChild; EnvironmentNode != null; EnvironmentNode = EnvironmentNode.NextSibling)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(EnvironmentNode.Name == "Environment")
|
|
|
|
|
|
{
|
|
|
|
|
|
// Read the tools nodes
|
|
|
|
|
|
XmlNode ToolsNode = EnvironmentNode.SelectSingleNode("Tools");
|
|
|
|
|
|
if(ToolsNode != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(XmlNode ToolNode = ToolsNode.FirstChild; ToolNode != null; ToolNode = ToolNode.NextSibling)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(ToolNode.Name == "Tool")
|
|
|
|
|
|
{
|
|
|
|
|
|
XmlNode Name = ToolNode.Attributes.GetNamedItem("Name");
|
|
|
|
|
|
if(Name != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
NameToTool.Add(Name.Value, ToolNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Read the environment variables for this environment. Each environment has its own set of variables
|
|
|
|
|
|
XmlNode VariablesNode = EnvironmentNode.SelectSingleNode("Variables");
|
|
|
|
|
|
if(VariablesNode != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
XmlNode Name = EnvironmentNode.Attributes.GetNamedItem("Name");
|
|
|
|
|
|
if(Name != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Dictionary<string, string> NamedEnvironment = new Dictionary<string,string>(CurrentEnvironment, StringComparer.InvariantCultureIgnoreCase);
|
|
|
|
|
|
for (XmlNode VariableNode = VariablesNode.FirstChild; VariableNode != null; VariableNode = VariableNode.NextSibling)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (VariableNode.Name == "Variable")
|
|
|
|
|
|
{
|
|
|
|
|
|
XmlNode VariableName = VariableNode.Attributes.GetNamedItem("Name");
|
|
|
|
|
|
if(VariableName != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
NamedEnvironment[VariableName.Value] = VariableNode.Attributes.GetNamedItem("Value").Value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
NameToEnvironment[Name.Value] = NamedEnvironment;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Read all the tasks for each project, and convert them into actions
|
|
|
|
|
|
List<BuildAction> Actions = new List<BuildAction>();
|
|
|
|
|
|
for(XmlNode ProjectNode = RootNode.FirstChild; ProjectNode != null; ProjectNode = ProjectNode.NextSibling)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(ProjectNode.Name == "Project")
|
|
|
|
|
|
{
|
|
|
|
|
|
int SortIndex = 0;
|
|
|
|
|
|
Dictionary<string, BuildAction> NameToAction = new Dictionary<string,BuildAction>();
|
|
|
|
|
|
for(XmlNode TaskNode = ProjectNode.FirstChild; TaskNode != null; TaskNode = TaskNode.NextSibling)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(TaskNode.Name == "Task")
|
|
|
|
|
|
{
|
|
|
|
|
|
XmlNode ToolNode;
|
|
|
|
|
|
if(NameToTool.TryGetValue(TaskNode.Attributes.GetNamedItem("Tool").Value, out ToolNode))
|
|
|
|
|
|
{
|
|
|
|
|
|
BuildAction Action = FindOrAddAction(NameToAction, TaskNode.Attributes.GetNamedItem("Name").Value, Actions);
|
|
|
|
|
|
Action.SortIndex = ++SortIndex;
|
|
|
|
|
|
TryGetAttribute(TaskNode, "Caption", out Action.Caption);
|
|
|
|
|
|
|
|
|
|
|
|
TryGetAttribute(ToolNode, "GroupPrefix", out Action.GroupPrefix);
|
|
|
|
|
|
TryGetAttribute(ToolNode, "OutputPrefix", out Action.OutputPrefix);
|
|
|
|
|
|
TryGetAttribute(ToolNode, "Path", out Action.ToolPath);
|
|
|
|
|
|
TryGetAttribute(ToolNode, "WorkingDir", out Action.WorkingDirectory);
|
|
|
|
|
|
|
|
|
|
|
|
string EnvironmentName;
|
|
|
|
|
|
if(!TryGetAttribute(ProjectNode, "Env", out EnvironmentName))
|
|
|
|
|
|
{
|
|
|
|
|
|
Action.Environment = CurrentEnvironment;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(!NameToEnvironment.TryGetValue(EnvironmentName, out Action.Environment))
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception(String.Format("Couldn't find environment '{0}'", EnvironmentName));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(TryGetAttribute(ToolNode, "Params", out Action.ToolArguments))
|
|
|
|
|
|
{
|
|
|
|
|
|
Action.ToolArguments = ExpandEnvironmentVariables(Action.ToolArguments, Action.Environment);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string SkipIfProjectFailed;
|
|
|
|
|
|
if(TryGetAttribute(TaskNode, "SkipIfProjectFailed", out SkipIfProjectFailed) && SkipIfProjectFailed == "True")
|
|
|
|
|
|
{
|
|
|
|
|
|
Action.bSkipIfProjectFailed = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string DependsOnList;
|
|
|
|
|
|
if(TryGetAttribute(TaskNode, "DependsOn", out DependsOnList))
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (string DependsOn in DependsOnList.Split(';'))
|
|
|
|
|
|
{
|
|
|
|
|
|
BuildAction DependsOnAction = FindOrAddAction(NameToAction, DependsOn, Actions);
|
|
|
|
|
|
if(!Action.Dependencies.Contains(DependsOnAction))
|
|
|
|
|
|
{
|
|
|
|
|
|
Action.Dependencies.Add(DependsOnAction);
|
|
|
|
|
|
}
|
|
|
|
|
|
if(!DependsOnAction.Dependants.Contains(Action))
|
|
|
|
|
|
{
|
|
|
|
|
|
DependsOnAction.Dependants.Add(Action);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HashSet<BuildAction> VisitedActions = new HashSet<BuildAction>();
|
|
|
|
|
|
RecursiveIncDependents(Action, VisitedActions);
|
|
|
|
|
|
|
|
|
|
|
|
Action.MissingDependencyCount = Action.Dependencies.Count;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure there have been no actions added which were referenced but never declared
|
|
|
|
|
|
foreach(KeyValuePair<string, BuildAction> Pair in NameToAction)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(Pair.Value.SortIndex == -1)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception(String.Format("Action {0} was referenced but never declared", Pair.Key));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return Actions;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool TryGetAttribute(XmlNode Node, string Name, out string Value)
|
|
|
|
|
|
{
|
|
|
|
|
|
XmlNode Attribute = Node.Attributes.GetNamedItem(Name);
|
|
|
|
|
|
if(Attribute == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Value = null;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Value = Attribute.Value;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static string ExpandEnvironmentVariables(string Input, IReadOnlyDictionary<string, string> Environment)
|
|
|
|
|
|
{
|
|
|
|
|
|
string Output = Input;
|
|
|
|
|
|
for(int StartIndex = 0;;)
|
|
|
|
|
|
{
|
|
|
|
|
|
int Index = Output.IndexOf("$(", StartIndex);
|
|
|
|
|
|
if(Index == -1) break;
|
|
|
|
|
|
|
|
|
|
|
|
int EndIndex = Output.IndexOf(")", Index);
|
|
|
|
|
|
if(EndIndex == -1) break;
|
|
|
|
|
|
|
|
|
|
|
|
string VariableName = Output.Substring(Index + 2, EndIndex - Index - 2);
|
|
|
|
|
|
|
|
|
|
|
|
string VariableValue;
|
|
|
|
|
|
if(Environment.TryGetValue(VariableName, out VariableValue))
|
|
|
|
|
|
{
|
|
|
|
|
|
Output = Output.Substring(0, Index) + VariableValue + Output.Substring(EndIndex + 1);
|
|
|
|
|
|
StartIndex = Index + VariableValue.Length;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
CommandUtils.LogWarning("Unknown environment variable '{0}' in script", VariableName);
|
|
|
|
|
|
StartIndex = EndIndex + 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return Output;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static BuildAction FindOrAddAction(Dictionary<string, BuildAction> NameToAction, string Name, List<BuildAction> Actions)
|
|
|
|
|
|
{
|
|
|
|
|
|
BuildAction Action;
|
|
|
|
|
|
if(!NameToAction.TryGetValue(Name, out Action))
|
|
|
|
|
|
{
|
|
|
|
|
|
Action = new BuildAction();
|
|
|
|
|
|
Actions.Add(Action);
|
|
|
|
|
|
NameToAction.Add(Name, Action);
|
|
|
|
|
|
}
|
|
|
|
|
|
return Action;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void RecursiveIncDependents(BuildAction Action, HashSet<BuildAction> VisitedActions)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach(BuildAction Dependency in Action.Dependencies)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(!VisitedActions.Contains(Action))
|
|
|
|
|
|
{
|
|
|
|
|
|
VisitedActions.Add(Action);
|
|
|
|
|
|
Dependency.TotalDependants++;
|
|
|
|
|
|
RecursiveIncDependents(Dependency, VisitedActions);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|