public void AddRuntimeDependenciesForCopying(ReadOnlyTargetRules Target) { if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32)) { RuntimeDependencies.Add(Path.Combine(ScriptsPath, "...")); if (AutoAddProjectScriptsInPackaging) { RuntimeDependencies.Add("$(ProjectDir)/Content/Scripts/..."); } //Copy binaries as dependencies if (UseThirdPartyPython) { string PlatformString = Target.Platform.ToString(); bool bVerboseBuild = false; //Don't add android stuff so we use a manual method to enum a directory Tools.DotNETCommon.DirectoryReference BinDir = new Tools.DotNETCommon.DirectoryReference(Path.Combine(BinariesPath, PlatformString, "...")); if (Tools.DotNETCommon.DirectoryReference.Exists(BinDir)) { foreach (Tools.DotNETCommon.FileReference File in Tools.DotNETCommon.DirectoryReference.EnumerateFiles(BinDir, "*", SearchOption.AllDirectories)) { //if (!File.ToString().Contains("android")) bool bValidFile = !File.ToString().Contains("Lib\\site-packages"); //don't copy site-packages (staging path likely too long) bValidFile = bValidFile && !File.ToString().Contains("Binaries\\Win64\\UE4Editor"); //don't copy UEEditor dll/pdbs. These are not used if (bValidFile) { RuntimeDependencies.Add(File.ToString()); } /*else if (bVerboseBuild) * { * Log.TraceInformation("Not adding the following file as RuntimeDependency: "); * Log.TraceInformation(File.ToString()); * }*/ } } //Copy the thirdparty dll so ue4 loads it by default string DLLName = PythonType.ToLower() + ".dll"; string PluginDLLPath = Path.Combine(BinariesPath, PlatformString, DLLName); CopyToProjectBinaries(PluginDLLPath, Target); //After it's been copied add it as a dependency so it gets copied on packaging string DLLPath = Path.GetFullPath(Path.Combine(GetUProjectPath(), "Binaries", PlatformString, DLLName)); RuntimeDependencies.Add(DLLPath); } //end if thirdparty } //end windows }
/// <summary> /// Create a full path by concatenating multiple strings /// </summary> /// <returns></returns> static protected string CombineStrings(DirectoryReference BaseDirectory, params string[] Fragments) { // Get the initial string to append to, and strip any root directory suffix from it StringBuilder NewFullName = new StringBuilder(BaseDirectory.FullName); if (NewFullName.Length > 0 && NewFullName[NewFullName.Length - 1] == Path.DirectorySeparatorChar) { NewFullName.Remove(NewFullName.Length - 1, 1); } // Scan through the fragments to append, appending them to a string and updating the base length as we go foreach (string Fragment in Fragments) { // Check if this fragment is an absolute path if ((Fragment.Length >= 2 && Fragment[1] == ':') || (Fragment.Length >= 1 && (Fragment[0] == '\\' || Fragment[0] == '/'))) { // It is. Reset the new name to the full version of this path. NewFullName.Clear(); NewFullName.Append(Path.GetFullPath(Fragment).TrimEnd(Path.DirectorySeparatorChar)); } else { // Append all the parts of this fragment to the end of the existing path. int StartIdx = 0; while (StartIdx < Fragment.Length) { // Find the end of this fragment. We may have been passed multiple paths in the same string. int EndIdx = StartIdx; while (EndIdx < Fragment.Length && Fragment[EndIdx] != '\\' && Fragment[EndIdx] != '/') { EndIdx++; } // Ignore any empty sections, like leading or trailing slashes, and '.' directory references. int Length = EndIdx - StartIdx; if (Length == 0) { // Multiple directory separators in a row; illegal. throw new ArgumentException(String.Format("Path fragment '{0}' contains invalid directory separators.", Fragment)); } else if (Length == 2 && Fragment[StartIdx] == '.' && Fragment[StartIdx + 1] == '.') { // Remove the last directory name for (int SeparatorIdx = NewFullName.Length - 1; SeparatorIdx >= 0; SeparatorIdx--) { if (NewFullName[SeparatorIdx] == Path.DirectorySeparatorChar) { NewFullName.Remove(SeparatorIdx, NewFullName.Length - SeparatorIdx); break; } } } else if (Length != 1 || Fragment[StartIdx] != '.') { // Append this fragment NewFullName.Append(Path.DirectorySeparatorChar); NewFullName.Append(Fragment, StartIdx, Length); } // Move to the next part StartIdx = EndIdx + 1; } } } // Append the directory separator if (NewFullName.Length == 0 || (NewFullName.Length == 2 && NewFullName[1] == ':')) { NewFullName.Append(Path.DirectorySeparatorChar); } // Set the new path variables return(NewFullName.ToString()); }
/// <summary> /// Manually serialize a file reference to a binary stream. /// </summary> /// <param name="Writer">Binary writer to write to</param> /// <param name="Directory">The directory reference to write</param> public static void Write(this BinaryWriter Writer, DirectoryReference Directory) { Writer.Write((Directory == null) ? String.Empty : Directory.FullName); }
/// <summary> /// Determines if the given object is at or under the given directory /// </summary> /// <param name="Other">Directory to check against</param> /// <returns>True if this path is under the given directory</returns> public bool IsUnderDirectory(DirectoryReference Other) { return(FullName.StartsWith(Other.FullName, Comparison) && (FullName.Length == Other.FullName.Length || FullName[Other.FullName.Length] == Path.DirectorySeparatorChar || Other.IsRootDirectory())); }
/// <summary> /// Creates a relative path from the given base directory /// </summary> /// <param name="Directory">The directory to create a relative path from</param> /// <returns>A relative path from the given directory</returns> public string MakeRelativeTo(DirectoryReference Directory) { // Find how much of the path is common between the two paths. This length does not include a trailing directory separator character. int CommonDirectoryLength = -1; for (int Idx = 0; ; Idx++) { if (Idx == FullName.Length) { // The two paths are identical. Just return the "." character. if (Idx == Directory.FullName.Length) { return("."); } // Check if we're finishing on a complete directory name if (Directory.FullName[Idx] == Path.DirectorySeparatorChar) { CommonDirectoryLength = Idx; } break; } else if (Idx == Directory.FullName.Length) { // Check whether the end of the directory name coincides with a boundary for the current name. if (FullName[Idx] == Path.DirectorySeparatorChar) { CommonDirectoryLength = Idx; } break; } else { // Check the two paths match, and bail if they don't. Increase the common directory length if we've reached a separator. if (String.Compare(FullName, Idx, Directory.FullName, Idx, 1, Comparison) != 0) { break; } if (FullName[Idx] == Path.DirectorySeparatorChar) { CommonDirectoryLength = Idx; } } } // If there's no relative path, just return the absolute path if (CommonDirectoryLength == -1) { return(FullName); } // Append all the '..' separators to get back to the common directory, then the rest of the string to reach the target item StringBuilder Result = new StringBuilder(); for (int Idx = CommonDirectoryLength + 1; Idx < Directory.FullName.Length; Idx++) { // Move up a directory Result.Append(".."); Result.Append(Path.DirectorySeparatorChar); // Scan to the next directory separator while (Idx < Directory.FullName.Length && Directory.FullName[Idx] != Path.DirectorySeparatorChar) { Idx++; } } if (CommonDirectoryLength + 1 < FullName.Length) { Result.Append(FullName, CommonDirectoryLength + 1, FullName.Length - CommonDirectoryLength - 1); } return(Result.ToString()); }
/// <summary> /// Constructs a file pattern from the given string, resolving relative paths to the given directory. /// </summary> /// <param name="RootDirectory">If a relative path is specified by the pattern, the root directory used to turn it into an absolute path</param> /// <param name="Pattern">The pattern to match. If the pattern ends with a directory separator, an implicit '...' is appended.</param> public FilePattern(DirectoryReference RootDirectory, string Pattern) { // Normalize the path separators StringBuilder Text = new StringBuilder(Pattern); if (Path.DirectorySeparatorChar != '\\') { Text.Replace('\\', Path.DirectorySeparatorChar); } if (Path.DirectorySeparatorChar != '/') { Text.Replace('/', Path.DirectorySeparatorChar); } // Find the base directory, stopping when we hit a wildcard. The source directory must end with a path specification. int BaseDirectoryLen = 0; for (int Idx = 0; Idx < Text.Length; Idx++) { if (Text[Idx] == Path.DirectorySeparatorChar) { BaseDirectoryLen = Idx + 1; } else if (Text[Idx] == '?' || Text[Idx] == '*' || (Idx + 2 < Text.Length && Text[Idx] == '.' && Text[Idx + 1] == '.' && Text[Idx + 2] == '.')) { break; } } // Extract the base directory BaseDirectory = DirectoryReference.Combine(RootDirectory, Text.ToString(0, BaseDirectoryLen)); // Convert any directory wildcards ("...") into complete directory wildcards ("\\...\\"). We internally treat use "...\\" as the wildcard // token so we can correctly match zero directories. Patterns such as "foo...bar" should require at least one directory separator, so // should be converted to "foo*\\...\\*bar". for (int Idx = BaseDirectoryLen; Idx < Text.Length; Idx++) { if (Text[Idx] == '.' && Text[Idx + 1] == '.' && Text[Idx + 2] == '.') { // Insert a directory separator before if (Idx > BaseDirectoryLen && Text[Idx - 1] != Path.DirectorySeparatorChar) { Text.Insert(Idx++, '*'); Text.Insert(Idx++, Path.DirectorySeparatorChar); } // Skip past the ellipsis Idx += 3; // Insert a directory separator after if (Idx == Text.Length || Text[Idx] != Path.DirectorySeparatorChar) { Text.Insert(Idx++, Path.DirectorySeparatorChar); Text.Insert(Idx++, '*'); } } } // Parse the tokens int LastIdx = BaseDirectoryLen; for (int Idx = BaseDirectoryLen; Idx < Text.Length; Idx++) { if (Text[Idx] == '?' || Text[Idx] == '*') { Tokens.Add(Text.ToString(LastIdx, Idx - LastIdx)); Tokens.Add(Text.ToString(Idx, 1)); LastIdx = Idx + 1; } else if (Idx - 3 >= BaseDirectoryLen && Text[Idx] == Path.DirectorySeparatorChar && Text[Idx - 1] == '.' && Text[Idx - 2] == '.' && Text[Idx - 3] == '.') { Tokens.Add(Text.ToString(LastIdx, Idx - 3 - LastIdx)); Tokens.Add(Text.ToString(Idx - 3, 4)); LastIdx = Idx + 1; } } Tokens.Add(Text.ToString(LastIdx, Text.Length - LastIdx)); }
/// <summary> /// Combine several fragments with a base directory, to form a new filename /// </summary> /// <param name="BaseDirectory">The base directory</param> /// <param name="Fragments">Fragments to combine with the base directory</param> /// <returns>The new file name</returns> public static FileReference Combine(DirectoryReference BaseDirectory, params string[] Fragments) { string FullName = FileSystemReference.CombineStrings(BaseDirectory, Fragments); return(new FileReference(FullName, Sanitize.None)); }
/// <summary> /// Constructs a file pattern which matches a single file /// </summary> /// <param name="File">Location of the file</param> public FilePattern(FileReference File) { BaseDirectory = File.Directory; Tokens.Add(File.GetFileName()); }
/// <summary> /// Checks that the given input files all exist and are under the given base directory /// </summary> /// <param name="InputFiles">Input files to check</param> /// <param name="BaseDirectory">Base directory for files</param> /// <returns>List of valid files</returns> public static List <FileReference> CheckInputFiles(IEnumerable <FileReference> InputFiles, DirectoryReference BaseDirectory) { List <FileReference> Files = new List <FileReference>(); foreach (FileReference InputFile in InputFiles) { if (!InputFile.IsUnderDirectory(BaseDirectory)) { throw new FilePatternException("Source file '{0}' is not under '{1}'", InputFile, BaseDirectory); } else if (!FileReference.Exists(InputFile)) { throw new FilePatternException("Source file '{0}' does not exist", InputFile); } else { Files.Add(InputFile); } } return(Files); }
/// <summary> /// Combine several fragments with a base directory, to form a new filename /// </summary> /// <param name="BaseDirectory">The base directory</param> /// <param name="Fragments">Fragments to combine with the base directory</param> /// <returns>The new file name</returns> public static FileReference Combine(DirectoryReference BaseDirectory, params string[] Fragments) { string FullName = FileSystemReference.CombineStrings(BaseDirectory, Fragments); return(new FileReference(FullName, FullName.ToLowerInvariant())); }
/// <summary> /// Finds all the restricted folder names relative to a base directory /// </summary> /// <param name="BaseDir">The base directory to check against</param> /// <param name="OtherDir">The file or directory to check</param> /// <returns>Array of restricted folder names</returns> public static List <RestrictedFolder> FindRestrictedFolders(DirectoryReference BaseDir, DirectoryReference OtherDir) { List <RestrictedFolder> Folders = new List <RestrictedFolder>(); if (OtherDir.IsUnderDirectory(BaseDir)) { foreach (Tuple <string, RestrictedFolder> Pair in NamesAndValues) { if (OtherDir.ContainsName(Pair.Item1, BaseDir.FullName.Length)) { Folders.Add(Pair.Item2); } } } return(Folders); }
/// <summary> /// Determines if the given object is at or under the given directory /// </summary> /// <param name="Other">Directory to check against</param> /// <returns>True if this path is under the given directory</returns> public bool IsUnderDirectory(DirectoryReference Other) { return(CanonicalName.StartsWith(Other.CanonicalName) && (CanonicalName.Length == Other.CanonicalName.Length || CanonicalName[Other.CanonicalName.Length] == Path.DirectorySeparatorChar || Other.IsRootDirectory())); }