/// <summary> /// Inserts variables to make a file relative to $(EngineDir) or $(ProjectDir) /// </summary> /// <param name="File">The file to insert variables into.</param> /// <param name="EngineDir">Value of the $(EngineDir) variable.</param> /// <param name="ProjectDir">Value of the $(ProjectDir) variable.</param> /// <returns>Converted path for the file.</returns> static string InsertPathVariables(FileReference File, DirectoryReference EngineDir, DirectoryReference ProjectDir) { if (File.IsUnderDirectory(EngineDir)) { return("$(EngineDir)/" + File.MakeRelativeTo(EngineDir).Replace(Path.DirectorySeparatorChar, '/')); } else if (ProjectDir != null && File.IsUnderDirectory(ProjectDir)) { return("$(ProjectDir)/" + File.MakeRelativeTo(ProjectDir).Replace(Path.DirectorySeparatorChar, '/')); } else { return(File.FullName); } }
/// <summary> /// Inserts variables to make a file relative to $(EngineDir) or $(ProjectDir) /// </summary> /// <param name="File">The file to insert variables into.</param> /// <param name="EngineDir">Value of the $(EngineDir) variable.</param> /// <param name="ProjectDir">Value of the $(ProjectDir) variable.</param> /// <returns>Converted path for the file.</returns> public static string InsertPathVariables(FileReference File, DirectoryReference EngineDir, DirectoryReference ProjectDir) { if (File.IsUnderDirectory(EngineDir)) { return("$(EngineDir)" + Path.DirectorySeparatorChar + File.MakeRelativeTo(EngineDir)); } else if (File.IsUnderDirectory(ProjectDir)) { return("$(ProjectDir)" + Path.DirectorySeparatorChar + File.MakeRelativeTo(ProjectDir)); } else { return(File.FullName); } }
/// <summary> /// Checks whether the given file is under an installed directory, and should not be overridden /// </summary> /// <param name="File">File to test</param> /// <returns>True if the file is part of the installed distribution, false otherwise</returns> static public bool IsFileInstalled(FileReference File) { if (IsEngineInstalled() && File.IsUnderDirectory(EngineDirectory)) { return(true); } if (IsEnterpriseInstalled() && File.IsUnderDirectory(EnterpriseDirectory)) { return(true); } if (IsProjectInstalled() && File.IsUnderDirectory(InstalledProjectFile.Directory)) { return(true); } return(false); }
/// <summary> /// Takes the given path and tries to rebase it relative to the project. /// </summary> public string NormalizeProjectPath(FileReference InputPath) { // Try to make it relative to the solution directory. if (InputPath.IsUnderDirectory(ProjectFileGenerator.MasterProjectPath)) { return(InputPath.MakeRelativeTo(ProjectFileGenerator.IntermediateProjectFilesPath)); } else { return(InputPath.FullName); } }
/// <summary> /// Checks if the given file is part of the working set /// </summary> /// <param name="File">File to check</param> /// <returns>True if the file is part of the working set, false otherwise</returns> public bool Contains(FileReference File) { WaitForBackgroundProcess(); if (Files.Contains(File) || Directories.Any(x => File.IsUnderDirectory(x))) { return(true); } if (Inner != null && Inner.Contains(File)) { return(true); } return(false); }
/// <summary> /// Downloads a single file from the remote /// </summary> /// <param name="LocalFile">The file to download</param> void DownloadFile(FileReference LocalFile) { RemoteMapping Mapping = Mappings.FirstOrDefault(x => LocalFile.IsUnderDirectory(x.LocalDirectory)); if (Mapping == null) { throw new BuildException("File for download '{0}' is not under any mapped directory.", LocalFile); } List <string> Arguments = new List <string>(CommonRsyncArguments); Arguments.Add(String.Format("\"{0}@{1}\":'{2}/{3}'", UserName, ServerName, Mapping.RemoteDirectory, LocalFile.MakeRelativeTo(Mapping.LocalDirectory).Replace('\\', '/'))); Arguments.Add(String.Format("\"{0}/\"", GetLocalCygwinPath(LocalFile.Directory))); Arguments.Add("-q"); int Result = Rsync(String.Join(" ", Arguments)); if (Result != 0) { throw new BuildException("Unable to download '{0}' from the remote Mac (exit code {1}).", LocalFile, Result); } }
/// <summary> /// Determines if this module can be precompiled for the current target. /// </summary> /// <param name="RulesFile">Path to the module rules file</param> /// <returns>True if the module can be precompiled, false otherwise</returns> internal bool IsValidForTarget(FileReference RulesFile) { if (Type == ModuleRules.ModuleType.CPlusPlus) { switch (PrecompileForTargets) { case ModuleRules.PrecompileTargetsType.None: return(false); case ModuleRules.PrecompileTargetsType.Default: return(Target.Type == TargetType.Editor || !RulesFile.IsUnderDirectory(UnrealBuildTool.EngineSourceDeveloperDirectory) || Plugin != null); case ModuleRules.PrecompileTargetsType.Game: return(Target.Type == TargetType.Client || Target.Type == TargetType.Server || Target.Type == TargetType.Game); case ModuleRules.PrecompileTargetsType.Editor: return(Target.Type == TargetType.Editor); case ModuleRules.PrecompileTargetsType.Any: return(true); } } return(false); }
/// <summary> /// Upload all the files in the workspace for the current project /// </summary> void UploadWorkspace(DirectoryReference TempDir) { // Path to the scripts to be uploaded FileReference ScriptPathsFileName = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "Rsync", "RsyncEngineScripts.txt"); // Read the list of scripts to be uploaded List <string> ScriptPaths = new List <string>(); foreach (string Line in FileReference.ReadAllLines(ScriptPathsFileName)) { string FileToUpload = Line.Trim(); if (FileToUpload.Length > 0 && FileToUpload[0] != ';') { ScriptPaths.Add(FileToUpload); } } // Fixup the line endings List <FileReference> TargetFiles = new List <FileReference>(); foreach (string ScriptPath in ScriptPaths) { FileReference SourceFile = FileReference.Combine(UnrealBuildTool.EngineDirectory, ScriptPath.TrimStart('/')); if (!FileReference.Exists(SourceFile)) { throw new BuildException("Missing script required for remote upload: {0}", SourceFile); } FileReference TargetFile = FileReference.Combine(TempDir, SourceFile.MakeRelativeTo(UnrealBuildTool.EngineDirectory)); if (!FileReference.Exists(TargetFile) || FileReference.GetLastWriteTimeUtc(TargetFile) < FileReference.GetLastWriteTimeUtc(SourceFile)) { DirectoryReference.CreateDirectory(TargetFile.Directory); string ScriptText = FileReference.ReadAllText(SourceFile); FileReference.WriteAllText(TargetFile, ScriptText.Replace("\r\n", "\n")); } TargetFiles.Add(TargetFile); } // Write a file that protects all the scripts from being overridden by the standard engine filters FileReference ScriptUploadList = FileReference.Combine(TempDir, "RsyncEngineScripts-Upload.txt"); using (StreamWriter Writer = new StreamWriter(ScriptUploadList.FullName)) { foreach (string ScriptPath in ScriptPaths) { for (int SlashIdx = ScriptPath.IndexOf('/', 1); SlashIdx != -1; SlashIdx = ScriptPath.IndexOf('/', SlashIdx + 1)) { Writer.WriteLine("+ {0}", ScriptPath.Substring(0, SlashIdx)); } Writer.WriteLine("+ {0}", ScriptPath); } Writer.WriteLine("protect *"); } // Write a file that protects all the scripts from being overridden by the standard engine filters FileReference ScriptProtectList = FileReference.Combine(TempDir, "RsyncEngineScripts-Protect.txt"); using (StreamWriter Writer = new StreamWriter(ScriptProtectList.FullName)) { foreach (string ScriptPath in ScriptPaths) { Writer.WriteLine("protect {0}", ScriptPath); } } // Upload these files to the remote List <FileReference> FilterLocations = new List <FileReference>(); FilterLocations.Add(ScriptUploadList); UploadDirectory(TempDir, GetRemotePath(UnrealBuildTool.EngineDirectory), FilterLocations); // Upload the engine files List <FileReference> EngineFilters = new List <FileReference>(); EngineFilters.Add(ScriptProtectList); EngineFilters.Add(FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "Rsync", "RsyncEngine.txt")); UploadDirectory(UnrealBuildTool.EngineDirectory, GetRemotePath(UnrealBuildTool.EngineDirectory), EngineFilters); // Upload the project files if (ProjectFile != null && !ProjectFile.IsUnderDirectory(UnrealBuildTool.EngineDirectory)) { List <FileReference> ProjectFilters = new List <FileReference>(); FileReference CustomProjectFilter = FileReference.Combine(ProjectFile.Directory, "Build", "Rsync", "RsyncProject.txt"); if (FileReference.Exists(CustomProjectFilter)) { ProjectFilters.Add(CustomProjectFilter); } ProjectFilters.Add(FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "Rsync", "RsyncProject.txt")); UploadDirectory(ProjectFile.Directory, GetRemotePath(ProjectFile.Directory), ProjectFilters); } }
/// <summary> /// Constructor /// </summary> /// <param name="ProjectFile">Project to read settings from</param> public RemoteMac(FileReference ProjectFile) { this.RsyncExe = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Rsync.exe"); this.SshExe = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "ThirdPartyNotUE", "DeltaCopy", "Binaries", "Ssh.exe"); this.ProjectFile = ProjectFile; this.ProjectDirectory = DirectoryReference.FromFile(ProjectFile); // Apply settings from the XML file XmlConfig.ApplyTo(this); // Get the project config file path DirectoryReference EngineIniPath = ProjectFile != null ? ProjectFile.Directory : null; if (EngineIniPath == null && UnrealBuildTool.GetRemoteIniPath() != null) { EngineIniPath = new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()); } ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, EngineIniPath, UnrealTargetPlatform.IOS); // Read the project settings if we don't have anything in the build configuration settings if (String.IsNullOrEmpty(ServerName)) { // Read the server name string IniServerName; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RemoteServerName", out IniServerName) && !String.IsNullOrEmpty(IniServerName)) { this.ServerName = IniServerName; } else { throw new BuildException("Remote compiling requires a server name. Use the editor (Project Settings > IOS) to set up your remote compilation settings."); } // Parse the username string IniUserName; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "RSyncUsername", out IniUserName) && !String.IsNullOrEmpty(IniUserName)) { this.UserName = IniUserName; } } // Split port out from the server name int PortIdx = ServerName.LastIndexOf(':'); if (PortIdx != -1) { string Port = ServerName.Substring(PortIdx + 1); if (!int.TryParse(Port, out ServerPort)) { throw new BuildException("Unable to parse port number from '{0}'", ServerName); } ServerName = ServerName.Substring(0, PortIdx); } // If a user name is not set, use the current user if (String.IsNullOrEmpty(UserName)) { UserName = Environment.UserName; } // Print out the server info Log.TraceInformation("[Remote] Using remote server '{0}' on port {1} (user '{2}')", ServerName, ServerPort, UserName); // Get the path to the SSH private key string OverrideSshPrivateKeyPath; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "SSHPrivateKeyOverridePath", out OverrideSshPrivateKeyPath) && !String.IsNullOrEmpty(OverrideSshPrivateKeyPath)) { SshPrivateKey = new FileReference(OverrideSshPrivateKeyPath); if (!FileReference.Exists(SshPrivateKey)) { throw new BuildException("SSH private key specified in config file ({0}) does not exist.", SshPrivateKey); } } // If it's not set, look in the standard locations. If that fails, spawn the batch file to generate one. if (SshPrivateKey == null && !TryGetSshPrivateKey(out SshPrivateKey)) { Log.TraceWarning("No SSH private key found for {0}@{1}. Launching SSH to generate one.", UserName, ServerName); StringBuilder CommandLine = new StringBuilder(); CommandLine.AppendFormat("/C \"\"{0}\"", FileReference.Combine(UnrealBuildTool.EngineDirectory, "Build", "BatchFiles", "MakeAndInstallSSHKey.bat")); CommandLine.AppendFormat(" \"{0}\"", SshExe); CommandLine.AppendFormat(" \"{0}\"", ServerPort); CommandLine.AppendFormat(" \"{0}\"", RsyncExe); CommandLine.AppendFormat(" \"{0}\"", UserName); CommandLine.AppendFormat(" \"{0}\"", ServerName); CommandLine.AppendFormat(" \"{0}\"", DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments)); CommandLine.AppendFormat(" \"{0}\"", GetLocalCygwinPath(DirectoryReference.GetSpecialFolder(Environment.SpecialFolder.MyDocuments))); CommandLine.AppendFormat(" \"{0}\"", UnrealBuildTool.EngineDirectory); CommandLine.Append("\""); using (Process ChildProcess = Process.Start("C:\\Windows\\System32\\Cmd.exe", CommandLine.ToString())) { ChildProcess.WaitForExit(); } if (!TryGetSshPrivateKey(out SshPrivateKey)) { throw new BuildException("Failed to generate SSH private key for {0}@{1}.", UserName, ServerName); } } // resolve the rest of the strings RsyncAuthentication = ExpandVariables(RsyncAuthentication); SshAuthentication = ExpandVariables(SshAuthentication); // Get the remote base directory RemoteBaseDir = String.Format("/Users/{0}/UE4/Builds/{1}", UserName, Environment.MachineName); // Build the list of directory mappings between the local and remote machines Mappings = new List <RemoteMapping>(); Mappings.Add(new RemoteMapping(UnrealBuildTool.EngineDirectory, GetRemotePath(UnrealBuildTool.EngineDirectory))); if (ProjectFile != null && !ProjectFile.IsUnderDirectory(UnrealBuildTool.EngineDirectory)) { Mappings.Add(new RemoteMapping(ProjectFile.Directory, GetRemotePath(ProjectFile.Directory))); } // Build a list of arguments for SSH CommonSshArguments = new List <string>(); CommonSshArguments.Add("-o BatchMode=yes"); CommonSshArguments.Add(SshAuthentication); CommonSshArguments.Add(String.Format("-p {0}", ServerPort)); CommonSshArguments.Add(String.Format("\"{0}@{1}\"", UserName, ServerName)); // Build a list of arguments for Rsync CommonRsyncArguments = new List <string>(); CommonRsyncArguments.Add("--compress"); CommonRsyncArguments.Add("--recursive"); CommonRsyncArguments.Add("--delete"); // Delete anything not in the source directory CommonRsyncArguments.Add("--delete-excluded"); // Delete anything not in the source directory CommonRsyncArguments.Add("--times"); // Preserve modification times CommonRsyncArguments.Add("--verbose"); CommonRsyncArguments.Add("-m"); CommonRsyncArguments.Add("--chmod=ug=rwX,o=rxX"); CommonRsyncArguments.Add(String.Format("--rsh=\"{0} -p {1}\"", RsyncAuthentication, ServerPort)); }
/// <summary> /// Checks if the given file is part of the working set /// </summary> /// <param name="File">File to check</param> /// <returns>True if the file is part of the working set, false otherwise</returns> public bool Contains(FileReference File) { WaitForBackgroundProcess(); return(Files.Contains(File) || Directories.Any(x => File.IsUnderDirectory(x))); }
private void MakePackage(TargetReceipt Receipt, TargetReceipt NewReceipt, WindowsArchitecture Architecture, List <string> UpdatedFiles) { string OutputName = String.Format("{0}_{1}_{2}_{3}", Receipt.TargetName, Receipt.Platform, Receipt.Configuration, WindowsExports.GetArchitectureSubpath(Architecture)); string IntermediateDirectory = Path.Combine(Receipt.ProjectDir != null ? Receipt.ProjectDir.FullName : UnrealBuildTool.EngineDirectory.FullName, "Intermediate", "Deploy", WindowsExports.GetArchitectureSubpath(Architecture)); string OutputDirectory = Receipt.Launch.Directory.FullName; string OutputAppX = Path.Combine(OutputDirectory, OutputName + ".appx"); string SigningCertificate = @"Build\HoloLens\SigningCertificate.pfx"; string SigningCertificatePath = Path.Combine(Receipt.ProjectDir != null ? Receipt.ProjectDir.FullName : UnrealBuildTool.EngineDirectory.FullName, SigningCertificate); string MapFilename = Path.Combine(IntermediateDirectory, OutputName + ".pkgmap"); var LocalRoot = Receipt.ProjectDir; var EngineRoot = UnrealBuildTool.RootDirectory; var AddedFiles = new Dictionary <string, string>(); bool PackageFileNeedToBeUpdated = !File.Exists(OutputAppX); DateTime AppXTime = DateTime.Now; PackageFileNeedToBeUpdated = true; if (!PackageFileNeedToBeUpdated) { AppXTime = File.GetLastWriteTimeUtc(OutputAppX); } { foreach (var Product in Receipt.BuildProducts) { if (Product.Type == BuildProductType.Executable || Product.Type == BuildProductType.DynamicLibrary || Product.Type == BuildProductType.RequiredResource) { string Filename; if (AddedFiles.ContainsKey(Product.Path.FullName)) { continue; } if (LocalRoot != null && Product.Path.IsUnderDirectory(LocalRoot)) { Filename = Product.Path.MakeRelativeTo(LocalRoot.ParentDirectory); } else if (Product.Path.IsUnderDirectory(EngineRoot)) { Filename = Product.Path.MakeRelativeTo(EngineRoot); } else { throw new BuildException("Failed to parse target receipt file. See log for details."); } AddedFiles.Add(Product.Path.FullName, Filename); } } foreach (var Dep in Receipt.RuntimeDependencies) { if (Dep.Type == StagedFileType.NonUFS) { if (AddedFiles.ContainsKey(Dep.Path.FullName)) { continue; } string Filename; if (LocalRoot != null && Dep.Path.IsUnderDirectory(LocalRoot)) { Filename = Dep.Path.MakeRelativeTo(LocalRoot.ParentDirectory); } else if (Dep.Path.IsUnderDirectory(EngineRoot)) { Filename = Dep.Path.MakeRelativeTo(EngineRoot); } else { throw new BuildException("Failed to parse target receipt file. See log for details."); } AddedFiles.Add(Dep.Path.FullName, Filename); } } } string ManifestName = String.Format("AppxManifest_{0}.xml", WindowsExports.GetArchitectureSubpath(Architecture)); AddedFiles.Add(Path.Combine(OutputDirectory, ManifestName), "AppxManifest.xml"); //manually add resources string PriFileName = String.Format("resources_{0}.pri", WindowsExports.GetArchitectureSubpath(Architecture)); AddedFiles.Add(Path.Combine(OutputDirectory, PriFileName), "resources.pri"); { DirectoryReference ResourceFolder = DirectoryReference.Combine(Receipt.Launch.Directory, WindowsExports.GetArchitectureSubpath(Architecture)); foreach (var ResourcePath in UpdatedFiles) { var ResourceFile = new FileReference(ResourcePath); if (ResourceFile.IsUnderDirectory(ResourceFolder)) { AddedFiles.Add(ResourceFile.FullName, ResourceFile.MakeRelativeTo(ResourceFolder)); } else { Log.TraceError("Wrong path to resource \'{0}\', the resource should be in \'{1}\'", ResourceFile.FullName, ResourceFolder.FullName); throw new BuildException("Failed to generate AppX file. See log for details."); } } } FileReference SourceNetworkManifestPath = new FileReference(Path.Combine(OutputDirectory, "NetworkManifest.xml")); if (FileReference.Exists(SourceNetworkManifestPath)) { AddedFiles.Add(SourceNetworkManifestPath.FullName, "NetworkManifest.xml"); } FileReference SourceXboxConfigPath = new FileReference(Path.Combine(OutputDirectory, "xboxservices.config")); if (FileReference.Exists(SourceXboxConfigPath)) { AddedFiles.Add(SourceXboxConfigPath.FullName, "xboxservices.config"); } do { if (PackageFileNeedToBeUpdated) { break; } if (!File.Exists(MapFilename)) { PackageFileNeedToBeUpdated = true; break; } string[] lines = File.ReadAllLines(MapFilename, Encoding.UTF8); int filesCount = 0; foreach (var line in lines) { if (line[0] == '[') { continue; } string[] files = line.Split('\t'); if (files.Length != 2) { PackageFileNeedToBeUpdated = true; break; } files[0] = files[0].Trim('\"'); files[1] = files[1].Trim('\"'); if (!AddedFiles.ContainsKey(files[0])) { PackageFileNeedToBeUpdated = true; break; } if (AddedFiles[files[0]] != files[1]) { PackageFileNeedToBeUpdated = true; break; } if (File.GetLastWriteTimeUtc(files[0]).CompareTo(AppXTime) >= 0) { PackageFileNeedToBeUpdated = true; break; } ++filesCount; } if (PackageFileNeedToBeUpdated) { break; } if (filesCount != AddedFiles.Count) { PackageFileNeedToBeUpdated = true; break; } if (File.Exists(SigningCertificatePath) && File.GetLastWriteTimeUtc(SigningCertificatePath).CompareTo(AppXTime) >= 0) { PackageFileNeedToBeUpdated = true; break; } }while(false); if (!PackageFileNeedToBeUpdated) { NewReceipt.BuildProducts.Add(new BuildProduct(new FileReference(OutputAppX), BuildProductType.Package)); return; } try { DeployHelper_DeleteFile(OutputAppX); } catch (Exception exceptionMessage) { Log.TraceError("Failed to delete {0} from deployment: {1}", OutputAppX, exceptionMessage); throw new BuildException("Failed to generate AppX file. See log for details."); } var AppXRecipeBuiltFiles = new StringBuilder(); AppXRecipeBuiltFiles.AppendLine(@"[Files]"); foreach (var f in AddedFiles) { AppXRecipeBuiltFiles.AppendLine(String.Format("\"{0}\"\t\"{1}\"", f.Key, f.Value)); } File.WriteAllText(MapFilename, AppXRecipeBuiltFiles.ToString(), Encoding.UTF8); NewReceipt.BuildProducts.Add(new BuildProduct(new FileReference(MapFilename), BuildProductType.MapFile)); }
/// <summary> /// Determines whether the given module name is a game module (as opposed to an engine module) /// </summary> public bool IsGameModule(string InModuleName) { FileReference ModuleFileName = GetModuleFileName(InModuleName); return(ModuleFileName != null && !ModuleFileName.IsUnderDirectory(UnrealBuildTool.EngineDirectory)); }
/// <summary> /// Return all data driven infos found /// </summary> /// <returns></returns> public static Dictionary <string, ConfigDataDrivenPlatformInfo> GetAllPlatformInfos() { // need to init? if (PlatformInfos == null) { PlatformInfos = new Dictionary <string, ConfigDataDrivenPlatformInfo>(); Dictionary <string, string> IniParents = new Dictionary <string, string>(); foreach (DirectoryReference EngineConfigDir in UnrealBuildTool.GetAllEngineDirectories("Config")) { // look through all config dirs looking for the data driven ini file foreach (string FilePath in Directory.EnumerateFiles(EngineConfigDir.FullName, "DataDrivenPlatformInfo.ini", SearchOption.AllDirectories)) { FileReference FileRef = new FileReference(FilePath); // get the platform name from the path string IniPlatformName; if (FileRef.IsUnderDirectory(DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Config"))) { // Foo/Engine/Config/<Platform>/DataDrivenPlatformInfo.ini IniPlatformName = Path.GetFileName(Path.GetDirectoryName(FilePath)); } else { // Foo/Engine/Platforms/<Platform>/Config/DataDrivenPlatformInfo.ini IniPlatformName = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(FilePath))); } // load the DataDrivenPlatformInfo from the path ConfigFile Config = new ConfigFile(FileRef); ConfigDataDrivenPlatformInfo NewInfo = new ConfigDataDrivenPlatformInfo(); // we must have the key section ConfigFileSection Section = null; if (Config.TryGetSection("DataDrivenPlatformInfo", out Section)) { ConfigHierarchySection ParsedSection = new ConfigHierarchySection(new List <ConfigFileSection>() { Section }); // get string values string IniParent; if (ParsedSection.TryGetValue("IniParent", out IniParent)) { IniParents[IniPlatformName] = IniParent; } // slightly nasty bool parsing for bool values string Temp; if (ParsedSection.TryGetValue("bIsConfidential", out Temp) == false || ConfigHierarchy.TryParse(Temp, out NewInfo.bIsConfidential) == false) { NewInfo.bIsConfidential = false; } // get a list of additional restricted folders IReadOnlyList <string> AdditionalRestrictedFolders; if (ParsedSection.TryGetValues("AdditionalRestrictedFolders", out AdditionalRestrictedFolders) && AdditionalRestrictedFolders.Count > 0) { NewInfo.AdditionalRestrictedFolders = AdditionalRestrictedFolders.Select(x => x.Trim()).Where(x => x.Length > 0).ToArray(); } // create cache it PlatformInfos[IniPlatformName] = NewInfo; } } } // now that all are read in, calculate the ini parent chain, starting with parent-most foreach (KeyValuePair <string, ConfigDataDrivenPlatformInfo> Pair in PlatformInfos) { string CurrentPlatform; // walk up the chain and build up the ini chain List <string> Chain = new List <string>(); if (IniParents.TryGetValue(Pair.Key, out CurrentPlatform)) { while (!string.IsNullOrEmpty(CurrentPlatform)) { // insert at 0 to reverse the order Chain.Insert(0, CurrentPlatform); if (IniParents.TryGetValue(CurrentPlatform, out CurrentPlatform) == false) { break; } } } // bake it into the info if (Chain.Count > 0) { Pair.Value.IniParentChain = Chain.ToArray(); } } } return(PlatformInfos); }
/// <summary> /// Determines if a file is part of the given module /// </summary> /// <param name="Location">Path to the file</param> /// <returns>True if the file is part of this module</returns> public virtual bool ContainsFile(FileReference Location) { return(Location.IsUnderDirectory(ModuleDirectory)); }
/// <summary> /// Creates an instance of a module rules descriptor object for the specified module name /// </summary> /// <param name="ModuleName">Name of the module</param> /// <param name="Target">Information about the target associated with this module</param> /// <param name="ReferenceChain">Chain of references leading to this module</param> /// <param name="ModuleFileName">The original source file name for the Module.cs file for this module</param> /// <returns>Compiled module rule info</returns> public ModuleRules CreateModuleRules(string ModuleName, ReadOnlyTargetRules Target, string ReferenceChain, out FileReference ModuleFileName) { // Currently, we expect the user's rules object type name to be the same as the module name string ModuleTypeName = ModuleName; // Make sure the module file is known to us if (!ModuleNameToModuleFile.TryGetValue(ModuleName, out ModuleFileName)) { if (Parent == null) { throw new BuildException("Could not find definition for module '{0}' (referenced via {1})", ModuleName, ReferenceChain); } else { return(Parent.CreateModuleRules(ModuleName, Target, ReferenceChain, out ModuleFileName)); } } // The build module must define a type named 'Rules' that derives from our 'ModuleRules' type. Type RulesObjectType = GetModuleRulesTypeInternal(ModuleName); if (RulesObjectType == null) { throw new BuildException("Expecting to find a type to be declared in a module rules named '{0}' in {1}. This type must derive from the 'ModuleRules' type defined by Unreal Build Tool.", ModuleTypeName, CompiledAssembly.FullName); } // Create an instance of the module's rules object try { // Create an uninitialized ModuleRules object and set some defaults. ModuleRules RulesObject = (ModuleRules)FormatterServices.GetUninitializedObject(RulesObjectType); RulesObject.bTreatAsEngineModule = bContainsEngineModules; RulesObject.bUseBackwardsCompatibleDefaults = bUseBackwardsCompatibleDefaults && Target.bUseBackwardsCompatibleDefaults; RulesObject.bPrecompile = RulesObject.bTreatAsEngineModule && Target.bPrecompile; RulesObject.bUsePrecompiled = (RulesObject.bTreatAsEngineModule && Target.bUsePrecompiled) || bInstalled; if (ModuleFileName.IsUnderDirectory(UnrealBuildTool.EnterpriseDirectory) && !UnrealBuildTool.IsEnterpriseInstalled()) { RulesObject.bUsePrecompiled = false; } // Call the constructor ConstructorInfo Constructor = RulesObjectType.GetConstructor(new Type[] { typeof(ReadOnlyTargetRules) }); if (Constructor == null) { throw new BuildException("No valid constructor found for {0}.", ModuleName); } Constructor.Invoke(RulesObject, new object[] { Target }); // Update the precompiled flags if (RulesObject.bPrecompile && !RulesObject.CanPrecompile(ModuleFileName)) { RulesObject.bPrecompile = false; } return(RulesObject); } catch (Exception Ex) { Exception MessageEx = (Ex is TargetInvocationException && Ex.InnerException != null)? Ex.InnerException : Ex; throw new BuildException(Ex, "Unable to instantiate module '{0}': {1}\n(referenced via {2})", ModuleName, MessageEx.ToString(), ReferenceChain); } }
private FileReference GetExecutableFilename(ProjectFile Project, ProjectTarget Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration) { TargetRules TargetRulesObject = Target.TargetRules; FileReference TargetFilePath = Target.TargetFilePath; string TargetName = TargetFilePath == null?Project.ProjectFilePath.GetFileNameWithoutExtension() : TargetFilePath.GetFileNameWithoutAnyExtensions(); string UBTPlatformName = Platform.ToString(); string UBTConfigurationName = Configuration.ToString(); string ProjectName = Project.ProjectFilePath.GetFileNameWithoutExtension(); // Setup output path UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform); // Figure out if this is a monolithic build bool bShouldCompileMonolithic = BuildPlatform.ShouldCompileMonolithicBinary(Platform); if (TargetRulesObject != null) { bShouldCompileMonolithic |= (Target.CreateRulesDelegate(Platform, Configuration).GetLegacyLinkType(Platform, Configuration) == TargetLinkType.Monolithic); } TargetType TargetRulesType = Target.TargetRules == null ? TargetType.Program : Target.TargetRules.Type; // Get the output directory DirectoryReference RootDirectory = UnrealBuildTool.EngineDirectory; if (TargetRulesType != TargetType.Program && (bShouldCompileMonolithic || TargetRulesObject.BuildEnvironment == TargetBuildEnvironment.Unique) && !TargetRulesObject.bOutputToEngineBinaries) { if (OnlyGameProject != null && TargetFilePath.IsUnderDirectory(OnlyGameProject.Directory)) { RootDirectory = OnlyGameProject.Directory; } else { FileReference ProjectFileName; if (UProjectInfo.TryGetProjectFileName(ProjectName, out ProjectFileName)) { RootDirectory = ProjectFileName.Directory; } } } if (TargetRulesType == TargetType.Program && (TargetRulesObject == null || !TargetRulesObject.bOutputToEngineBinaries)) { FileReference ProjectFileName; if (UProjectInfo.TryGetProjectForTarget(TargetName, out ProjectFileName)) { RootDirectory = ProjectFileName.Directory; } } // Get the output directory DirectoryReference OutputDirectory = DirectoryReference.Combine(RootDirectory, "Binaries", UBTPlatformName); // Get the executable name (minus any platform or config suffixes) string BaseExeName = TargetName; if (!bShouldCompileMonolithic && TargetRulesType != TargetType.Program) { // Figure out what the compiled binary will be called so that we can point the IDE to the correct file string TargetConfigurationName = TargetRulesType.ToString(); if (TargetConfigurationName != TargetType.Game.ToString() && TargetConfigurationName != TargetType.Program.ToString()) { BaseExeName = "UE4" + TargetConfigurationName; } } // Make the output file path string ExecutableFilename = FileReference.Combine(OutputDirectory, BaseExeName).ToString(); if ((Configuration != UnrealTargetConfiguration.DebugGame || bShouldCompileMonolithic)) { ExecutableFilename += "-" + UBTPlatformName + "-" + UBTConfigurationName; } ExecutableFilename += TargetRulesObject.Architecture; ExecutableFilename += BuildPlatform.GetBinaryExtension(UEBuildBinaryType.Executable); return(FileReference.MakeFromNormalizedFullPath(ExecutableFilename)); }