Пример #1
0
        /// <summary>
        /// Entry point for the commandlet
        /// </summary>
        public override void ExecuteBuild()
        {
            string OutputDir = ParseParamValue("OutputDir");
            string ContentOnlyPlatformsString = ParseParamValue("ContentOnlyPlatforms");
            IEnumerable <UnrealTargetPlatform> ContentOnlyPlatforms = Enumerable.Empty <UnrealTargetPlatform>();

            if (!String.IsNullOrWhiteSpace(ContentOnlyPlatformsString))
            {
                ContentOnlyPlatforms = ContentOnlyPlatformsString.Split(';').Where(x => !String.IsNullOrWhiteSpace(x)).Select(x => (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), x));
            }
            string AnalyticsTypeOverride = ParseParamValue("AnalyticsTypeOverride");

            // Write InstalledBuild.txt to indicate Engine is installed
            string InstalledBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledBuild.txt");

            CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledBuildFile));
            CommandUtils.WriteAllText(InstalledBuildFile, "");

            // Write InstalledBuild.txt to indicate Engine is installed
            string Project = ParseParamValue("Project");

            if (Project != null)
            {
                string InstalledProjectBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledProjectBuild.txt");
                CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledProjectBuildFile));
                CommandUtils.WriteAllText(InstalledProjectBuildFile, new FileReference(Project).MakeRelativeTo(new DirectoryReference(OutputDir)));
            }

            string         OutputEnginePath     = Path.Combine(OutputDir, "Engine");
            string         OutputBaseEnginePath = Path.Combine(OutputEnginePath, "Config", "BaseEngine.ini");
            FileAttributes OutputAttributes     = FileAttributes.ReadOnly;
            List <String>  IniLines             = new List <String>();

            // Should always exist but if not, we don't need extra line
            if (File.Exists(OutputBaseEnginePath))
            {
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath);
                IniLines.Add("");
            }
            else
            {
                CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(OutputBaseEnginePath));
                CommandUtils.WriteAllText(OutputBaseEnginePath, "");
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath) | OutputAttributes;
            }

            // Create list of platform configurations installed in a Rocket build
            List <InstalledPlatformInfo.InstalledPlatformConfiguration> InstalledConfigs = new List <InstalledPlatformInfo.InstalledPlatformConfiguration>();

            // Add the editor platform, otherwise we'll never be able to run UAT
            InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.Development, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, "", "", EProjectType.Unknown, false));

            foreach (UnrealTargetPlatform CodeTargetPlatform in Enum.GetValues(typeof(UnrealTargetPlatform)))
            {
                if (PlatformExports.IsPlatformAvailable(CodeTargetPlatform))
                {
                    string Architecture = PlatformExports.GetDefaultArchitecture(CodeTargetPlatform, null);

                    // Try to parse additional Architectures from the command line
                    string Architectures    = ParseParamValue(CodeTargetPlatform.ToString() + "Architectures");
                    string GPUArchitectures = ParseParamValue(CodeTargetPlatform.ToString() + "GPUArchitectures");

                    // Build a list of pre-compiled architecture combinations for this platform if any
                    List <string> AllArchNames;

                    if (!String.IsNullOrWhiteSpace(Architectures) && !String.IsNullOrWhiteSpace(GPUArchitectures))
                    {
                        AllArchNames = (from Arch in Architectures.Split('+')
                                        from GPUArch in GPUArchitectures.Split('+')
                                        select "-" + Arch + "-" + GPUArch).ToList();
                    }
                    else if (!String.IsNullOrWhiteSpace(Architectures))
                    {
                        AllArchNames = Architectures.Split('+').ToList();
                    }
                    else
                    {
                        AllArchNames = new List <string>();
                    }

                    // Check whether this platform should only be used for content based projects
                    EProjectType ProjectType = ContentOnlyPlatforms.Contains(CodeTargetPlatform) ? EProjectType.Content : EProjectType.Any;

                    // Allow Content only platforms to be shown as options in all projects
                    bool bCanBeDisplayed = ProjectType == EProjectType.Content;
                    foreach (UnrealTargetConfiguration CodeTargetConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                    {
                        // Need to check for development receipt as we use that for the Engine code in DebugGame
                        UnrealTargetConfiguration EngineConfiguration = (CodeTargetConfiguration == UnrealTargetConfiguration.DebugGame) ? UnrealTargetConfiguration.Development : CodeTargetConfiguration;
                        string ReceiptFileName = TargetReceipt.GetDefaultPath(OutputEnginePath, "UE4Game", CodeTargetPlatform, EngineConfiguration, Architecture);

                        if (File.Exists(ReceiptFileName))
                        {
                            // Strip the output folder so that this can be used on any machine
                            ReceiptFileName = new FileReference(ReceiptFileName).MakeRelativeTo(new DirectoryReference(OutputDir));

                            // If we have pre-compiled architectures for this platform then add an entry for each of these -
                            // there isn't a receipt for each architecture like some other platforms
                            if (AllArchNames.Count > 0)
                            {
                                foreach (string Arch in AllArchNames)
                                {
                                    InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, TargetType.Game, Arch, ReceiptFileName, ProjectType, bCanBeDisplayed));
                                }
                            }
                            else
                            {
                                InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, TargetType.Game, Architecture, ReceiptFileName, ProjectType, bCanBeDisplayed));
                            }
                        }
                    }
                }
            }

            UnrealBuildTool.InstalledPlatformInfo.WriteConfigFileEntries(InstalledConfigs, ref IniLines);

            if (!String.IsNullOrEmpty(AnalyticsTypeOverride))
            {
                // Write Custom Analytics type setting
                IniLines.Add("");
                IniLines.Add("[Analytics]");
                IniLines.Add(String.Format("UE4TypeOverride=\"{0}\"", AnalyticsTypeOverride));
            }

            // Make sure we can write to the the config file
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes & ~FileAttributes.ReadOnly);
            File.AppendAllLines(OutputBaseEnginePath, IniLines);
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes);
        }
        /// <summary>
        /// Entry point for the commandlet
        /// </summary>
        public override void ExecuteBuild()
        {
            string OutputDir = ParseRequiredStringParam("OutputDir");
            List <UnrealTargetPlatform> Platforms            = ParsePlatformsParamValue("Platforms");
            List <UnrealTargetPlatform> ContentOnlyPlatforms = ParsePlatformsParamValue("ContentOnlyPlatforms");
            string AnalyticsTypeOverride = ParseParamValue("AnalyticsTypeOverride");

            // Write InstalledBuild.txt to indicate Engine is installed
            string InstalledBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledBuild.txt");

            CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledBuildFile));
            CommandUtils.WriteAllText(InstalledBuildFile, "");

            // Write InstalledBuild.txt to indicate Engine is installed
            string Project = ParseParamValue("Project");

            if (Project != null)
            {
                string InstalledProjectBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledProjectBuild.txt");
                CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledProjectBuildFile));
                CommandUtils.WriteAllText(InstalledProjectBuildFile, new FileReference(Project).MakeRelativeTo(new DirectoryReference(OutputDir)));
            }

            string         OutputEnginePath     = Path.Combine(OutputDir, "Engine");
            string         OutputBaseEnginePath = Path.Combine(OutputEnginePath, "Config", "BaseEngine.ini");
            FileAttributes OutputAttributes     = FileAttributes.ReadOnly;
            List <String>  IniLines             = new List <String>();

            // Should always exist but if not, we don't need extra line
            if (File.Exists(OutputBaseEnginePath))
            {
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath);
                IniLines.Add("");
            }
            else
            {
                CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(OutputBaseEnginePath));
                CommandUtils.WriteAllText(OutputBaseEnginePath, "");
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath) | OutputAttributes;
            }

            // Create list of platform configurations installed in a Rocket build
            List <InstalledPlatformInfo.InstalledPlatformConfiguration> InstalledConfigs = new List <InstalledPlatformInfo.InstalledPlatformConfiguration>();

            // Add the editor platform, otherwise we'll never be able to run UAT
            string EditorArchitecture = PlatformExports.GetDefaultArchitecture(HostPlatform.Current.HostEditorPlatform, null);

            InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.Development, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false));
            InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.DebugGame, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false));

            foreach (UnrealTargetPlatform CodeTargetPlatform in Platforms)
            {
                string Architecture = PlatformExports.GetDefaultArchitecture(CodeTargetPlatform, null);

                // Try to parse additional Architectures from the command line
                string Architectures    = ParseParamValue(CodeTargetPlatform.ToString() + "Architectures");
                string GPUArchitectures = ParseParamValue(CodeTargetPlatform.ToString() + "GPUArchitectures");

                // Build a list of pre-compiled architecture combinations for this platform if any
                List <string> AllArchNames;

                if (!String.IsNullOrWhiteSpace(Architectures) && !String.IsNullOrWhiteSpace(GPUArchitectures))
                {
                    AllArchNames = (from Arch in Architectures.Split('+')
                                    from GPUArch in GPUArchitectures.Split('+')
                                    select "-" + Arch + "-" + GPUArch).ToList();
                }
                else if (!String.IsNullOrWhiteSpace(Architectures))
                {
                    AllArchNames = Architectures.Split('+').ToList();
                }
                // if there aren't any, use the default
                else
                {
                    AllArchNames = new List <string>()
                    {
                        Architecture
                    };
                }

                // Check whether this platform should only be used for content based projects
                EProjectType ProjectType = ContentOnlyPlatforms.Contains(CodeTargetPlatform) ? EProjectType.Content : EProjectType.Any;

                // Allow Content only platforms to be shown as options in all projects
                bool bCanBeDisplayed = ProjectType == EProjectType.Content;
                foreach (UnrealTargetConfiguration CodeTargetConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                {
                    Dictionary <String, TargetType> Targets = new Dictionary <string, TargetType>()
                    {
                        { "UE4Game", TargetType.Game },
                        { "UE4Client", TargetType.Client },
                        { "UE4Server", TargetType.Server }
                    };
                    foreach (KeyValuePair <string, TargetType> Target in Targets)
                    {
                        string     CurrentTargetName = Target.Key;
                        TargetType CurrentTargetType = Target.Value;

                        // Need to check for development receipt as we use that for the Engine code in DebugGame
                        UnrealTargetConfiguration EngineConfiguration = (CodeTargetConfiguration == UnrealTargetConfiguration.DebugGame) ? UnrealTargetConfiguration.Development : CodeTargetConfiguration;

                        // Android has multiple architecture flavors built without receipts, so use the default arch target instead
                        if (CodeTargetPlatform == UnrealTargetPlatform.Android)
                        {
                            FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Architecture);
                            if (FileReference.Exists(ReceiptFileName))
                            {
                                // Strip the output folder so that this can be used on any machine
                                string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir));

                                // Blindly append all of the architecture names
                                if (AllArchNames.Count > 0)
                                {
                                    foreach (string Arch in AllArchNames)
                                    {
                                        InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed));
                                    }
                                }
                                // if for some reason we didn't specify any flavors, just add the default one.
                                else
                                {
                                    InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Architecture, RelativeReceiptFileName, ProjectType, bCanBeDisplayed));
                                }
                            }
                        }
                        // If we're not Android, check the existence of the target receipts for each architecture specified.
                        else
                        {
                            foreach (string Arch in AllArchNames)
                            {
                                FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Arch);
                                if (FileReference.Exists(ReceiptFileName))
                                {
                                    string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir));
                                    InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed));
                                }
                            }
                        }
                    }
                }
            }

            UnrealBuildTool.InstalledPlatformInfo.WriteConfigFileEntries(InstalledConfigs, ref IniLines);

            if (!String.IsNullOrEmpty(AnalyticsTypeOverride))
            {
                // Write Custom Analytics type setting
                IniLines.Add("");
                IniLines.Add("[Analytics]");
                IniLines.Add(String.Format("UE4TypeOverride=\"{0}\"", AnalyticsTypeOverride));
            }

            // Make sure we can write to the the config file
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes & ~FileAttributes.ReadOnly);
            File.AppendAllLines(OutputBaseEnginePath, IniLines);
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes);
        }
Пример #3
0
        /// <summary>
        /// Execute the command
        /// </summary>
        public override void ExecuteBuild()
        {
            // Get the source and target streams
            string Stream   = ParseParamValue("Stream", P4Env.BuildRootP4);
            string Changes  = ParseParamValue("Changes", null);
            string Lockdown = ParseParamValue("Lockdown", "Nick.Penwarden");

            // Get changes which haven't been copied up from the current stream
            string Descriptions;
            string SourceStream;
            int    LastCl;

            if (Changes == null)
            {
                IProcessResult Result = P4.P4(String.Format("interchanges -l -S {0}", Stream), AllowSpew: false);
                Descriptions = Result.Output.Replace("\r\n", "\n");
                SourceStream = Stream;

                // Get the last submitted change in the source stream
                List <P4Connection.ChangeRecord> ChangeRecords;
                if (!P4.Changes(out ChangeRecords, String.Format("-m1 {0}/...", SourceStream), AllowSpew: false))
                {
                    throw new AutomationException("Couldn't get changes for this branch");
                }
                LastCl = ChangeRecords[0].CL;
            }
            else
            {
                IProcessResult Result = P4.P4(String.Format("changes -l {0}", Changes), AllowSpew: false);
                Descriptions = Result.Output.Replace("\r\n", "\n");
                SourceStream = Regex.Replace(Changes, @"(\/(?:\/[^\/]*){2}).*", "$1");
                LastCl       = Int32.Parse(Regex.Replace(Changes, ".*,", ""));
            }

            // Clean any workspace names that may reveal internal information
            Descriptions = Regex.Replace(Descriptions, "(Change[^@]*)@.*", "$1", RegexOptions.Multiline);

            // Remove changes by the build machine
            Descriptions = Regex.Replace(Descriptions, "[^\n]*buildmachine\n(\n|\t[^\n]*\n)*", "");

            // Remove all the tags we don't care about
            Descriptions = Regex.Replace(Descriptions, "^[ \t]*#(rb|fyi|codereview|lockdown)\\s.*$", "", RegexOptions.Multiline);

            // Empty out lines which just contain whitespace
            Descriptions = Regex.Replace(Descriptions, "^[ \t]+$", "", RegexOptions.Multiline);

            // Remove multiple consecutive blank lines
            Descriptions = Regex.Replace(Descriptions, "\n\n+", "\n\n");

            // Only include one newline at the end of each description
            Descriptions = Regex.Replace(Descriptions, "\n+Change", "\n\nChange");

            // Remove merge-only changelists
            Descriptions = Regex.Replace(Descriptions, "(?<=(^|\\n))Change .*\\s*Merging .* to .*\\s*\\n(?=(Change|$))", "");

            // Figure out the target stream
            IProcessResult StreamResult = P4.P4(String.Format("stream -o {0}", Stream), AllowSpew: false);

            if (StreamResult.ExitCode != 0)
            {
                throw new AutomationException("Couldn't get stream description for {0}", Stream);
            }
            string Target = P4Spec.FromString(StreamResult.Output).GetField("Parent");

            if (Target == null)
            {
                throw new AutomationException("Couldn't get parent stream for {0}", Stream);
            }

            // Write the output file
            string OutputDirName = Path.Combine(CommandUtils.CmdEnv.LocalRoot, "Engine", "Intermediate");

            CommandUtils.CreateDirectory(OutputDirName);
            string OutputFileName = Path.Combine(OutputDirName, "Changes.txt");

            using (StreamWriter Writer = new StreamWriter(OutputFileName))
            {
                Writer.WriteLine("Copying {0} to {1} (Source: {2} @ {3})", Stream, Target.Trim(), SourceStream, LastCl);
                Writer.WriteLine("#lockdown {0}", Lockdown);
                Writer.WriteLine();
                Writer.WriteLine("==========================");
                Writer.WriteLine("MAJOR FEATURES + CHANGES");
                Writer.WriteLine("==========================");
                Writer.WriteLine();

                foreach (string Line in Descriptions.Split('\n'))
                {
                    Writer.WriteLine(Line);
                }
            }
            Log("Written {0}.", OutputFileName);

            // Open it with the default text editor
            Process.Start(OutputFileName);
        }