Esempio n. 1
0
        /// <summary>
        /// Gets the dependency cache path and filename for the specified target.
        /// </summary>
        /// <param name="Target">Current build target</param>
        /// <returns>Cache Path</returns>
        public static string GetDependencyCachePathForTarget(UEBuildTarget Target)
        {
            string PlatformIntermediatePath = BuildConfiguration.PlatformIntermediatePath;

            if (UnrealBuildTool.HasUProjectFile())
            {
                PlatformIntermediatePath = Path.Combine(UnrealBuildTool.GetUProjectPath(), BuildConfiguration.PlatformIntermediateFolder);
            }
            string CachePath = Path.Combine(PlatformIntermediatePath, Target.GetTargetName(), "DependencyCache.bin");

            return(CachePath);
        }
Esempio n. 2
0
        /// <summary>
        /// Collects all header files included in a CPPFile
        /// </summary>
        /// <param name="CPPFile"></param>
        /// <param name="Result"></param>
        /// <param name="FileToRead"></param>
        /// <param name="FileContents"></param>
        /// <param name="InstalledFolder"></param>
        /// <param name="StartIndex"></param>
        /// <param name="EndIndex"></param>
        private static void CollectHeaders(FileItem CPPFile, List <DependencyInclude> Result, string FileToRead, string FileContents, string InstalledFolder, int StartIndex, int EndIndex)
        {
            Match             M  = CPPHeaderRegex.Match(FileContents, StartIndex, EndIndex - StartIndex);
            CaptureCollection CC = M.Groups["HeaderFile"].Captures;

            Result.Capacity = Math.Max(Result.Count + CC.Count, Result.Capacity);
            foreach (Capture C in CC)
            {
                string HeaderValue = C.Value;

                if (HeaderValue.IndexOfAny(Path.GetInvalidPathChars()) != -1)
                {
                    throw new BuildException("In {0}: An #include statement contains invalid characters.  You might be missing a double-quote character. (\"{1}\")", FileToRead, C.Value);
                }

                //@TODO: The intermediate exclusion is to work around autogenerated absolute paths in Module.SomeGame.cpp style files
                bool bIsIntermediateOrThirdParty = FileToRead.Contains("Intermediate") || FileToRead.Contains("ThirdParty");
                bool bCheckForBackwardSlashes    = FileToRead.StartsWith(InstalledFolder);
                if (UnrealBuildTool.HasUProjectFile())
                {
                    bCheckForBackwardSlashes |= Utils.IsFileUnderDirectory(FileToRead, UnrealBuildTool.GetUProjectPath());
                }
                if (bCheckForBackwardSlashes && !bIsIntermediateOrThirdParty)
                {
                    if (HeaderValue.IndexOf('\\', 0) >= 0)
                    {
                        throw new BuildException("In {0}: #include \"{1}\" contains backslashes ('\\'), please use forward slashes ('/') instead.", FileToRead, C.Value);
                    }
                }
                HeaderValue = Utils.CleanDirectorySeparators(HeaderValue);
                Result.Add(new DependencyInclude(HeaderValue));
            }

            // also look for #import in objective C files
            string Ext = Path.GetExtension(CPPFile.AbsolutePath).ToUpperInvariant();

            if (Ext == ".MM" || Ext == ".M")
            {
                M  = MMHeaderRegex.Match(FileContents, StartIndex, EndIndex - StartIndex);
                CC = M.Groups["HeaderFile"].Captures;
                Result.Capacity += CC.Count;
                foreach (Capture C in CC)
                {
                    Result.Add(new DependencyInclude(C.Value));
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Get the name of the response file for the current linker environment and output file
        /// </summary>
        /// <param name="LinkEnvironment"></param>
        /// <param name="OutputFile"></param>
        /// <returns></returns>
        public static string GetResponseFileName(LinkEnvironment LinkEnvironment, FileItem OutputFile)
        {
            // Construct a relative path for the intermediate response file
            string ResponseFileName = Path.Combine(LinkEnvironment.Config.IntermediateDirectory, Path.GetFileName(OutputFile.AbsolutePath) + ".response");

            if (UnrealBuildTool.HasUProjectFile())
            {
                // If this is the uproject being built, redirect the intermediate
                if (Utils.IsFileUnderDirectory(OutputFile.AbsolutePath, UnrealBuildTool.GetUProjectPath()))
                {
                    ResponseFileName = Path.Combine(
                        UnrealBuildTool.GetUProjectPath(),
                        BuildConfiguration.PlatformIntermediateFolder,
                        Path.GetFileNameWithoutExtension(UnrealBuildTool.GetUProjectFile()),
                        LinkEnvironment.Config.Target.Configuration.ToString(),
                        Path.GetFileName(OutputFile.AbsolutePath) + ".response");
                }
            }
            // Convert the relative path to an absolute path
            ResponseFileName = Path.GetFullPath(ResponseFileName);

            return(ResponseFileName);
        }
Esempio n. 4
0
        /// <summary>
        /// Generates a full path to action history file for the specified target.
        /// </summary>
        public static string GeneratePathForTarget(UEBuildTarget Target)
        {
            string Folder = null;

            if (Target.ShouldCompileMonolithic() || Target.TargetType == TargetRules.TargetType.Program)
            {
                // Monolithic configs and programs have their Action History stored in their respective project folders
                // or under engine intermediate folder + program name folder
                string RootDirectory = UnrealBuildTool.GetUProjectPath();
                if (String.IsNullOrEmpty(RootDirectory))
                {
                    RootDirectory = Path.GetFullPath(BuildConfiguration.RelativeEnginePath);
                }
                Folder = Path.Combine(RootDirectory, BuildConfiguration.PlatformIntermediateFolder, Target.GetTargetName());
            }
            else
            {
                // Shared action history (unless this is a rocket target)
                Folder = (UnrealBuildTool.RunningRocket() && UnrealBuildTool.HasUProjectFile()) ?
                         Path.Combine(UnrealBuildTool.GetUProjectPath(), BuildConfiguration.BaseIntermediateFolder) :
                         BuildConfiguration.BaseIntermediatePath;
            }
            return(Path.Combine(Folder, "ActionHistory.bin").Replace("\\", "/"));
        }
Esempio n. 5
0
        public override bool WriteProjectFile(List <UnrealTargetPlatform> InPlatforms, List <UnrealTargetConfiguration> InConfigurations)
        {
            bool bSuccess = false;

            string ProjectPath             = ProjectFilePath;
            string ProjectExtension        = Path.GetExtension(ProjectFilePath);
            string ProjectPlatformName     = BuildHostPlatform.Current.Platform.ToString();
            string ProjectRelativeFilePath = this.RelativeProjectFilePath;

            // Get the output directory
            string EngineRootDirectory = Path.GetFullPath(ProjectFileGenerator.EngineRelativePath);

            //
            // Build the working directory of the Game executable.
            //

            string GameWorkingDirectory = "";

            if (UnrealBuildTool.HasUProjectFile())
            {
                GameWorkingDirectory = Path.Combine(Path.GetDirectoryName(UnrealBuildTool.GetUProjectFile()), "Binaries", ProjectPlatformName);
            }
            //
            // Build the working directory of the UE4Editor executable.
            //
            string UE4EditorWorkingDirectory = Path.Combine(EngineRootDirectory, "Binaries", ProjectPlatformName);

            //
            // Create the folder where the project files goes if it does not exist
            //
            String FilePath = Path.GetDirectoryName(ProjectFilePath);

            if ((FilePath.Length > 0) && !Directory.Exists(FilePath))
            {
                Directory.CreateDirectory(FilePath);
            }

            string GameProjectFile = UnrealBuildTool.GetUProjectFile();

            //
            // Write all targets which will be separate projects.
            //
            foreach (ProjectTarget target in ProjectTargets)
            {
                string[] tmp = target.ToString().Split('.');
                string   ProjectTargetFileName = Path.GetDirectoryName(ProjectFilePath) + "/" + tmp [0] + ProjectExtension;
                String   ProjectName           = tmp [0];
                var      ProjectTargetType     = target.TargetRules.Type;

                //
                // Create the CodeLites root element.
                //
                XElement   CodeLiteProject = new XElement("CodeLite_Project");
                XAttribute CodeLiteProjectAttributeName = new XAttribute("Name", ProjectName);
                CodeLiteProject.Add(CodeLiteProjectAttributeName);

                //
                // Select only files we want to add.
                // TODO Maybe skipping those files directly in the following foreach loop is faster?
                //
                List <SourceFile> FilterSourceFile = SourceFiles.FindAll(s => (
                                                                             Path.GetExtension(s.FilePath).Equals(".h") ||
                                                                             Path.GetExtension(s.FilePath).Equals(".cpp") ||
                                                                             Path.GetExtension(s.FilePath).Equals(".cs") ||
                                                                             Path.GetExtension(s.FilePath).Equals(".uproject") ||
                                                                             Path.GetExtension(s.FilePath).Equals(".ini") ||
                                                                             Path.GetExtension(s.FilePath).Equals(".usf")
                                                                             ));

                //
                // Find/Create the correct virtual folder and place the file into it.
                //
                foreach (var CurrentFile in FilterSourceFile)
                {
                    //
                    // Try to get the correct relative folder representation for the project.
                    //
                    String CurrentFilePath = "";
                    // TODO It seems that the full pathname doesn't work for some files like .ini, .usf
                    if ((ProjectTargetType == TargetRules.TargetType.Client) ||
                        (ProjectTargetType == TargetRules.TargetType.Editor) ||
                        (ProjectTargetType == TargetRules.TargetType.Server))
                    {
                        if (ProjectName.Contains("UE4"))
                        {
                            int Idx = Path.GetFullPath(ProjectFileGenerator.EngineRelativePath).Length;
                            CurrentFilePath = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.FilePath)).Substring(Idx);
                        }
                        else
                        {
                            int    IdxProjectName = ProjectName.IndexOf("Editor");
                            string ProjectNameRaw = ProjectName;
                            if (IdxProjectName > 0)
                            {
                                ProjectNameRaw = ProjectName.Substring(0, IdxProjectName);
                            }
                            int Idx = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.FilePath)).IndexOf(ProjectNameRaw) + ProjectNameRaw.Length;
                            CurrentFilePath = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.FilePath)).Substring(Idx);
                        }
                    }
                    else if (ProjectTargetType == TargetRules.TargetType.Program)
                    {
                        //
                        // We do not need all the editors subfolders to show the content. Find the correct programs subfolder.
                        //
                        int Idx = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.FilePath)).IndexOf(ProjectName) + ProjectName.Length;
                        CurrentFilePath = Path.GetFullPath(Path.GetDirectoryName(CurrentFile.FilePath)).Substring(Idx);
                    }
                    else if (ProjectTargetType == TargetRules.TargetType.Game)
                    {
//						int lengthOfProjectRootPath = Path.GetFullPath(ProjectFileGenerator.MasterProjectRelativePath).Length;
//						CurrentFilePath = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.FilePath)).Substring(lengthOfProjectRootPath);
                        //	int lengthOfProjectRootPath = EngineRootDirectory.Length;
                        int Idx = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.FilePath)).IndexOf(ProjectName) + ProjectName.Length;
                        CurrentFilePath = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.FilePath)).Substring(Idx);
                    }

                    string [] SplitFolders = CurrentFilePath.Split('/');
                    //
                    // Set the CodeLite root folder again.
                    //
                    XElement root = CodeLiteProject;

                    //
                    // Iterate through all XElement virtual folders until we find the right place to put the file.
                    // TODO this looks more like a hack to me.
                    //
                    foreach (var FolderName in SplitFolders)
                    {
                        if (FolderName.Equals(""))
                        {
                            continue;
                        }

                        //
                        // Let's look if there is a virtual folder withint the current XElement.
                        //
                        IEnumerable <XElement> tests = root.Elements("VirtualDirectory");
                        if (IsEmpty(tests))
                        {
                            //
                            // No, then we have to create.
                            //
                            XElement   vf  = new XElement("VirtualDirectory");
                            XAttribute vfn = new XAttribute("Name", FolderName);
                            vf.Add(vfn);
                            root.Add(vf);
                            root = vf;
                        }
                        else
                        {
                            //
                            // Yes, then let's find the correct sub XElement.
                            //
                            bool notfound = true;

                            //
                            // We have some virtual directories let's find the correct one.
                            //
                            foreach (var element in tests)
                            {
                                //
                                // Look the the following folder
                                XAttribute attribute = element.Attribute("Name");
                                if (attribute.Value == FolderName)
                                {
                                    // Ok, we found the folder as subfolder, let's use it.
                                    root     = element;
                                    notfound = false;
                                    break;
                                }
                            }
                            //
                            // If we are here we didn't find any XElement with that subfolder, then we have to create.
                            //
                            if (notfound)
                            {
                                XElement   vf  = new XElement("VirtualDirectory");
                                XAttribute vfn = new XAttribute("Name", FolderName);
                                vf.Add(vfn);
                                root.Add(vf);
                                root = vf;
                            }
                        }
                    }

                    //
                    // If we are at this point we found the correct XElement folder
                    //
                    XElement   file          = new XElement("File");
                    XAttribute fileAttribute = new XAttribute("Name", Path.GetFullPath(CurrentFile.FilePath));
                    file.Add(fileAttribute);
                    root.Add(file);
                }

                XElement CodeLiteSettings = new XElement("Settings");
                CodeLiteProject.Add(CodeLiteSettings);

                XElement CodeLiteGlobalSettings = new XElement("GlobalSettings");
                CodeLiteSettings.Add(CodeLiteSettings);


                foreach (var CurConf in InConfigurations)
                {
                    XElement   CodeLiteConfiguration     = new XElement("Configuration");
                    XAttribute CodeLiteConfigurationName = new XAttribute("Name", CurConf.ToString());
                    CodeLiteConfiguration.Add(CodeLiteConfigurationName);

                    //
                    // Create Configuration General part.
                    //
                    XElement CodeLiteConfigurationGeneral = new XElement("General");

                    //
                    // Create the executable filename.
                    //
                    string ExecutableToRun       = "";
                    string PlatformConfiguration = "-" + ProjectPlatformName + "-" + CurConf.ToString();
                    switch (BuildHostPlatform.Current.Platform)
                    {
                    case UnrealTargetPlatform.Linux:
                    {
                        ExecutableToRun = "./" + ProjectName;
                        if ((ProjectTargetType == TargetRules.TargetType.Game) || (ProjectTargetType == TargetRules.TargetType.Program))
                        {
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                        else if (ProjectTargetType == TargetRules.TargetType.Editor)
                        {
                            ExecutableToRun = "./UE4Editor";
                        }
                    }
                    break;

                    case UnrealTargetPlatform.Mac:
                    {
                        ExecutableToRun = "./" + ProjectName;
                        if ((ProjectTargetType == TargetRules.TargetType.Game) || (ProjectTargetType == TargetRules.TargetType.Program))
                        {
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                            ExecutableToRun += ".app/Contents/MacOS/" + ProjectName;
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                        else if (ProjectTargetType == TargetRules.TargetType.Editor)
                        {
                            ExecutableToRun = "./UE4Editor";
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                            ExecutableToRun += ".app/Contents/MacOS/UE4Editor";
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                    }
                    break;

                    case UnrealTargetPlatform.Win64:
                    case UnrealTargetPlatform.Win32:
                    {
                        ExecutableToRun = ProjectName;
                        if ((ProjectTargetType == TargetRules.TargetType.Game) || (ProjectTargetType == TargetRules.TargetType.Program))
                        {
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                        else if (ProjectTargetType == TargetRules.TargetType.Editor)
                        {
                            ExecutableToRun = "UE4Editor";
                        }

                        ExecutableToRun += ".exe";
                    }
                    break;

                    default:
                        throw new BuildException("Unsupported platform.");
                    }


                    // Is this project a Game type?
                    XAttribute GeneralExecutableToRun = new XAttribute("Command", ExecutableToRun);
                    if (ProjectTargetType == TargetRules.TargetType.Game)
                    {
                        if (CurConf.ToString().Contains("Debug"))
                        {
                            string     commandArguments = " -debug";
                            XAttribute GeneralExecutableToRunArguments = new XAttribute("CommandArguments", commandArguments);
                            CodeLiteConfigurationGeneral.Add(GeneralExecutableToRunArguments);
                        }
                        if (ProjectName.Equals("UE4Game"))
                        {
                            XAttribute GeneralExecutableWorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                            CodeLiteConfigurationGeneral.Add(GeneralExecutableWorkingDirectory);
                        }
                        else
                        {
                            XAttribute GeneralExecutableWorkingDirectory = new XAttribute("WorkingDirectory", GameWorkingDirectory);
                            CodeLiteConfigurationGeneral.Add(GeneralExecutableWorkingDirectory);
                        }
                    }
                    else if (ProjectTargetType == TargetRules.TargetType.Editor)
                    {
                        if (ProjectName != "UE4Editor")
                        {
                            string     commandArguments = "\"" + GameProjectFile + "\"" + " -game";
                            XAttribute CommandArguments = new XAttribute("CommandArguments", commandArguments);
                            CodeLiteConfigurationGeneral.Add(CommandArguments);
                        }
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    else if (ProjectTargetType == TargetRules.TargetType.Program)
                    {
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    else if (ProjectTargetType == TargetRules.TargetType.Client)
                    {
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    else if (ProjectTargetType == TargetRules.TargetType.Server)
                    {
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    CodeLiteConfigurationGeneral.Add(GeneralExecutableToRun);

                    CodeLiteConfiguration.Add(CodeLiteConfigurationGeneral);

                    //
                    // End of Create Configuration General part.
                    //

                    //
                    // Create Configuration Custom Build part.
                    //
                    XElement CodeLiteConfigurationCustomBuild = new XElement("CustomBuild");
                    CodeLiteConfiguration.Add(CodeLiteConfigurationGeneral);
                    XAttribute CodeLiteConfigurationCustomBuildEnabled = new XAttribute("Enabled", "yes");
                    CodeLiteConfigurationCustomBuild.Add(CodeLiteConfigurationCustomBuildEnabled);

                    //
                    // Add the working directory for the custom build commands.
                    //
                    XElement CustomBuildWorkingDirectory  = new XElement("WorkingDirectory");
                    XText    CustuomBuildWorkingDirectory = new XText(Path.GetDirectoryName(UnrealBuildTool.GetUBTPath()));
                    CustomBuildWorkingDirectory.Add(CustuomBuildWorkingDirectory);
                    CodeLiteConfigurationCustomBuild.Add(CustomBuildWorkingDirectory);

                    //
                    // End of Add the working directory for the custom build commands.
                    //



                    //
                    // Make Build Target.
                    //
                    XElement CustomBuildCommand = new XElement("BuildCommand");
                    CodeLiteConfigurationCustomBuild.Add(CustomBuildCommand);

                    string BuildTarget = Path.GetFileName(UnrealBuildTool.GetUBTPath()) + " " + ProjectName + " " + ProjectPlatformName + " " + CurConf.ToString();
                    if ((BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Win64) &&
                        (BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Win32))
                    {
                        BuildTarget = "mono " + BuildTarget;
                    }

                    if (GameProjectFile.Length > 0)
                    {
                        BuildTarget += " -project=" + "\"" + GameProjectFile + "\"";
                    }

                    XText commandLine = new XText(BuildTarget);
                    CustomBuildCommand.Add(commandLine);

                    //
                    // End of Make Build Target
                    //

                    //
                    // Clean Build Target.
                    //
                    XElement CustomCleanCommand = new XElement("CleanCommand");
                    CodeLiteConfigurationCustomBuild.Add(CustomCleanCommand);

                    string CleanTarget      = BuildTarget + " -clean";
                    XText  CleanCommandLine = new XText(CleanTarget);

                    CustomCleanCommand.Add(CleanCommandLine);


                    //
                    // End of Clean Build Target.
                    //

                    //
                    // Rebuild Build Target.
                    //
                    XElement CustomRebuildCommand = new XElement("RebuildCommand");
                    CodeLiteConfigurationCustomBuild.Add(CustomRebuildCommand);

                    string RebuildTarget      = CleanTarget + "\n" + BuildTarget;
                    XText  RebuildCommandLine = new XText(RebuildTarget);

                    CustomRebuildCommand.Add(RebuildCommandLine);

                    //
                    // End of Clean Build Target.
                    //


                    //
                    // Some other fun Custom Targets.
                    //
                    if (ProjectTargetType == TargetRules.TargetType.Game)
                    {
                        string CookGameCommandLine = "mono AutomationTool.exe BuildCookRun ";

                        // Projects filename
                        CookGameCommandLine += "-project=\"" + UnrealBuildTool.GetUProjectFile() + "\" ";

                        // Disables Perforce functionality
                        CookGameCommandLine += "-noP4 ";

                        // Do not kill any spawned processes on exit
                        CookGameCommandLine += "-nokill ";
                        CookGameCommandLine += "-clientconfig=" + CurConf.ToString() + " ";
                        CookGameCommandLine += "-serverconfig=" + CurConf.ToString() + " ";
                        CookGameCommandLine += "-platform=" + ProjectPlatformName + " ";
                        CookGameCommandLine += "-targetplatform=" + ProjectPlatformName + " ";                                 // TODO Maybe I can add all the supported one.
                        CookGameCommandLine += "-nocompile ";
                        CookGameCommandLine += "-compressed -stage -deploy";

                        //
                        // Cook Game.
                        //
                        XElement   CookGame        = new XElement("Target");
                        XAttribute CookGameName    = new XAttribute("Name", "Cook Game");
                        XText      CookGameCommand = new XText(CookGameCommandLine + " -cook");
                        CookGame.Add(CookGameName);
                        CookGame.Add(CookGameCommand);
                        CodeLiteConfigurationCustomBuild.Add(CookGame);

                        XElement   CookGameOnTheFly         = new XElement("Target");
                        XAttribute CookGameNameOnTheFlyName = new XAttribute("Name", "Cook Game on the fly");
                        XText      CookGameOnTheFlyCommand  = new XText(CookGameCommandLine + " -cookonthefly");
                        CookGameOnTheFly.Add(CookGameNameOnTheFlyName);
                        CookGameOnTheFly.Add(CookGameOnTheFlyCommand);
                        CodeLiteConfigurationCustomBuild.Add(CookGameOnTheFly);

                        XElement   SkipCook        = new XElement("Target");
                        XAttribute SkipCookName    = new XAttribute("Name", "Skip Cook Game");
                        XText      SkipCookCommand = new XText(CookGameCommandLine + " -skipcook");
                        SkipCook.Add(SkipCookName);
                        SkipCook.Add(SkipCookCommand);
                        CodeLiteConfigurationCustomBuild.Add(SkipCook);
                    }
                    //
                    // End of Some other fun Custom Targets.
                    //
                    CodeLiteConfiguration.Add(CodeLiteConfigurationCustomBuild);

                    //
                    // End of Create Configuration Custom Build part.
                    //

                    CodeLiteSettings.Add(CodeLiteConfiguration);
                }

                CodeLiteSettings.Add(CodeLiteGlobalSettings);

                //
                // Save the XML file.
                //
                CodeLiteProject.Save(ProjectTargetFileName);

                bSuccess = true;
            }
            return(bSuccess);
        }
Esempio n. 6
0
        /**
         * Builds and runs the header tool and touches the header directories.
         * Performs any early outs if headers need no changes, given the UObject modules, tool path, game name, and configuration
         */
        public static bool ExecuteHeaderToolIfNecessary(UEBuildTarget Target, CPPEnvironment GlobalCompileEnvironment, List <UHTModuleInfo> UObjectModules, string ModuleInfoFileName, ref ECompilationResult UHTResult)
        {
            if (ProgressWriter.bWriteMarkup)
            {
                Log.WriteLine(TraceEventType.Information, "@progress push 5%");
            }
            using (ProgressWriter Progress = new ProgressWriter("Generating code...", false))
            {
                // We never want to try to execute the header tool when we're already trying to build it!
                var bIsBuildingUHT = Target.GetTargetName().Equals("UnrealHeaderTool", StringComparison.InvariantCultureIgnoreCase);

                var BuildPlatform = UEBuildPlatform.GetBuildPlatform(Target.Platform);
                var CppPlatform   = BuildPlatform.GetCPPTargetPlatform(Target.Platform);
                var ToolChain     = UEToolChain.GetPlatformToolChain(CppPlatform);
                var RootLocalPath = Path.GetFullPath(ProjectFileGenerator.RootRelativePath);

                // check if UHT is out of date
                DateTime HeaderToolTimestamp = DateTime.MaxValue;
                bool     bHaveHeaderTool     = !bIsBuildingUHT && GetHeaderToolTimestamp(out HeaderToolTimestamp);

                // ensure the headers are up to date
                bool bUHTNeedsToRun = (UEBuildConfiguration.bForceHeaderGeneration == true || !bHaveHeaderTool || AreGeneratedCodeFilesOutOfDate(UObjectModules, HeaderToolTimestamp));
                if (bUHTNeedsToRun || UnrealBuildTool.IsGatheringBuild)
                {
                    // Since code files are definitely out of date, we'll now finish computing information about the UObject modules for UHT.  We
                    // want to save this work until we know that UHT actually needs to be run to speed up best-case iteration times.
                    if (UnrealBuildTool.IsGatheringBuild)                               // In assembler-only mode, PCH info is loaded from our UBTMakefile!
                    {
                        foreach (var UHTModuleInfo in UObjectModules)
                        {
                            // Only cache the PCH name if we don't already have one.  When running in 'gather only' mode, this will have already been cached
                            if (string.IsNullOrEmpty(UHTModuleInfo.PCH))
                            {
                                UHTModuleInfo.PCH = "";

                                // We need to figure out which PCH header this module is including, so that UHT can inject an include statement for it into any .cpp files it is synthesizing
                                var DependencyModuleCPP      = (UEBuildModuleCPP)Target.GetModuleByName(UHTModuleInfo.ModuleName);
                                var ModuleCompileEnvironment = DependencyModuleCPP.CreateModuleCompileEnvironment(GlobalCompileEnvironment);
                                DependencyModuleCPP.CachePCHUsageForModuleSourceFiles(ModuleCompileEnvironment);
                                if (DependencyModuleCPP.ProcessedDependencies.UniquePCHHeaderFile != null)
                                {
                                    UHTModuleInfo.PCH = DependencyModuleCPP.ProcessedDependencies.UniquePCHHeaderFile.AbsolutePath;
                                }
                            }
                        }
                    }
                }

                // @todo ubtmake: Optimization: Ideally we could avoid having to generate this data in the case where UHT doesn't even need to run!  Can't we use the existing copy?  (see below use of Manifest)
                UHTManifest Manifest = new UHTManifest(Target, RootLocalPath, ToolChain.ConvertPath(RootLocalPath + '\\'), UObjectModules);

                if (!bIsBuildingUHT && bUHTNeedsToRun)
                {
                    // Always build UnrealHeaderTool if header regeneration is required, unless we're running within a Rocket ecosystem or hot-reloading
                    if (UnrealBuildTool.RunningRocket() == false &&
                        UEBuildConfiguration.bDoNotBuildUHT == false &&
                        UEBuildConfiguration.bHotReloadFromIDE == false &&
                        !(bHaveHeaderTool && !UnrealBuildTool.IsGatheringBuild && UnrealBuildTool.IsAssemblingBuild))                                   // If running in "assembler only" mode, we assume UHT is already up to date for much faster iteration!
                    {
                        // If it is out of date or not there it will be built.
                        // If it is there and up to date, it will add 0.8 seconds to the build time.
                        Log.TraceInformation("Building UnrealHeaderTool...");

                        var UBTArguments = new StringBuilder();

                        UBTArguments.Append("UnrealHeaderTool");

                        // Which desktop platform do we need to compile UHT for?
                        UBTArguments.Append(" " + BuildHostPlatform.Current.Platform.ToString());
                        // NOTE: We force Development configuration for UHT so that it runs quickly, even when compiling debug
                        UBTArguments.Append(" " + UnrealTargetConfiguration.Development.ToString());

                        // NOTE: We disable mutex when launching UBT from within UBT to compile UHT
                        UBTArguments.Append(" -NoMutex");

                        if (UnrealBuildTool.CommandLineContains("-noxge"))
                        {
                            UBTArguments.Append(" -noxge");
                        }

                        // Propagate command-line option to switch back to old 2013 toolchain
                        if (UnrealBuildTool.CommandLineContains("-2013"))
                        {
                            UBTArguments.Append(" -2013");
                        }

                        if (RunExternalExecutable(UnrealBuildTool.GetUBTPath(), UBTArguments.ToString()) != 0)
                        {
                            return(false);
                        }
                    }

                    Progress.Write(1, 3);

                    var ActualTargetName = String.IsNullOrEmpty(Target.GetTargetName()) ? "UE4" : Target.GetTargetName();
                    Log.TraceInformation("Parsing headers for {0}", ActualTargetName);

                    string HeaderToolPath = GetHeaderToolPath();
                    if (!File.Exists(HeaderToolPath))
                    {
                        throw new BuildException("Unable to generate headers because UnrealHeaderTool binary was not found ({0}).", Path.GetFullPath(HeaderToolPath));
                    }

                    // Disable extensions when serializing to remove the $type fields
                    Directory.CreateDirectory(Path.GetDirectoryName(ModuleInfoFileName));
                    System.IO.File.WriteAllText(ModuleInfoFileName, fastJSON.JSON.Instance.ToJSON(Manifest, new fastJSON.JSONParameters {
                        UseExtensions = false
                    }));

                    string CmdLine = (UnrealBuildTool.HasUProjectFile()) ? "\"" + UnrealBuildTool.GetUProjectFile() + "\"" : Target.GetTargetName();
                    CmdLine += " \"" + ModuleInfoFileName + "\" -LogCmds=\"loginit warning, logexit warning, logdatabase error\"";
                    if (UnrealBuildTool.RunningRocket())
                    {
                        CmdLine += " -rocket -installed";
                    }

                    if (UEBuildConfiguration.bFailIfGeneratedCodeChanges)
                    {
                        CmdLine += " -FailIfGeneratedCodeChanges";
                    }

                    Log.TraceInformation("  Running UnrealHeaderTool {0}", CmdLine);

                    Stopwatch s = new Stopwatch();
                    s.Start();
                    UHTResult = (ECompilationResult)RunExternalExecutable(ExternalExecution.GetHeaderToolPath(), CmdLine);
                    s.Stop();

                    if (UHTResult != ECompilationResult.Succeeded)
                    {
                        // On Linux and Mac, the shell will return 128+signal number exit codes if UHT gets a signal (e.g. crashes or is interrupted)
                        if ((BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Linux ||
                             BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) &&
                            (int)(UHTResult) >= 128
                            )
                        {
                            // SIGINT is 2, so 128 + SIGINT is 130
                            UHTResult = ((int)(UHTResult) == 130) ? ECompilationResult.Canceled : ECompilationResult.CrashOrAssert;
                        }

                        Log.TraceInformation("Error: Failed to generate code for {0} - error code: {2} ({1})", ActualTargetName, (int)UHTResult, UHTResult.ToString());
                        return(false);
                    }

                    Log.TraceInformation("Reflection code generated for {0} in {1} seconds", ActualTargetName, s.Elapsed.TotalSeconds);
                    if (BuildConfiguration.bPrintPerformanceInfo)
                    {
                        Log.TraceInformation("UnrealHeaderTool took {1}", ActualTargetName, (double)s.ElapsedMilliseconds / 1000.0);
                    }

                    // Now that UHT has successfully finished generating code, we need to update all cached FileItems in case their last write time has changed.
                    // Otherwise UBT might not detect changes UHT made.
                    DateTime StartTime = DateTime.UtcNow;
                    FileItem.ResetInfos();
                    double ResetDuration = (DateTime.UtcNow - StartTime).TotalSeconds;
                    Log.TraceVerbose("FileItem.ResetInfos() duration: {0}s", ResetDuration);
                }
                else
                {
                    Log.TraceVerbose("Generated code is up to date.");
                }

                Progress.Write(2, 3);

                // There will never be generated code if we're building UHT, so this should never be called.
                if (!bIsBuildingUHT)
                {
                    // Allow generated code to be sync'd to remote machines if needed. This needs to be done even if UHT did not run because
                    // generated headers include other generated headers using absolute paths which in case of building remotely are already
                    // the remote machine absolute paths. Because of that parsing headers will not result in finding all includes properly.
                    // @todo ubtmake: Need to figure out what this does in the assembler case, and whether we need to run it
                    ToolChain.PostCodeGeneration(Manifest);
                }

                // touch the directories
                UpdateDirectoryTimestamps(UObjectModules);

                Progress.Write(3, 3);
            }
            if (ProgressWriter.bWriteMarkup)
            {
                Log.WriteLine(TraceEventType.Information, "@progress pop");
            }
            return(true);
        }
Esempio n. 7
0
        private static string ResolveString(string Input, bool bIsPath)
        {
            string Result = Input;

            // these assume entire string is a path, and will do file operations on the whole string
            if (bIsPath)
            {
                if (Result.Contains("${PROGRAM_FILES}"))
                {
                    // first look in real ProgramFiles
                    string Temp = Result.Replace("${PROGRAM_FILES}", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles, Environment.SpecialFolderOption.DoNotVerify));
                    if (File.Exists(Temp) || Directory.Exists(Temp))
                    {
                        Result = Temp;
                    }
                    else
                    {
                        // fallback to ProgramFilesX86
                        Temp = Result.Replace("${PROGRAM_FILES}", Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86, Environment.SpecialFolderOption.DoNotVerify));
                        if (File.Exists(Temp) || Directory.Exists(Temp))
                        {
                            Result = Temp;
                        }
                    }
                }

                if (Result.Contains("${ENGINE_ROOT}"))
                {
                    string Temp = Result.Replace("${ENGINE_ROOT}", Path.GetFullPath(BuildConfiguration.RelativeEnginePath + "\\.."));

                    // get the best version
                    Result = LookForSpecialFile(Temp);
                }

                if (Result.Contains("${PROJECT_ROOT}"))
                {
                    if (!UnrealBuildTool.HasUProjectFile())
                    {
                        throw new BuildException("Configuration setting was using ${PROJECT_ROOT}, but there was no project specified");
                    }

                    string Temp = Result.Replace("${PROJECT_ROOT}", Path.GetFullPath(UnrealBuildTool.GetUProjectPath()));

                    // get the best version
                    Result = LookForSpecialFile(Temp);
                }
            }

            // non path variables
            Result = Result.Replace("${CURRENT_USER}", Environment.UserName);

            // needs a resolved key (which isn't required if user is using alternate authentication)
            if (Result.Contains("${SSH_PRIVATE_KEY}") || Result.Contains("${CYGWIN_SSH_PRIVATE_KEY}"))
            {
                // if it needs the key, then make sure we have it!
                if (ResolvedSSHPrivateKey != null)
                {
                    Result = Result.Replace("${SSH_PRIVATE_KEY}", ResolvedSSHPrivateKey);
                    Result = Result.Replace("${CYGWIN_SSH_PRIVATE_KEY}", ConvertPathToCygwin(ResolvedSSHPrivateKey));
                }
                else
                {
                    Result = null;
                }
            }

            return(Result);
        }