/// <summary> /// Attempts to autodetect project properties. /// </summary> /// <param name="RawProjectPath">Full project path.</param> /// <returns>Project properties.</returns> private static ProjectProperties DetectProjectProperties(string RawProjectPath, List<UnrealTargetPlatform> ClientTargetPlatforms) { var Properties = new ProjectProperties(); Properties.RawProjectPath = RawProjectPath; // detect if the project is content only, but has non-default build settings List<string> ExtraSearchPaths = null; if (!string.IsNullOrEmpty(RawProjectPath)) { if (RequiresTempTarget(RawProjectPath, ClientTargetPlatforms)) { GenerateTempTarget(RawProjectPath); Properties.bWasGenerated = true; ExtraSearchPaths = new List<string>(); ExtraSearchPaths.Add(CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source")); } else if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs"))) { File.Delete(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs")); } } if (CommandUtils.CmdEnv.HasCapabilityToCompile) { DetectTargetsForProject(Properties, ExtraSearchPaths); Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs); } else { // should never ask for engine targets if we can't compile if (String.IsNullOrEmpty(RawProjectPath)) { throw new AutomationException("Cannot determine engine targets if we can't compile."); } Properties.bIsCodeBasedProject = Properties.bWasGenerated; // if there's a Source directory with source code in it, then mark us as having source code string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source"); if (Directory.Exists(SourceDir)) { string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories); string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories); Properties.bIsCodeBasedProject |= (CppFiles.Length > 0 || HFiles.Length > 0); } } // check to see if the uproject loads modules, only if we haven't already determined it is a code based project if (!Properties.bIsCodeBasedProject) { string uprojectStr = File.ReadAllText(RawProjectPath); Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\""); } // Get all ini files if (!String.IsNullOrWhiteSpace(RawProjectPath)) { CommandUtils.LogVerbose("Loading ini files for {0}", RawProjectPath); var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine"); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory); Properties.EngineConfigs.Add(TargetPlatformType, Config); } } foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath)); Properties.GameConfigs.Add(TargetPlatformType, Config); } } } return Properties; }
/// <summary> /// Finds all targets for the project. /// </summary> /// <param name="Properties">Project properties.</param> /// <param name="ExtraSearchPaths">Additional search paths.</param> private static void DetectTargetsForProject(ProjectProperties Properties, List<string> ExtraSearchPaths = null) { Properties.Targets = new Dictionary<TargetRules.TargetType, SingleTargetProperties>(); string TargetsDllFilename; string FullProjectPath = null; var GameFolders = new List<string>(); var RulesFolder = GetRulesAssemblyFolder(); if (!String.IsNullOrEmpty(Properties.RawProjectPath)) { CommandUtils.LogVerbose("Looking for targets for project {0}", Properties.RawProjectPath); TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", Properties.RawProjectPath.GetHashCode())); FullProjectPath = CommandUtils.GetDirectoryName(Properties.RawProjectPath); GameFolders.Add(FullProjectPath); CommandUtils.LogVerbose("Searching for target rule files in {0}", FullProjectPath); } else { TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", "_BaseEngine_")); } RulesCompiler.SetAssemblyNameAndGameFolders(TargetsDllFilename, GameFolders); // the UBT code assumes a certain CWD, but artists don't have this CWD. var SourceDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source"); bool DirPushed = false; if (CommandUtils.DirectoryExists_NoExceptions(SourceDir)) { CommandUtils.PushDir(SourceDir); DirPushed = true; } var TargetScripts = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Target, ExtraSearchPaths); if (DirPushed) { CommandUtils.PopDir(); } if (!CommandUtils.IsNullOrEmpty(TargetScripts)) { // We only care about project target script so filter out any scripts not in the project folder, or take them all if we are just doing engine stuff var ProjectTargetScripts = new List<string>(); foreach (var Filename in TargetScripts) { var FullScriptPath = CommandUtils.CombinePaths(Path.GetFullPath(Filename)); if (FullProjectPath == null || FullScriptPath.StartsWith(FullProjectPath, StringComparison.InvariantCultureIgnoreCase)) { ProjectTargetScripts.Add(FullScriptPath); } } TargetScripts = ProjectTargetScripts; } if (!CommandUtils.IsNullOrEmpty(TargetScripts)) { CommandUtils.LogVerbose("Found {0} target rule files:", TargetScripts.Count); foreach (var Filename in TargetScripts) { CommandUtils.LogVerbose(" {0}", Filename); } // Check if the scripts require compilation bool DoNotCompile = false; if (!CommandUtils.IsBuildMachine && !CheckIfScriptAssemblyIsOutOfDate(TargetsDllFilename, TargetScripts)) { Log.TraceInformation("Targets DLL {0} is up to date.", TargetsDllFilename); DoNotCompile = true; } if (!DoNotCompile && CommandUtils.FileExists_NoExceptions(TargetsDllFilename)) { if (!CommandUtils.DeleteFile_NoExceptions(TargetsDllFilename, true)) { DoNotCompile = true; CommandUtils.Log("Could not delete {0} assuming it is up to date and reusable for a recursive UAT call.", TargetsDllFilename); } } CompileAndLoadTargetsAssembly(Properties, TargetsDllFilename, DoNotCompile, TargetScripts); } }
public BranchUProject() { GameName = "UE4"; Properties = ProjectUtils.GetProjectProperties(""); if (!Properties.Targets.ContainsKey(TargetRules.TargetType.Editor)) { throw new AutomationException("Base UE4 project did not contain an editor target."); } }
/// <summary> /// Optionally compiles and loads target rules assembly. /// </summary> /// <param name="Properties"></param> /// <param name="TargetsDllFilename"></param> /// <param name="DoNotCompile"></param> /// <param name="TargetScripts"></param> private static void CompileAndLoadTargetsAssembly(ProjectProperties Properties, string TargetsDllFilename, bool DoNotCompile, List<string> TargetScripts) { CommandUtils.Log("Compiling targets DLL: {0}", TargetsDllFilename); var ReferencedAssemblies = new List<string>() { "System.dll", "System.Core.dll", "System.Xml.dll", typeof(UnrealBuildTool.UnrealBuildTool).Assembly.Location }; var TargetsDLL = DynamicCompilation.CompileAndLoadAssembly(TargetsDllFilename, TargetScripts, ReferencedAssemblies, null, DoNotCompile); var DummyTargetInfo = new TargetInfo(BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development); var AllCompiledTypes = TargetsDLL.GetTypes(); foreach (Type TargetType in AllCompiledTypes) { // Find TargetRules but skip all "UE4Editor", "UE4Game" targets. if (typeof(TargetRules).IsAssignableFrom(TargetType)) { // Create an instance of this type CommandUtils.LogVerbose("Creating target rules object: {0}", TargetType.Name); var Rules = Activator.CreateInstance(TargetType, DummyTargetInfo) as TargetRules; CommandUtils.LogVerbose("Adding target: {0} ({1})", TargetType.Name, Rules.Type); SingleTargetProperties TargetData; TargetData.TargetName = GetTargetName(TargetType); Rules.TargetName = TargetData.TargetName; TargetData.Rules = Rules; if (Rules.Type == TargetRules.TargetType.Program) { Properties.Programs.Add(TargetData); } else { Properties.Targets.Add(Rules.Type, TargetData); } Properties.bUsesSteam |= Rules.bUsesSteam; Properties.bUsesCEF3 |= Rules.bUsesCEF3; Properties.bUsesSlate |= Rules.bUsesSlate; Properties.bDebugBuildsActuallyUseDebugCRT |= Rules.bDebugBuildsActuallyUseDebugCRT; Properties.bUsesSlateEditorStyle |= Rules.bUsesSlateEditorStyle; } } }
/// <summary> /// Attempts to autodetect project properties. /// </summary> /// <param name="RawProjectPath">Full project path.</param> /// <returns>Project properties.</returns> private static ProjectProperties DetectProjectProperties(string RawProjectPath) { var Properties = new ProjectProperties(); Properties.RawProjectPath = RawProjectPath; if (CommandUtils.CmdEnv.HasCapabilityToCompile) { DetectTargetsForProject(Properties); Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs); } else { // should never ask for engine targets if we can't compile if (String.IsNullOrEmpty(RawProjectPath)) { throw new AutomationException("Cannot dtermine engine targets if we can't compile."); } Properties.bIsCodeBasedProject = false; // if there's a Source directory with source code in it, then mark us as having source code string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source"); if (Directory.Exists(SourceDir)) { string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories); string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories); Properties.bIsCodeBasedProject = CppFiles.Length > 0 || HFiles.Length > 0; } } // check to see if the uproject loads modules, only if we haven't already determined it is a code based project if (!Properties.bIsCodeBasedProject) { string uprojectStr = File.ReadAllText(RawProjectPath); Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\""); } // Get all ini files if (!String.IsNullOrWhiteSpace(RawProjectPath)) { CommandUtils.Log("Loading ini files for {0}", RawProjectPath); var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine"); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory); Properties.EngineConfigs.Add(TargetPlatformType, Config); } } foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath)); Properties.GameConfigs.Add(TargetPlatformType, Config); } } } return Properties; }
public BranchUProject(UnrealBuildTool.UProjectInfo InfoEntry) { GameName = InfoEntry.GameName; //not sure what the heck this path is relative to FilePath = Path.GetFullPath(CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Binaries", InfoEntry.FilePath)); if (!CommandUtils.FileExists_NoExceptions(FilePath)) { throw new AutomationException("Could not resolve relative path corrctly {0} -> {1} which doesn't exist.", InfoEntry.FilePath, FilePath); } Properties = ProjectUtils.GetProjectProperties(Path.GetFullPath(FilePath)); }
/// <summary> /// Attempts to autodetect project properties. /// </summary> /// <param name="RawProjectPath">Full project path.</param> /// <returns>Project properties.</returns> private static ProjectProperties DetectProjectProperties(string RawProjectPath) { var Properties = new ProjectProperties(); Properties.RawProjectPath = RawProjectPath; if (CommandUtils.CmdEnv.HasCapabilityToCompile) { DetectTargetsForProject(Properties); Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets); } else { // should never ask for engine targets if we can't compile if (String.IsNullOrEmpty(RawProjectPath)) { throw new AutomationException("Cannot dtermine engine targets if we can't compile."); } Properties.bIsCodeBasedProject = false; // if there's a Source directory with source code in it, then mark us as having source code string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source"); if (Directory.Exists(SourceDir)) { string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories); string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories); Properties.bIsCodeBasedProject = CppFiles.Length > 0 || HFiles.Length > 0; } } return Properties; }
public BranchUProject(UnrealBuildTool.UProjectInfo InfoEntry) { GameName = InfoEntry.GameName; //not sure what the heck this path is relative to FilePath = InfoEntry.FilePath; if (!CommandUtils.FileExists_NoExceptions(FilePath.FullName)) { throw new AutomationException("Could not resolve relative path corrctly {0} -> {1} which doesn't exist.", InfoEntry.FilePath, FilePath); } Properties = ProjectUtils.GetProjectProperties(FilePath); }
/// <summary> /// Finds all targets for the project. /// </summary> /// <param name="Properties">Project properties.</param> /// <param name="ExtraSearchPaths">Additional search paths.</param> private static void DetectTargetsForProject(ProjectProperties Properties, List <string> ExtraSearchPaths = null) { Properties.Targets = new Dictionary <TargetRules.TargetType, SingleTargetProperties>(); string TargetsDllFilename; string FullProjectPath = null; var GameFolders = new List <string>(); var RulesFolder = GetRulesAssemblyFolder(); if (!String.IsNullOrEmpty(Properties.RawProjectPath)) { CommandUtils.Log("Looking for targets for project {0}", Properties.RawProjectPath); TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", Properties.RawProjectPath.GetHashCode())); FullProjectPath = CommandUtils.GetDirectoryName(Properties.RawProjectPath); GameFolders.Add(FullProjectPath); CommandUtils.Log("Searching for target rule files in {0}", FullProjectPath); } else { TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", "_BaseEngine_")); } RulesCompiler.SetAssemblyNameAndGameFolders(TargetsDllFilename, GameFolders); // the UBT code assumes a certain CWD, but artists don't have this CWD. var SourceDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source"); bool DirPushed = false; if (CommandUtils.DirectoryExists_NoExceptions(SourceDir)) { CommandUtils.PushDir(SourceDir); DirPushed = true; } var TargetScripts = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Target, ExtraSearchPaths); if (DirPushed) { CommandUtils.PopDir(); } if (!CommandUtils.IsNullOrEmpty(TargetScripts)) { // We only care about project target script so filter out any scripts not in the project folder, or take them all if we are just doing engine stuff var ProjectTargetScripts = new List <string>(); foreach (var Filename in TargetScripts) { var FullScriptPath = CommandUtils.CombinePaths(Path.GetFullPath(Filename)); if (FullProjectPath == null || FullScriptPath.StartsWith(FullProjectPath, StringComparison.InvariantCultureIgnoreCase)) { ProjectTargetScripts.Add(FullScriptPath); } } TargetScripts = ProjectTargetScripts; } if (!CommandUtils.IsNullOrEmpty(TargetScripts)) { CommandUtils.LogVerbose("Found {0} target rule files:", TargetScripts.Count); foreach (var Filename in TargetScripts) { CommandUtils.LogVerbose(" {0}", Filename); } // Check if the scripts require compilation bool DoNotCompile = false; if (!CommandUtils.IsBuildMachine && !CheckIfScriptAssemblyIsOutOfDate(TargetsDllFilename, TargetScripts)) { Log.TraceInformation("Targets DLL {0} is up to date.", TargetsDllFilename); DoNotCompile = true; } if (!DoNotCompile && CommandUtils.FileExists_NoExceptions(TargetsDllFilename)) { if (!CommandUtils.DeleteFile_NoExceptions(TargetsDllFilename, true)) { DoNotCompile = true; CommandUtils.Log("Could not delete {0} assuming it is up to date and reusable for a recursive UAT call.", TargetsDllFilename); } } CompileAndLoadTargetsAssembly(Properties, TargetsDllFilename, DoNotCompile, TargetScripts); } }
/// <summary> /// Attempts to autodetect project properties. /// </summary> /// <param name="RawProjectPath">Full project path.</param> /// <returns>Project properties.</returns> private static ProjectProperties DetectProjectProperties(string RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms) { var Properties = new ProjectProperties(); Properties.RawProjectPath = RawProjectPath; // detect if the project is content only, but has non-default build settings List <string> ExtraSearchPaths = null; if (!string.IsNullOrEmpty(RawProjectPath)) { if (RequiresTempTarget(RawProjectPath, ClientTargetPlatforms)) { GenerateTempTarget(RawProjectPath); Properties.bWasGenerated = true; ExtraSearchPaths = new List <string>(); ExtraSearchPaths.Add(CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source")); } else if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs"))) { File.Delete(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs")); } } if (CommandUtils.CmdEnv.HasCapabilityToCompile) { DetectTargetsForProject(Properties, ExtraSearchPaths); Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs); } else { // should never ask for engine targets if we can't compile if (String.IsNullOrEmpty(RawProjectPath)) { throw new AutomationException("Cannot dtermine engine targets if we can't compile."); } Properties.bIsCodeBasedProject = Properties.bWasGenerated; // if there's a Source directory with source code in it, then mark us as having source code string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source"); if (Directory.Exists(SourceDir)) { string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories); string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories); Properties.bIsCodeBasedProject |= (CppFiles.Length > 0 || HFiles.Length > 0); } } // check to see if the uproject loads modules, only if we haven't already determined it is a code based project if (!Properties.bIsCodeBasedProject) { string uprojectStr = File.ReadAllText(RawProjectPath); Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\""); } // Get all ini files if (!String.IsNullOrWhiteSpace(RawProjectPath)) { CommandUtils.Log("Loading ini files for {0}", RawProjectPath); var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine"); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory); Properties.EngineConfigs.Add(TargetPlatformType, Config); } } foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath)); Properties.GameConfigs.Add(TargetPlatformType, Config); } } } return(Properties); }
/// <summary> /// Attempts to autodetect project properties. /// </summary> /// <param name="RawProjectPath">Full project path.</param> /// <returns>Project properties.</returns> private static ProjectProperties DetectProjectProperties(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested) { var Properties = new ProjectProperties(); Properties.RawProjectPath = RawProjectPath; // detect if the project is content only, but has non-default build settings List <string> ExtraSearchPaths = null; if (RawProjectPath != null) { if (RequiresTempTarget(RawProjectPath, ClientTargetPlatforms, AssetNativizationRequested)) { GenerateTempTarget(RawProjectPath); Properties.bWasGenerated = true; ExtraSearchPaths = new List <string>(); string TempTargetDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source"); ExtraSearchPaths.Add(TempTargetDir); // in case the RulesCompiler (what we use to find all the // Target.cs files) has already cached the contents of this // directory, then we need to invalidate that cache (so // it'll find/use the new Target.cs file) RulesCompiler.InvalidateRulesFileCache(TempTargetDir); } else if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath.FullName) + ".Target.cs"))) { File.Delete(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath.FullName) + ".Target.cs")); } } if (CommandUtils.CmdEnv.HasCapabilityToCompile) { DetectTargetsForProject(Properties, ExtraSearchPaths); Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs); } else { // should never ask for engine targets if we can't compile if (RawProjectPath == null) { throw new AutomationException("Cannot determine engine targets if we can't compile."); } Properties.bIsCodeBasedProject = Properties.bWasGenerated; // if there's a Source directory with source code in it, then mark us as having source code string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Source"); if (Directory.Exists(SourceDir)) { string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories); string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories); Properties.bIsCodeBasedProject |= (CppFiles.Length > 0 || HFiles.Length > 0); } } // check to see if the uproject loads modules, only if we haven't already determined it is a code based project if (!Properties.bIsCodeBasedProject && RawProjectPath != null) { string uprojectStr = File.ReadAllText(RawProjectPath.FullName); Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\""); } // Get all ini files if (RawProjectPath != null) { CommandUtils.LogVerbose("Loading ini files for {0}", RawProjectPath); var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine"); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = ConfigCacheIni.CreateConfigCacheIni(TargetPlatformType, "Engine", RawProjectPath.Directory, new DirectoryReference(EngineDirectory)); Properties.EngineConfigs.Add(TargetPlatformType, Config); } } foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = ConfigCacheIni.CreateConfigCacheIni(TargetPlatformType, "Game", RawProjectPath.Directory); Properties.GameConfigs.Add(TargetPlatformType, Config); } } } return(Properties); }
/// <summary> /// Finds all targets for the project. /// </summary> /// <param name="Properties">Project properties.</param> /// <param name="ExtraSearchPaths">Additional search paths.</param> private static void DetectTargetsForProject(ProjectProperties Properties, List <string> ExtraSearchPaths = null) { Properties.Targets = new List <SingleTargetProperties>(); FileReference TargetsDllFilename; string FullProjectPath = null; List <DirectoryReference> GameFolders = new List <DirectoryReference>(); DirectoryReference RulesFolder = new DirectoryReference(GetRulesAssemblyFolder()); if (Properties.RawProjectPath != null) { CommandUtils.LogVerbose("Looking for targets for project {0}", Properties.RawProjectPath); TargetsDllFilename = FileReference.Combine(RulesFolder, String.Format("UATRules{0}.dll", Properties.RawProjectPath.GetHashCode())); FullProjectPath = CommandUtils.GetDirectoryName(Properties.RawProjectPath.FullName); GameFolders.Add(new DirectoryReference(FullProjectPath)); CommandUtils.LogVerbose("Searching for target rule files in {0}", FullProjectPath); } else { TargetsDllFilename = FileReference.Combine(RulesFolder, String.Format("UATRules{0}.dll", "_BaseEngine_")); } // the UBT code assumes a certain CWD, but artists don't have this CWD. string SourceDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source"); bool DirPushed = false; if (CommandUtils.DirectoryExists_NoExceptions(SourceDir)) { CommandUtils.PushDir(SourceDir); DirPushed = true; } List <DirectoryReference> ExtraSearchDirectories = (ExtraSearchPaths == null)? null : ExtraSearchPaths.Select(x => new DirectoryReference(x)).ToList(); List <FileReference> TargetScripts = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Target, GameFolders: GameFolders, ForeignPlugins: null, AdditionalSearchPaths: ExtraSearchDirectories, bIncludeEnterprise: false); if (DirPushed) { CommandUtils.PopDir(); } if (!CommandUtils.IsNullOrEmpty(TargetScripts)) { // We only care about project target script so filter out any scripts not in the project folder, or take them all if we are just doing engine stuff List <FileReference> ProjectTargetScripts = new List <FileReference>(); foreach (FileReference TargetScript in TargetScripts) { if (FullProjectPath == null || TargetScript.IsUnderDirectory(new DirectoryReference(FullProjectPath))) { ProjectTargetScripts.Add(TargetScript); } } TargetScripts = ProjectTargetScripts; } if (!CommandUtils.IsNullOrEmpty(TargetScripts)) { CommandUtils.LogVerbose("Found {0} target rule files:", TargetScripts.Count); foreach (FileReference Filename in TargetScripts) { CommandUtils.LogVerbose(" {0}", Filename); } // Check if the scripts require compilation bool DoNotCompile = false; if (!CommandUtils.IsBuildMachine && !CheckIfScriptAssemblyIsOutOfDate(TargetsDllFilename, TargetScripts)) { Log.TraceVerbose("Targets DLL {0} is up to date.", TargetsDllFilename); DoNotCompile = true; } if (!DoNotCompile && CommandUtils.FileExists_NoExceptions(TargetsDllFilename.FullName)) { if (!CommandUtils.DeleteFile_NoExceptions(TargetsDllFilename.FullName, true)) { DoNotCompile = true; CommandUtils.LogVerbose("Could not delete {0} assuming it is up to date and reusable for a recursive UAT call.", TargetsDllFilename); } } CompileAndLoadTargetsAssembly(Properties, TargetsDllFilename, DoNotCompile, TargetScripts); } }
/// <summary> /// Attempts to autodetect project properties. /// </summary> /// <param name="RawProjectPath">Full project path.</param> /// <returns>Project properties.</returns> private static ProjectProperties DetectProjectProperties(string RawProjectPath) { var Properties = new ProjectProperties(); Properties.RawProjectPath = RawProjectPath; if (CommandUtils.CmdEnv.HasCapabilityToCompile) { DetectTargetsForProject(Properties); Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs); } else { // should never ask for engine targets if we can't compile if (String.IsNullOrEmpty(RawProjectPath)) { throw new AutomationException("Cannot dtermine engine targets if we can't compile."); } Properties.bIsCodeBasedProject = false; // if there's a Source directory with source code in it, then mark us as having source code string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source"); if (Directory.Exists(SourceDir)) { string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories); string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories); Properties.bIsCodeBasedProject = CppFiles.Length > 0 || HFiles.Length > 0; } } // check to see if the uproject loads modules, only if we haven't already determined it is a code based project if (!Properties.bIsCodeBasedProject) { string uprojectStr = File.ReadAllText(RawProjectPath); Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\""); } // Get all ini files if (!String.IsNullOrWhiteSpace(RawProjectPath)) { CommandUtils.Log("Loading ini files for {0}", RawProjectPath); var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine"); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory); Properties.EngineConfigs.Add(TargetPlatformType, Config); } } foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath)); Properties.GameConfigs.Add(TargetPlatformType, Config); } } } return(Properties); }