/// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="Arguments">Command-line arguments</param>
        /// <returns>One of the values of ECompilationResult</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            // Read the XML configuration files
            XmlConfig.ApplyTo(this);

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            Arguments.ApplyTo(BuildConfiguration);

            // Read the actions file
            List <Action> Actions;

            using (Timeline.ScopeEvent("ActionGraph.ReadActions()"))
            {
                Actions = ActionGraph.ImportJson(ActionsFile);
            }

            // Link the action graph
            using (Timeline.ScopeEvent("ActionGraph.Link()"))
            {
                ActionGraph.Link(Actions);
            }

            // Execute the actions
            using (Timeline.ScopeEvent("ActionGraph.ExecuteActions()"))
            {
                ActionGraph.ExecuteActions(BuildConfiguration, Actions);
            }

            return(0);
        }
Esempio n. 2
0
        /// <summary>
        /// Execute the mode
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns></returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            Arguments.ApplyTo(BuildConfiguration);

            // Ensure the path to the output file is valid
            if (OutputFile == null)
            {
                OutputFile = GetDefaultOutputFile(ProjectFile);
            }

            // Create the rules assembly
            RulesAssembly Assembly;

            if (ProjectFile == null)
            {
                Assembly = RulesCompiler.CreateEnterpriseRulesAssembly(BuildConfiguration.bUsePrecompiled, BuildConfiguration.bSkipRulesCompile);
            }
            else
            {
                Assembly = RulesCompiler.CreateProjectRulesAssembly(ProjectFile, BuildConfiguration.bUsePrecompiled, BuildConfiguration.bSkipRulesCompile);
            }

            // Write information about these targets
            WriteTargetInfo(ProjectFile, Assembly, OutputFile, Arguments);
            Log.TraceInformation("Written {0}", OutputFile);
            return(0);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        public HybridExecutor()
        {
            this.LocalExecutor  = new ParallelExecutor();
            this.RemoteExecutor = new XGE();

            XmlConfig.ApplyTo(this);

            if (MaxLocalActions == 0)
            {
                MaxLocalActions = Utils.GetPhysicalProcessorCount();
            }
        }
        /// <summary>
        /// Execute this command
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code (always zero)</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            List <TargetDescriptor> TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, false, false);

            foreach (TargetDescriptor TargetDescriptor in TargetDescriptors)
            {
                // Create the target
                UEBuildTarget Target = UEBuildTarget.Create(TargetDescriptor, false, false);

                // Get the output file
                FileReference OutputFile = TargetDescriptor.AdditionalArguments.GetFileReferenceOrDefault("-OutputFile=", null);
                if (OutputFile == null)
                {
                    OutputFile = Target.ReceiptFileName.ChangeExtension(".json");
                }

                // Execute code generation actions
                if (bExecCodeGenActions)
                {
                    using (ISourceFileWorkingSet WorkingSet = new EmptySourceFileWorkingSet())
                    {
                        // Create the build configuration object, and read the settings
                        BuildConfiguration BuildConfiguration = new BuildConfiguration();
                        XmlConfig.ApplyTo(BuildConfiguration);
                        Arguments.ApplyTo(BuildConfiguration);

                        // Create the makefile
                        const bool     bIsAssemblingBuild = true;
                        TargetMakefile Makefile           = Target.Build(BuildConfiguration, WorkingSet, bIsAssemblingBuild, TargetDescriptor.SingleFileToCompile);
                        ActionGraph.Link(Makefile.Actions);

                        // Filter all the actions to execute
                        HashSet <FileItem> PrerequisiteItems   = new HashSet <FileItem>(Makefile.Actions.SelectMany(x => x.ProducedItems).Where(x => x.HasExtension(".h") || x.HasExtension(".cpp")));
                        List <Action>      PrerequisiteActions = ActionGraph.GatherPrerequisiteActions(Makefile.Actions, PrerequisiteItems);

                        // Execute these actions
                        if (PrerequisiteActions.Count > 0)
                        {
                            Log.TraceInformation("Exeucting actions that produce source files...");
                            ActionGraph.ExecuteActions(BuildConfiguration, PrerequisiteActions);
                        }
                    }
                }

                // Write the output file
                Log.TraceInformation("Writing {0}...", OutputFile);
                Target.ExportJson(OutputFile);
            }
            return(0);
        }
Esempio n. 5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="MaxLocalActions">How many actions to execute in parallel. When 0 a default will be chosen based on system resources</param>
        public LocalExecutor(int MaxLocalActions = 0)
        {
            XmlConfig.ApplyTo(this);

            // if specified this caps how many processors we can use
            if (MaxLocalActions > 0)
            {
                NumParallelProcesses = MaxLocalActions;
            }
            else
            {
                // Figure out how many processors to use
                NumParallelProcesses = GetMaxActionsToExecuteInParallel();
            }
        }
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="MaxLocalActions">How many actions to execute in parallel</param>
		public ParallelExecutor(int MaxLocalActions)
		{
			XmlConfig.ApplyTo(this);

			// if specified this caps how many processors we can use
			if (MaxLocalActions > 0)
			{
				NumParallelProcesses = MaxLocalActions;
			}
			else
			{
				// Figure out how many processors to use
				NumParallelProcesses = Math.Min((int)(Environment.ProcessorCount * ProcessorCountMultiplier), MaxProcessorCount);
			}
		}
Esempio n. 7
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="InOnlyGameProject">The single project to generate project files for, or null</param>
        /// <param name="InProjectFileFormat">Override the project file format to use</param>
        /// <param name="InOverrideCompiler">Override the compiler version to use</param>
        public VCProjectFileGenerator(FileReference InOnlyGameProject, VCProjectFileFormat InProjectFileFormat, WindowsCompiler InOverrideCompiler)
            : base(InOnlyGameProject)
        {
            XmlConfig.ApplyTo(this);

            if (InProjectFileFormat != VCProjectFileFormat.Default)
            {
                ProjectFileFormat = InProjectFileFormat;
            }

            if (InOverrideCompiler == WindowsCompiler.VisualStudio2015)
            {
                BuildToolOverride = "-2015";
            }
            else if (InOverrideCompiler == WindowsCompiler.VisualStudio2017)
            {
                BuildToolOverride = "-2017";
            }
        }
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="InOnlyGameProject">The single project to generate project files for, or null</param>
        /// <param name="InProjectFileFormat">Override the project file format to use</param>
        /// <param name="InArguments">Additional command line arguments</param>
        public VCProjectFileGenerator(FileReference InOnlyGameProject, VCProjectFileFormat InProjectFileFormat, CommandLineArguments InArguments)
            : base(InOnlyGameProject)
        {
            XmlConfig.ApplyTo(this);

            if (InProjectFileFormat != VCProjectFileFormat.Default)
            {
                ProjectFileFormat = InProjectFileFormat;
            }

            if (InArguments.HasOption("-2015"))
            {
                BuildToolOverride = "-2015";
            }
            else if (InArguments.HasOption("-2017"))
            {
                BuildToolOverride = "-2017";
            }
            else if (InArguments.HasOption("-2019"))
            {
                BuildToolOverride = "-2019";
            }
        }
 public SNDBS()
 {
     XmlConfig.ApplyTo(this);
 }
Esempio n. 10
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="ProjectFile">Project to read settings from</param>
        public RemoteMac(FileReference ProjectFile)
        {
            this.RsyncExe         = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Rsync.exe");
            this.SshExe           = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Ssh.exe");
            this.ProjectFile      = ProjectFile;
            this.ProjectDirectory = DirectoryReference.FromFile(ProjectFile);

            // Apply settings from the XML file
            XmlConfig.ApplyTo(this);

            // Get the project config file path
            DirectoryReference EngineIniPath = ProjectFile != null ? ProjectFile.Directory : null;

            if (EngineIniPath == null && UnrealBuildTool.GetRemoteIniPath() != null)
            {
                EngineIniPath = new DirectoryReference(UnrealBuildTool.GetRemoteIniPath());
            }
            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, EngineIniPath, UnrealTargetPlatform.IOS);

            // Read the project settings if we don't have anything in the build configuration settings
            if (String.IsNullOrEmpty(ServerName))
            {
                // Read the server name
                string IniServerName;
                if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RemoteServerName", out IniServerName) && !String.IsNullOrEmpty(IniServerName))
                {
                    this.ServerName = IniServerName;
                }
                else
                {
                    throw new BuildException("Remote compiling requires a server name. Use the editor (Project Settings > IOS) to set up your remote compilation settings.");
                }

                // Parse the username
                string IniUserName;
                if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RSyncUsername", out IniUserName) && !String.IsNullOrEmpty(IniUserName))
                {
                    this.UserName = IniUserName;
                }
            }

            // Split port out from the server name
            int PortIdx = ServerName.LastIndexOf(':');

            if (PortIdx != -1)
            {
                string Port = ServerName.Substring(PortIdx + 1);
                if (!int.TryParse(Port, out ServerPort))
                {
                    throw new BuildException("Unable to parse port number from '{0}'", ServerName);
                }
                ServerName = ServerName.Substring(0, PortIdx);
            }

            // If a user name is not set, use the current user
            if (String.IsNullOrEmpty(UserName))
            {
                UserName = Environment.UserName;
            }

            // Print out the server info
            Log.TraceInformation("[Remote] Using remote server '{0}' on port {1} (user '{2}')", ServerName, ServerPort, UserName);

            // Get the path to the SSH private key
            string OverrideSshPrivateKeyPath;

            if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SSHPrivateKeyOverridePath", out OverrideSshPrivateKeyPath) && !String.IsNullOrEmpty(OverrideSshPrivateKeyPath))
            {
                SshPrivateKey = new FileReference(OverrideSshPrivateKeyPath);
                if (!FileReference.Exists(SshPrivateKey))
                {
                    throw new BuildException("SSH private key specified in config file ({0}) does not exist.", SshPrivateKey);
                }
            }

            // If it's not set, look in the standard locations. If that fails, spawn the batch file to generate one.
            if (SshPrivateKey == null && !TryGetSshPrivateKey(out SshPrivateKey))
            {
                Log.TraceWarning("No SSH private key found for {0}@{1}. Launching SSH to generate one.", UserName, ServerName);

                StringBuilder CommandLine = new StringBuilder();
                CommandLine.AppendFormat("/C \"\"{0}\"", FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "BatchFiles", "MakeAndInstallSSHKey.bat"));
                CommandLine.AppendFormat(" \"{0}\"", SshExe);
                CommandLine.AppendFormat(" \"{0}\"", ServerPort);
                CommandLine.AppendFormat(" \"{0}\"", RsyncExe);
                CommandLine.AppendFormat(" \"{0}\"", UserName);
                CommandLine.AppendFormat(" \"{0}\"", ServerName);
                CommandLine.AppendFormat(" \"{0}\"", DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments));
                CommandLine.AppendFormat(" \"{0}\"", GetLocalCygwinPath(DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments)));
                CommandLine.AppendFormat(" \"{0}\"", UnrealBuildTool.EngineDirectory);
                CommandLine.Append("\"");

                using (Process ChildProcess = Process.Start("C:\\Windows\\System32\\Cmd.exe", CommandLine.ToString()))
                {
                    ChildProcess.WaitForExit();
                }

                if (!TryGetSshPrivateKey(out SshPrivateKey))
                {
                    throw new BuildException("Failed to generate SSH private key for {0}@{1}.", UserName, ServerName);
                }
            }

            // resolve the rest of the strings
            RsyncAuthentication = ExpandVariables(RsyncAuthentication);
            SshAuthentication   = ExpandVariables(SshAuthentication);

            // Get the remote base directory
            RemoteBaseDir = String.Format("/Users/{0}/UE4/Builds/{1}", UserName, Environment.MachineName);

            // Build the list of directory mappings between the local and remote machines
            Mappings = new List <RemoteMapping>();
            Mappings.Add(new RemoteMapping(UnrealBuildTool.EngineDirectory, GetRemotePath(UnrealBuildTool.EngineDirectory)));
            if (ProjectFile != null && !ProjectFile.IsUnderDirectory(UnrealBuildTool.EngineDirectory))
            {
                Mappings.Add(new RemoteMapping(ProjectFile.Directory, GetRemotePath(ProjectFile.Directory)));
            }

            // Build a list of arguments for SSH
            CommonSshArguments = new List <string>();
            CommonSshArguments.Add("-o BatchMode=yes");
            CommonSshArguments.Add(SshAuthentication);
            CommonSshArguments.Add(String.Format("-p {0}", ServerPort));
            CommonSshArguments.Add(String.Format("\"{0}@{1}\"", UserName, ServerName));

            // Build a list of arguments for Rsync
            CommonRsyncArguments = new List <string>();
            CommonRsyncArguments.Add("--compress");
            CommonRsyncArguments.Add("--recursive");
            CommonRsyncArguments.Add("--delete");            // Delete anything not in the source directory
            CommonRsyncArguments.Add("--delete-excluded");   // Delete anything not in the source directory
            CommonRsyncArguments.Add("--times");             // Preserve modification times
            CommonRsyncArguments.Add("--verbose");
            CommonRsyncArguments.Add("-m");
            CommonRsyncArguments.Add("--chmod=ug=rwX,o=rxX");
            CommonRsyncArguments.Add(String.Format("--rsh=\"{0} -p {1}\"", RsyncAuthentication, ServerPort));
        }
Esempio n. 11
0
 /// <summary>
 /// Default constructor. Reads settings from the XmlConfig files.
 /// </summary>
 public BuildConfiguration()
 {
     XmlConfig.ApplyTo(this);
 }
Esempio n. 12
0
 /// <summary>
 /// Constructor
 /// </summary>
 public WindowsTargetRules()
 {
     XmlConfig.ApplyTo(this);
 }
Esempio n. 13
0
 public LocalExecutor()
 {
     XmlConfig.ApplyTo(this);
 }
Esempio n. 14
0
        /// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="Arguments">Command-line arguments</param>
        /// <returns>One of the values of ECompilationResult</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            // Initialize the log system, buffering the output until we can create the log file
            StartupTraceListener StartupListener = new StartupTraceListener();

            Trace.Listeners.Add(StartupListener);

            // Write the command line
            Log.TraceLog("Command line: {0}", Environment.CommandLine);

            // Grab the environment.
            UnrealBuildTool.InitialEnvironment = Environment.GetEnvironmentVariables();
            if (UnrealBuildTool.InitialEnvironment.Count < 1)
            {
                throw new BuildException("Environment could not be read");
            }

            // Read the XML configuration files
            XmlConfig.ApplyTo(this);

            // Fixup the log path if it wasn't overridden by a config file
            if (BaseLogFileName == null)
            {
                BaseLogFileName = FileReference.Combine(UnrealBuildTool.EngineProgramSavedDirectory, "UnrealBuildTool", "Log.txt").FullName;
            }

            // Create the log file, and flush the startup listener to it
            if (!Arguments.HasOption("-NoLog") && !Log.HasFileWriter())
            {
                FileReference LogFile = new FileReference(BaseLogFileName);
                foreach (string LogSuffix in Arguments.GetValues("-LogSuffix="))
                {
                    LogFile = LogFile.ChangeExtension(null) + "_" + LogSuffix + LogFile.GetExtension();
                }

                TextWriterTraceListener LogTraceListener = Log.AddFileWriter("DefaultLogTraceListener", LogFile);
                StartupListener.CopyTo(LogTraceListener);
            }
            Trace.Listeners.Remove(StartupListener);

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            Arguments.ApplyTo(BuildConfiguration);

            // Check the root path length isn't too long
            if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64 && UnrealBuildTool.RootDirectory.FullName.Length > BuildConfiguration.MaxRootPathLength)
            {
                Log.TraceWarning("Running from a path with a long directory name (\"{0}\" = {1} characters). Root paths shorter than {2} characters are recommended to avoid exceeding maximum path lengths on Windows.", UnrealBuildTool.RootDirectory, UnrealBuildTool.RootDirectory.FullName.Length, BuildConfiguration.MaxRootPathLength);
            }

            // now that we know the available platforms, we can delete other platforms' junk. if we're only building specific modules from the editor, don't touch anything else (it may be in use).
            if (!bIgnoreJunk && !UnrealBuildTool.IsEngineInstalled())
            {
                using (Timeline.ScopeEvent("DeleteJunk()"))
                {
                    JunkDeleter.DeleteJunk();
                }
            }

            // Parse and build the targets
            try
            {
                List <TargetDescriptor> TargetDescriptors;

                // Parse all the target descriptors
                using (Timeline.ScopeEvent("TargetDescriptor.ParseCommandLine()"))
                {
                    TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, BuildConfiguration.bSkipRulesCompile);
                }

                // Hack for specific files compile; don't build the ShaderCompileWorker target that's added to the command line for generated project files
                if (TargetDescriptors.Count >= 2)
                {
                    TargetDescriptors.RemoveAll(x => (x.Name == "ShaderCompileWorker" || x.Name == "LiveCodingConsole") && x.SpecificFilesToCompile.Count > 0);
                }

                // Handle remote builds
                for (int Idx = 0; Idx < TargetDescriptors.Count; ++Idx)
                {
                    TargetDescriptor TargetDesc = TargetDescriptors[Idx];
                    if (RemoteMac.HandlesTargetPlatform(TargetDesc.Platform))
                    {
                        FileReference BaseLogFile   = Log.OutputFile ?? new FileReference(BaseLogFileName);
                        FileReference RemoteLogFile = FileReference.Combine(BaseLogFile.Directory, BaseLogFile.GetFileNameWithoutExtension() + "_Remote.txt");

                        RemoteMac RemoteMac = new RemoteMac(TargetDesc.ProjectFile);
                        if (!RemoteMac.Build(TargetDesc, RemoteLogFile, bSkipPreBuildTargets))
                        {
                            return((int)CompilationResult.Unknown);
                        }

                        TargetDescriptors.RemoveAt(Idx--);
                    }
                }

                // Handle local builds
                if (TargetDescriptors.Count > 0)
                {
                    // Get a set of all the project directories
                    HashSet <DirectoryReference> ProjectDirs = new HashSet <DirectoryReference>();
                    foreach (TargetDescriptor TargetDesc in TargetDescriptors)
                    {
                        if (TargetDesc.ProjectFile != null)
                        {
                            DirectoryReference ProjectDirectory = TargetDesc.ProjectFile.Directory;
                            FileMetadataPrefetch.QueueProjectDirectory(ProjectDirectory);
                            ProjectDirs.Add(ProjectDirectory);
                        }
                    }

                    // Get all the build options
                    BuildOptions Options = BuildOptions.None;
                    if (bSkipBuild)
                    {
                        Options |= BuildOptions.SkipBuild;
                    }
                    if (bXGEExport)
                    {
                        Options |= BuildOptions.XGEExport;
                    }
                    if (bNoEngineChanges)
                    {
                        Options |= BuildOptions.NoEngineChanges;
                    }

                    // Create the working set provider per group.
                    using (ISourceFileWorkingSet WorkingSet = SourceFileWorkingSet.Create(UnrealBuildTool.RootDirectory, ProjectDirs))
                    {
                        Build(TargetDescriptors, BuildConfiguration, WorkingSet, Options, WriteOutdatedActionsFile, bSkipPreBuildTargets);
                    }
                }
            }
            finally
            {
                // Save all the caches
                SourceFileMetadataCache.SaveAll();
                CppDependencyCache.SaveAll();
            }
            return(0);
        }
Esempio n. 15
0
 /// <summary>
 /// Constructor
 /// </summary>
 public LinuxTargetRules()
 {
     XmlConfig.ApplyTo(this);
 }
Esempio n. 16
0
 /// <summary>
 /// Constructor
 /// </summary>
 public HTML5TargetRules()
 {
     XmlConfig.ApplyTo(this);
 }
 /// <summary>
 /// Constructor
 /// </summary>
 public ParallelExecutor()
 {
     XmlConfig.ApplyTo(this);
 }
        /// <summary>
        /// Execute the tool mode
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            // Apply any command line arguments to this class
            Arguments.ApplyTo(this);

            // Apply the XML config to this class
            XmlConfig.ApplyTo(this);

            // Parse rocket-specific arguments.
            FileReference ProjectFile;

            TryParseProjectFileArgument(Arguments, out ProjectFile);

            // If there aren't any formats set, read the default project file format from the config file
            if (ProjectFileFormats.Count == 0)
            {
                // Read from the XML config
                if (!String.IsNullOrEmpty(ProjectFileGeneratorSettings.Format))
                {
                    ProjectFileFormats.UnionWith(ProjectFileGeneratorSettings.ParseFormatList(ProjectFileGeneratorSettings.Format));
                }

                // Read from the editor config
                ProjectFileFormat PreferredSourceCodeAccessor;
                if (ProjectFileGenerator.GetPreferredSourceCodeAccessor(ProjectFile, out PreferredSourceCodeAccessor))
                {
                    ProjectFileFormats.Add(PreferredSourceCodeAccessor);
                }

                // If there's still nothing set, get the default project file format for this platform
                if (ProjectFileFormats.Count == 0)
                {
                    ProjectFileFormats.UnionWith(BuildHostPlatform.Current.GetDefaultProjectFileFormats());
                }
            }

            // Register all the platform project generators
            PlatformProjectGeneratorCollection PlatformProjectGenerators = new PlatformProjectGeneratorCollection();

            foreach (Type CheckType in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (CheckType.IsClass && !CheckType.IsAbstract && CheckType.IsSubclassOf(typeof(PlatformProjectGenerator)))
                {
                    PlatformProjectGenerator Generator = (PlatformProjectGenerator)Activator.CreateInstance(CheckType, Arguments);
                    foreach (UnrealTargetPlatform Platform in Generator.GetPlatforms())
                    {
                        if (DisablePlatformProjectGenerators == null || !DisablePlatformProjectGenerators.Any(x => x.Equals(Platform.ToString(), StringComparison.OrdinalIgnoreCase)))
                        {
                            Log.TraceVerbose("Registering project generator {0} for {1}", CheckType, Platform);
                            PlatformProjectGenerators.RegisterPlatformProjectGenerator(Platform, Generator);
                        }
                    }
                }
            }

            // Create each project generator and run it
            List <ProjectFileGenerator> Generators = new List <ProjectFileGenerator>();

            foreach (ProjectFileFormat ProjectFileFormat in ProjectFileFormats.Distinct())
            {
                ProjectFileGenerator Generator;
                switch (ProjectFileFormat)
                {
                case ProjectFileFormat.Make:
                    Generator = new MakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CMake:
                    Generator = new CMakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.QMake:
                    Generator = new QMakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.KDevelop:
                    Generator = new KDevelopGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CodeLite:
                    Generator = new CodeLiteGenerator(ProjectFile, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.Default, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2012:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2012, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2013:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2013, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2015:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2015, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2017:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2017, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2019:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2019, Arguments);
                    break;

                case ProjectFileFormat.XCode:
                    Generator = new XcodeProjectFileGenerator(ProjectFile, Arguments);
                    break;

                case ProjectFileFormat.Eddie:
                    Generator = new EddieProjectFileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.VisualStudioCode:
                    Generator = new VSCodeProjectFileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CLion:
                    Generator = new CLionGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.VisualStudioMac:
                    Generator = new VCMacProjectFileGenerator(ProjectFile, Arguments);
                    break;

                default:
                    throw new BuildException("Unhandled project file type '{0}", ProjectFileFormat);
                }
                Generators.Add(Generator);
            }

            // Check there are no superfluous command line arguments
            // TODO (still pass raw arguments below)
            // Arguments.CheckAllArgumentsUsed();

            // Now generate project files
            ProjectFileGenerator.bGenerateProjectFiles = true;
            foreach (ProjectFileGenerator Generator in Generators)
            {
                if (!Generator.GenerateProjectFiles(PlatformProjectGenerators, Arguments.GetRawArray()))
                {
                    return((int)CompilationResult.OtherCompilationError);
                }
            }
            return((int)CompilationResult.Succeeded);
        }
Esempio n. 19
0
 /// <summary>
 /// Constructor
 /// </summary>
 public MacTargetRules()
 {
     XmlConfig.ApplyTo(this);
 }
Esempio n. 20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ProjectFile"></param>
        /// <param name="Executable"></param>
        /// <param name="StageDirectory"></param>
        /// <param name="PlatformType"></param>
        public static void GenerateAssetCatalog(FileReference ProjectFile, string Executable, string StageDirectory, UnrealTargetPlatform PlatformType)
        {
            // Initialize the toolchain.
            IOSProjectSettings ProjectSettings = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(PlatformType)).ReadProjectSettings(null);
            IOSToolChain       ToolChain       = new IOSToolChain(ProjectFile, ProjectSettings);

            // Determine whether the user has modified icons that require a remote Mac to build.
            CppPlatform Platform         = PlatformType == UnrealTargetPlatform.IOS ? CppPlatform.IOS : CppPlatform.TVOS;
            bool        bUserImagesExist = false;

            ToolChain.GenerateAssetCatalog(Platform, ref bUserImagesExist);

            // Don't attempt to do anything remotely if the user is using the default UE4 images.
            if (!bUserImagesExist)
            {
                return;
            }

            // Also don't attempt to use a remote Mac if packaging for TVOS on PC.
            if (Platform == CppPlatform.TVOS && BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac)
            {
                return;
            }

            // Save off the current bUseRPCUtil setting to restore at the end of this function.
            // At this time, iPhonePackager needs to be called with bUseRPCUtil == true.
            bool bSaveUseRPCUtil = RemoteToolChain.bUseRPCUtil;

            // Initialize the remote calling environment, taking into account the user's SSH setting.
            ToolChain.SetUpGlobalEnvironment(false);

            // Build the asset catalog ActionGraph.
            ActionGraph     ActionGraph = new ActionGraph();
            List <FileItem> OutputFiles = new List <FileItem>();

            ToolChain.CompileAssetCatalog(FileItem.GetItemByPath(Executable), Platform, ActionGraph, OutputFiles);

            ActionGraph.FinalizeActionGraph();

            // I'm not sure how to derive the UE4Game and Development arguments programmatically.
            string[] Arguments = new string[] { "UE4Game", (PlatformType == UnrealTargetPlatform.IOS ? "IOS" : "TVOS"), "Development", "-UniqueBuildEnvironment" };

            // Perform all of the setup necessary to actually execute the ActionGraph instance.
            ReadOnlyBuildVersion Version        = new ReadOnlyBuildVersion(BuildVersion.ReadDefault());
            List <string[]>      TargetSettings = new List <string[]>();

            TargetSettings.Add(Arguments);
            var Targets = new List <UEBuildTarget>();
            Dictionary <UEBuildTarget, CPPHeaders> TargetToHeaders = new Dictionary <UEBuildTarget, CPPHeaders>();
            List <TargetDescriptor> TargetDescs = new List <TargetDescriptor>();

            foreach (string[] TargetSetting in TargetSettings)
            {
                TargetDescs.AddRange(TargetDescriptor.ParseCommandLine(TargetSetting, ref ProjectFile));
            }
            foreach (TargetDescriptor TargetDesc in TargetDescs)
            {
                UEBuildTarget Target = UEBuildTarget.CreateTarget(TargetDesc, Arguments, false, Version);
                if (Target == null)
                {
                    continue;
                }
                Targets.Add(Target);
                TargetToHeaders.Add(Target, null);
            }

            bool bIsRemoteCompile = BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac;

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            CommandLine.ParseArguments(Arguments, BuildConfiguration);
            BuildConfiguration.bUseUBTMakefiles = false;

            Action[] PrerequisiteActions;
            {
                HashSet <Action> PrerequisiteActionsSet = new HashSet <Action>();
                foreach (FileItem OutputFile in OutputFiles)
                {
                    ActionGraph.GatherPrerequisiteActions(OutputFile, ref PrerequisiteActionsSet);
                }
                PrerequisiteActions = PrerequisiteActionsSet.ToArray();
            }

            // Copy any asset catalog files to the remote Mac, if necessary.
            foreach (UEBuildTarget Target in Targets)
            {
                UEBuildPlatform.GetBuildPlatform(Target.Platform).PreBuildSync();
            }

            // Begin execution of the ActionGraph.
            Dictionary <UEBuildTarget, List <FileItem> > TargetToOutdatedPrerequisitesMap;
            List <Action> ActionsToExecute = ActionGraph.GetActionsToExecute(BuildConfiguration, PrerequisiteActions, Targets, TargetToHeaders, true, true, out TargetToOutdatedPrerequisitesMap);
            string        ExecutorName     = "Unknown";
            bool          bSuccess         = ActionGraph.ExecuteActions(BuildConfiguration, ActionsToExecute, bIsRemoteCompile, out ExecutorName, "", EHotReload.Disabled);

            if (bSuccess)
            {
                if (bIsRemoteCompile)
                {
                    // Copy the remotely built AssetCatalog directory locally.
                    foreach (FileItem OutputFile in OutputFiles)
                    {
                        string   RemoteDirectory = System.IO.Path.GetDirectoryName(OutputFile.AbsolutePath).Replace("\\", "/");
                        FileItem LocalExecutable = ToolChain.RemoteToLocalFileItem(FileItem.GetItemByPath(Executable));
                        string   LocalDirectory  = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(LocalExecutable.AbsolutePath), "AssetCatalog");
                        LocalDirectory = StageDirectory;
                        RPCUtilHelper.CopyDirectory(RemoteDirectory, LocalDirectory, RPCUtilHelper.ECopyOptions.DoNotReplace);
                    }
                }
                else
                {
                    // Copy the built AssetCatalog directory to the StageDirectory.
                    foreach (FileItem OutputFile in OutputFiles)
                    {
                        string SourceDirectory = System.IO.Path.GetDirectoryName(OutputFile.AbsolutePath).Replace("\\", "/");
                        System.IO.DirectoryInfo SourceDirectoryInfo = new System.IO.DirectoryInfo(SourceDirectory);
                        if (!System.IO.Directory.Exists(StageDirectory))
                        {
                            System.IO.Directory.CreateDirectory(StageDirectory);
                        }
                        System.IO.FileInfo[] SourceFiles = SourceDirectoryInfo.GetFiles();
                        foreach (System.IO.FileInfo SourceFile in SourceFiles)
                        {
                            string DestinationPath = System.IO.Path.Combine(StageDirectory, SourceFile.Name);
                            SourceFile.CopyTo(DestinationPath, true);
                        }
                    }
                }
            }

            // Restore the former bUseRPCUtil setting.
            RemoteToolChain.bUseRPCUtil = bSaveUseRPCUtil;
        }
Esempio n. 21
0
        /// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="Arguments">Command-line arguments</param>
        /// <returns>One of the values of ECompilationResult</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            // Initialize the log system, buffering the output until we can create the log file
            StartupTraceListener StartupListener = new StartupTraceListener();

            Trace.Listeners.Add(StartupListener);

            // Write the command line
            Log.TraceLog("Command line: {0}", Environment.CommandLine);

            // Grab the environment.
            UnrealBuildTool.InitialEnvironment = Environment.GetEnvironmentVariables();
            if (UnrealBuildTool.InitialEnvironment.Count < 1)
            {
                throw new BuildException("Environment could not be read");
            }

            // Read the XML configuration files
            XmlConfig.ApplyTo(this);

            // Create the log file, and flush the startup listener to it
            if (!Arguments.HasOption("-NoLog") && !Log.HasFileWriter())
            {
                FileReference LogFile = new FileReference(BaseLogFileName);
                foreach (string LogSuffix in Arguments.GetValues("-LogSuffix="))
                {
                    LogFile = LogFile.ChangeExtension(null) + "_" + LogSuffix + LogFile.GetExtension();
                }

                TextWriterTraceListener LogTraceListener = Log.AddFileWriter("DefaultLogTraceListener", LogFile);
                StartupListener.CopyTo(LogTraceListener);
            }
            Trace.Listeners.Remove(StartupListener);

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            Arguments.ApplyTo(BuildConfiguration);

            // now that we know the available platforms, we can delete other platforms' junk. if we're only building specific modules from the editor, don't touch anything else (it may be in use).
            if (!bIgnoreJunk && !UnrealBuildTool.IsEngineInstalled())
            {
                using (Timeline.ScopeEvent("DeleteJunk()"))
                {
                    JunkDeleter.DeleteJunk();
                }
            }

            // Parse and build the targets
            try
            {
                // Parse all the target descriptors
                List <TargetDescriptor> TargetDescriptors;
                using (Timeline.ScopeEvent("TargetDescriptor.ParseCommandLine()"))
                {
                    TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, BuildConfiguration.bSkipRulesCompile);
                }

                // Hack for single file compile; don't build the ShaderCompileWorker target that's added to the command line for generated project files
                if (TargetDescriptors.Count >= 2)
                {
                    TargetDescriptors.RemoveAll(x => x.Name == "ShaderCompileWorker" && x.SingleFileToCompile != null);
                }

                // Handle remote builds
                for (int Idx = 0; Idx < TargetDescriptors.Count; Idx++)
                {
                    TargetDescriptor TargetDesc = TargetDescriptors[Idx];
                    if (RemoteMac.HandlesTargetPlatform(TargetDesc.Platform))
                    {
                        FileReference BaseLogFile   = Log.OutputFile ?? new FileReference(BaseLogFileName);
                        FileReference RemoteLogFile = FileReference.Combine(BaseLogFile.Directory, BaseLogFile.GetFileNameWithoutExtension() + "_Remote.txt");

                        RemoteMac RemoteMac = new RemoteMac(TargetDesc.ProjectFile);
                        if (!RemoteMac.Build(TargetDesc, RemoteLogFile))
                        {
                            return((int)CompilationResult.Unknown);
                        }

                        TargetDescriptors.RemoveAt(Idx--);
                    }
                }

                // Handle local builds
                if (TargetDescriptors.Count > 0)
                {
                    // Get a set of all the project directories
                    HashSet <DirectoryReference> ProjectDirs = new HashSet <DirectoryReference>();
                    foreach (TargetDescriptor TargetDesc in TargetDescriptors)
                    {
                        if (TargetDesc.ProjectFile != null)
                        {
                            DirectoryReference ProjectDirectory = TargetDesc.ProjectFile.Directory;
                            FileMetadataPrefetch.QueueProjectDirectory(ProjectDirectory);
                            ProjectDirs.Add(ProjectDirectory);
                        }
                    }

                    // Get all the build options
                    BuildOptions Options = BuildOptions.None;
                    if (bSkipBuild)
                    {
                        Options |= BuildOptions.SkipBuild;
                    }
                    if (bXGEExport)
                    {
                        Options |= BuildOptions.XGEExport;
                    }

                    // Create the working set provider
                    using (ISourceFileWorkingSet WorkingSet = SourceFileWorkingSet.Create(UnrealBuildTool.RootDirectory, ProjectDirs))
                    {
                        Build(TargetDescriptors, BuildConfiguration, WorkingSet, Options);
                    }
                }
            }
            finally
            {
                // Save all the caches
                SourceFileMetadataCache.SaveAll();
                CppDependencyCache.SaveAll();
            }
            return(0);
        }
Esempio n. 22
0
 public XGE()
 {
     XmlConfig.ApplyTo(this);
 }
Esempio n. 23
0
        public Distcc()
        {
            XmlConfig.ApplyTo(this);

            // The default for normal Mac users should be to use DistCode which installs as an Xcode plugin and provides dynamic host management
            if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
            {
                string UserDir = Environment.GetEnvironmentVariable("HOME");
                string MacDistccExecutablesPath = UserDir + "/Library/Application Support/Developer/Shared/Xcode/Plug-ins/Distcc 3.2.xcplugin/Contents/usr/bin";

                // But we should use the standard Posix directory when not installed - a build farm would use a static .dmucs hosts file not DistCode.
                if (System.IO.Directory.Exists(MacDistccExecutablesPath))
                {
                    DistccExecutablesPath = MacDistccExecutablesPath;
                }

                if (System.IO.File.Exists(UserDir + "/Library/Preferences/com.marksatt.DistCode.plist"))
                {
                    using (System.Diagnostics.Process DefaultsProcess = new System.Diagnostics.Process())
                    {
                        try
                        {
                            DefaultsProcess.StartInfo.FileName               = "/usr/bin/defaults";
                            DefaultsProcess.StartInfo.CreateNoWindow         = true;
                            DefaultsProcess.StartInfo.UseShellExecute        = false;
                            DefaultsProcess.StartInfo.RedirectStandardOutput = true;
                            DefaultsProcess.StartInfo.RedirectStandardError  = true;
                            DefaultsProcess.StartInfo.Arguments              = "read com.marksatt.DistCode DistProp";
                            DefaultsProcess.Start();
                            string Output = DefaultsProcess.StandardOutput.ReadToEnd();
                            DefaultsProcess.WaitForExit();
                            if (DefaultsProcess.ExitCode == 0)
                            {
                                DMUCSDistProp = Output;
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }
                    using (System.Diagnostics.Process CoordModeProcess = new System.Diagnostics.Process())
                    {
                        using (System.Diagnostics.Process DefaultsProcess = new System.Diagnostics.Process())
                        {
                            try
                            {
                                CoordModeProcess.StartInfo.FileName               = "/usr/bin/defaults";
                                CoordModeProcess.StartInfo.CreateNoWindow         = true;
                                CoordModeProcess.StartInfo.UseShellExecute        = false;
                                CoordModeProcess.StartInfo.RedirectStandardOutput = true;
                                CoordModeProcess.StartInfo.RedirectStandardError  = true;
                                CoordModeProcess.StartInfo.Arguments              = "read com.marksatt.DistCode CoordinatorMode";
                                CoordModeProcess.Start();
                                string CoordModeProcessOutput = CoordModeProcess.StandardOutput.ReadToEnd();
                                CoordModeProcess.WaitForExit();
                                if (CoordModeProcess.ExitCode == 0 && CoordModeProcessOutput.StartsWith("1"))
                                {
                                    DefaultsProcess.StartInfo.FileName               = "/usr/bin/defaults";
                                    DefaultsProcess.StartInfo.CreateNoWindow         = true;
                                    DefaultsProcess.StartInfo.UseShellExecute        = false;
                                    DefaultsProcess.StartInfo.RedirectStandardOutput = true;
                                    DefaultsProcess.StartInfo.RedirectStandardError  = true;
                                    DefaultsProcess.StartInfo.Arguments              = "read com.marksatt.DistCode CoordinatorIP";
                                    DefaultsProcess.Start();
                                    string Output = DefaultsProcess.StandardOutput.ReadToEnd();
                                    DefaultsProcess.WaitForExit();
                                    if (DefaultsProcess.ExitCode == 0)
                                    {
                                        DMUCSCoordinator = Output;
                                    }
                                }
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                }
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Main entry point
        /// </summary>
        /// <param name="Arguments">Command-line arguments</param>
        /// <returns>One of the values of ECompilationResult</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            Arguments.ApplyTo(BuildConfiguration);

            // Parse all the targets being built
            List <TargetDescriptor> TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, bSkipRulesCompile);

            if (TargetDescriptors.Count == 0)
            {
                throw new BuildException("No targets specified to clean");
            }

            // Also add implicit descriptors for cleaning UnrealBuildTool
            if (!BuildConfiguration.bDoNotBuildUHT)
            {
                const string UnrealHeaderToolTarget = "UnrealHeaderTool";

                // Get a list of project files to clean UHT for
                List <FileReference> ProjectFiles = new List <FileReference>();
                foreach (TargetDescriptor TargetDesc in TargetDescriptors)
                {
                    if (TargetDesc.Name != UnrealHeaderToolTarget && !RemoteMac.HandlesTargetPlatform(TargetDesc.Platform))
                    {
                        if (ProjectFiles.Count == 0)
                        {
                            ProjectFiles.Add(null);
                        }
                        if (TargetDesc.ProjectFile != null && !ProjectFiles.Contains(TargetDesc.ProjectFile))
                        {
                            ProjectFiles.Add(TargetDesc.ProjectFile);
                        }
                    }
                }

                // Add descriptors for cleaning UHT with all these projects
                if (ProjectFiles.Count > 0)
                {
                    UnrealTargetConfiguration Configuration = BuildConfiguration.bForceDebugUnrealHeaderTool ? UnrealTargetConfiguration.Debug : UnrealTargetConfiguration.Development;
                    string Architecture = UEBuildPlatform.GetBuildPlatform(BuildHostPlatform.Current.Platform).GetDefaultArchitecture(null);
                    foreach (FileReference ProjectFile in ProjectFiles)
                    {
                        TargetDescriptors.Add(new TargetDescriptor(ProjectFile, UnrealHeaderToolTarget, BuildHostPlatform.Current.Platform, Configuration, Architecture, null));
                    }
                }
            }

            // Output the list of targets that we're cleaning
            Log.TraceInformation("Cleaning {0} binaries...", StringUtils.FormatList(TargetDescriptors.Select(x => x.Name).Distinct()));

            // Loop through all the targets, and clean them all
            HashSet <FileReference>      FilesToDelete       = new HashSet <FileReference>();
            HashSet <DirectoryReference> DirectoriesToDelete = new HashSet <DirectoryReference>();

            foreach (TargetDescriptor TargetDescriptor in TargetDescriptors)
            {
                // Create the rules assembly
                RulesAssembly RulesAssembly = RulesCompiler.CreateTargetRulesAssembly(TargetDescriptor.ProjectFile, TargetDescriptor.Name, bSkipRulesCompile, BuildConfiguration.bUsePrecompiled, TargetDescriptor.ForeignPlugin);

                // Create the rules object
                ReadOnlyTargetRules Target = new ReadOnlyTargetRules(RulesAssembly.CreateTargetRules(TargetDescriptor.Name, TargetDescriptor.Platform, TargetDescriptor.Configuration, TargetDescriptor.Architecture, TargetDescriptor.ProjectFile, TargetDescriptor.AdditionalArguments));

                // Find the base folders that can contain binaries
                List <DirectoryReference> BaseDirs = new List <DirectoryReference>();
                BaseDirs.Add(UnrealBuildTool.EngineDirectory);
                BaseDirs.Add(UnrealBuildTool.EnterpriseDirectory);
                foreach (FileReference Plugin in Plugins.EnumeratePlugins(Target.ProjectFile))
                {
                    BaseDirs.Add(Plugin.Directory);
                }
                if (Target.ProjectFile != null)
                {
                    BaseDirs.Add(Target.ProjectFile.Directory);
                }

                // If we're running a precompiled build, remove anything under the engine folder
                BaseDirs.RemoveAll(x => RulesAssembly.IsReadOnly(x));

                // Get all the names which can prefix build products
                List <string> NamePrefixes = new List <string>();
                if (Target.Type != TargetType.Program)
                {
                    NamePrefixes.Add(UEBuildTarget.GetAppNameForTargetType(Target.Type));
                }
                NamePrefixes.Add(Target.Name);

                // Get the suffixes for this configuration
                List <string> NameSuffixes = new List <string>();
                if (Target.Configuration == Target.UndecoratedConfiguration)
                {
                    NameSuffixes.Add("");
                }
                NameSuffixes.Add(String.Format("-{0}-{1}", Target.Platform.ToString(), Target.Configuration.ToString()));
                if (!String.IsNullOrEmpty(Target.Architecture))
                {
                    NameSuffixes.AddRange(NameSuffixes.ToArray().Select(x => x + Target.Architecture));
                }

                // Add all the makefiles and caches to be deleted
                FilesToDelete.Add(TargetMakefile.GetLocation(Target.ProjectFile, Target.Name, Target.Platform, Target.Configuration));
                FilesToDelete.UnionWith(SourceFileMetadataCache.GetFilesToClean(Target.ProjectFile));
                FilesToDelete.UnionWith(ActionHistory.GetFilesToClean(Target.ProjectFile, Target.Name, Target.Platform, Target.Type));

                // Add all the intermediate folders to be deleted
                foreach (DirectoryReference BaseDir in BaseDirs)
                {
                    foreach (string NamePrefix in NamePrefixes)
                    {
                        DirectoryReference GeneratedCodeDir = DirectoryReference.Combine(BaseDir, "Intermediate", "Build", Target.Platform.ToString(), NamePrefix, "Inc");
                        if (DirectoryReference.Exists(GeneratedCodeDir))
                        {
                            DirectoriesToDelete.Add(GeneratedCodeDir);
                        }

                        DirectoryReference IntermediateDir = DirectoryReference.Combine(BaseDir, "Intermediate", "Build", Target.Platform.ToString(), NamePrefix, Target.Configuration.ToString());
                        if (DirectoryReference.Exists(IntermediateDir))
                        {
                            DirectoriesToDelete.Add(IntermediateDir);
                        }
                    }
                }

                // List of additional files and directories to clean, specified by the target platform
                List <FileReference>      AdditionalFilesToDelete       = new List <FileReference>();
                List <DirectoryReference> AdditionalDirectoriesToDelete = new List <DirectoryReference>();

                // Add all the build products from this target
                string[] NamePrefixesArray = NamePrefixes.Distinct().ToArray();
                string[] NameSuffixesArray = NameSuffixes.Distinct().ToArray();
                foreach (DirectoryReference BaseDir in BaseDirs)
                {
                    DirectoryReference BinariesDir = DirectoryReference.Combine(BaseDir, "Binaries", Target.Platform.ToString());
                    if (DirectoryReference.Exists(BinariesDir))
                    {
                        UEBuildPlatform.GetBuildPlatform(Target.Platform).FindBuildProductsToClean(BinariesDir, NamePrefixesArray, NameSuffixesArray, AdditionalFilesToDelete, AdditionalDirectoriesToDelete);
                    }
                }

                // Get all the additional intermediate folders created by this platform
                UEBuildPlatform.GetBuildPlatform(Target.Platform).FindAdditionalBuildProductsToClean(Target, AdditionalFilesToDelete, AdditionalDirectoriesToDelete);

                // Add the platform's files and directories to the main list
                FilesToDelete.UnionWith(AdditionalFilesToDelete);
                DirectoriesToDelete.UnionWith(AdditionalDirectoriesToDelete);
            }

            // Delete all the directories, then all the files. By sorting the list of directories before we delete them, we avoid spamming the log if a parent directory is deleted first.
            foreach (DirectoryReference DirectoryToDelete in DirectoriesToDelete.OrderBy(x => x.FullName))
            {
                if (DirectoryReference.Exists(DirectoryToDelete))
                {
                    Log.TraceVerbose("    Deleting {0}{1}...", DirectoryToDelete, Path.DirectorySeparatorChar);
                    try
                    {
                        DirectoryReference.Delete(DirectoryToDelete, true);
                    }
                    catch (Exception Ex)
                    {
                        throw new BuildException(Ex, "Unable to delete {0} ({1})", DirectoryToDelete, Ex.Message.TrimEnd());
                    }
                }
            }

            foreach (FileReference FileToDelete in FilesToDelete.OrderBy(x => x.FullName))
            {
                if (FileReference.Exists(FileToDelete))
                {
                    Log.TraceVerbose("    Deleting " + FileToDelete);
                    try
                    {
                        FileReference.Delete(FileToDelete);
                    }
                    catch (Exception Ex)
                    {
                        throw new BuildException(Ex, "Unable to delete {0} ({1})", FileToDelete, Ex.Message.TrimEnd());
                    }
                }
            }

            // Also clean all the remote targets
            for (int Idx = 0; Idx < TargetDescriptors.Count; Idx++)
            {
                TargetDescriptor TargetDescriptor = TargetDescriptors[Idx];
                if (RemoteMac.HandlesTargetPlatform(TargetDescriptor.Platform))
                {
                    RemoteMac RemoteMac = new RemoteMac(TargetDescriptor.ProjectFile);
                    RemoteMac.Clean(TargetDescriptor);
                }
            }

            return(0);
        }
Esempio n. 25
0
        /// <summary>
        /// Execute the command
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            Arguments.ApplyTo(BuildConfiguration);

            // Parse the filter argument
            FileFilter FileFilter = null;

            if (FilterRules.Count > 0)
            {
                FileFilter = new FileFilter(FileFilterType.Exclude);
                foreach (string FilterRule in FilterRules)
                {
                    FileFilter.AddRules(FilterRule.Split(';'));
                }
            }

            // Parse all the target descriptors
            List <TargetDescriptor> TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, BuildConfiguration.bSkipRulesCompile);

            // Generate the compile DB for each target
            using (ISourceFileWorkingSet WorkingSet = new EmptySourceFileWorkingSet())
            {
                // Find the compile commands for each file in the target
                Dictionary <FileReference, string> FileToCommand = new Dictionary <FileReference, string>();
                foreach (TargetDescriptor TargetDescriptor in TargetDescriptors)
                {
                    // Disable PCHs and unity builds for the target
                    TargetDescriptor.AdditionalArguments = TargetDescriptor.AdditionalArguments.Append(new string[] { "-NoPCH", "-DisableUnity" });

                    // Create a makefile for the target
                    UEBuildTarget Target = UEBuildTarget.Create(TargetDescriptor, BuildConfiguration.bSkipRulesCompile, BuildConfiguration.bUsePrecompiled);

                    // Find the location of the compiler
                    VCEnvironment Environment = VCEnvironment.Create(WindowsCompiler.Clang, Target.Platform, Target.Rules.WindowsPlatform.Architecture, null, Target.Rules.WindowsPlatform.WindowsSdkVersion, null);
                    FileReference ClangPath   = FileReference.Combine(Environment.CompilerDir, "bin", "clang++.exe");

                    // Convince each module to output its generated code include path
                    foreach (UEBuildBinary Binary in Target.Binaries)
                    {
                        foreach (UEBuildModuleCPP Module in Binary.Modules.OfType <UEBuildModuleCPP>())
                        {
                            Module.bAddGeneratedCodeIncludePath = true;
                        }
                    }

                    // Create all the binaries and modules
                    CppCompileEnvironment GlobalCompileEnvironment = Target.CreateCompileEnvironmentForProjectFiles();
                    foreach (UEBuildBinary Binary in Target.Binaries)
                    {
                        CppCompileEnvironment BinaryCompileEnvironment = Binary.CreateBinaryCompileEnvironment(GlobalCompileEnvironment);
                        foreach (UEBuildModuleCPP Module in Binary.Modules.OfType <UEBuildModuleCPP>())
                        {
                            if (!Module.Rules.bUsePrecompiled)
                            {
                                UEBuildModuleCPP.InputFileCollection InputFileCollection = Module.FindInputFiles(Target.Platform, new Dictionary <DirectoryItem, FileItem[]>());

                                List <FileItem> InputFiles = new List <FileItem>();
                                InputFiles.AddRange(InputFileCollection.CPPFiles);
                                InputFiles.AddRange(InputFileCollection.CCFiles);

                                CppCompileEnvironment ModuleCompileEnvironment = Module.CreateModuleCompileEnvironment(Target.Rules, BinaryCompileEnvironment);

                                StringBuilder CommandBuilder = new StringBuilder();
                                CommandBuilder.AppendFormat("\"{0}\"", ClangPath.FullName);
                                foreach (FileItem ForceIncludeFile in ModuleCompileEnvironment.ForceIncludeFiles)
                                {
                                    CommandBuilder.AppendFormat(" -include \"{0}\"", ForceIncludeFile.FullName);
                                }
                                foreach (string Definition in ModuleCompileEnvironment.Definitions)
                                {
                                    CommandBuilder.AppendFormat(" -D\"{0}\"", Definition);
                                }
                                foreach (DirectoryReference IncludePath in ModuleCompileEnvironment.UserIncludePaths)
                                {
                                    CommandBuilder.AppendFormat(" -I\"{0}\"", IncludePath);
                                }
                                foreach (DirectoryReference IncludePath in ModuleCompileEnvironment.SystemIncludePaths)
                                {
                                    CommandBuilder.AppendFormat(" -I\"{0}\"", IncludePath);
                                }

                                foreach (FileItem InputFile in InputFiles)
                                {
                                    if (FileFilter == null || FileFilter.Matches(InputFile.Location.MakeRelativeTo(UnrealBuildTool.RootDirectory)))
                                    {
                                        FileToCommand[InputFile.Location] = String.Format("{0} \"{1}\"", CommandBuilder, InputFile.FullName);
                                    }
                                }
                            }
                        }
                    }
                }

                // Write the compile database
                FileReference DatabaseFile = FileReference.Combine(UnrealBuildTool.RootDirectory, "compile_commands.json");
                using (JsonWriter Writer = new JsonWriter(DatabaseFile))
                {
                    Writer.WriteArrayStart();
                    foreach (KeyValuePair <FileReference, string> FileCommandPair in FileToCommand.OrderBy(x => x.Key.FullName))
                    {
                        Writer.WriteObjectStart();
                        Writer.WriteValue("file", FileCommandPair.Key.FullName);
                        Writer.WriteValue("command", FileCommandPair.Value);
                        Writer.WriteValue("directory", UnrealBuildTool.EngineSourceDirectory.ToString());
                        Writer.WriteObjectEnd();
                    }
                    Writer.WriteArrayEnd();
                }
            }

            return(0);
        }