예제 #1
0
        /// <summary>
        /// Attempts to autodetect project properties.
        /// </summary>
        /// <param name="RawProjectPath">Full project path.</param>
        /// <returns>Project properties.</returns>
        private static ProjectProperties DetectProjectProperties(string RawProjectPath, List<UnrealTargetPlatform> ClientTargetPlatforms)
        {
            var Properties = new ProjectProperties();
            Properties.RawProjectPath = RawProjectPath;

            // detect if the project is content only, but has non-default build settings
            List<string> ExtraSearchPaths = null;
            if (!string.IsNullOrEmpty(RawProjectPath))
            {
                if (RequiresTempTarget(RawProjectPath, ClientTargetPlatforms))
                {
                    GenerateTempTarget(RawProjectPath);
                    Properties.bWasGenerated = true;
                    ExtraSearchPaths = new List<string>();
                    ExtraSearchPaths.Add(CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source"));
                }
                else if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs")))
                {
                    File.Delete(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs"));
                }
            }

            if (CommandUtils.CmdEnv.HasCapabilityToCompile)
            {
                DetectTargetsForProject(Properties, ExtraSearchPaths);
                Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs);
            }
            else
            {
                // should never ask for engine targets if we can't compile
                if (String.IsNullOrEmpty(RawProjectPath))
                {
                    throw new AutomationException("Cannot determine engine targets if we can't compile.");
                }

                Properties.bIsCodeBasedProject = Properties.bWasGenerated;
                // if there's a Source directory with source code in it, then mark us as having source code
                string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source");
                if (Directory.Exists(SourceDir))
                {
                    string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories);
                    string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories);
                    Properties.bIsCodeBasedProject |= (CppFiles.Length > 0 || HFiles.Length > 0);
                }
            }

            // check to see if the uproject loads modules, only if we haven't already determined it is a code based project
            if (!Properties.bIsCodeBasedProject)
            {
                string uprojectStr = File.ReadAllText(RawProjectPath);
                Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\"");
            }

            // Get all ini files
            if (!String.IsNullOrWhiteSpace(RawProjectPath))
            {
                CommandUtils.LogVerbose("Loading ini files for {0}", RawProjectPath);

                var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine");
                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory);
                        Properties.EngineConfigs.Add(TargetPlatformType, Config);
                    }
                }

                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath));
                        Properties.GameConfigs.Add(TargetPlatformType, Config);
                    }
                }
            }

            return Properties;
        }
예제 #2
0
        /// <summary>
        /// Finds all targets for the project.
        /// </summary>
        /// <param name="Properties">Project properties.</param>
        /// <param name="ExtraSearchPaths">Additional search paths.</param>
        private static void DetectTargetsForProject(ProjectProperties Properties, List<string> ExtraSearchPaths = null)
        {
            Properties.Targets = new Dictionary<TargetRules.TargetType, SingleTargetProperties>();
            string TargetsDllFilename;
            string FullProjectPath = null;

            var GameFolders = new List<string>();
            var RulesFolder = GetRulesAssemblyFolder();
            if (!String.IsNullOrEmpty(Properties.RawProjectPath))
            {
                CommandUtils.LogVerbose("Looking for targets for project {0}", Properties.RawProjectPath);

                TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", Properties.RawProjectPath.GetHashCode()));

                FullProjectPath = CommandUtils.GetDirectoryName(Properties.RawProjectPath);
                GameFolders.Add(FullProjectPath);
                CommandUtils.LogVerbose("Searching for target rule files in {0}", FullProjectPath);
            }
            else
            {
                TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", "_BaseEngine_"));
            }
            RulesCompiler.SetAssemblyNameAndGameFolders(TargetsDllFilename, GameFolders);

            // the UBT code assumes a certain CWD, but artists don't have this CWD.
            var SourceDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source");
            bool DirPushed = false;
            if (CommandUtils.DirectoryExists_NoExceptions(SourceDir))
            {
                CommandUtils.PushDir(SourceDir);
                DirPushed = true;
            }
            var TargetScripts = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Target, ExtraSearchPaths);
            if (DirPushed)
            {
                CommandUtils.PopDir();
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                // We only care about project target script so filter out any scripts not in the project folder, or take them all if we are just doing engine stuff
                var ProjectTargetScripts = new List<string>();
                foreach (var Filename in TargetScripts)
                {
                    var FullScriptPath = CommandUtils.CombinePaths(Path.GetFullPath(Filename));
                    if (FullProjectPath == null || FullScriptPath.StartsWith(FullProjectPath, StringComparison.InvariantCultureIgnoreCase))
                    {
                        ProjectTargetScripts.Add(FullScriptPath);
                    }
                }
                TargetScripts = ProjectTargetScripts;
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                CommandUtils.LogVerbose("Found {0} target rule files:", TargetScripts.Count);
                foreach (var Filename in TargetScripts)
                {
                    CommandUtils.LogVerbose("  {0}", Filename);
                }

                // Check if the scripts require compilation
                bool DoNotCompile = false;
                if (!CommandUtils.IsBuildMachine && !CheckIfScriptAssemblyIsOutOfDate(TargetsDllFilename, TargetScripts))
                {
                    Log.TraceInformation("Targets DLL {0} is up to date.", TargetsDllFilename);
                    DoNotCompile = true;
                }
                if (!DoNotCompile && CommandUtils.FileExists_NoExceptions(TargetsDllFilename))
                {
                    if (!CommandUtils.DeleteFile_NoExceptions(TargetsDllFilename, true))
                    {
                        DoNotCompile = true;
                        CommandUtils.Log("Could not delete {0} assuming it is up to date and reusable for a recursive UAT call.", TargetsDllFilename);
                    }
                }

                CompileAndLoadTargetsAssembly(Properties, TargetsDllFilename, DoNotCompile, TargetScripts);
            }
        }
예제 #3
0
 public BranchUProject()
 {
     GameName = "UE4";
     Properties = ProjectUtils.GetProjectProperties("");
     if (!Properties.Targets.ContainsKey(TargetRules.TargetType.Editor))
     {
         throw new AutomationException("Base UE4 project did not contain an editor target.");
     }
 }
예제 #4
0
        /// <summary>
        /// Optionally compiles and loads target rules assembly.
        /// </summary>
        /// <param name="Properties"></param>
        /// <param name="TargetsDllFilename"></param>
        /// <param name="DoNotCompile"></param>
        /// <param name="TargetScripts"></param>
        private static void CompileAndLoadTargetsAssembly(ProjectProperties Properties, string TargetsDllFilename, bool DoNotCompile, List<string> TargetScripts)
        {
            CommandUtils.Log("Compiling targets DLL: {0}", TargetsDllFilename);

            var ReferencedAssemblies = new List<string>()
                    {
                        "System.dll",
                        "System.Core.dll",
                        "System.Xml.dll",
                        typeof(UnrealBuildTool.UnrealBuildTool).Assembly.Location
                    };
            var TargetsDLL = DynamicCompilation.CompileAndLoadAssembly(TargetsDllFilename, TargetScripts, ReferencedAssemblies, null, DoNotCompile);
            var DummyTargetInfo = new TargetInfo(BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development);
            var AllCompiledTypes = TargetsDLL.GetTypes();
            foreach (Type TargetType in AllCompiledTypes)
            {
                // Find TargetRules but skip all "UE4Editor", "UE4Game" targets.
                if (typeof(TargetRules).IsAssignableFrom(TargetType))
                {
                    // Create an instance of this type
                    CommandUtils.LogVerbose("Creating target rules object: {0}", TargetType.Name);
                    var Rules = Activator.CreateInstance(TargetType, DummyTargetInfo) as TargetRules;
                    CommandUtils.LogVerbose("Adding target: {0} ({1})", TargetType.Name, Rules.Type);

                    SingleTargetProperties TargetData;
                    TargetData.TargetName = GetTargetName(TargetType);
                    Rules.TargetName = TargetData.TargetName;
                    TargetData.Rules = Rules;
                    if (Rules.Type == TargetRules.TargetType.Program)
                    {
                        Properties.Programs.Add(TargetData);
                    }
                    else
                    {
                        Properties.Targets.Add(Rules.Type, TargetData);
                    }

                    Properties.bUsesSteam |= Rules.bUsesSteam;
                    Properties.bUsesCEF3 |= Rules.bUsesCEF3;
                    Properties.bUsesSlate |= Rules.bUsesSlate;
                    Properties.bDebugBuildsActuallyUseDebugCRT |= Rules.bDebugBuildsActuallyUseDebugCRT;
                    Properties.bUsesSlateEditorStyle |= Rules.bUsesSlateEditorStyle;
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Attempts to autodetect project properties.
        /// </summary>
        /// <param name="RawProjectPath">Full project path.</param>
        /// <returns>Project properties.</returns>
        private static ProjectProperties DetectProjectProperties(string RawProjectPath)
        {
            var Properties = new ProjectProperties();
            Properties.RawProjectPath = RawProjectPath;

            if (CommandUtils.CmdEnv.HasCapabilityToCompile)
            {
                DetectTargetsForProject(Properties);
                Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs);
            }
            else
            {
                // should never ask for engine targets if we can't compile
                if (String.IsNullOrEmpty(RawProjectPath))
                {
                    throw new AutomationException("Cannot dtermine engine targets if we can't compile.");
                }

                Properties.bIsCodeBasedProject = false;
                // if there's a Source directory with source code in it, then mark us as having source code
                string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source");
                if (Directory.Exists(SourceDir))
                {
                    string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories);
                    string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories);
                    Properties.bIsCodeBasedProject = CppFiles.Length > 0 || HFiles.Length > 0;
                }
            }

            // check to see if the uproject loads modules, only if we haven't already determined it is a code based project
            if (!Properties.bIsCodeBasedProject)
            {
                string uprojectStr = File.ReadAllText(RawProjectPath);
                Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\"");
            }

            // Get all ini files
            if (!String.IsNullOrWhiteSpace(RawProjectPath))
            {
                CommandUtils.Log("Loading ini files for {0}", RawProjectPath);

                var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine");
                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory);
                        Properties.EngineConfigs.Add(TargetPlatformType, Config);
                    }
                }

                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath));
                        Properties.GameConfigs.Add(TargetPlatformType, Config);
                    }
                }
            }

            return Properties;
        }
예제 #6
0
            public BranchUProject(UnrealBuildTool.UProjectInfo InfoEntry)
            {
                GameName = InfoEntry.GameName;

                //not sure what the heck this path is relative to
                FilePath = Path.GetFullPath(CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Binaries", InfoEntry.FilePath));

                if (!CommandUtils.FileExists_NoExceptions(FilePath))
                {
                    throw new AutomationException("Could not resolve relative path corrctly {0} -> {1} which doesn't exist.", InfoEntry.FilePath, FilePath);
                }

                Properties = ProjectUtils.GetProjectProperties(Path.GetFullPath(FilePath));
            }
예제 #7
0
        /// <summary>
        /// Attempts to autodetect project properties.
        /// </summary>
        /// <param name="RawProjectPath">Full project path.</param>
        /// <returns>Project properties.</returns>
        private static ProjectProperties DetectProjectProperties(string RawProjectPath)
        {
            var Properties = new ProjectProperties();
            Properties.RawProjectPath = RawProjectPath;

            if (CommandUtils.CmdEnv.HasCapabilityToCompile)
            {
                DetectTargetsForProject(Properties);
                Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets);
            }
            else
            {
                // should never ask for engine targets if we can't compile
                if (String.IsNullOrEmpty(RawProjectPath))
                {
                    throw new AutomationException("Cannot dtermine engine targets if we can't compile.");
                }

                Properties.bIsCodeBasedProject = false;
                // if there's a Source directory with source code in it, then mark us as having source code
                string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source");
                if (Directory.Exists(SourceDir))
                {
                    string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories);
                    string[] HFiles = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories);
                    Properties.bIsCodeBasedProject = CppFiles.Length > 0 || HFiles.Length > 0;
                }
            }

            return Properties;
        }
예제 #8
0
            public BranchUProject(UnrealBuildTool.UProjectInfo InfoEntry)
            {
                GameName = InfoEntry.GameName;

                //not sure what the heck this path is relative to
                FilePath = InfoEntry.FilePath;

                if (!CommandUtils.FileExists_NoExceptions(FilePath.FullName))
                {
                    throw new AutomationException("Could not resolve relative path corrctly {0} -> {1} which doesn't exist.", InfoEntry.FilePath, FilePath);
                }

                Properties = ProjectUtils.GetProjectProperties(FilePath);



            }
예제 #9
0
        /// <summary>
        /// Finds all targets for the project.
        /// </summary>
        /// <param name="Properties">Project properties.</param>
        /// <param name="ExtraSearchPaths">Additional search paths.</param>
        private static void DetectTargetsForProject(ProjectProperties Properties, List <string> ExtraSearchPaths = null)
        {
            Properties.Targets = new Dictionary <TargetRules.TargetType, SingleTargetProperties>();
            string TargetsDllFilename;
            string FullProjectPath = null;

            var GameFolders = new List <string>();
            var RulesFolder = GetRulesAssemblyFolder();

            if (!String.IsNullOrEmpty(Properties.RawProjectPath))
            {
                CommandUtils.Log("Looking for targets for project {0}", Properties.RawProjectPath);

                TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", Properties.RawProjectPath.GetHashCode()));

                FullProjectPath = CommandUtils.GetDirectoryName(Properties.RawProjectPath);
                GameFolders.Add(FullProjectPath);
                CommandUtils.Log("Searching for target rule files in {0}", FullProjectPath);
            }
            else
            {
                TargetsDllFilename = CommandUtils.CombinePaths(RulesFolder, String.Format("UATRules{0}.dll", "_BaseEngine_"));
            }
            RulesCompiler.SetAssemblyNameAndGameFolders(TargetsDllFilename, GameFolders);

            // the UBT code assumes a certain CWD, but artists don't have this CWD.
            var  SourceDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source");
            bool DirPushed = false;

            if (CommandUtils.DirectoryExists_NoExceptions(SourceDir))
            {
                CommandUtils.PushDir(SourceDir);
                DirPushed = true;
            }
            var TargetScripts = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Target, ExtraSearchPaths);

            if (DirPushed)
            {
                CommandUtils.PopDir();
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                // We only care about project target script so filter out any scripts not in the project folder, or take them all if we are just doing engine stuff
                var ProjectTargetScripts = new List <string>();
                foreach (var Filename in TargetScripts)
                {
                    var FullScriptPath = CommandUtils.CombinePaths(Path.GetFullPath(Filename));
                    if (FullProjectPath == null || FullScriptPath.StartsWith(FullProjectPath, StringComparison.InvariantCultureIgnoreCase))
                    {
                        ProjectTargetScripts.Add(FullScriptPath);
                    }
                }
                TargetScripts = ProjectTargetScripts;
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                CommandUtils.LogVerbose("Found {0} target rule files:", TargetScripts.Count);
                foreach (var Filename in TargetScripts)
                {
                    CommandUtils.LogVerbose("  {0}", Filename);
                }

                // Check if the scripts require compilation
                bool DoNotCompile = false;
                if (!CommandUtils.IsBuildMachine && !CheckIfScriptAssemblyIsOutOfDate(TargetsDllFilename, TargetScripts))
                {
                    Log.TraceInformation("Targets DLL {0} is up to date.", TargetsDllFilename);
                    DoNotCompile = true;
                }
                if (!DoNotCompile && CommandUtils.FileExists_NoExceptions(TargetsDllFilename))
                {
                    if (!CommandUtils.DeleteFile_NoExceptions(TargetsDllFilename, true))
                    {
                        DoNotCompile = true;
                        CommandUtils.Log("Could not delete {0} assuming it is up to date and reusable for a recursive UAT call.", TargetsDllFilename);
                    }
                }

                CompileAndLoadTargetsAssembly(Properties, TargetsDllFilename, DoNotCompile, TargetScripts);
            }
        }
예제 #10
0
        /// <summary>
        /// Attempts to autodetect project properties.
        /// </summary>
        /// <param name="RawProjectPath">Full project path.</param>
        /// <returns>Project properties.</returns>
        private static ProjectProperties DetectProjectProperties(string RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms)
        {
            var Properties = new ProjectProperties();

            Properties.RawProjectPath = RawProjectPath;

            // detect if the project is content only, but has non-default build settings
            List <string> ExtraSearchPaths = null;

            if (!string.IsNullOrEmpty(RawProjectPath))
            {
                if (RequiresTempTarget(RawProjectPath, ClientTargetPlatforms))
                {
                    GenerateTempTarget(RawProjectPath);
                    Properties.bWasGenerated = true;
                    ExtraSearchPaths         = new List <string>();
                    ExtraSearchPaths.Add(CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source"));
                }
                else if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs")))
                {
                    File.Delete(Path.Combine(Path.GetDirectoryName(RawProjectPath), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath) + ".Target.cs"));
                }
            }

            if (CommandUtils.CmdEnv.HasCapabilityToCompile)
            {
                DetectTargetsForProject(Properties, ExtraSearchPaths);
                Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs);
            }
            else
            {
                // should never ask for engine targets if we can't compile
                if (String.IsNullOrEmpty(RawProjectPath))
                {
                    throw new AutomationException("Cannot dtermine engine targets if we can't compile.");
                }

                Properties.bIsCodeBasedProject = Properties.bWasGenerated;
                // if there's a Source directory with source code in it, then mark us as having source code
                string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source");
                if (Directory.Exists(SourceDir))
                {
                    string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories);
                    string[] HFiles   = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories);
                    Properties.bIsCodeBasedProject |= (CppFiles.Length > 0 || HFiles.Length > 0);
                }
            }

            // check to see if the uproject loads modules, only if we haven't already determined it is a code based project
            if (!Properties.bIsCodeBasedProject)
            {
                string uprojectStr = File.ReadAllText(RawProjectPath);
                Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\"");
            }

            // Get all ini files
            if (!String.IsNullOrWhiteSpace(RawProjectPath))
            {
                CommandUtils.Log("Loading ini files for {0}", RawProjectPath);

                var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine");
                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory);
                        Properties.EngineConfigs.Add(TargetPlatformType, Config);
                    }
                }

                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath));
                        Properties.GameConfigs.Add(TargetPlatformType, Config);
                    }
                }
            }

            return(Properties);
        }
예제 #11
0
        /// <summary>
        /// Attempts to autodetect project properties.
        /// </summary>
        /// <param name="RawProjectPath">Full project path.</param>
        /// <returns>Project properties.</returns>
        private static ProjectProperties DetectProjectProperties(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested)
        {
            var Properties = new ProjectProperties();

            Properties.RawProjectPath = RawProjectPath;

            // detect if the project is content only, but has non-default build settings
            List <string> ExtraSearchPaths = null;

            if (RawProjectPath != null)
            {
                if (RequiresTempTarget(RawProjectPath, ClientTargetPlatforms, AssetNativizationRequested))
                {
                    GenerateTempTarget(RawProjectPath);
                    Properties.bWasGenerated = true;
                    ExtraSearchPaths         = new List <string>();

                    string TempTargetDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source");
                    ExtraSearchPaths.Add(TempTargetDir);

                    // in case the RulesCompiler (what we use to find all the
                    // Target.cs files) has already cached the contents of this
                    // directory, then we need to invalidate that cache (so
                    // it'll find/use the new Target.cs file)
                    RulesCompiler.InvalidateRulesFileCache(TempTargetDir);
                }
                else if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath.FullName) + ".Target.cs")))
                {
                    File.Delete(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath.FullName) + ".Target.cs"));
                }
            }

            if (CommandUtils.CmdEnv.HasCapabilityToCompile)
            {
                DetectTargetsForProject(Properties, ExtraSearchPaths);
                Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs);
            }
            else
            {
                // should never ask for engine targets if we can't compile
                if (RawProjectPath == null)
                {
                    throw new AutomationException("Cannot determine engine targets if we can't compile.");
                }

                Properties.bIsCodeBasedProject = Properties.bWasGenerated;
                // if there's a Source directory with source code in it, then mark us as having source code
                string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Source");
                if (Directory.Exists(SourceDir))
                {
                    string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories);
                    string[] HFiles   = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories);
                    Properties.bIsCodeBasedProject |= (CppFiles.Length > 0 || HFiles.Length > 0);
                }
            }

            // check to see if the uproject loads modules, only if we haven't already determined it is a code based project
            if (!Properties.bIsCodeBasedProject && RawProjectPath != null)
            {
                string uprojectStr = File.ReadAllText(RawProjectPath.FullName);
                Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\"");
            }

            // Get all ini files
            if (RawProjectPath != null)
            {
                CommandUtils.LogVerbose("Loading ini files for {0}", RawProjectPath);

                var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine");
                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = ConfigCacheIni.CreateConfigCacheIni(TargetPlatformType, "Engine", RawProjectPath.Directory, new DirectoryReference(EngineDirectory));
                        Properties.EngineConfigs.Add(TargetPlatformType, Config);
                    }
                }

                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = ConfigCacheIni.CreateConfigCacheIni(TargetPlatformType, "Game", RawProjectPath.Directory);
                        Properties.GameConfigs.Add(TargetPlatformType, Config);
                    }
                }
            }

            return(Properties);
        }
예제 #12
0
        /// <summary>
        /// Finds all targets for the project.
        /// </summary>
        /// <param name="Properties">Project properties.</param>
        /// <param name="ExtraSearchPaths">Additional search paths.</param>
        private static void DetectTargetsForProject(ProjectProperties Properties, List <string> ExtraSearchPaths = null)
        {
            Properties.Targets = new List <SingleTargetProperties>();
            FileReference TargetsDllFilename;
            string        FullProjectPath = null;

            List <DirectoryReference> GameFolders = new List <DirectoryReference>();
            DirectoryReference        RulesFolder = new DirectoryReference(GetRulesAssemblyFolder());

            if (Properties.RawProjectPath != null)
            {
                CommandUtils.LogVerbose("Looking for targets for project {0}", Properties.RawProjectPath);

                TargetsDllFilename = FileReference.Combine(RulesFolder, String.Format("UATRules{0}.dll", Properties.RawProjectPath.GetHashCode()));

                FullProjectPath = CommandUtils.GetDirectoryName(Properties.RawProjectPath.FullName);
                GameFolders.Add(new DirectoryReference(FullProjectPath));
                CommandUtils.LogVerbose("Searching for target rule files in {0}", FullProjectPath);
            }
            else
            {
                TargetsDllFilename = FileReference.Combine(RulesFolder, String.Format("UATRules{0}.dll", "_BaseEngine_"));
            }

            // the UBT code assumes a certain CWD, but artists don't have this CWD.
            string SourceDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source");
            bool   DirPushed = false;

            if (CommandUtils.DirectoryExists_NoExceptions(SourceDir))
            {
                CommandUtils.PushDir(SourceDir);
                DirPushed = true;
            }
            List <DirectoryReference> ExtraSearchDirectories = (ExtraSearchPaths == null)? null : ExtraSearchPaths.Select(x => new DirectoryReference(x)).ToList();
            List <FileReference>      TargetScripts          = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Target, GameFolders: GameFolders, ForeignPlugins: null, AdditionalSearchPaths: ExtraSearchDirectories, bIncludeEnterprise: false);

            if (DirPushed)
            {
                CommandUtils.PopDir();
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                // We only care about project target script so filter out any scripts not in the project folder, or take them all if we are just doing engine stuff
                List <FileReference> ProjectTargetScripts = new List <FileReference>();
                foreach (FileReference TargetScript in TargetScripts)
                {
                    if (FullProjectPath == null || TargetScript.IsUnderDirectory(new DirectoryReference(FullProjectPath)))
                    {
                        ProjectTargetScripts.Add(TargetScript);
                    }
                }
                TargetScripts = ProjectTargetScripts;
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                CommandUtils.LogVerbose("Found {0} target rule files:", TargetScripts.Count);
                foreach (FileReference Filename in TargetScripts)
                {
                    CommandUtils.LogVerbose("  {0}", Filename);
                }

                // Check if the scripts require compilation
                bool DoNotCompile = false;
                if (!CommandUtils.IsBuildMachine && !CheckIfScriptAssemblyIsOutOfDate(TargetsDllFilename, TargetScripts))
                {
                    Log.TraceVerbose("Targets DLL {0} is up to date.", TargetsDllFilename);
                    DoNotCompile = true;
                }
                if (!DoNotCompile && CommandUtils.FileExists_NoExceptions(TargetsDllFilename.FullName))
                {
                    if (!CommandUtils.DeleteFile_NoExceptions(TargetsDllFilename.FullName, true))
                    {
                        DoNotCompile = true;
                        CommandUtils.LogVerbose("Could not delete {0} assuming it is up to date and reusable for a recursive UAT call.", TargetsDllFilename);
                    }
                }

                CompileAndLoadTargetsAssembly(Properties, TargetsDllFilename, DoNotCompile, TargetScripts);
            }
        }
예제 #13
0
        /// <summary>
        /// Attempts to autodetect project properties.
        /// </summary>
        /// <param name="RawProjectPath">Full project path.</param>
        /// <returns>Project properties.</returns>
        private static ProjectProperties DetectProjectProperties(string RawProjectPath)
        {
            var Properties = new ProjectProperties();

            Properties.RawProjectPath = RawProjectPath;

            if (CommandUtils.CmdEnv.HasCapabilityToCompile)
            {
                DetectTargetsForProject(Properties);
                Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs);
            }
            else
            {
                // should never ask for engine targets if we can't compile
                if (String.IsNullOrEmpty(RawProjectPath))
                {
                    throw new AutomationException("Cannot dtermine engine targets if we can't compile.");
                }

                Properties.bIsCodeBasedProject = false;
                // if there's a Source directory with source code in it, then mark us as having source code
                string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath), "Source");
                if (Directory.Exists(SourceDir))
                {
                    string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories);
                    string[] HFiles   = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories);
                    Properties.bIsCodeBasedProject = CppFiles.Length > 0 || HFiles.Length > 0;
                }
            }

            // check to see if the uproject loads modules, only if we haven't already determined it is a code based project
            if (!Properties.bIsCodeBasedProject)
            {
                string uprojectStr = File.ReadAllText(RawProjectPath);
                Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\"");
            }

            // Get all ini files
            if (!String.IsNullOrWhiteSpace(RawProjectPath))
            {
                CommandUtils.Log("Loading ini files for {0}", RawProjectPath);

                var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine");
                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Engine", Path.GetDirectoryName(RawProjectPath), EngineDirectory);
                        Properties.EngineConfigs.Add(TargetPlatformType, Config);
                    }
                }

                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = new ConfigCacheIni(TargetPlatformType, "Game", Path.GetDirectoryName(RawProjectPath));
                        Properties.GameConfigs.Add(TargetPlatformType, Config);
                    }
                }
            }

            return(Properties);
        }