/// <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);
     }
 }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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);
            }
        }
示例#5
0
        /// <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)));
 }