/// <summary> /// Converts an optional string list parameter to a well-defined hash set. /// </summary> protected HashSet <DirectoryReference> CreateDirectoryHashSet(IEnumerable <string> InEnumerableStrings) { HashSet <DirectoryReference> Directories = new HashSet <DirectoryReference>(); if (InEnumerableStrings != null) { foreach (string InputString in InEnumerableStrings) { string ExpandedString = Utils.ExpandVariables(InputString); if (ExpandedString.Contains("$(")) { throw new BuildException("Unable to expand variable in '{0}'", InputString); } DirectoryReference Dir = new DirectoryReference(ExpandedString); if (DirectoryReference.Exists(Dir)) { Directories.Add(Dir); } else { Log.WriteLineOnce(LogEventType.Warning, LogFormatOptions.NoSeverityPrefix, "{0}: warning: Referenced directory '{1}' does not exist.", RulesFile, Dir); } } } return(Directories); }
/// <summary> /// Tries to get the commands for a given host platform /// </summary> /// <param name="HostPlatform">The host platform to look for</param> /// <param name="Variables">Lookup of additional environment variables to expand</param> /// <param name="OutCommands">Array of commands</param> /// <returns>True if a list of commands was generated</returns> public bool TryGetCommands(UnrealTargetPlatform HostPlatform, Dictionary <string, string> Variables, out string[] OutCommands) { string[] Commands; if (HostPlatformToCommands.TryGetValue(HostPlatform, out Commands) && Commands.Length > 0) { OutCommands = Commands.Select(x => Utils.ExpandVariables(x, Variables)).ToArray(); return(true); } else { OutCommands = null; return(false); } }
/// <summary> /// Converts an optional string list parameter to a well-defined hash set. /// </summary> protected static HashSet <DirectoryReference> CreateDirectoryHashSet(IEnumerable <string> InEnumerableStrings) { HashSet <DirectoryReference> Directories = new HashSet <DirectoryReference>(); if (InEnumerableStrings != null) { foreach (string InputString in InEnumerableStrings) { string ExpandedString = Utils.ExpandVariables(InputString); if (ExpandedString.Contains("$(")) { throw new BuildException("Unable to expand variable in '{0}'", InputString); } Directories.Add(new DirectoryReference(ExpandedString)); } } return(Directories); }
/// <summary> /// Expand all the path variables in the manifest, including a list of supplied variable values. /// </summary> /// <param name="EngineDir">Value for the $(EngineDir) variable</param> /// <param name="ProjectDir">Value for the $(ProjectDir) variable</param> public void ExpandPathVariables(DirectoryReference EngineDir, DirectoryReference ProjectDir, IDictionary <string, string> OtherVariables) { // Build a dictionary containing the standard variable expansions Dictionary <string, string> Variables = new Dictionary <string, string>(OtherVariables); Variables["EngineDir"] = EngineDir.FullName; Variables["ProjectDir"] = ProjectDir.FullName; // Replace all the variables in the paths foreach (BuildProduct BuildProduct in BuildProducts) { BuildProduct.Path = Utils.ExpandVariables(BuildProduct.Path, Variables); } foreach (RuntimeDependency RuntimeDependency in RuntimeDependencies) { RuntimeDependency.Path = Utils.ExpandVariables(RuntimeDependency.Path, Variables); } }
/// <summary> /// Expand all the path variables in the manifest, including a list of supplied variable values. /// </summary> /// <param name="EngineDir">Value for the $(EngineDir) variable</param> /// <param name="ProjectDir">Value for the $(ProjectDir) variable</param> public void ExpandPathVariables(DirectoryReference EngineDir, DirectoryReference ProjectDir, IDictionary <string, string> OtherVariables) { // Build a dictionary containing the standard variable expansions Dictionary <string, string> Variables = new Dictionary <string, string>(OtherVariables); Variables["EngineDir"] = EngineDir.FullName; Variables["ProjectDir"] = ProjectDir.FullName; // Replace all the variables in the paths foreach (BuildProduct BuildProduct in BuildProducts) { BuildProduct.Path = Utils.ExpandVariables(BuildProduct.Path, Variables); } foreach (RuntimeDependency RuntimeDependency in RuntimeDependencies) { RuntimeDependency.Path = Utils.ExpandVariables(RuntimeDependency.Path, Variables); } // Replace the variables in the precompiled dependencies PrecompiledBuildDependencies = new HashSet <string>(PrecompiledBuildDependencies.Select(x => Utils.ExpandVariables(x, Variables)), StringComparer.InvariantCultureIgnoreCase); PrecompiledRuntimeDependencies = new HashSet <string>(PrecompiledRuntimeDependencies.Select(x => Utils.ExpandVariables(x, Variables)), StringComparer.InvariantCultureIgnoreCase); }
/// <summary> /// Expand all the path variables in the manifest, including a list of supplied variable values. /// </summary> /// <param name="EngineDir">Value for the $(EngineDir) variable</param> /// <param name="ProjectDir">Value for the $(ProjectDir) variable</param> public void ExpandPathVariables(string EngineDir, string ProjectDir, IDictionary <string, string> OtherVariables) { // Build a dictionary containing the standard variable expansions Dictionary <string, string> Variables = new Dictionary <string, string>(OtherVariables); Variables["EngineDir"] = Path.GetFullPath(EngineDir).TrimEnd(Path.DirectorySeparatorChar); Variables["ProjectDir"] = Path.GetFullPath(ProjectDir).TrimEnd(Path.DirectorySeparatorChar); // Replace all the variables in the paths foreach (BuildProduct BuildProduct in BuildProducts) { BuildProduct.Path = Utils.ExpandVariables(BuildProduct.Path, Variables); } foreach (RuntimeDependency RuntimeDependency in RuntimeDependencies) { RuntimeDependency.Path = Utils.ExpandVariables(RuntimeDependency.Path, Variables); if (RuntimeDependency.StagePath != null) { RuntimeDependency.StagePath = Utils.ExpandVariables(RuntimeDependency.StagePath, Variables); } } }
public override CPPOutput CompileISPCFiles(CppCompileEnvironment CompileEnvironment, List <FileItem> InputFiles, DirectoryReference OutputDir, IActionGraphBuilder Graph) { CPPOutput Result = new CPPOutput(); if (!CompileEnvironment.bCompileISPC) { return(Result); } List <string> CompileTargets = GetISPCCompileTargets(CompileEnvironment.Platform, null); foreach (FileItem ISPCFile in InputFiles) { Action CompileAction = Graph.CreateAction(ActionType.Compile); CompileAction.CommandDescription = "Compile"; CompileAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory; CompileAction.CommandPath = new FileReference(GetISPCHostCompilerPath(BuildHostPlatform.Current.Platform)); CompileAction.StatusDescription = Path.GetFileName(ISPCFile.AbsolutePath); // Disable remote execution to workaround mismatched case on XGE CompileAction.bCanExecuteRemotely = false; List <string> Arguments = new List <string>(); // Add the ISPC file to be compiled. Arguments.Add(String.Format(" \"{0}\"", ISPCFile.AbsolutePath)); List <FileItem> CompiledISPCObjFiles = new List <FileItem>(); string TargetString = ""; foreach (string Target in CompileTargets) { string ObjTarget = Target; if (Target.Contains("-")) { // Remove lane width and gang size from obj file name ObjTarget = Target.Split('-')[0]; } FileItem CompiledISPCObjFile; if (CompileTargets.Count > 1) { CompiledISPCObjFile = FileItem.GetItemByFileReference( FileReference.Combine( OutputDir, Path.GetFileName(ISPCFile.AbsolutePath) + "_" + ObjTarget + GetISPCObjectFileSuffix(CompileEnvironment.Platform) ) ); } else { CompiledISPCObjFile = FileItem.GetItemByFileReference( FileReference.Combine( OutputDir, Path.GetFileName(ISPCFile.AbsolutePath) + GetISPCObjectFileSuffix(CompileEnvironment.Platform) ) ); } // Add the ISA specific ISPC obj files to the produced item list. CompiledISPCObjFiles.Add(CompiledISPCObjFile); // Build target string. No comma on last if (Target == CompileTargets[CompileTargets.Count - 1]) // .Last() { TargetString += Target; } else { TargetString += Target + ","; } } // Add the common ISPC obj file to the produced item list. FileItem CompiledISPCObjFileNoISA = FileItem.GetItemByFileReference( FileReference.Combine( OutputDir, Path.GetFileName(ISPCFile.AbsolutePath) + GetISPCObjectFileSuffix(CompileEnvironment.Platform) ) ); CompiledISPCObjFiles.Add(CompiledISPCObjFileNoISA); // Add the output ISPC obj file Arguments.Add(String.Format("-o \"{0}\"", CompiledISPCObjFileNoISA)); // Build target triplet Arguments.Add(String.Format("--target-os=\"{0}\"", GetISPCOSTarget(CompileEnvironment.Platform))); Arguments.Add(String.Format("--arch=\"{0}\"", GetISPCArchTarget(CompileEnvironment.Platform, null))); Arguments.Add(String.Format("--target=\"{0}\"", TargetString)); if (CompileEnvironment.Configuration == CppConfiguration.Debug) { Arguments.Add("-g -O0"); } else { Arguments.Add("-O2"); } // PIC is needed for modular builds except on Windows if ((CompileEnvironment.bIsBuildingDLL || CompileEnvironment.bIsBuildingLibrary) && !UEBuildPlatform.IsPlatformInGroup(CompileEnvironment.Platform, UnrealPlatformGroup.Windows)) { Arguments.Add("--pic"); } // Include paths. Don't use AddIncludePath() here, since it uses the full path and exceeds the max command line length. foreach (DirectoryReference IncludePath in CompileEnvironment.UserIncludePaths) { Arguments.Add(String.Format("-I\"{0}\"", IncludePath)); } // System include paths. foreach (DirectoryReference SystemIncludePath in CompileEnvironment.SystemIncludePaths) { Arguments.Add(String.Format("-I\"{0}\"", SystemIncludePath)); } // Preprocessor definitions. foreach (string Definition in CompileEnvironment.Definitions) { Arguments.Add(String.Format("-D\"{0}\"", Definition)); } // Consume the included header dependency list if (CompileEnvironment.bGenerateDependenciesFile) { FileItem DependencyListFile = FileItem.GetItemByFileReference(FileReference.Combine(OutputDir, Path.GetFileName(ISPCFile.AbsolutePath) + ".txt")); CompileAction.DependencyListFile = DependencyListFile; CompileAction.PrerequisiteItems.Add(DependencyListFile); } CompileAction.ProducedItems.AddRange(CompiledISPCObjFiles); Result.ObjectFiles.AddRange(CompiledISPCObjFiles); FileReference ResponseFileName = new FileReference(CompiledISPCObjFileNoISA.AbsolutePath + ".response"); FileItem ResponseFileItem = Graph.CreateIntermediateTextFile(ResponseFileName, Arguments.Select(x => Utils.ExpandVariables(x))); CompileAction.CommandArguments = " @\"" + ResponseFileName + "\""; CompileAction.PrerequisiteItems.Add(ResponseFileItem); // Add the source file and its included files to the prerequisite item list. CompileAction.PrerequisiteItems.Add(ISPCFile); Log.TraceVerbose(" ISPC Compiling " + CompileAction.StatusDescription + ": \"" + CompileAction.CommandPath + "\"" + CompileAction.CommandArguments); } return(Result); }
public override CPPOutput GenerateISPCHeaders(CppCompileEnvironment CompileEnvironment, List <FileItem> InputFiles, DirectoryReference OutputDir, IActionGraphBuilder Graph) { CPPOutput Result = new CPPOutput(); if (!CompileEnvironment.bCompileISPC) { return(Result); } List <string> CompileTargets = GetISPCCompileTargets(CompileEnvironment.Platform, null); foreach (FileItem ISPCFile in InputFiles) { Action CompileAction = Graph.CreateAction(ActionType.Compile); CompileAction.CommandDescription = "Compile"; CompileAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory; CompileAction.CommandPath = new FileReference(GetISPCHostCompilerPath(BuildHostPlatform.Current.Platform)); CompileAction.StatusDescription = Path.GetFileName(ISPCFile.AbsolutePath); // Disable remote execution to workaround mismatched case on XGE CompileAction.bCanExecuteRemotely = false; List <string> Arguments = new List <string>(); // Add the ISPC obj file as a prerequisite of the action. CompileAction.CommandArguments = String.Format("\"{0}\" ", ISPCFile.AbsolutePath); // Add the ISPC h file to the produced item list. FileItem ISPCIncludeHeaderFile = FileItem.GetItemByFileReference( FileReference.Combine( OutputDir, Path.GetFileName(ISPCFile.AbsolutePath) + ".generated.dummy.h" ) ); // Add the ISPC file to be compiled. Arguments.Add(String.Format("-h \"{0}\"", ISPCIncludeHeaderFile)); // Build target string. No comma on last string TargetString = ""; foreach (string Target in CompileTargets) { if (Target == CompileTargets[CompileTargets.Count - 1]) // .Last() { TargetString += Target; } else { TargetString += Target + ","; } } // Build target triplet Arguments.Add(String.Format("--target-os={0}", GetISPCOSTarget(CompileEnvironment.Platform))); Arguments.Add(String.Format("--arch={0}", GetISPCArchTarget(CompileEnvironment.Platform, null))); Arguments.Add(String.Format("--target={0}", TargetString)); // PIC is needed for modular builds except on Windows if ((CompileEnvironment.bIsBuildingDLL || CompileEnvironment.bIsBuildingLibrary) && !UEBuildPlatform.IsPlatformInGroup(CompileEnvironment.Platform, UnrealPlatformGroup.Windows)) { Arguments.Add("--pic"); } // Include paths. Don't use AddIncludePath() here, since it uses the full path and exceeds the max command line length. // Because ISPC response files don't support white space in arguments, paths with white space need to be passed to the command line directly. foreach (DirectoryReference IncludePath in CompileEnvironment.UserIncludePaths) { Arguments.Add(String.Format("-I\"{0}\"", IncludePath)); } // System include paths. foreach (DirectoryReference SystemIncludePath in CompileEnvironment.SystemIncludePaths) { Arguments.Add(String.Format("-I\"{0}\"", SystemIncludePath)); } // Generate the included header dependency list if (CompileEnvironment.bGenerateDependenciesFile) { FileItem DependencyListFile = FileItem.GetItemByFileReference(FileReference.Combine(OutputDir, Path.GetFileName(ISPCFile.AbsolutePath) + ".txt")); Arguments.Add(String.Format("-MMM \"{0}\"", DependencyListFile.AbsolutePath.Replace('\\', '/'))); CompileAction.DependencyListFile = DependencyListFile; CompileAction.ProducedItems.Add(DependencyListFile); } CompileAction.ProducedItems.Add(ISPCIncludeHeaderFile); FileReference ResponseFileName = new FileReference(ISPCIncludeHeaderFile.AbsolutePath + ".response"); FileItem ResponseFileItem = Graph.CreateIntermediateTextFile(ResponseFileName, Arguments.Select(x => Utils.ExpandVariables(x))); CompileAction.CommandArguments += String.Format("@\"{0}\"", ResponseFileName); CompileAction.PrerequisiteItems.Add(ResponseFileItem); // Add the source file and its included files to the prerequisite item list. CompileAction.PrerequisiteItems.Add(ISPCFile); FileItem ISPCFinalHeaderFile = FileItem.GetItemByFileReference( FileReference.Combine( OutputDir, Path.GetFileName(ISPCFile.AbsolutePath) + ".generated.h" ) ); // Fix interrupted build issue by copying header after generation completes FileReference SourceFile = ISPCIncludeHeaderFile.Location; FileReference TargetFile = ISPCFinalHeaderFile.Location; FileItem SourceFileItem = FileItem.GetItemByFileReference(SourceFile); FileItem TargetFileItem = FileItem.GetItemByFileReference(TargetFile); Action CopyAction = Graph.CreateAction(ActionType.BuildProject); CopyAction.CommandDescription = "Copy"; CopyAction.CommandPath = BuildHostPlatform.Current.Shell; if (BuildHostPlatform.Current.ShellType == ShellType.Cmd) { CopyAction.CommandArguments = String.Format("/C \"copy /Y \"{0}\" \"{1}\" 1>nul\"", SourceFile, TargetFile); } else { CopyAction.CommandArguments = String.Format("-c 'cp -f \"{0}\" \"{1}\"'", SourceFile.FullName, TargetFile.FullName); } CopyAction.WorkingDirectory = UnrealBuildTool.EngineSourceDirectory; CopyAction.PrerequisiteItems.Add(SourceFileItem); CopyAction.ProducedItems.Add(TargetFileItem); CopyAction.StatusDescription = TargetFileItem.Location.GetFileName(); CopyAction.bCanExecuteRemotely = false; CopyAction.bShouldOutputStatusDescription = false; Result.GeneratedHeaderFiles.Add(TargetFileItem); Log.TraceVerbose(" ISPC Generating Header " + CompileAction.StatusDescription + ": \"" + CompileAction.CommandPath + "\"" + CompileAction.CommandArguments); } return(Result); }
static string GetFullIncludePath(string IncludePath) { return(Path.GetFullPath(Utils.ExpandVariables(IncludePath))); }