/// <summary> /// Execute the task and run the cooker. /// </summary> /// <param name="BuildProducts">List of build products for the current node. Cooking build products will be appended to this list.</param> /// <returns>True if the node succeeded</returns> public override bool Execute(List <string> BuildProducts) { // Figure out the project that this target belongs to FileReference ProjectFile; if (UProjectInfo.TryGetProjectForTarget(Target, out ProjectFile)) { ProjectFile = null; } // Execute the cooker using (TelemetryStopwatch CookStopwatch = new TelemetryStopwatch("Cook.{0}.{1}", ProjectFile.GetFileNameWithoutExtension(), CookPlatform)) { CommandUtils.CookCommandlet(ProjectFile, "UE4Editor-Cmd.exe", Maps, null, null, null, CookPlatform, Arguments); } // Find all the cooked files DirectoryReference CookedDirectory = DirectoryReference.Combine(ProjectFile.Directory, "Saved", "Cooked", CookPlatform); List <FileReference> CookedFiles = CookedDirectory.EnumerateFileReferences().ToList(); if (CookedFiles.Count == 0) { throw new AutomationException("Cooking did not produce any files in {0}", CookedDirectory.FullName); } BuildProducts.AddRange(CookedFiles.Select(x => x.FullName)); return(true); }
public static void RunCommandlet(string ProjectName, string UE4Exe, string Commandlet, string Parameters = null) { FileReference ProjectFile; if (!UProjectInfo.TryGetProjectFileName(ProjectName, out ProjectFile)) { throw new AutomationException("Cannot determine project file for {0}", ProjectName); } RunCommandlet(ProjectFile, UE4Exe, Commandlet, Parameters); }
internal string GetEngineSuffix() { //grab first project listed in order to resolve ini path string iniPath = ""; List <UProjectInfo> projects = UProjectInfo.FilterGameProjects(false, null); foreach (UProjectInfo upi in projects) { iniPath = upi.Folder.FullName; break; } //no INI, default to CPU if (iniPath.Length == 0) { return("CPU"); } //We can't use the ConfigCacheIni file here because it bypasses the Substance section. try { iniPath = Path.Combine(iniPath, Path.Combine("Config", "DefaultEngine.ini")); //parse INI file line by line until we find our result StreamReader file = new StreamReader(iniPath); string line; string suffix = "CPU"; string startsWith = "SubstanceEngine="; while ((line = file.ReadLine()) != null) { if (line.StartsWith(startsWith)) { string value = line.Substring(startsWith.Length); if (value == "SET_CPU") { suffix = "CPU"; } else if (value == "SET_GPU") { suffix = "GPU"; } break; } } return(suffix); } catch (Exception) { return("CPU"); } }
public static void CookCommandlet(string ProjectName) { FileReference ProjectFile; if (ProjectName.Contains('/') || ProjectName.Contains('\\')) { ProjectFile = new FileReference(ProjectName); } else if (!UProjectInfo.TryGetProjectFileName(ProjectName, out ProjectFile)) { throw new AutomationException("Cannot determine project path for {0}", ProjectName); } CookCommandlet(ProjectFile); }
public LibuvSupport(ReadOnlyTargetRules Target) : base(Target) { /* * PublicIncludePaths.AddRange( * new string[] { * "LibuvSupport/" * } * ); * * PrivateIncludePaths.AddRange( * new string[] { * "LibuvSupport" * } * ); */ PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine" }); RulesAssembly RA; FileReference CheckProjectFile; UProjectInfo.TryGetProjectForTarget("NeverSalvation", out CheckProjectFile); RA = RulesCompiler.CreateProjectRulesAssembly(CheckProjectFile); FileReference FR = RA.GetModuleFileName(this.GetType().Name); string ModulePath = Path.GetDirectoryName(FR.CanonicalName); string ThirdPartyPath = Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); // gets the ThirdParty folder directory path string LibuvConnectorPath = ThirdPartyPath + "libuv/"; // gets the Libuv Connector.C 6.1 folder path string LibuvConnectorLibraryPath = LibuvConnectorPath + "lib/"; // gets the path of the lib folder string LibuvConnectorIncludePath = LibuvConnectorPath + "include/"; // gets the path of the include folder string LibuvConnectorImportLibraryName = Path.Combine(LibuvConnectorLibraryPath, "libuv.lib"); // gets the file path and name of the libmysql.lib static import library string LibuvConnectorDLLName = Path.Combine(LibuvConnectorLibraryPath, "libuv.dll"); if (!File.Exists(LibuvConnectorImportLibraryName)) // check to ensure the static import lib can be located, or else we'll be in trouble { throw new BuildException(string.Format("{0} could not be found.", LibuvConnectorImportLibraryName)); // log an error message explaining what went wrong if not found } if (!File.Exists(LibuvConnectorDLLName)) // check to make sure the dll can be located or else we'll be in trouble { throw new BuildException(string.Format("{0} could not be found.", LibuvConnectorDLLName)); // log an error message explaining what went wrong if not found } PublicIncludePaths.Add(LibuvConnectorIncludePath); // add the "include" folder to our dependencies. I've chosen PrivateIncludePaths since I hide the mysql headers from external code PublicLibraryPaths.Add(LibuvConnectorLibraryPath); // add the "lib" folder to our dependencies PublicAdditionalLibraries.Add(LibuvConnectorImportLibraryName); // add libmysql.lib static import library as a dependency PublicDelayLoadDLLs.Add(LibuvConnectorDLLName); // add libmysql.dll as a dll RuntimeDependencies.Add(new RuntimeDependency("$(ProjectDir)/Binaries/Win64/libuv.dll")); // 自动添加libmysql.dll到指定的打包目录中 }
/// <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, FileReference TargetsDllFilename, bool DoNotCompile, List <FileReference> TargetScripts) { CommandUtils.LogVerbose("Compiling targets DLL: {0}", TargetsDllFilename); var ReferencedAssemblies = new List <string>() { "System.dll", "System.Core.dll", "System.Xml.dll", typeof(UnrealBuildTool.PlatformExports).Assembly.Location }; var TargetsDLL = DynamicCompilation.CompileAndLoadAssembly(TargetsDllFilename, TargetScripts, ReferencedAssemblies, null, DoNotCompile); var AllCompiledTypes = TargetsDLL.GetTypes(); foreach (Type TargetType in AllCompiledTypes) { // Find TargetRules but skip all "UE4Editor", "UE4Game" targets. if (typeof(TargetRules).IsAssignableFrom(TargetType)) { string TargetName = GetTargetName(TargetType); FileReference ProjectFile; UProjectInfo.TryGetProjectForTarget(TargetName, out ProjectFile); var DummyTargetInfo = new TargetInfo(TargetName, BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development, "", ProjectFile); // 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); TargetData.Rules = Rules; if (Rules.Type == global::UnrealBuildTool.TargetType.Program) { Properties.Programs.Add(TargetData); } else { Properties.Targets.Add(Rules.Type, TargetData); } } } }
public MyProj(ReadOnlyTargetRules Target) : base(Target) { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); FileReference CheckProjectFile; UProjectInfo.TryGetProjectForTarget("MyProj", out CheckProjectFile); r = RulesCompiler.CreateProjectRulesAssembly(CheckProjectFile); if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64)) { bEnableExceptions = true; } LoadProtobuf(Target); }
public MySQLConnectorUE4Plugin(TargetInfo Target) { //File.WriteAllText("c:/temp/qqq.txt", this.GetType().Name); //string ModulePath = Path.GetDirectoryName( RulesAssembly.GetModuleFilename( this.GetType().Name ) ); UEBuildConfiguration.bForceEnableExceptions = true; RulesAssembly r; FileReference CheckProjectFile; UProjectInfo.TryGetProjectForTarget("MyGame", out CheckProjectFile); r = RulesCompiler.CreateProjectRulesAssembly(CheckProjectFile); FileReference f = r.GetModuleFileName(this.GetType().Name); //File.WriteAllText("c:/temp/qqq2.txt", f.CanonicalName ); string ModulePath = Path.GetDirectoryName(f.CanonicalName); string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "x64" : "x86"; string ThirdPartyPath = Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); string LibrariesPath = Path.Combine(ThirdPartyPath, "MySQLConnector", "Lib"); string LibraryName = Path.Combine(LibrariesPath, "mariadbclient." + PlatformString + ".lib"); PublicAdditionalLibraries.Add(LibraryName); PrivateIncludePaths.AddRange(new string[] { "MySQLConnectorUE4Plugin/Private" }); PublicIncludePaths.AddRange(new string[] { "MySQLConnectorUE4Plugin/Public" }); string IncludesPath = Path.Combine(ThirdPartyPath, "MySQLConnector", "Include"); PublicIncludePaths.Add(IncludesPath); string IncludesPath2 = Path.Combine(ThirdPartyPath, "MySQLConnector", "Include", "cppconn"); PublicIncludePaths.Add(IncludesPath2); PublicDependencyModuleNames.AddRange(new string[] { "Engine", "Core", "CoreUObject" }); }
private static void FindAndCompileScriptModules(string ScriptsForProjectFileName, List <string> AdditionalScriptsFolders) { Log.TraceInformation("Compiling scripts."); var OldCWD = Environment.CurrentDirectory; var UnrealBuildToolCWD = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source"); Environment.CurrentDirectory = UnrealBuildToolCWD; // Configure the rules compiler // Get all game folders and convert them to build subfolders. List <DirectoryReference> AllGameFolders; if (ScriptsForProjectFileName == null) { AllGameFolders = UProjectInfo.FilterGameProjects(true, null).Select(x => x.Folder).ToList(); } else { AllGameFolders = new List <DirectoryReference> { new DirectoryReference(Path.GetDirectoryName(ScriptsForProjectFileName)) }; } var AllAdditionalScriptFolders = new List <DirectoryReference>(AdditionalScriptsFolders.Select(x => new DirectoryReference(x))); foreach (var Folder in AllGameFolders) { var GameBuildFolder = DirectoryReference.Combine(Folder, "Build"); if (DirectoryReference.Exists(GameBuildFolder)) { AllAdditionalScriptFolders.Add(GameBuildFolder); } } Log.TraceVerbose("Discovering game folders."); var DiscoveredModules = UnrealBuildTool.RulesCompiler.FindAllRulesSourceFiles(UnrealBuildTool.RulesCompiler.RulesFileType.AutomationModule, GameFolders: AllGameFolders, ForeignPlugins: null, AdditionalSearchPaths: AllAdditionalScriptFolders); var ModulesToCompile = new List <string>(DiscoveredModules.Count); foreach (var ModuleFilename in DiscoveredModules) { if (HostPlatform.Current.IsScriptModuleSupported(ModuleFilename.GetFileNameWithoutAnyExtensions())) { ModulesToCompile.Add(ModuleFilename.FullName); } else { CommandUtils.LogVerbose("Script module {0} filtered by the Host Platform and will not be compiled.", ModuleFilename); } } if ((UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealBuildTool.UnrealTargetPlatform.Win64) || (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealBuildTool.UnrealTargetPlatform.Win32)) { string Modules = string.Join(";", ModulesToCompile.ToArray()); var UATProj = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, @"Engine\Source\Programs\AutomationTool\Scripts\UAT.proj"); var CmdLine = String.Format("\"{0}\" /p:Modules=\"{1}\" /p:Configuration={2} /verbosity:minimal /nologo", UATProj, Modules, BuildConfig); // suppress the run command because it can be long and intimidating, making the logs around this code harder to read. var Result = CommandUtils.Run(CommandUtils.CmdEnv.MsBuildExe, CmdLine, Options: CommandUtils.ERunOptions.Default | CommandUtils.ERunOptions.NoLoggingOfRunCommand | CommandUtils.ERunOptions.LoggingOfRunDuration); if (Result.ExitCode != 0) { throw new AutomationException(String.Format("Failed to build \"{0}\":{1}{2}", UATProj, Environment.NewLine, Result.Output)); } } else { CompileModules(ModulesToCompile); } Environment.CurrentDirectory = OldCWD; }
private static bool RequiresTempTarget(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { return(false); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return(false); } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project return(true); } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // Change the working directory to be the Engine/Source folder. We are running from Engine/Binaries/DotNET string oldCWD = Directory.GetCurrentDirectory(); if (BuildConfiguration.RelativeEnginePath == "../../Engine/") { string EngineSourceDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "..", "..", "..", "Engine", "Source"); if (!Directory.Exists(EngineSourceDirectory)) // only set the directory if it exists, this should only happen if we are launching the editor from an artist sync { EngineSourceDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "..", "..", "..", "Engine", "Binaries"); } Directory.SetCurrentDirectory(EngineSourceDirectory); } // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath.FullName); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(new DirectoryReference(BuildConfiguration.RelativeEnginePath), RawProjectPath); // check the target platforms for any differences in build settings or additional plugins bool RetVal = false; foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { UEBuildPlatform BuildPlat = UEBuildPlatform.GetBuildPlatform(TargetPlatformType, true); if (!Automation.IsEngineInstalled() && BuildPlat != null && !(BuildPlat as UEBuildPlatform).HasDefaultBuildConfig(TargetPlatformType, RawProjectPath.Directory)) { RetVal = true; break; } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForProject = UProjectInfo.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetRules.TargetType.Game); if ((bPluginEnabledForProject && !Plugin.Descriptor.bEnabledByDefault) || (bPluginEnabledForProject && Plugin.Descriptor.bInstalled)) { if (Plugin.Descriptor.Modules.Any(Module => Module.IsCompiledInConfiguration(TargetPlatformType, TargetRules.TargetType.Game, bBuildDeveloperTools: false, bBuildEditor: false))) { RetVal = true; break; } } } } // Change back to the original directory Directory.SetCurrentDirectory(oldCWD); return(RetVal); }
private static bool RequiresTempTarget(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { return(false); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return(false); } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project return(true); } if (ClientTargetPlatforms != null) { foreach (UnrealTargetPlatform ClientPlatform in ClientTargetPlatforms) { String EncryptionKey; String[] SigningKeys; EncryptionAndSigning.ParseEncryptionIni(RawProjectPath.Directory, ClientPlatform, out SigningKeys, out EncryptionKey); if (SigningKeys != null || !string.IsNullOrEmpty(EncryptionKey)) { return(true); } } } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // Change the working directory to be the Engine/Source folder. We are running from Engine/Binaries/DotNET DirectoryReference oldCWD = DirectoryReference.GetCurrentDirectory(); try { DirectoryReference EngineSourceDirectory = DirectoryReference.Combine(CommandUtils.EngineDirectory, "Source"); if (!DirectoryReference.Exists(EngineSourceDirectory)) // only set the directory if it exists, this should only happen if we are launching the editor from an artist sync { EngineSourceDirectory = DirectoryReference.Combine(CommandUtils.EngineDirectory, "Binaries"); } Directory.SetCurrentDirectory(EngineSourceDirectory.FullName); // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath.FullName); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(CommandUtils.EngineDirectory, RawProjectPath, Project.AdditionalPluginDirectories); // check the target platforms for any differences in build settings or additional plugins bool RetVal = false; foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { if (!Automation.IsEngineInstalled() && !PlatformExports.HasDefaultBuildConfig(RawProjectPath, TargetPlatformType)) { RetVal = true; break; } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForProject = UProjectInfo.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetType.Game); if ((bPluginEnabledForProject && !Plugin.EnabledByDefault) || (bPluginEnabledForProject && Plugin.Descriptor.bInstalled)) { // NOTE: this code was only marking plugins that compiled for the platform to upgrade to code project, however // this doesn't work in practice, because the runtime code will look for the plugin, without a .uplugin file, // and will fail. This is the safest way to make sure all platforms are acting the same. However, if you // whitelist the plugin in the .uproject file, the above UProjectInfo.IsPluginEnabledForProject check won't pass // so you won't get in here. Leaving this commented out code in there, because someone is bound to come looking // for why a non-whitelisted platform module is causing a project to convert to code-based. // As an aside, if you run the project with UE4Game (not your Project's binary) from the debugger, it will work // _in this case_ because the .uplugin file will have been staged, and there is no needed library // if(Plugin.Descriptor.Modules.Any(Module => Module.IsCompiledInConfiguration(TargetPlatformType, TargetType.Game, bBuildDeveloperTools: false, bBuildEditor: false))) { RetVal = true; break; } } } } return(RetVal); } finally { // Change back to the original directory Directory.SetCurrentDirectory(oldCWD.FullName); } }
private static bool RequiresTempTarget(string RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms) { // check to see if we already have a Target.cs file // @todo: Target.cs may not be the same name as the project in the future, so look at a better way to determine this if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs"))) { return(false); } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // check the target platforms for any differences in build settings or additional plugins foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { IUEBuildPlatform BuildPlat = UEBuildPlatform.GetBuildPlatform(TargetPlatformType, true); if (BuildPlat != null && !(BuildPlat as UEBuildPlatform).HasDefaultBuildConfig(TargetPlatformType, Path.GetDirectoryName(RawProjectPath))) { return(true); } // find if there are any plugins List <string> PluginList = new List <string>(); // Use the project settings to update the plugin list for this target PluginList = UProjectInfo.GetEnabledPlugins(RawProjectPath, PluginList, TargetPlatformType); if (PluginList.Count > 0) { foreach (var PluginName in PluginList) { // check the plugin info for this plugin itself foreach (var Plugin in Plugins.AllPlugins) { if (Plugin.Name == PluginName) { foreach (var Module in Plugin.Modules) { if (Module.Platforms.Count > 0 && Module.Platforms.Contains(TargetPlatformType)) { return(true); } } break; } } } } } return(false); }
private static bool RequiresTempTarget(string RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs"))) { return(false); } else { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.GetDirectoryName(RawProjectPath)).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return(false); } } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // Change the working directory to be the Engine/Source folder. We are running from Engine/Binaries/DotNET string oldCWD = Directory.GetCurrentDirectory(); if (BuildConfiguration.RelativeEnginePath == "../../Engine/") { string EngineSourceDirectory = Path.Combine(UnrealBuildTool.Utils.GetExecutingAssemblyDirectory(), "..", "..", "..", "Engine", "Source"); if (!Directory.Exists(EngineSourceDirectory)) // only set the directory if it exists, this should only happen if we are launching the editor from an artist sync { EngineSourceDirectory = Path.Combine(UnrealBuildTool.Utils.GetExecutingAssemblyDirectory(), "..", "..", "..", "Engine", "Binaries"); } Directory.SetCurrentDirectory(EngineSourceDirectory); } // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(RawProjectPath); // check the target platforms for any differences in build settings or additional plugins bool RetVal = false; foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { IUEBuildPlatform BuildPlat = UEBuildPlatform.GetBuildPlatform(TargetPlatformType, true); if (BuildPlat != null && !(BuildPlat as UEBuildPlatform).HasDefaultBuildConfig(TargetPlatformType, Path.GetDirectoryName(RawProjectPath))) { RetVal = true; break; } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { if (UProjectInfo.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType) != Plugin.Descriptor.bEnabledByDefault) { if (Plugin.Descriptor.Modules.Any(Module => Module.IsCompiledInConfiguration(TargetPlatformType, TargetRules.TargetType.Game))) { RetVal = true; break; } } } } // Change back to the original directory Directory.SetCurrentDirectory(oldCWD); return(RetVal); }