/// <summary>
        /// Creates a text file with the given contents.  If the contents of the text file aren't changed, it won't write the new contents to
        /// the file to avoid causing an action to be considered outdated.
        /// </summary>
        /// <param name="Location">Path to the intermediate file to create</param>
        /// <param name="Contents">Contents of the new file</param>
        /// <returns>File item for the newly created file</returns>
        public static FileItem CreateIntermediateTextFile(FileReference Location, string Contents)
        {
            // Only write the file if its contents have changed.
            if (!FileReference.Exists(Location))
            {
                DirectoryReference.CreateDirectory(Location.Directory);
                FileReference.WriteAllText(Location, Contents, GetEncodingForString(Contents));
            }
            else
            {
                string CurrentContents = Utils.ReadAllText(Location.FullName);
                if (!String.Equals(CurrentContents, Contents, StringComparison.InvariantCultureIgnoreCase))
                {
                    FileReference BackupFile = new FileReference(Location.FullName + ".old");
                    try
                    {
                        Log.TraceLog("Updating {0}: contents have changed. Saving previous version to {1}.", Location, BackupFile);
                        FileReference.Delete(BackupFile);
                        FileReference.Move(Location, BackupFile);
                    }
                    catch (Exception Ex)
                    {
                        Log.TraceWarning("Unable to rename {0} to {1}", Location, BackupFile);
                        Log.TraceLog("{0}", ExceptionUtils.FormatExceptionDetails(Ex));
                    }
                    FileReference.WriteAllText(Location, Contents, GetEncodingForString(Contents));
                }
            }

            // Reset the file info, in case it already knows about the old file
            FileItem Item = GetItemByFileReference(Location);

            Item.ResetCachedInfo();
            return(Item);
        }
        /// <summary>
        /// Creates a text file with the given contents.  If the contents of the text file aren't changed, it won't write the new contents to
        /// the file to avoid causing an action to be considered outdated.
        /// </summary>
        /// <param name="AbsolutePath">Path to the intermediate file to create</param>
        /// <param name="Contents">Contents of the new file</param>
        /// <returns>File item for the newly created file</returns>
        public static FileItem CreateIntermediateTextFile(FileReference AbsolutePath, string Contents)
        {
            // Create the directory if it doesn't exist.
            Directory.CreateDirectory(Path.GetDirectoryName(AbsolutePath.FullName));

            // Only write the file if its contents have changed.
            if (!FileReference.Exists(AbsolutePath))
            {
                File.WriteAllText(AbsolutePath.FullName, Contents, GetEncodingForString(Contents));
            }
            else
            {
                string CurrentContents = Utils.ReadAllText(AbsolutePath.FullName);
                if (!String.Equals(CurrentContents, Contents, StringComparison.InvariantCultureIgnoreCase))
                {
                    try
                    {
                        FileReference PrevAbsolutePath = new FileReference(AbsolutePath.FullName + ".prev");
                        FileReference.Delete(PrevAbsolutePath);
                        FileReference.Move(AbsolutePath, PrevAbsolutePath);
                        Log.TraceLog("Updating {0} - contents have changed (previous version renamed to {1}).", AbsolutePath.FullName, PrevAbsolutePath);
                    }
                    catch
                    {
                        Log.TraceLog("Updating {0} - contents have changed (unable to rename). Previous:\n  {1}\nNew:\n  {2}", AbsolutePath.FullName, CurrentContents.Replace("\n", "\n  "), Contents.Replace("\n", "\n  "));
                    }
                    File.WriteAllText(AbsolutePath.FullName, Contents, GetEncodingForString(Contents));
                }
            }
            return(GetItemByFileReference(AbsolutePath));
        }
Exemple #3
0
        /// <summary>
        /// Loads the cache from the passed in file.
        /// </summary>
        /// <param name="Cache">File to deserialize from</param>
        public static DependencyCache Load(FileReference CacheFile)
        {
            DependencyCache Result = null;

            try
            {
                string CacheBuildMutexPath = CacheFile.FullName + ".buildmutex";

                // If the .buildmutex file for the cache is present, it means that something went wrong between loading
                // and saving the cache last time (most likely the UBT process being terminated), so we don't want to load
                // it.
                if (!File.Exists(CacheBuildMutexPath))
                {
                    using (File.Create(CacheBuildMutexPath))
                    {
                    }

                    using (BinaryReader Reader = new BinaryReader(new FileStream(CacheFile.FullName, FileMode.Open, FileAccess.Read)))
                    {
                        if (Reader.ReadInt32() == FileSignature)
                        {
                            Result = DependencyCache.Deserialize(Reader);
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                Console.Error.WriteLine("Failed to read dependency cache: {0}", Ex.Message);
                CacheFile.Delete();
            }
            return(Result);
        }
Exemple #4
0
        /// <summary>
        /// Loads the cache from disk
        /// </summary>
        /// <param name="Cache">The file to load</param>
        /// <returns>The loaded instance</returns>
        public static FlatCPPIncludeDependencyCache Load(FileReference BackingFile)
        {
            FlatCPPIncludeDependencyCache Result = null;

            try
            {
                string CacheBuildMutexPath = BackingFile.FullName + ".buildmutex";

                // If the .buildmutex file for the cache is present, it means that something went wrong between loading
                // and saving the cache last time (most likely the UBT process being terminated), so we don't want to load
                // it.
                if (!File.Exists(CacheBuildMutexPath))
                {
                    using (File.Create(CacheBuildMutexPath))
                    {
                    }

                    using (BinaryReader Reader = new BinaryReader(new FileStream(BackingFile.FullName, FileMode.Open, FileAccess.Read)))
                    {
                        // @todo ubtmake: We can store the cache in a cheaper/smaller way using hash file names and indices into included headers, but it might actually slow down load times
                        // @todo ubtmake: If we can index PCHs here, we can avoid storing all of the PCH's included headers (PCH's action should have been invalidated, so we shouldn't even have to report the PCH's includes as our indirect includes)
                        if (Reader.ReadInt32() == FileSignature)
                        {
                            Result = Deserialize(Reader);
                        }
                    }
                }
            }
            catch (Exception Ex)
            {
                Console.Error.WriteLine("Failed to read FlatCPPIncludeDependencyCache: {0}", Ex.Message);
                BackingFile.Delete();
            }
            return(Result);
        }
		public override void CleanProjectFiles(DirectoryReference InMasterProjectDirectory, string InMasterProjectName, DirectoryReference InIntermediateProjectFilesDirectory)
		{
			FileReference MasterProjectFile = FileReference.Combine(InMasterProjectDirectory, "CMakeLists.txt");
			if (MasterProjectFile.Exists())
			{
				MasterProjectFile.Delete();
			}
		}
        /// <summary>
        /// Loads the cache from disk
        /// </summary>
        /// <param name="BackingFile">The file to read from</param>
        /// <param name="Cache">The loaded cache</param>
        /// <returns>True if successful</returns>
        public static bool TryRead(FileReference BackingFile, out FlatCPPIncludeDependencyCache Cache)
        {
            if (!FileReference.Exists(BackingFile))
            {
                Cache = null;
                return(false);
            }

            if (UnrealBuildTool.bPrintPerformanceInfo)
            {
                Log.TraceInformation("Loading existing FlatCPPIncludeDependencyCache: " + BackingFile.FullName);
            }

            DateTime TimerStartTime = DateTime.UtcNow;

            try
            {
                // If the .buildmutex file for the cache is present, it means that something went wrong between loading
                // and saving the cache last time (most likely the UBT process being terminated), so we don't want to load
                // it.
                string CacheBuildMutexPath = BackingFile.FullName + ".buildmutex";
                if (File.Exists(CacheBuildMutexPath))
                {
                    Cache = null;
                    return(false);
                }
                File.Create(CacheBuildMutexPath).Close();

                using (BinaryReader Reader = new BinaryReader(new FileStream(BackingFile.FullName, FileMode.Open, FileAccess.Read)))
                {
                    // @todo ubtmake: We can store the cache in a cheaper/smaller way using hash file names and indices into included headers, but it might actually slow down load times
                    // @todo ubtmake: If we can index PCHs here, we can avoid storing all of the PCH's included headers (PCH's action should have been invalidated, so we shouldn't even have to report the PCH's includes as our indirect includes)
                    if (Reader.ReadInt32() != FileSignature)
                    {
                        Cache = null;
                        return(false);
                    }

                    Cache = Deserialize(Reader);

                    if (UnrealBuildTool.bPrintPerformanceInfo)
                    {
                        TimeSpan TimerDuration = DateTime.UtcNow - TimerStartTime;
                        Log.TraceInformation("Loading FlatCPPIncludeDependencyCache took " + TimerDuration.TotalSeconds + "s");
                    }

                    return(true);
                }
            }
            catch (Exception Ex)
            {
                Console.Error.WriteLine("Failed to read FlatCPPIncludeDependencyCache: {0}", Ex.Message);
                FileReference.Delete(BackingFile);
                Cache = null;
                return(false);
            }
        }
Exemple #7
0
        /// <summary>
        /// Saves the dependency cache to disk using the update time as the creation time.
        /// </summary>
        public void Save()
        {
            // Only save if we've made changes to it since load.
            if (bIsDirty)
            {
                DateTime TimerStartTime = DateTime.UtcNow;

                // Save update date as new creation date.
                CreationTimeUtc = UpdateTimeUtc;

                // Serialize the cache to disk.
                try
                {
                    BackingFile.Directory.CreateDirectory();
                    using (BinaryWriter Writer = new BinaryWriter(new FileStream(BackingFile.FullName, FileMode.Create, FileAccess.Write)))
                    {
                        Writer.Write(FileSignature);
                        Serialize(Writer);
                    }
                }
                catch (Exception Ex)
                {
                    Console.Error.WriteLine("Failed to write dependency cache: {0}", Ex.Message);
                }

                if (BuildConfiguration.bPrintPerformanceInfo)
                {
                    TimeSpan TimerDuration = DateTime.UtcNow - TimerStartTime;
                    Log.TraceInformation("Saving IncludeFileCache took " + TimerDuration.TotalSeconds + "s");
                }
            }
            else
            {
                if (BuildConfiguration.bPrintPerformanceInfo)
                {
                    Log.TraceInformation("IncludeFileCache did not need to be saved (bIsDirty=false)");
                }
            }

            FileReference MutexPath = BackingFile + ".buildmutex";

            if (MutexPath.Exists())
            {
                try
                {
                    MutexPath.Delete();
                }
                catch
                {
                    // We don't care if we couldn't delete this file, as maybe it couldn't have been created in the first place.
                }
            }
        }
Exemple #8
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, FileReference Executable, DirectoryReference StageDirectory, UnrealTargetPlatform PlatformType)
        {
            CppPlatform Platform = PlatformType == UnrealTargetPlatform.IOS ? CppPlatform.IOS : CppPlatform.TVOS;

            // Determine whether the user has modified icons that require a remote Mac to build.
            bool bUserImagesExist           = false;
            DirectoryReference ResourcesDir = IOSToolChain.GenerateAssetCatalog(ProjectFile, 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;
            }

            // Compile the asset catalog immediately
            if (BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac)
            {
                FileReference OutputFile = FileReference.Combine(StageDirectory, "Assets.car");

                RemoteMac Remote = new RemoteMac(ProjectFile);
                Remote.RunAssetCatalogTool(Platform, ResourcesDir, OutputFile);
            }
            else
            {
                // Get the output file
                FileReference OutputFile = IOSToolChain.GetAssetCatalogFile(Platform, Executable);

                // Delete the Assets.car file to force the asset catalog to build every time, because
                // removals of files or copies of icons (for instance) with a timestamp earlier than
                // the last generated Assets.car will result in nothing built.
                if (FileReference.Exists(OutputFile))
                {
                    FileReference.Delete(OutputFile);
                }

                // Run the process locally
                using (Process Process = new Process())
                {
                    Process.StartInfo.FileName        = "/usr/bin/xcrun";
                    Process.StartInfo.Arguments       = IOSToolChain.GetAssetCatalogArgs(Platform, ResourcesDir.FullName, OutputFile.Directory.FullName);;
                    Process.StartInfo.UseShellExecute = false;
                    Utils.RunLocalProcess(Process);
                }
            }
        }
        /// <summary>
        /// Delete all temporary files created by previous hot reload invocations
        /// </summary>
        /// <param name="HotReloadStateFile">Location of the state file</param>
        public static void DeleteTemporaryFiles(FileReference HotReloadStateFile)
        {
            if (FileReference.Exists(HotReloadStateFile))
            {
                // Try to load the state file. If it fails, we'll just warn and continue.
                HotReloadState State = null;
                try
                {
                    State = HotReloadState.Load(HotReloadStateFile);
                }
                catch (Exception Ex)
                {
                    Log.TraceWarning("Unable to read hot reload state file: {0}", HotReloadStateFile);
                    Log.WriteException(Ex, null);
                    return;
                }

                // Delete all the output files
                foreach (FileReference Location in State.TemporaryFiles.OrderBy(x => x.FullName, StringComparer.OrdinalIgnoreCase))
                {
                    if (FileReference.Exists(Location))
                    {
                        try
                        {
                            FileReference.Delete(Location);
                        }
                        catch (Exception Ex)
                        {
                            throw new BuildException(Ex, "Unable to delete hot-reload file: {0}", Location);
                        }
                        Log.TraceInformation("Deleted hot-reload file: {0}", Location);
                    }
                }

                // Delete the state file itself
                try
                {
                    FileReference.Delete(HotReloadStateFile);
                }
                catch (Exception Ex)
                {
                    throw new BuildException(Ex, "Unable to delete hot-reload state file: {0}", HotReloadStateFile);
                }
            }
        }
        /// <summary>
        /// </summary>
        public override void CleanProjectFiles(DirectoryReference InMasterProjectDirectory, string InMasterProjectName, DirectoryReference InIntermediateProjectFilesDirectory)
        {
            FileReference MasterProjectFile        = FileReference.Combine(InMasterProjectDirectory, InMasterProjectName);
            FileReference MasterProjDeleteFilename = MasterProjectFile + ".sln";

            if (FileReference.Exists(MasterProjDeleteFilename))
            {
                FileReference.Delete(MasterProjDeleteFilename);
            }
            MasterProjDeleteFilename = MasterProjectFile + ".sdf";
            if (FileReference.Exists(MasterProjDeleteFilename))
            {
                FileReference.Delete(MasterProjDeleteFilename);
            }
            MasterProjDeleteFilename = MasterProjectFile + ".suo";
            if (FileReference.Exists(MasterProjDeleteFilename))
            {
                FileReference.Delete(MasterProjDeleteFilename);
            }
            MasterProjDeleteFilename = MasterProjectFile + ".v11.suo";
            if (FileReference.Exists(MasterProjDeleteFilename))
            {
                FileReference.Delete(MasterProjDeleteFilename);
            }
            MasterProjDeleteFilename = MasterProjectFile + ".v12.suo";
            if (FileReference.Exists(MasterProjDeleteFilename))
            {
                FileReference.Delete(MasterProjDeleteFilename);
            }

            // Delete the project files folder
            if (DirectoryReference.Exists(InIntermediateProjectFilesDirectory))
            {
                try
                {
                    DirectoryReference.Delete(InIntermediateProjectFilesDirectory, true);
                }
                catch (Exception Ex)
                {
                    Log.TraceInformation("Error while trying to clean project files path {0}. Ignored.", InIntermediateProjectFilesDirectory);
                    Log.TraceInformation("\t" + Ex.Message);
                }
            }
        }
        public override void CleanProjectFiles(DirectoryReference InMasterProjectDirectory, string InMasterProjectName, DirectoryReference InIntermediateProjectFilesDirectory)
        {
            // TODO Delete all files here. Not finished yet.
            string SolutionFileName               = InMasterProjectName + SolutionExtension;
            string CodeCompletionFile             = InMasterProjectName + CodeCompletionFileName;
            string CodeCompletionPreProcessorFile = InMasterProjectName + CodeCompletionPreProcessorFileName;

            FileReference FullCodeLiteMasterFile                     = FileReference.Combine(InMasterProjectDirectory, SolutionFileName);
            FileReference FullCodeLiteCodeCompletionFile             = FileReference.Combine(InMasterProjectDirectory, CodeCompletionFile);
            FileReference FullCodeLiteCodeCompletionPreProcessorFile = FileReference.Combine(InMasterProjectDirectory, CodeCompletionPreProcessorFile);

            if (FileReference.Exists(FullCodeLiteMasterFile))
            {
                FileReference.Delete(FullCodeLiteMasterFile);
            }
            if (FileReference.Exists(FullCodeLiteCodeCompletionFile))
            {
                FileReference.Delete(FullCodeLiteCodeCompletionFile);
            }
            if (FileReference.Exists(FullCodeLiteCodeCompletionPreProcessorFile))
            {
                FileReference.Delete(FullCodeLiteCodeCompletionPreProcessorFile);
            }

            // Delete the project files folder
            if (DirectoryReference.Exists(InIntermediateProjectFilesDirectory))
            {
                try
                {
                    Directory.Delete(InIntermediateProjectFilesDirectory.FullName, true);
                }
                catch (Exception Ex)
                {
                    Log.TraceInformation("Error while trying to clean project files path {0}. Ignored.", InIntermediateProjectFilesDirectory);
                    Log.TraceInformation("\t" + Ex.Message);
                }
            }
        }
Exemple #12
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);
        }
        /// <summary>
        /// Checks if the editor is currently running and this is a hot-reload
        /// </summary>
        public static bool ShouldDoHotReloadFromIDE(BuildConfiguration BuildConfiguration, TargetDescriptor TargetDesc)
        {
            // Check if Hot-reload is disabled globally for this project
            ConfigHierarchy Hierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirectoryReference.FromFile(TargetDesc.ProjectFile), TargetDesc.Platform);
            bool            bAllowHotReloadFromIDE;

            if (Hierarchy.TryGetValue("BuildConfiguration", "bAllowHotReloadFromIDE", out bAllowHotReloadFromIDE) && !bAllowHotReloadFromIDE)
            {
                return(false);
            }

            if (!BuildConfiguration.bAllowHotReloadFromIDE)
            {
                return(false);
            }

            // Check if we're using LiveCode instead
            ConfigHierarchy EditorPerProjectHierarchy = ConfigCache.ReadHierarchy(ConfigHierarchyType.EditorPerProjectUserSettings, DirectoryReference.FromFile(TargetDesc.ProjectFile), TargetDesc.Platform);
            bool            bEnableLiveCode;

            if (EditorPerProjectHierarchy.GetBool("/Script/LiveCoding.LiveCodingSettings", "bEnabled", out bEnableLiveCode) && bEnableLiveCode)
            {
                return(false);
            }

            bool bIsRunning = false;

            // @todo ubtmake: Kind of cheating here to figure out if an editor target.  At this point we don't have access to the actual target description, and
            // this code must be able to execute before we create or load module rules DLLs so that hot reload can work with bUseUBTMakefiles
            if (TargetDesc.Name.EndsWith("Editor", StringComparison.OrdinalIgnoreCase))
            {
                string EditorBaseFileName = "UE4Editor";
                if (TargetDesc.Configuration != UnrealTargetConfiguration.Development)
                {
                    EditorBaseFileName = String.Format("{0}-{1}-{2}", EditorBaseFileName, TargetDesc.Platform, TargetDesc.Configuration);
                }

                FileReference EditorLocation;
                if (TargetDesc.Platform == UnrealTargetPlatform.Win64)
                {
                    EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Win64", String.Format("{0}.exe", EditorBaseFileName));
                }
                else if (TargetDesc.Platform == UnrealTargetPlatform.Mac)
                {
                    EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Mac", String.Format("{0}.app/Contents/MacOS/{0}", EditorBaseFileName));
                }
                else if (TargetDesc.Platform == UnrealTargetPlatform.Linux)
                {
                    EditorLocation = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "Linux", EditorBaseFileName);
                }
                else
                {
                    throw new BuildException("Unknown editor filename for this platform");
                }

                using (Timeline.ScopeEvent("Finding editor processes for hot-reload"))
                {
                    DirectoryReference EditorRunsDir = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Intermediate", "EditorRuns");
                    if (!DirectoryReference.Exists(EditorRunsDir))
                    {
                        return(false);
                    }

                    if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64)
                    {
                        foreach (FileReference EditorInstanceFile in DirectoryReference.EnumerateFiles(EditorRunsDir))
                        {
                            int ProcessId;
                            if (!Int32.TryParse(EditorInstanceFile.GetFileName(), out ProcessId))
                            {
                                FileReference.Delete(EditorInstanceFile);
                                continue;
                            }

                            Process RunningProcess;
                            try
                            {
                                RunningProcess = Process.GetProcessById(ProcessId);
                            }
                            catch
                            {
                                RunningProcess = null;
                            }

                            if (RunningProcess == null)
                            {
                                FileReference.Delete(EditorInstanceFile);
                                continue;
                            }

                            FileReference MainModuleFile;
                            try
                            {
                                MainModuleFile = new FileReference(RunningProcess.MainModule.FileName);
                            }
                            catch
                            {
                                MainModuleFile = null;
                            }

                            if (!bIsRunning && EditorLocation == MainModuleFile)
                            {
                                bIsRunning = true;
                            }
                        }
                    }
                    else
                    {
                        FileInfo[] EditorRunsFiles = new DirectoryInfo(EditorRunsDir.FullName).GetFiles();
                        BuildHostPlatform.ProcessInfo[] Processes = BuildHostPlatform.Current.GetProcesses();

                        foreach (FileInfo File in EditorRunsFiles)
                        {
                            int PID;
                            BuildHostPlatform.ProcessInfo Proc = null;
                            if (!Int32.TryParse(File.Name, out PID) || (Proc = Processes.FirstOrDefault(P => P.PID == PID)) == default(BuildHostPlatform.ProcessInfo))
                            {
                                // Delete stale files (it may happen if editor crashes).
                                File.Delete();
                                continue;
                            }

                            // Don't break here to allow clean-up of other stale files.
                            if (!bIsRunning)
                            {
                                // Otherwise check if the path matches.
                                bIsRunning = new FileReference(Proc.Filename) == EditorLocation;
                            }
                        }
                    }
                }
            }
            return(bIsRunning);
        }
Exemple #14
0
        public override void CleanProjectFiles(DirectoryReference InMasterProjectDirectory, string InMasterProjectName, DirectoryReference InIntermediateProjectFilesDirectory)
        {
            // Remove Project File
            FileReference MasterProjectFile = FileReference.Combine(InMasterProjectDirectory, ProjectFileName);

            if (FileReference.Exists(MasterProjectFile))
            {
                FileReference.Delete(MasterProjectFile);
            }

            // Remove Headers Files
            FileReference EngineHeadersFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeEngineHeadersFileName);

            if (FileReference.Exists(EngineHeadersFile))
            {
                FileReference.Delete(EngineHeadersFile);
            }
            FileReference ProjectHeadersFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeProjectHeadersFileName);

            if (FileReference.Exists(ProjectHeadersFile))
            {
                FileReference.Delete(ProjectHeadersFile);
            }

            // Remove Sources Files
            FileReference EngineSourcesFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeEngineSourcesFileName);

            if (FileReference.Exists(EngineSourcesFile))
            {
                FileReference.Delete(EngineSourcesFile);
            }
            FileReference ProjectSourcesFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeProjectSourcesFileName);

            if (FileReference.Exists(ProjectSourcesFile))
            {
                FileReference.Delete(ProjectSourcesFile);
            }

            // Remove Includes File
            FileReference IncludeFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeIncludesFileName);

            if (FileReference.Exists(IncludeFile))
            {
                FileReference.Delete(IncludeFile);
            }

            // Remove CSharp Files
            FileReference EngineCSFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeEngineCSFileName);

            if (FileReference.Exists(EngineCSFile))
            {
                FileReference.Delete(EngineCSFile);
            }
            FileReference ProjectCSFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeProjectCSFileName);

            if (FileReference.Exists(ProjectCSFile))
            {
                FileReference.Delete(ProjectCSFile);
            }

            // Remove Config Files
            FileReference EngineConfigFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeEngineConfigsFileName);

            if (FileReference.Exists(EngineConfigFile))
            {
                FileReference.Delete(EngineConfigFile);
            }
            FileReference ProjectConfigsFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeProjectConfigsFileName);

            if (FileReference.Exists(ProjectConfigsFile))
            {
                FileReference.Delete(ProjectConfigsFile);
            }

            // Remove Config Files
            FileReference EngineShadersFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeEngineShadersFileName);

            if (FileReference.Exists(EngineShadersFile))
            {
                FileReference.Delete(EngineShadersFile);
            }
            FileReference ProjectShadersFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeProjectShadersFileName);

            if (FileReference.Exists(ProjectShadersFile))
            {
                FileReference.Delete(ProjectShadersFile);
            }

            // Remove Definitions File
            FileReference DefinitionsFile = FileReference.Combine(InIntermediateProjectFilesDirectory, CMakeDefinitionsFileName);

            if (FileReference.Exists(DefinitionsFile))
            {
                FileReference.Delete(DefinitionsFile);
            }
        }