Пример #1
0
    void CompilePluginWithUBT(FileReference HostProjectFile, FileReference HostProjectPluginFile, PluginDescriptor Plugin, string TargetName, TargetType TargetType, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, List <FileReference> ManifestFileNames, string InAdditionalArgs)
    {
        // Find a list of modules that need to be built for this plugin
        bool bCompilePlatform = false;

        if (Plugin.Modules != null)
        {
            bool bBuildDeveloperTools     = (TargetType == TargetType.Editor || TargetType == TargetType.Program || (Configuration != UnrealTargetConfiguration.Test && Configuration != UnrealTargetConfiguration.Shipping));
            bool bBuildRequiresCookedData = (TargetType != TargetType.Editor && TargetType != TargetType.Program);

            foreach (ModuleDescriptor Module in Plugin.Modules)
            {
                if (Module.IsCompiledInConfiguration(Platform, Configuration, TargetName, TargetType, bBuildDeveloperTools, bBuildRequiresCookedData))
                {
                    bCompilePlatform = true;
                }
            }
        }

        // Add these modules to the build agenda
        if (bCompilePlatform)
        {
            if (Platform == UnrealTargetPlatform.HoloLens)
            {
                // Make sure to save the manifests for each architecture with unique names so they don't get overwritten.
                // This fixes packaging issues when building from binary engine releases, where the build produces a manifest for the plugin for ARM64, which
                // then gets overwritten by the manifest for x64. Then during packaging, the plugin is referencing a manifest for the wrong architecture.
                foreach (string Arch in HoloLensArchitecture.Split('+'))
                {
                    FileReference ManifestFileName = FileReference.Combine(HostProjectFile.Directory, "Saved", String.Format("Manifest-{0}-{1}-{2}-{3}.xml", TargetName, Platform, Configuration, Arch));
                    ManifestFileNames.Add(ManifestFileName);
                    string Arguments = String.Format("-plugin={0} -iwyu -noubtmakefiles -manifest={1} -nohotreload", CommandUtils.MakePathSafeToUseWithCommandLine(HostProjectPluginFile.FullName), CommandUtils.MakePathSafeToUseWithCommandLine(ManifestFileName.FullName));
                    Arguments += String.Format(" -Architecture={0}", Arch);
                    if (!String.IsNullOrEmpty(InAdditionalArgs))
                    {
                        Arguments += InAdditionalArgs;
                    }
                    CommandUtils.RunUBT(CmdEnv, UE4Build.GetUBTExecutable(), HostProjectFile, TargetName, Platform, Configuration, Arguments);
                }
            }
            else
            {
                FileReference ManifestFileName = FileReference.Combine(HostProjectFile.Directory, "Saved", String.Format("Manifest-{0}-{1}-{2}.xml", TargetName, Platform, Configuration));
                ManifestFileNames.Add(ManifestFileName);

                string Arguments = String.Format("-plugin={0} -iwyu -noubtmakefiles -manifest={1} -nohotreload", CommandUtils.MakePathSafeToUseWithCommandLine(HostProjectPluginFile.FullName), CommandUtils.MakePathSafeToUseWithCommandLine(ManifestFileName.FullName));
                if (Platform == UnrealTargetPlatform.Android)
                {
                    Arguments += String.Format(" -architectures={0}", AndroidArchitectures);
                }

                if (!String.IsNullOrEmpty(InAdditionalArgs))
                {
                    Arguments += InAdditionalArgs;
                }

                CommandUtils.RunUBT(CmdEnv, UE4Build.GetUBTExecutable(), HostProjectFile, TargetName, Platform, Configuration, Arguments);
            }
        }
    }
    void CompilePluginWithUBT(FileReference HostProjectFile, FileReference HostProjectPluginFile, PluginDescriptor Plugin, string TargetName, TargetType TargetType, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, List <FileReference> ManifestFileNames, string InAdditionalArgs)
    {
        // Find a list of modules that need to be built for this plugin
        bool bCompilePlatform = false;

        if (Plugin.Modules != null)
        {
            foreach (ModuleDescriptor Module in Plugin.Modules)
            {
                bool bBuildDeveloperTools     = (TargetType == TargetType.Editor || TargetType == TargetType.Program);
                bool bBuildEditor             = (TargetType == TargetType.Editor);
                bool bBuildRequiresCookedData = (TargetType != TargetType.Editor && TargetType != TargetType.Program);
                if (Module.IsCompiledInConfiguration(Platform, Configuration, TargetName, TargetType, bBuildDeveloperTools, bBuildEditor, bBuildRequiresCookedData))
                {
                    bCompilePlatform = true;
                }
            }
        }

        // Add these modules to the build agenda
        if (bCompilePlatform)
        {
            FileReference ManifestFileName = FileReference.Combine(HostProjectFile.Directory, "Saved", String.Format("Manifest-{0}-{1}-{2}.xml", TargetName, Platform, Configuration));
            ManifestFileNames.Add(ManifestFileName);

            string Arguments = String.Format("-plugin={0} -iwyu -noubtmakefiles -manifest={1}", CommandUtils.MakePathSafeToUseWithCommandLine(HostProjectPluginFile.FullName), CommandUtils.MakePathSafeToUseWithCommandLine(ManifestFileName.FullName));
            if (!String.IsNullOrEmpty(InAdditionalArgs))
            {
                Arguments += InAdditionalArgs;
            }

            CommandUtils.RunUBT(CmdEnv, UE4Build.GetUBTExecutable(), String.Format("{0} {1} {2} {3}", TargetName, Platform, Configuration, Arguments));
        }
    }
Пример #3
0
    IEnumerable <string> EnumerateBuildFolders(string Target, string Configuration, string Platform, bool DebugRun)
    {
        FileReference OutputFile = FileReference.Combine(CommandUtils.EngineDirectory, "Intermediate", "Build", "ThirdParty.json");

        IProcessResult Result = Run(UE4Build.GetUBTExecutable(), String.Format("{0} {1} {2} -jsonexport=\"{3}\" -skipbuild", Target, Configuration, Platform, OutputFile.FullName), Options: DebugRun ? ERunOptions.Default : ERunOptions.NoLoggingOfRunCommand);

        if (Result.ExitCode != 0)
        {
            throw new AutomationException("Failed to run UBT");
        }

        JsonObject Object = JsonObject.Read(OutputFile);

        // local function that takes a RuntimeDependency path and resolves it (replacing Env vars that we support)
        Func <string, DirectoryReference> ResolveRuntimeDependencyFolder = (string DependencyPath) =>
        {
            return(new DirectoryReference(Path.GetDirectoryName(
                                              // Regex to replace the env vars we support $(EngineDir|ProjectDir), ignoring case
                                              Regex.Replace(DependencyPath, @"\$\((?<Type>Engine|Project)Dir\)", M =>
                                                            M.Groups["Type"].Value.Equals("Engine", StringComparison.InvariantCultureIgnoreCase)
                                                ? CommandUtils.EngineDirectory.FullName
                                                : new FileReference(Object.GetStringField("ProjectFile")).Directory.FullName,
                                                            RegexOptions.IgnoreCase))));
        };

        JsonObject Modules = Object.GetObjectField("Modules");

        // Create a set of directories used for each binary
        List <DirectoryReference> DirectoriesToScan = Modules
                                                      // get all directories that the module uses (source folder and any runtime dependencies)
                                                      .KeyNames.Select(KeyName => Modules.GetObjectField(KeyName))
                                                      .SelectMany(Module => Module
                                                                  // resolve any runtime dependency folders and add them.
                                                                  .GetObjectArrayField("RuntimeDependencies").Select(Dependency => ResolveRuntimeDependencyFolder(Dependency.GetStringField("Path")))
                                                      // Add on the module source directory
                                                                  .Concat(new[] { new DirectoryReference(Module.GetStringField("Directory")) }))
                                                      // remove any duplicate folders since some modules may be from the same plugin
                                                      .Distinct()
                                                      // Project to a list as we need to do an O(n^2) operation below.
                                                      .ToList();

        List <string> FinalDirs = DirectoriesToScan.Where(RemovalCandidate =>
                                                          // O(n^2) search to remove subfolders of any we are already searching.
                                                          // look for directories that aren't subdirectories of any other directory in the list.
                                                          !DirectoriesToScan.Any(DirectoryToScan =>
                                                          // != check because this inner loop will eventually check against itself
                                                                                 RemovalCandidate != DirectoryToScan &&
                                                                                 RemovalCandidate.IsUnderDirectory(DirectoryToScan)))
                                  // grab the full name
                                  .Select(Dir => Dir.FullName)
                                  // sort the final output
                                  .OrderBy(Dir => Dir)
                                  // log the folders
                                  .ToList();

        return(FinalDirs);
    }
Пример #4
0
    void CompilePluginWithUBT(FileReference HostProjectFile, FileReference HostProjectPluginFile, PluginDescriptor Plugin, string TargetName, TargetType TargetType, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, List <FileReference> ReceiptFileNames, string InAdditionalArgs)
    {
        // Find a list of modules that need to be built for this plugin
        List <string> ModuleNames = new List <string>();

        if (Plugin.Modules != null)
        {
            foreach (ModuleDescriptor Module in Plugin.Modules)
            {
                bool bBuildDeveloperTools     = (TargetType == TargetType.Editor || TargetType == TargetType.Program);
                bool bBuildEditor             = (TargetType == TargetType.Editor);
                bool bBuildRequiresCookedData = (TargetType != TargetType.Editor && TargetType != TargetType.Program);
                if (Module.IsCompiledInConfiguration(Platform, TargetType, bBuildDeveloperTools, bBuildEditor, bBuildRequiresCookedData))
                {
                    ModuleNames.Add(Module.Name);
                }
            }
        }

        // Add these modules to the build agenda
        if (ModuleNames.Count > 0)
        {
            string Arguments = "-iwyu";            // String.Format("-plugin={0}", CommandUtils.MakePathSafeToUseWithCommandLine(PluginFile.FullName));
            foreach (string ModuleName in ModuleNames)
            {
                Arguments += String.Format(" -module={0}", ModuleName);
            }

            string Architecture = PlatformExports.GetDefaultArchitecture(Platform, HostProjectFile);

            FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(HostProjectPluginFile.Directory, TargetName, Platform, Configuration, Architecture);
            Arguments += String.Format(" -receipt={0}", CommandUtils.MakePathSafeToUseWithCommandLine(ReceiptFileName.FullName));
            ReceiptFileNames.Add(ReceiptFileName);

            if (!String.IsNullOrEmpty(InAdditionalArgs))
            {
                Arguments += InAdditionalArgs;
            }

            CommandUtils.RunUBT(CmdEnv, UE4Build.GetUBTExecutable(), String.Format("{0} {1} {2}{3} {4}", TargetName, Platform, Configuration, (HostProjectFile == null)? "" : String.Format(" -project=\"{0}\"", HostProjectFile.FullName), Arguments));
        }
    }
    void CompilePluginWithUBT(FileReference HostProjectFile, FileReference HostProjectPluginFile, PluginDescriptor Plugin, string TargetName, TargetType TargetType, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, List <FileReference> ReceiptFileNames, string InAdditionalArgs)
    {
        // Find a list of modules that need to be built for this plugin
        bool bCompilePlatform = false;

        if (Plugin.Modules != null)
        {
            foreach (ModuleDescriptor Module in Plugin.Modules)
            {
                bool bBuildDeveloperTools     = (TargetType == TargetType.Editor || TargetType == TargetType.Program);
                bool bBuildEditor             = (TargetType == TargetType.Editor);
                bool bBuildRequiresCookedData = (TargetType != TargetType.Editor && TargetType != TargetType.Program);
                if (Module.IsCompiledInConfiguration(Platform, TargetType, bBuildDeveloperTools, bBuildEditor, bBuildRequiresCookedData))
                {
                    bCompilePlatform = true;
                }
            }
        }

        // Add these modules to the build agenda
        if (bCompilePlatform)
        {
            string Architecture = PlatformExports.GetDefaultArchitecture(Platform, HostProjectFile);

            FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(HostProjectPluginFile.Directory, TargetName, Platform, Configuration, Architecture);
            ReceiptFileNames.Add(ReceiptFileName);

            string Arguments = String.Format("-plugin {0} -iwyu -precompile -nosharedpch -noubtmakefiles -receipt {1}", CommandUtils.MakePathSafeToUseWithCommandLine(HostProjectPluginFile.FullName), CommandUtils.MakePathSafeToUseWithCommandLine(ReceiptFileName.FullName));
            if (!String.IsNullOrEmpty(InAdditionalArgs))
            {
                Arguments += InAdditionalArgs;
            }

            CommandUtils.RunUBT(CmdEnv, UE4Build.GetUBTExecutable(), String.Format("{0} {1} {2} {3}", TargetName, Platform, Configuration, Arguments));
        }
    }
Пример #6
0
    public override void ExecuteBuild()
    {
        CommandUtils.Log("************************* List Third Party Software");

        string ProjectPath = ParseParamValue("Project", String.Empty);

        //Add quotes to avoid issues with spaces in project path
        if (ProjectPath != String.Empty)
        {
            ProjectPath = "\"" + ProjectPath + "\"";
        }

        // Parse the list of targets to list TPS for. Each target is specified by -Target="Name|Configuration|Platform" on the command line.
        HashSet <FileReference> TpsFiles = new HashSet <FileReference>();

        foreach (string Target in ParseParamValues(Params, "Target"))
        {
            // Get the path to store the exported JSON target data
            FileReference OutputFile = FileReference.Combine(CommandUtils.EngineDirectory, "Intermediate", "Build", "ThirdParty.json");

            IProcessResult Result;

            Result = Run(UE4Build.GetUBTExecutable(), String.Format("{0} {1} -jsonexport=\"{2}\" -skipbuild", Target.Replace('|', ' '), ProjectPath, OutputFile.FullName), Options: ERunOptions.Default);

            if (Result.ExitCode != 0)
            {
                throw new AutomationException("Failed to run UBT");
            }

            // Read the exported target info back in
            JsonObject Object = JsonObject.Read(OutputFile);

            // Get the project file if there is one
            FileReference ProjectFile = null;
            string        ProjectFileName;
            if (Object.TryGetStringField("ProjectFile", out ProjectFileName))
            {
                ProjectFile = new FileReference(ProjectFileName);
            }

            // Get the default paths to search
            HashSet <DirectoryReference> DirectoriesToScan = new HashSet <DirectoryReference>();
            DirectoriesToScan.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Shaders"));
            DirectoriesToScan.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Content"));
            if (ProjectFile != null)
            {
                DirectoriesToScan.Add(DirectoryReference.Combine(ProjectFile.Directory, "Content"));
            }

            // Get the variables to be expanded in any runtime dependencies variables
            Dictionary <string, string> Variables = new Dictionary <string, string>();
            Variables.Add("EngineDir", CommandUtils.EngineDirectory.FullName);
            if (ProjectFile != null)
            {
                Variables.Add("ProjectDir", ProjectFile.Directory.FullName);
            }

            // Add all the paths for each module, and its runtime dependencies
            JsonObject Modules = Object.GetObjectField("Modules");
            foreach (string ModuleName in Modules.KeyNames)
            {
                JsonObject Module = Modules.GetObjectField(ModuleName);
                DirectoriesToScan.Add(new DirectoryReference(Module.GetStringField("Directory")));

                foreach (JsonObject RuntimeDependency in Module.GetObjectArrayField("RuntimeDependencies"))
                {
                    string RuntimeDependencyPath = RuntimeDependency.GetStringField("Path");
                    RuntimeDependencyPath = Utils.ExpandVariables(RuntimeDependencyPath, Variables);
                    DirectoriesToScan.Add(new FileReference(RuntimeDependencyPath).Directory);
                }
            }

            // Remove any directories that are under other directories, and sort the output list
            List <DirectoryReference> SortedDirectoriesToScan = new List <DirectoryReference>();
            foreach (DirectoryReference DirectoryToScan in DirectoriesToScan.OrderBy(x => x.FullName))
            {
                if (SortedDirectoriesToScan.Count == 0 || !DirectoryToScan.IsUnderDirectory(SortedDirectoriesToScan[SortedDirectoriesToScan.Count - 1]))
                {
                    SortedDirectoriesToScan.Add(DirectoryToScan);
                }
            }

            // Get the platforms to exclude
            List <UnrealTargetPlatform> SupportedPlatforms = new List <UnrealTargetPlatform> {
                (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), Object.GetStringField("Platform"))
            };
            FileSystemName[] ExcludePlatformNames = Utils.MakeListOfUnsupportedPlatforms(SupportedPlatforms).Select(x => new FileSystemName(x)).ToArray();

            // Find all the TPS files under the engine directory which match
            foreach (DirectoryReference DirectoryToScan in SortedDirectoriesToScan)
            {
                foreach (FileReference TpsFile in DirectoryReference.EnumerateFiles(DirectoryToScan, "*.tps", SearchOption.AllDirectories))
                {
                    if (!TpsFile.ContainsAnyNames(ExcludePlatformNames, DirectoryToScan))
                    {
                        TpsFiles.Add(TpsFile);
                    }
                }
            }
        }

        // Also add any redirects
        List <string> OutputMessages = new List <string>();

        foreach (FileReference TpsFile in TpsFiles)
        {
            string Message = TpsFile.FullName;

            string[] Lines = FileReference.ReadAllLines(TpsFile);
            foreach (string Line in Lines)
            {
                const string RedirectPrefix = "Redirect:";

                int Idx = Line.IndexOf(RedirectPrefix, StringComparison.InvariantCultureIgnoreCase);
                if (Idx >= 0)
                {
                    FileReference RedirectTpsFile = FileReference.Combine(TpsFile.Directory, Line.Substring(Idx + RedirectPrefix.Length).Trim());
                    Message = String.Format("{0} (redirect from {1})", RedirectTpsFile.FullName, TpsFile.FullName);
                    break;
                }
            }

            OutputMessages.Add(Message);
        }
        OutputMessages.Sort();

        // Print them all out
        foreach (string OutputMessage in OutputMessages)
        {
            CommandUtils.Log(OutputMessage);
        }
    }
Пример #7
0
    public override void ExecuteBuild()
    {
        CommandUtils.Log("************************* List Third Party Software");
        bool DebugRun = ParseParam("Debug");

        // first get a list of all TPS files available (as a lookup of Dir -> List of TPS files in Dir).
        var AllTPSFiles =
            Directory.EnumerateFiles(CombinePaths(CmdEnv.LocalRoot), "*.tps", SearchOption.AllDirectories)
            .ToLookup(TPSFile => Path.GetDirectoryName(TPSFile), StringComparer.InvariantCultureIgnoreCase);

        ParseParamValues(Params, "Target")                      // Grab all the Target params.
        .Select(TargetArg => TargetArg.Split(new[] { '|' }, 3)) // split the arg up by |
        .Where(Target => Target.Length == 3)                    // ensure it has three parts
        .Select(Target => new                                   // strongly name the parts of the target and
        {
            Name          = Target[0],
            Configuration = Target[1],
            Platform      = Target[2],
            // create a list of unsupported platform strings for that target, which we'll use later to cull out irrelvant TPS files
            UnsupportedSubstrings =
                Utils.MakeListOfUnsupportedPlatforms(new List <UnrealTargetPlatform> {
                (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), Target[2])
            })
                .Select(PlatformName => Path.DirectorySeparatorChar + PlatformName + Path.DirectorySeparatorChar) // convert to /Platform/
                .ToList(),                                                                                        // project to list
        })
        .SelectMany(Target =>
                    // run UBT on each target to get the build folders, add a few hard-coded paths, then search for TPS files in relevant folders to them
                    RunAndLog(UE4Build.GetUBTExecutable(), string.Format("{0} {1} {2} -listbuildfolders", Target.Name, Target.Configuration, Target.Platform), Options: DebugRun?ERunOptions.Default: ERunOptions.NoLoggingOfRunCommand) // run UBT to get the raw output
                    .EnumerateLines()                                                                                                                                                                                                    // split it into separate lines
                    .Where(Line => Line.StartsWith("BuildFolder:", StringComparison.InvariantCultureIgnoreCase))                                                                                                                         // find the output lines that we need
                    .Select(Line => Line.Substring("BuildFolder:".Length))                                                                                                                                                               // chop it down to the path name
                                                                                                                                                                                                                                         // tack on the target content directory, which we could infer from one of a few places
                    .Concat(new[]
        {
            Path.Combine(Path.GetDirectoryName(Target.Name), "Content"), // The target could be a .uproject, so look for a content folder there
            Path.Combine(CmdEnv.LocalRoot, Target.Name, "Content"),      // the target could be a root project, so look for a content folder there
        }.Where(Folder => Directory.Exists(Folder))                      // only accept Content folders that actually exist.
                            )
                                                                         // tack on hard-coded engine shaders and content folder
                    .Concat(new List <string> {
            "Shaders", "Content",
        }.Select(Folder => Path.Combine(CmdEnv.LocalRoot, "Engine", Folder)))
                    // canonicalize the path and convert separators. We do string compares below, so we need separators to be in consistent formats.
                    .Select(FolderToScan => CombinePaths(FolderToScan))
                    // scan each folder for TPS files that appear relevant to that folder
                    .SelectMany(FolderToScan =>
                                AllTPSFiles
                                // A relevant folder is one that is in a subfolders or parent folder to that folder
                                .Where(TPSFileDir => FolderToScan.StartsWith(TPSFileDir.Key, StringComparison.InvariantCultureIgnoreCase) || TPSFileDir.Key.StartsWith(FolderToScan, StringComparison.InvariantCultureIgnoreCase))
                                // flatten the list of all the TPS files in any folders we found (remember we were just looking at folders above, which could have a list of TPS files)
                                .SelectMany(TPSFileDir => TPSFileDir)
                                // filter out TPS from unwanted platforms for the current target.
                                // This is a bit hard to follow, but we are only looking for unsupported platform names INSIDE the folder to search.
                                // for instance, if the folder is Foo/PS4/Plugins/PadSupport and we are building for windows, we don't want to filter it out even though it has PS4 in the name.
                                // but if the TPS file is Foo/PS4/Plugins/PadSupport/Android/TPS.TPS, then we do want to filter out because of the Android folder.
                                // this basically checks if an unsupported platform string is found AFTER the original folder we are looking in.
                                .Where(TpsFile => Target.UnsupportedSubstrings.Max(PlatformDir => TpsFile.IndexOf(PlatformDir, StringComparison.InvariantCultureIgnoreCase)) < FolderToScan.Length)
                                )
                    )
        .Distinct()         // remove duplicate TPS files.
        // pull out the redirect if present (but leave a breadcrumb to where the redirect came from)
        .Select(TPSFile =>
                // read all the lines in the file
                File.ReadAllLines(TPSFile)
                                                                                                                     // look for a line with a redirect
                .Where(Line => Line.IndexOf("Redirect:", StringComparison.InvariantCultureIgnoreCase) >= 0)
                                                                                                                     // grab the redirect file and canonicalize it, tacking on some info on where the redirect was from.
                .Select(Line => CombinePaths(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(TPSFile), Line.Split(new[] { ':' }, 2)[1].Trim()))) + " (redirect from " + TPSFile + ")")
                                                                                                                     // take the first one found, or just use the TPS file directly if no redirect was present.
                .SingleOrDefault() ?? TPSFile)
        .OrderBy(TPSFile => TPSFile)                                                                                 // sort them.
        .ToList().ForEach(TPSFile => UnrealBuildTool.Log.WriteLine(0, string.Empty, LogEventType.Console, TPSFile)); // log them.
    }