public static void FindProjects(DirectoryReference BaseDir, List <FileReference> ProjectFiles)
        {
            if (BaseDir != CommandUtils.EngineDirectory)
            {
                int InitialProjectFileCount = ProjectFiles.Count;

                ProjectFiles.AddRange(DirectoryReference.EnumerateFiles(BaseDir, "*.uproject"));

                if (InitialProjectFileCount == ProjectFiles.Count)
                {
                    foreach (DirectoryReference SubDir in DirectoryReference.EnumerateDirectories(BaseDir))
                    {
                        FindProjects(SubDir, ProjectFiles);
                    }
                }
            }
        }
Beispiel #2
0
    /// <summary>
    /// Finds files to stage under a given base directory.
    /// </summary>
    /// <param name="BaseDir">The directory to search under</param>
    /// <param name="Pattern">Pattern for files to match</param>
    /// <param name="ExcludePatterns">Patterns to exclude from staging</param>
    /// <param name="Option">Options for the search</param>
    /// <param name="Files">List to receive the enumerated files</param>
    private void FindFilesToStageInternal(DirectoryReference BaseDir, string Pattern, StageFilesSearch Option, List <FileReference> Files)
    {
        // Enumerate all the files in this directory
        Files.AddRange(DirectoryReference.EnumerateFiles(BaseDir, Pattern));

        // Recurse through subdirectories if necessary
        if (Option == StageFilesSearch.AllDirectories)
        {
            foreach (DirectoryReference SubDir in DirectoryReference.EnumerateDirectories(BaseDir))
            {
                FileSystemName Name = new FileSystemName(SubDir);
                if (!RestrictedFolderNames.Contains(Name))
                {
                    FindFilesToStageInternal(SubDir, Pattern, Option, Files);
                }
            }
        }
    }
Beispiel #3
0
        public override void ExecuteBuild()
        {
            // Parse the arguments
            DirectoryReference FromDir = ParseRequiredDirectoryReferenceParam("From");

            if (!DirectoryReference.Exists(FromDir))
            {
                throw new AutomationException("Source directory '{0}' does not exist", FromDir);
            }

            // Just copy all the files into place
            foreach (FileReference SourceFile in DirectoryReference.EnumerateFiles(FromDir, "*", SearchOption.AllDirectories))
            {
                FileReference TargetFile = FileReference.Combine(RootDirectory, SourceFile.MakeRelativeTo(FromDir));
                LogInformation("Copying {0} to {1}", SourceFile, TargetFile);
                CopyFile(SourceFile.FullName, TargetFile.FullName);
            }
        }
        private static void CleanupScriptsAssemblies()
        {
            if (!CommandUtils.IsEngineInstalled())
            {
                CommandUtils.LogVerbose("Cleaning up script DLL folder");
                CommandUtils.DeleteDirectory(GetScriptAssemblyFolder());

                // Bug in PortalPublishingTool caused these DLLs to be copied into Engine/Binaries/DotNET. Delete any files left over.
                DirectoryReference BinariesDir = DirectoryReference.Combine(CommandUtils.RootDirectory, "Engine", "Binaries", "DotNET");
                foreach (FileReference FileToDelete in DirectoryReference.EnumerateFiles(BinariesDir, "*.automation.dll"))
                {
                    CommandUtils.DeleteFile(FileToDelete.FullName);
                }
                foreach (FileReference FileToDelete in DirectoryReference.EnumerateFiles(BinariesDir, "*.automation.pdb"))
                {
                    CommandUtils.DeleteFile(FileToDelete.FullName);
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Returns true/false based on whether the project supports a client configuration
        /// </summary>
        /// <param name="ProjectName"></param>
        /// <returns></returns>
        FileReference FindProjectSourceFile(FileReference InProjectFile)
        {
            FileReference SourceFile = null;

            if (InProjectFile != null)
            {
                DirectoryReference SourceDir = DirectoryReference.Combine(InProjectFile.Directory, "Source", InProjectFile.GetFileNameWithoutAnyExtensions());

                var Files = DirectoryReference.EnumerateFiles(SourceDir, "*.cpp", System.IO.SearchOption.AllDirectories);

                SourceFile = Files.FirstOrDefault();
            }

            if (SourceFile == null)
            {
                // touch the write time on a file, first making it writable since it may be under P4
                SourceFile = FileReference.Combine(CommandUtils.EngineDirectory, "Source/Runtime/Engine/Private/UnrealEngine.cpp");
            }

            Log.TraceVerbose("Will compile {0} for single-file compilation test for {1}", SourceFile, InProjectFile.GetFileNameWithoutAnyExtensions());

            return(SourceFile);
        }
Beispiel #6
0
    public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
    {
        // Stage all the build products
        foreach (StageTarget Target in SC.StageTargets)
        {
            SC.StageBuildProductsFromReceipt(Target.Receipt, Target.RequireFilesExist, Params.bTreatNonShippingBinariesAsDebugFiles);
        }

        if (SC.bStageCrashReporter)
        {
            StagedDirectoryReference CrashReportClientPath = StagedDirectoryReference.Combine("Engine/Binaries", SC.PlatformDir, "CrashReportClient.app");
            StageAppBundle(SC, DirectoryReference.Combine(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir, "CrashReportClient.app"), CrashReportClientPath);
        }

        // Find the app bundle path
        List <FileReference> Exes = GetExecutableNames(SC);

        foreach (var Exe in Exes)
        {
            StagedDirectoryReference AppBundlePath = null;
            if (Exe.IsUnderDirectory(DirectoryReference.Combine(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir)))
            {
                AppBundlePath = StagedDirectoryReference.Combine(SC.ShortProjectName, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe.FullName) + ".app");
            }
            else if (Exe.IsUnderDirectory(DirectoryReference.Combine(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)))
            {
                AppBundlePath = StagedDirectoryReference.Combine("Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe.FullName) + ".app");
            }

            // Copy the custom icon and Steam dylib, if needed
            if (AppBundlePath != null)
            {
                FileReference AppIconsFile = FileReference.Combine(SC.ProjectRoot, "Build", "Mac", "Application.icns");
                if (FileReference.Exists(AppIconsFile))
                {
                    SC.StageFile(StagedFileType.NonUFS, AppIconsFile, StagedFileReference.Combine(AppBundlePath, "Contents", "Resources", "Application.icns"));
                }
            }
        }

        // Copy the splash screen, Mac specific
        FileReference SplashImage = FileReference.Combine(SC.ProjectRoot, "Content", "Splash", "Splash.bmp");

        if (FileReference.Exists(SplashImage))
        {
            SC.StageFile(StagedFileType.NonUFS, SplashImage);
        }

        // Stage the bootstrap executable
        if (!Params.NoBootstrapExe)
        {
            foreach (StageTarget Target in SC.StageTargets)
            {
                BuildProduct Executable = Target.Receipt.BuildProducts.FirstOrDefault(x => x.Type == BuildProductType.Executable);
                if (Executable != null)
                {
                    // only create bootstraps for executables
                    List <StagedFileReference> StagedFiles = SC.FilesToStage.NonUFSFiles.Where(x => x.Value == Executable.Path).Select(x => x.Key).ToList();
                    if (StagedFiles.Count > 0 && Executable.Path.FullName.Replace("\\", "/").Contains("/" + TargetPlatformType.ToString() + "/"))
                    {
                        string BootstrapArguments = "";
                        if (!ShouldStageCommandLine(Params, SC))
                        {
                            if (!SC.IsCodeBasedProject)
                            {
                                BootstrapArguments = String.Format("../../../{0}/{0}.uproject", SC.ShortProjectName);
                            }
                            else
                            {
                                BootstrapArguments = SC.ShortProjectName;
                            }
                        }

                        string BootstrapExeName;
                        if (SC.StageTargetConfigurations.Count > 1)
                        {
                            BootstrapExeName = Path.GetFileName(Executable.Path.FullName) + ".app";
                        }
                        else if (Params.IsCodeBasedProject)
                        {
                            BootstrapExeName = Target.Receipt.TargetName + ".app";
                        }
                        else
                        {
                            BootstrapExeName = SC.ShortProjectName + ".app";
                        }

                        string AppSuffix = ".app" + Path.DirectorySeparatorChar;

                        string AppPath = Executable.Path.FullName.Substring(0, Executable.Path.FullName.LastIndexOf(AppSuffix) + AppSuffix.Length);
                        foreach (var DestPath in StagedFiles)
                        {
                            string AppRelativePath = DestPath.Name.Substring(0, DestPath.Name.LastIndexOf(AppSuffix) + AppSuffix.Length);
                            StageBootstrapExecutable(SC, BootstrapExeName, AppPath, AppRelativePath, BootstrapArguments);
                        }
                    }
                }
            }
        }

        // Copy the ShaderCache files, if they exist
        FileReference DrawCacheFile = FileReference.Combine(SC.ProjectRoot, "Content", "DrawCache.ushadercache");

        if (FileReference.Exists(DrawCacheFile))
        {
            SC.StageFile(StagedFileType.UFS, DrawCacheFile);
        }

        FileReference ByteCodeCacheFile = FileReference.Combine(SC.ProjectRoot, "Content", "ByteCodeCache.ushadercode");

        if (FileReference.Exists(ByteCodeCacheFile))
        {
            SC.StageFile(StagedFileType.UFS, ByteCodeCacheFile);
        }

        {
            // Stage any *.metallib files as NonUFS.
            // Get the final output directory for cooked data
            DirectoryReference CookOutputDir;
            if (!String.IsNullOrEmpty(Params.CookOutputDir))
            {
                CookOutputDir = DirectoryReference.Combine(new DirectoryReference(Params.CookOutputDir), SC.CookPlatform);
            }
            else if (Params.CookInEditor)
            {
                CookOutputDir = DirectoryReference.Combine(SC.ProjectRoot, "Saved", "EditorCooked", SC.CookPlatform);
            }
            else
            {
                CookOutputDir = DirectoryReference.Combine(SC.ProjectRoot, "Saved", "Cooked", SC.CookPlatform);
            }
            if (DirectoryReference.Exists(CookOutputDir))
            {
                List <FileReference> CookedFiles = DirectoryReference.EnumerateFiles(CookOutputDir, "*.metallib", SearchOption.AllDirectories).ToList();
                foreach (FileReference CookedFile in CookedFiles)
                {
                    SC.StageFile(StagedFileType.NonUFS, CookedFile, new StagedFileReference(CookedFile.MakeRelativeTo(CookOutputDir)));
                }
            }
        }
    }
    public override void ExecuteBuild()
    {
        // just calling this DesiredTargetVersion because TargetVersion and TargetedVersion get super confusing.
        string DesiredTargetVersion = this.ParseParamValue("TargetVersion", null);

        if (string.IsNullOrEmpty(DesiredTargetVersion))
        {
            throw new AutomationException("-TargetVersion was not specified.");
        }
        CommandUtils.Log("Scanning for all csproj's...");
        // Check for all csproj's in the engine dir
        DirectoryReference EngineDir = CommandUtils.EngineDirectory;

        // grab the targeted version.,
        Regex FrameworkRegex         = new Regex("<TargetFrameworkVersion>v(\\d\\.\\d\\.?\\d?)<\\/TargetFrameworkVersion>");
        Regex PossibleAppConfigRegex = new Regex("<TargetFrameworkProfile>(.+)<\\/TargetFrameworkProfile>");
        Regex AppConfigRegex         = new Regex("<supportedRuntime version=\"v(\\d\\.\\d\\.?\\d?)\" sku=\"\\.NETFramework,Version=v(\\d\\.\\d\\.?\\d?),Profile=(.+)\"\\/>");

        foreach (FileReference CsProj in DirectoryReference.EnumerateFiles(EngineDir, "*.csproj", SearchOption.AllDirectories))
        {
            if (CsProj.ContainsName(new FileSystemName("ThirdParty"), EngineDir) ||
                (CsProj.ContainsName(new FileSystemName("UE4TemplateProject"), EngineDir) && CsProj.GetFileName().Equals("ProjectTemplate.csproj")))
            {
                continue;
            }

            // read in the file
            string Contents = File.ReadAllText(CsProj.FullName);
            Match  m        = FrameworkRegex.Match(Contents);
            if (m.Success)
            {
                string TargetedVersion = m.Groups[1].Value;
                // make sure we match, throw warning otherwise
                if (!DesiredTargetVersion.Equals(TargetedVersion, StringComparison.InvariantCultureIgnoreCase))
                {
                    CommandUtils.LogWarning("Targeted Framework version for project: {0} was not {1}! Targeted Version: {2}", CsProj, DesiredTargetVersion, TargetedVersion);
                }
            }
            // if we don't have a TargetFrameworkVersion, check for the existence of TargetFrameworkProfile.
            else
            {
                m = PossibleAppConfigRegex.Match(Contents);
                if (!m.Success)
                {
                    CommandUtils.Log("No TargetFrameworkVersion or TargetFrameworkProfile found for project {0}, is it a mono project? If not, does it compile properly?", CsProj);
                    continue;
                }

                // look for the app config
                FileReference AppConfigFile = FileReference.Combine(CsProj.Directory, "app.config");
                string        Profile       = m.Groups[1].Value;
                if (!FileReference.Exists(AppConfigFile))
                {
                    CommandUtils.Log("Found TargetFrameworkProfile but no associated app.config containing the version for project {0}.", CsProj);
                    continue;
                }

                // read in the app config
                Contents = File.ReadAllText(AppConfigFile.FullName);
                m        = AppConfigRegex.Match(Contents);
                if (!m.Success)
                {
                    CommandUtils.Log("Couldn't find a supportedRuntime match for the version in the app.config for project {0}.", CsProj);
                    continue;
                }

                // Version1 is the one that appears right after supportedRuntime
                // Version2 is the one in the sku
                // ProfileString should match the TargetFrameworkProfile from the csproj
                string Version1String = m.Groups[1].Value;
                string Version2String = m.Groups[2].Value;
                string ProfileString  = m.Groups[3].Value;

                // not sure how this is possible, but check for it anyway
                if (!ProfileString.Equals(Profile, StringComparison.InvariantCultureIgnoreCase))
                {
                    CommandUtils.LogWarning("The TargetFrameworkProfile in csproj {0} ({1}) doesn't match the sku in it's app.config ({2}).", CsProj, Profile, ProfileString);
                    continue;
                }

                // if the version numbers don't match the app.config is probably corrupt.
                if (!Version1String.Equals(Version2String, StringComparison.InvariantCultureIgnoreCase))
                {
                    CommandUtils.LogWarning("The supportedRunTimeVersion ({0}) and the sku version ({1}) in the app.config for project {2} don't match.", Version1String, Version2String, CsProj);
                    continue;
                }

                // make sure the versions match
                if (!(DesiredTargetVersion.Equals(Version1String, StringComparison.InvariantCultureIgnoreCase)))
                {
                    CommandUtils.LogWarning("Targeted Framework version for project: {0} was not {1}! Targeted Version: {2}", CsProj, DesiredTargetVersion, Version1String);
                }
            }
        }
    }
Beispiel #8
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);
        }
    }
        public override void ExecuteBuild()
        {
            string[] ProjectParams = ParseParamValues("Project");

            string UpdateDirParam = ParseParamValue("UpdateDir", null);

            if (UpdateDirParam == null)
            {
                throw new AutomationException("Missing -UpdateDir=... parameter");
            }
            DirectoryReference UpdateDir = new DirectoryReference(UpdateDirParam);

            bool bWrite = ParseParam("Write");

            // Get all the root dirs
            HashSet <DirectoryReference> RootDirs = new HashSet <DirectoryReference>();

            RootDirs.Add(EngineDirectory);

            // Add the enterprise edirectory
            DirectoryReference EnterpriseDirectory = DirectoryReference.Combine(RootDirectory, "Enterprise");

            if (DirectoryReference.Exists(EnterpriseDirectory))
            {
                RootDirs.Add(EnterpriseDirectory);
            }

            // Add the project directories
            foreach (string ProjectParam in ProjectParams)
            {
                FileReference ProjectLocation = new FileReference(ProjectParam);
                if (!FileReference.Exists(ProjectLocation))
                {
                    throw new AutomationException("Unable to find project '{0}'", ProjectLocation);
                }
                RootDirs.Add(ProjectLocation.Directory);
            }

            // Find all the modules
            HashSet <DirectoryReference> ModuleDirs = new HashSet <DirectoryReference>();

            foreach (DirectoryReference RootDir in RootDirs)
            {
                // Find all the modules from the source folder
                DirectoryReference SourceDir = DirectoryReference.Combine(RootDir, "Source");
                if (DirectoryReference.Exists(SourceDir))
                {
                    foreach (FileReference ModuleFile in DirectoryReference.EnumerateFiles(SourceDir, "*.Build.cs", SearchOption.AllDirectories))
                    {
                        ModuleDirs.Add(ModuleFile.Directory);
                    }
                }

                // Find all the modules under the plugins folder
                DirectoryReference PluginsDir = DirectoryReference.Combine(RootDir, "Plugins");
                foreach (FileReference PluginFile in DirectoryReference.EnumerateFiles(PluginsDir, "*.uplugin", SearchOption.AllDirectories))
                {
                    DirectoryReference PluginSourceDir = DirectoryReference.Combine(PluginFile.Directory, "Source");
                    if (DirectoryReference.Exists(PluginSourceDir))
                    {
                        foreach (FileReference PluginModuleFile in DirectoryReference.EnumerateFiles(PluginSourceDir, "*.Build.cs", SearchOption.AllDirectories))
                        {
                            ModuleDirs.Add(PluginModuleFile.Directory);
                        }
                    }
                }
            }

            // Find a mapping from old to new include paths
            Dictionary <string, Tuple <string, FileReference> > RemapIncludePaths = new Dictionary <string, Tuple <string, FileReference> >(StringComparer.InvariantCultureIgnoreCase);

            foreach (DirectoryReference ModuleDir in ModuleDirs)
            {
                DirectoryReference ModulePublicDir = DirectoryReference.Combine(ModuleDir, "Public");
                if (DirectoryReference.Exists(ModulePublicDir))
                {
                    foreach (FileReference HeaderFile in DirectoryReference.EnumerateFiles(ModulePublicDir, "*.h", SearchOption.AllDirectories))
                    {
                        string BaseIncludeFile = HeaderFile.GetFileName();

                        Tuple <string, FileReference> ExistingIncludeName;
                        if (RemapIncludePaths.TryGetValue(BaseIncludeFile, out ExistingIncludeName))
                        {
                            LogWarning("Multiple include paths for {0}: {1}, {2}", BaseIncludeFile, ExistingIncludeName.Item2, HeaderFile);
                        }
                        else
                        {
                            RemapIncludePaths.Add(BaseIncludeFile, Tuple.Create(HeaderFile.MakeRelativeTo(ModulePublicDir).Replace('\\', '/'), HeaderFile));
                        }
                    }
                }
            }

            // List of folders to exclude from updates
            string[] ExcludeFoldersFromUpdate =
            {
                "Intermediate",
                "ThirdParty"
            };

            // Enumerate all the files to update
            HashSet <FileReference> UpdateFiles = new HashSet <FileReference>();

            foreach (FileReference UpdateFile in DirectoryReference.EnumerateFiles(UpdateDir, "*", SearchOption.AllDirectories))
            {
                if (!UpdateFile.ContainsAnyNames(ExcludeFoldersFromUpdate, UpdateDir))
                {
                    if (UpdateFile.HasExtension(".cpp") | UpdateFile.HasExtension(".h") || UpdateFile.HasExtension(".inl"))
                    {
                        UpdateFiles.Add(UpdateFile);
                    }
                }
            }

            // Process all the source files
            Dictionary <FileReference, string[]> ModifiedFiles = new Dictionary <FileReference, string[]>();

            foreach (FileReference UpdateFile in UpdateFiles)
            {
                bool bModifiedFile = false;

                string[] Lines = FileReference.ReadAllLines(UpdateFile);
                for (int Idx = 0; Idx < Lines.Length; Idx++)
                {
                    Match Match = Regex.Match(Lines[Idx], "^(\\s*#\\s*include\\s+\\\")([^\"]+)(\\\".*)$");
                    if (Match.Success)
                    {
                        string IncludePath = Match.Groups[2].Value;

                        Tuple <string, FileReference> NewIncludePath;
                        if (RemapIncludePaths.TryGetValue(IncludePath, out NewIncludePath))
                        {
                            if (IncludePath != NewIncludePath.Item1)
                            {
//								Log("{0}: Changing {1} -> {2}", UpdateFile, IncludePath, NewIncludePath.Item1);
                                Lines[Idx]    = String.Format("{0}{1}{2}", Match.Groups[1].Value, NewIncludePath.Item1, Match.Groups[3].Value);
                                bModifiedFile = true;
                            }
                        }
                    }
                }
                if (bModifiedFile)
                {
                    ModifiedFiles.Add(UpdateFile, Lines);
                }
            }

            // Output them all to disk
            if (bWrite && ModifiedFiles.Count > 0)
            {
                LogInformation("Updating {0} files...", ModifiedFiles.Count);

                List <FileReference> FilesToCheckOut = new List <FileReference>();
                foreach (FileReference ModifiedFile in ModifiedFiles.Keys)
                {
                    if ((FileReference.GetAttributes(ModifiedFile) & FileAttributes.ReadOnly) != 0)
                    {
                        FilesToCheckOut.Add(ModifiedFile);
                    }
                }

                if (FilesToCheckOut.Count > 0)
                {
                    if (!P4Enabled)
                    {
                        throw new AutomationException("{0} files have been modified, but are read only. Run with -P4 to enable Perforce checkout.\n{1}", FilesToCheckOut.Count, String.Join("\n", FilesToCheckOut.Select(x => "  " + x)));
                    }

                    LogInformation("Checking out files from Perforce");

                    int ChangeNumber = P4.CreateChange(Description: "Updating source files");
                    P4.Edit(ChangeNumber, FilesToCheckOut.Select(x => x.FullName).ToList(), false);
                }

                foreach (KeyValuePair <FileReference, string[]> FileToWrite in ModifiedFiles)
                {
                    LogInformation("Writing {0}", FileToWrite.Key);
                    FileReference.WriteAllLines(FileToWrite.Key, FileToWrite.Value);
                }
            }
        }
Beispiel #10
0
        public override void ExecuteBuild()
        {
            string RootDirParam = ParseParamValue("RootDir", null);

            if (RootDirParam == null)
            {
                throw new AutomationException("Missing -BaseDir=... parameter");
            }

            string CreatedBy    = ParseParamValue("CreatedBy", null);
            string CreatedByUrl = ParseParamValue("CreatedByUrl", null);
            bool   bForce       = ParseParam("Force");

            foreach (FileReference PluginFile in DirectoryReference.EnumerateFiles(new DirectoryReference(RootDirParam), "*.uplugin", System.IO.SearchOption.AllDirectories))
            {
                Log("Reading {0}", PluginFile);
                string InputText = File.ReadAllText(PluginFile.FullName);

                // Parse the descriptor
                PluginDescriptor Descriptor;
                try
                {
                    Descriptor = new PluginDescriptor(JsonObject.Parse(InputText));
                }
                catch (JsonParseException Ex)
                {
                    LogError("Unable to parse {0}: {1}", PluginFile, Ex.ToString());
                    continue;
                }

                // Update the fields
                if (CreatedBy != null && Descriptor.CreatedBy != CreatedBy)
                {
                    Log("  Updating 'CreatedBy' field from '{0}' to '{1}'", Descriptor.CreatedBy ?? "<empty>", CreatedBy);
                    Descriptor.CreatedBy = CreatedBy;
                }
                if (CreatedByUrl != null)
                {
                    Log("  Updating 'CreatedByURL' field from '{0}' to '{1}'", Descriptor.CreatedByURL ?? "<empty>", CreatedByUrl);
                    Descriptor.CreatedByURL = CreatedByUrl;
                }

                // Format the output text
                StringBuilder Output = new StringBuilder();
                using (JsonWriter Writer = new JsonWriter(new StringWriter(Output)))
                {
                    Writer.WriteObjectStart();
                    Descriptor.Write(Writer);
                    Writer.WriteObjectEnd();
                }

                // Compare the output and input; write it if it differs
                string OutputText = Output.ToString();
                if (InputText != OutputText)
                {
                    if (CommandUtils.IsReadOnly(PluginFile.FullName))
                    {
                        if (!bForce)
                        {
                            LogWarning("File is read only; skipping write.");
                            continue;
                        }
                        CommandUtils.SetFileAttributes(PluginFile.FullName, ReadOnly: false);
                    }
                    Log("  Writing updated file.", PluginFile);
                    FileReference.WriteAllText(PluginFile, OutputText);
                }
            }
        }
    public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC)
    {
        //		if (UnrealBuildTool.BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac)
        {
            // copy the icons/launch screens from the engine
            {
                FileReference SourcePath = FileReference.Combine(SC.LocalRoot, "Engine", "Binaries", "TVOS", "AssetCatalog", "Assets.car");
                if (FileReference.Exists(SourcePath))
                {
                    SC.StageFile(StagedFileType.SystemNonUFS, SourcePath, new StagedFileReference("Assets.car"));
                }
            }

            // copy any additional framework assets that will be needed at runtime
            {
                DirectoryReference SourcePath = DirectoryReference.Combine((SC.IsCodeBasedProject ? SC.ProjectRoot : SC.EngineRoot), "Intermediate", "TVOS", "FrameworkAssets");
                if (DirectoryReference.Exists(SourcePath))
                {
                    SC.StageFiles(StagedFileType.SystemNonUFS, SourcePath, StageFilesSearch.AllDirectories, StagedDirectoryReference.Root);
                }
            }

            // copy the icons/launch screens from the game (may stomp the engine copies)
            {
                FileReference SourcePath = FileReference.Combine(SC.ProjectRoot, "Binaries", "TVOS", "AssetCatalog", "Assets.car");
                if (FileReference.Exists(SourcePath))
                {
                    SC.StageFile(StagedFileType.SystemNonUFS, SourcePath, new StagedFileReference("Assets.car"));
                }
            }

            // copy the plist (only if code signing, as it's protected by the code sign blob in the executable and can't be modified independently)
            if (GetCodeSignDesirability(Params))
            {
                DirectoryReference SourcePath      = DirectoryReference.Combine((SC.IsCodeBasedProject ? SC.ProjectRoot : SC.EngineRoot), "Intermediate", "TVOS");
                FileReference      TargetPListFile = FileReference.Combine(SourcePath, (SC.IsCodeBasedProject ? SC.ShortProjectName : "UE4Game") + "-Info.plist");
                //				if (!File.Exists(TargetPListFile))
                {
                    // ensure the plist, entitlements, and provision files are properly copied
                    Console.WriteLine("CookPlat {0}, this {1}", GetCookPlatform(false, false), ToString());
                    if (!SC.IsCodeBasedProject)
                    {
                        UnrealBuildTool.PlatformExports.SetRemoteIniPath(SC.ProjectRoot.FullName);
                    }

                    if (SC.StageTargetConfigurations.Count != 1)
                    {
                        throw new AutomationException("iOS is currently only able to package one target configuration at a time, but StageTargetConfigurations contained {0} configurations", SC.StageTargetConfigurations.Count);
                    }

                    var TargetConfiguration = SC.StageTargetConfigurations[0];

                    bool bSupportsPortrait  = false;
                    bool bSupportsLandscape = false;
                    bool bSkipIcons         = false;
                    DeployGeneratePList(SC.RawProjectPath, TargetConfiguration, (SC.IsCodeBasedProject ? SC.ProjectRoot : SC.EngineRoot), !SC.IsCodeBasedProject, (SC.IsCodeBasedProject ? SC.ShortProjectName : "UE4Game"), Params.Client, SC.ShortProjectName, SC.EngineRoot, DirectoryReference.Combine((SC.IsCodeBasedProject ? SC.ProjectRoot : SC.EngineRoot), "Binaries", "TVOS", "Payload", (SC.IsCodeBasedProject ? SC.ShortProjectName : "UE4Game") + ".app"), SC.StageExecutables[0], out bSupportsPortrait, out bSupportsLandscape, out bSkipIcons);
                }


                // copy the udebugsymbols if they exist
                {
                    ConfigHierarchy PlatformGameConfig;
                    bool            bIncludeSymbols = false;
                    if (Params.EngineConfigs.TryGetValue(SC.StageTargetPlatform.PlatformType, out PlatformGameConfig))
                    {
                        PlatformGameConfig.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bGenerateCrashReportSymbols", out bIncludeSymbols);
                    }
                    if (bIncludeSymbols)
                    {
                        FileReference SymbolFileName = FileReference.Combine((SC.IsCodeBasedProject ? SC.ProjectRoot : SC.EngineRoot), "Binaries", "TVOS", SC.StageExecutables[0] + ".udebugsymbols");
                        if (FileReference.Exists(SymbolFileName))
                        {
                            SC.StageFile(StagedFileType.NonUFS, SymbolFileName, new StagedFileReference((Params.ShortProjectName + ".udebugsymbols").ToLowerInvariant()));
                        }
                    }
                }
                SC.StageFile(StagedFileType.SystemNonUFS, TargetPListFile, new StagedFileReference("Info.plist"));
            }
        }

        // copy the movies from the project
        {
            StageMovieFiles(DirectoryReference.Combine(SC.EngineRoot, "Content", "Movies"), SC);
            StageMovieFiles(DirectoryReference.Combine(SC.ProjectRoot, "Content", "Movies"), SC);
        }

        {
            // Stage any *.metallib files as NonUFS.
            // Get the final output directory for cooked data
            DirectoryReference CookOutputDir;
            if (!String.IsNullOrEmpty(Params.CookOutputDir))
            {
                CookOutputDir = DirectoryReference.Combine(new DirectoryReference(Params.CookOutputDir), SC.CookPlatform);
            }
            else if (Params.CookInEditor)
            {
                CookOutputDir = DirectoryReference.Combine(SC.ProjectRoot, "Saved", "EditorCooked", SC.CookPlatform);
            }
            else
            {
                CookOutputDir = DirectoryReference.Combine(SC.ProjectRoot, "Saved", "Cooked", SC.CookPlatform);
            }
            if (DirectoryReference.Exists(CookOutputDir))
            {
                List <FileReference> CookedFiles = DirectoryReference.EnumerateFiles(CookOutputDir, "*.metallib", SearchOption.AllDirectories).ToList();
                foreach (FileReference CookedFile in CookedFiles)
                {
                    SC.StageFile(StagedFileType.NonUFS, CookedFile, new StagedFileReference(CookedFile.MakeRelativeTo(CookOutputDir)));
                }
            }
        }
    }
Beispiel #12
0
    public override bool PublishSymbols(DirectoryReference SymbolStoreDirectory, List <FileReference> Files, string Product, string BuildVersion = null)
    {
        // Get the SYMSTORE.EXE path, using the latest SDK version we can find.
        FileReference SymStoreExe = GetSymStoreExe();

        List <FileReference> FilesToAdd = Files.Where(x => x.HasExtension(".pdb") || x.HasExtension(".exe") || x.HasExtension(".dll")).ToList();

        if (FilesToAdd.Count > 0)
        {
            DateTime           Start           = DateTime.Now;
            DirectoryReference TempSymStoreDir = DirectoryReference.Combine(RootDirectory, "Saved", "SymStore");
            DirectoryReference.CreateDirectory(TempSymStoreDir);
            DeleteDirectoryContents(TempSymStoreDir);

            string TempFileName = Path.GetTempFileName();
            try
            {
                File.WriteAllLines(TempFileName, FilesToAdd.Select(x => x.FullName), Encoding.ASCII);

                // Copy everything to the temp symstore
                ProcessStartInfo StartInfo = new ProcessStartInfo();
                StartInfo.FileName        = SymStoreExe.FullName;
                StartInfo.Arguments       = string.Format("add /f \"@{0}\" /s \"{1}\" /t \"{2}\" /compress", TempFileName, TempSymStoreDir, Product);
                StartInfo.UseShellExecute = false;
                StartInfo.CreateNoWindow  = true;
                if (Utils.RunLocalProcessAndLogOutput(StartInfo) != 0)
                {
                    return(false);
                }
            }
            finally
            {
                File.Delete(TempFileName);
            }
            DateTime CompressDone = DateTime.Now;
            LogInformation("Took {0}s to compress the symbol files", (CompressDone - Start).TotalSeconds);

            // Take each new compressed file made and try and copy it to the real symstore.  Exclude any symstore admin files
            foreach (FileReference File in DirectoryReference.EnumerateFiles(TempSymStoreDir, "*.*", SearchOption.AllDirectories).Where(File => File.HasExtension(".dl_") || File.HasExtension(".ex_") || File.HasExtension(".pd_")))
            {
                string        RelativePath          = File.MakeRelativeTo(DirectoryReference.Combine(TempSymStoreDir));
                FileReference ActualDestinationFile = FileReference.Combine(SymbolStoreDirectory, RelativePath);

                // Try and add a version file.  Do this before checking to see if the symbol is there already in the case of exact matches (multiple builds could use the same pdb, for example)
                if (!string.IsNullOrWhiteSpace(BuildVersion))
                {
                    FileReference BuildVersionFile = FileReference.Combine(ActualDestinationFile.Directory, string.Format("{0}.version", BuildVersion));
                    // Attempt to create the file. Just continue if it fails.
                    try
                    {
                        DirectoryReference.CreateDirectory(BuildVersionFile.Directory);
                        FileReference.WriteAllText(BuildVersionFile, string.Empty);
                    }
                    catch (Exception Ex)
                    {
                        LogWarning("Failed to write the version file, reason {0}", Ex.ToString());
                    }
                }

                // Don't bother copying the temp file if the destination file is there already.
                if (FileReference.Exists(ActualDestinationFile))
                {
                    LogInformation("Destination file {0} already exists, skipping", ActualDestinationFile.FullName);
                    continue;
                }

                FileReference TempDestinationFile = new FileReference(ActualDestinationFile.FullName + Guid.NewGuid().ToString());
                try
                {
                    CommandUtils.CopyFile(File.FullName, TempDestinationFile.FullName);
                }
                catch (Exception Ex)
                {
                    throw new AutomationException("Couldn't copy the symbol file to the temp store! Reason: {0}", Ex.ToString());
                }
                // Move the file in the temp store over.
                try
                {
                    FileReference.Move(TempDestinationFile, ActualDestinationFile);
                }
                catch (Exception Ex)
                {
                    // If the file is there already, it was likely either copied elsewhere (and this is an ioexception) or it had a file handle open already.
                    // Either way, it's fine to just continue on.
                    if (FileReference.Exists(ActualDestinationFile))
                    {
                        LogInformation("Destination file {0} already exists or was in use, skipping.", ActualDestinationFile.FullName);
                        continue;
                    }
                    // If it doesn't exist, we actually failed to copy it entirely.
                    else
                    {
                        LogWarning("Couldn't move temp file {0} to the symbol store at location {1}! Reason: {2}", TempDestinationFile.FullName, ActualDestinationFile.FullName, Ex.ToString());
                    }
                }
                // Delete the temp one no matter what, don't want them hanging around in the symstore
                finally
                {
                    FileReference.Delete(TempDestinationFile);
                }
            }
            LogInformation("Took {0}s to copy the symbol files to the store", (DateTime.Now - CompressDone).TotalSeconds);
        }

        return(true);
    }
        /// <summary>
        /// Finds and/or compiles all script files and assemblies.
        /// </summary>
        /// <param name="ScriptsForProjectFileName">Path to the current project. May be null, in which case we compile scripts for all projects.</param>
        /// <param name="AdditionalScriptsFolders">Additional script fodlers to look for source files in.</param>
        public static void FindAndCompileAllScripts(string ScriptsForProjectFileName, List <string> AdditionalScriptsFolders)
        {
            // Find all the project files
            Stopwatch            SearchTimer  = Stopwatch.StartNew();
            List <FileReference> ProjectFiles = FindAutomationProjects(ScriptsForProjectFileName, AdditionalScriptsFolders);

            Log.TraceLog("Found {0} project files in {1:0.000}s", ProjectFiles.Count, SearchTimer.Elapsed.TotalSeconds);

            // Get the default properties for compiling the projects
            Dictionary <string, string> MsBuildProperties = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            MsBuildProperties.Add("Platform", "AnyCPU");
            MsBuildProperties.Add("Configuration", BuildConfig);
            MsBuildProperties.Add("EngineDir", CommandUtils.EngineDirectory.FullName);

            // Read all the projects
            Stopwatch ParsingTimer = Stopwatch.StartNew();

            CsProjectInfo[] Projects = new CsProjectInfo[ProjectFiles.Count];
            Parallel.For(0, ProjectFiles.Count, Idx => Projects[Idx] = CsProjectInfo.Read(ProjectFiles[Idx], MsBuildProperties));
            Log.TraceLog("Parsed project files in {0:0.000}s", ParsingTimer.Elapsed.TotalSeconds);

            // Compile only if not disallowed.
            if (GlobalCommandLine.Compile && !String.IsNullOrEmpty(CommandUtils.CmdEnv.MsBuildExe))
            {
                List <CsProjectInfo> CompileProjects = new List <CsProjectInfo>(Projects);
                if (CommandUtils.IsEngineInstalled())
                {
                    CompileProjects.RemoveAll(x => x.ProjectPath.IsUnderDirectory(CommandUtils.EngineDirectory));
                }
                CompileAutomationProjects(CompileProjects, MsBuildProperties);
            }

            // Get all the build artifacts
            BuildProducts = new HashSet <FileReference>();

            HashSet <DirectoryReference> OutputDirs = new HashSet <DirectoryReference>();

            OutputDirs.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Binaries", "DotNET"));             // Don't want any artifacts from this directory (just AutomationTool.exe and AutomationScripts.dll)

            foreach (CsProjectInfo Project in Projects)
            {
                DirectoryReference OutputDir;
                if (!Project.TryGetOutputDir(out OutputDir))
                {
                    throw new AutomationException("Unable to get output directory for {0}", Project.ProjectPath);
                }

                if (OutputDirs.Add(OutputDir))
                {
                    BuildProducts.UnionWith(DirectoryReference.EnumerateFiles(OutputDir));
                }
            }

            // Load everything
            Stopwatch       LoadTimer  = Stopwatch.StartNew();
            List <Assembly> Assemblies = LoadAutomationAssemblies(Projects);

            Log.TraceLog("Loaded assemblies in {0:0.000}s", LoadTimer.Elapsed.TotalSeconds);

            // Setup platforms
            Platform.InitializePlatforms(Assemblies.ToArray());

            // Instantiate all the automation classes for interrogation
            Log.TraceVerbose("Creating commands.");
            ScriptCommands = new Dictionary <string, Type>(StringComparer.InvariantCultureIgnoreCase);
            foreach (Assembly CompiledScripts in Assemblies)
            {
                try
                {
                    foreach (Type ClassType in CompiledScripts.GetTypes())
                    {
                        if (ClassType.IsSubclassOf(typeof(BuildCommand)) && ClassType.IsAbstract == false)
                        {
                            if (ScriptCommands.ContainsKey(ClassType.Name) == false)
                            {
                                ScriptCommands.Add(ClassType.Name, ClassType);
                            }
                            else
                            {
                                bool IsSame = string.Equals(ClassType.AssemblyQualifiedName, ScriptCommands[ClassType.Name].AssemblyQualifiedName);

                                if (IsSame == false)
                                {
                                    Log.TraceWarning("Unable to add command {0} twice. Previous: {1}, Current: {2}", ClassType.Name,
                                                     ClassType.AssemblyQualifiedName, ScriptCommands[ClassType.Name].AssemblyQualifiedName);
                                }
                            }
                        }
                    }
                }
                catch (ReflectionTypeLoadException LoadEx)
                {
                    foreach (Exception SubEx in LoadEx.LoaderExceptions)
                    {
                        Log.TraceWarning("Got type loader exception: {0}", SubEx.ToString());
                    }
                    throw new AutomationException("Failed to add commands from {0}. {1}", CompiledScripts, LoadEx);
                }
                catch (Exception Ex)
                {
                    throw new AutomationException("Failed to add commands from {0}. {1}", CompiledScripts, Ex);
                }
            }
        }