コード例 #1
0
        public override FileItem LinkFiles(LinkEnvironment LinkEnvironment, bool bBuildImportLibraryOnly)
        {
            Debug.Assert(!bBuildImportLibraryOnly);

            List <string> RPaths = new List <string>();

            if (LinkEnvironment.Config.bIsBuildingLibrary || bBuildImportLibraryOnly)
            {
                return(CreateArchiveAndIndex(LinkEnvironment));
            }

            // Create an action that invokes the linker.
            Action LinkAction = new Action(ActionType.Link);

            LinkAction.WorkingDirectory = Path.GetFullPath(".");
            if (String.IsNullOrEmpty(ClangPath))
            {
                LinkAction.CommandPath = GCCPath;
            }
            else
            {
                LinkAction.CommandPath = ClangPath;
            }

            // Get link arguments.
            LinkAction.CommandArguments = GetLinkArguments(LinkEnvironment);

            // Tell the action that we're building an import library here and it should conditionally be
            // ignored as a prerequisite for other actions
            LinkAction.bProducesImportLibrary = LinkEnvironment.Config.bIsBuildingDLL;

            // Add the output file as a production of the link action.
            FileItem OutputFile = FileItem.GetItemByPath(LinkEnvironment.Config.OutputFilePath);

            LinkAction.ProducedItems.Add(OutputFile);
            LinkAction.CommandDescription = "Link";
            LinkAction.StatusDescription  = Path.GetFileName(OutputFile.AbsolutePath);

            // Add the output file to the command-line.
            LinkAction.CommandArguments += string.Format(" -o \"{0}\"", OutputFile.AbsolutePath);

            // Add the input files to a response file, and pass the response file on the command-line.
            List <string> InputFileNames = new List <string>();

            foreach (FileItem InputFile in LinkEnvironment.InputFiles)
            {
                InputFileNames.Add(string.Format("\"{0}\"", InputFile.AbsolutePath.Replace("\\", "/")));
                LinkAction.PrerequisiteItems.Add(InputFile);
            }

            string ResponseFileName = GetResponseFileName(LinkEnvironment, OutputFile);

            LinkAction.CommandArguments += string.Format(" -Wl,@\"{0}\"", ResponseFile.Create(ResponseFileName, InputFileNames));

            if (LinkEnvironment.Config.bIsBuildingDLL)
            {
                LinkAction.CommandArguments += string.Format(" -Wl,-soname={0}", OutputFile);
            }

            // Start with the configured LibraryPaths and also add paths to any libraries that
            // we depend on (libraries that we've build ourselves).
            List <string> AllLibraryPaths = LinkEnvironment.Config.LibraryPaths;

            foreach (string AdditionalLibrary in LinkEnvironment.Config.AdditionalLibraries)
            {
                string PathToLib = Path.GetDirectoryName(AdditionalLibrary);
                if (!String.IsNullOrEmpty(PathToLib))
                {
                    // make path absolute, because FixDependencies script may be executed in a different directory
                    string AbsolutePathToLib = Path.GetFullPath(PathToLib);
                    if (!AllLibraryPaths.Contains(AbsolutePathToLib))
                    {
                        AllLibraryPaths.Add(AbsolutePathToLib);
                    }
                }

                if ((AdditionalLibrary.Contains("Plugins") || AdditionalLibrary.Contains("Binaries/ThirdParty") || AdditionalLibrary.Contains("Binaries\\ThirdParty")) && Path.GetDirectoryName(AdditionalLibrary) != Path.GetDirectoryName(OutputFile.AbsolutePath))
                {
                    string RelativePath = Utils.MakePathRelativeTo(Path.GetDirectoryName(AdditionalLibrary), Path.GetDirectoryName(OutputFile.AbsolutePath));
                    if (!RPaths.Contains(RelativePath))
                    {
                        RPaths.Add(RelativePath);
                        LinkAction.CommandArguments += string.Format(" -Wl,-rpath=\"${{ORIGIN}}/{0}\"", RelativePath);
                    }
                }
            }

            LinkAction.CommandArguments += string.Format(" -Wl,-rpath-link=\"{0}\"", Path.GetDirectoryName(OutputFile.AbsolutePath));

            // Add the library paths to the argument list.
            foreach (string LibraryPath in AllLibraryPaths)
            {
                // use absolute paths because of FixDependencies script again
                LinkAction.CommandArguments += string.Format(" -L\"{0}\"", Path.GetFullPath(LibraryPath));
            }

            // add libraries in a library group
            LinkAction.CommandArguments += string.Format(" -Wl,--start-group");

            List <string> EngineAndGameLibraries = new List <string>();

            foreach (string AdditionalLibrary in LinkEnvironment.Config.AdditionalLibraries)
            {
                if (String.IsNullOrEmpty(Path.GetDirectoryName(AdditionalLibrary)))
                {
                    // library was passed just like "jemalloc", turn it into -ljemalloc
                    LinkAction.CommandArguments += string.Format(" -l{0}", AdditionalLibrary);
                }
                else if (Path.GetExtension(AdditionalLibrary) == ".a")
                {
                    // static library passed in, pass it along but make path absolute, because FixDependencies script may be executed in a different directory
                    string AbsoluteAdditionalLibrary = Path.GetFullPath(AdditionalLibrary);
                    if (AbsoluteAdditionalLibrary.Contains(" "))
                    {
                        AbsoluteAdditionalLibrary = string.Format("\"{0}\"", AbsoluteAdditionalLibrary);
                    }
                    LinkAction.CommandArguments += (" " + AbsoluteAdditionalLibrary);
                    LinkAction.PrerequisiteItems.Add(FileItem.GetItemByPath(AdditionalLibrary));
                }
                else
                {
                    // Skip over full-pathed library dependencies when building DLLs to avoid circular
                    // dependencies.
                    FileItem LibraryDependency = FileItem.GetItemByPath(AdditionalLibrary);

                    var LibName = Path.GetFileNameWithoutExtension(AdditionalLibrary);
                    if (LibName.StartsWith("lib"))
                    {
                        // Remove lib prefix
                        LibName = LibName.Remove(0, 3);
                    }
                    string LibLinkFlag = string.Format(" -l{0}", LibName);

                    if (LinkEnvironment.Config.bIsBuildingDLL && LinkEnvironment.Config.bIsCrossReferenced)
                    {
                        // We are building a cross referenced DLL so we can't actually include
                        // dependencies at this point. Instead we add it to the list of
                        // libraries to be used in the FixDependencies step.
                        EngineAndGameLibraries.Add(LibLinkFlag);
                        if (!LinkAction.CommandArguments.Contains("--allow-shlib-undefined"))
                        {
                            LinkAction.CommandArguments += string.Format(" -Wl,--allow-shlib-undefined");
                        }
                    }
                    else
                    {
                        LinkAction.PrerequisiteItems.Add(LibraryDependency);
                        LinkAction.CommandArguments += LibLinkFlag;
                    }
                }
            }
            LinkAction.CommandArguments += " -lrt"; // needed for clock_gettime()
            LinkAction.CommandArguments += " -lm";  // math
            LinkAction.CommandArguments += string.Format(" -Wl,--end-group");

            // Add the additional arguments specified by the environment.
            LinkAction.CommandArguments += LinkEnvironment.Config.AdditionalArguments;
            LinkAction.CommandArguments  = LinkAction.CommandArguments.Replace("\\\\", "/");
            LinkAction.CommandArguments  = LinkAction.CommandArguments.Replace("\\", "/");

            // prepare a linker script
            string LinkerScriptPath = Path.Combine(LinkEnvironment.Config.LocalShadowDirectory, "remove-sym.ldscript");

            if (!Directory.Exists(LinkEnvironment.Config.LocalShadowDirectory))
            {
                Directory.CreateDirectory(LinkEnvironment.Config.LocalShadowDirectory);
            }
            if (File.Exists(LinkerScriptPath))
            {
                File.Delete(LinkerScriptPath);
            }

            using (StreamWriter Writer = File.CreateText(LinkerScriptPath))
            {
                Writer.WriteLine("UE4 {");
                Writer.WriteLine("  global: *;");
                Writer.WriteLine("  local: _Znwm;");
                Writer.WriteLine("         _Znam;");
                Writer.WriteLine("         _ZdaPv;");
                Writer.WriteLine("         _ZdlPv;");
                Writer.WriteLine("};");
            };

            LinkAction.CommandArguments += string.Format(" -Wl,--version-script=\"{0}\"", LinkerScriptPath);

            // Only execute linking on the local PC.
            LinkAction.bCanExecuteRemotely = false;

            // Prepare a script that will run later, once all shared libraries and the executable
            // are created. This script will be called by action created in FixDependencies()
            if (LinkEnvironment.Config.bIsCrossReferenced && LinkEnvironment.Config.bIsBuildingDLL)
            {
                bool   bUseCmdExe = BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64 || BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win32;
                string ScriptName = bUseCmdExe ? "FixDependencies.bat" : "FixDependencies.sh";

                string FixDepsScriptPath = Path.Combine(LinkEnvironment.Config.LocalShadowDirectory, ScriptName);
                if (!bHasWipedFixDepsScript)
                {
                    bHasWipedFixDepsScript = true;
                    Log.TraceVerbose("Creating script: {0}", FixDepsScriptPath);
                    StreamWriter Writer = File.CreateText(FixDepsScriptPath);

                    if (bUseCmdExe)
                    {
                        Writer.Write("@echo off\n");
                        Writer.Write("rem Automatically generated by UnrealBuildTool\n");
                        Writer.Write("rem *DO NOT EDIT*\n\n");
                    }
                    else
                    {
                        Writer.Write("#!/bin/sh\n");
                        Writer.Write("# Automatically generated by UnrealBuildTool\n");
                        Writer.Write("# *DO NOT EDIT*\n\n");
                        Writer.Write("set -o errexit\n");
                    }
                    Writer.Close();
                }

                StreamWriter FixDepsScript = File.AppendText(FixDepsScriptPath);

                string EngineAndGameLibrariesString = "";
                foreach (string Library in EngineAndGameLibraries)
                {
                    EngineAndGameLibrariesString += Library;
                }

                FixDepsScript.Write(string.Format("echo Fixing {0}\n", Path.GetFileName(OutputFile.AbsolutePath)));
                if (!bUseCmdExe)
                {
                    FixDepsScript.Write(string.Format("TIMESTAMP=`stat --format %y \"{0}\"`\n", OutputFile.AbsolutePath));
                }
                string FixDepsLine = LinkAction.CommandPath + " " + LinkAction.CommandArguments;
                string Replace     = "-Wl,--allow-shlib-undefined";

                FixDepsLine = FixDepsLine.Replace(Replace, EngineAndGameLibrariesString);
                string OutputFileForwardSlashes = OutputFile.AbsolutePath.Replace("\\", "/");
                FixDepsLine = FixDepsLine.Replace(OutputFileForwardSlashes, OutputFileForwardSlashes + ".fixed");
                FixDepsLine = FixDepsLine.Replace("$", "\\$");
                FixDepsScript.Write(FixDepsLine + "\n");
                if (bUseCmdExe)
                {
                    FixDepsScript.Write(string.Format("move /Y \"{0}.fixed\" \"{0}\"\n", OutputFile.AbsolutePath));
                }
                else
                {
                    FixDepsScript.Write(string.Format("mv \"{0}.fixed\" \"{0}\"\n", OutputFile.AbsolutePath));
                    FixDepsScript.Write(string.Format("touch -d \"$TIMESTAMP\" \"{0}\"\n\n", OutputFile.AbsolutePath));
                }
                FixDepsScript.Close();
            }

            //LinkAction.CommandArguments += " -v";

            return(OutputFile);
        }
コード例 #2
0
        /// <summary>
        /// Adds the include directory to the list, after converting it to an absolute path to UE4 root directory.
        /// </summary>
        /// <param name="FileContent">File content.</param>
        private void WriteIncludeSection(ref StringBuilder FileContent)
        {
            List <string> IncludeDirectories       = new List <string>();
            List <string> SystemIncludeDirectories = new List <string>();

            var UnrealEngineRootPath = UnrealBuildTool.RootDirectory.FullName;

            int IncludeIndex = 1;

            // Iterate through all the include paths that
            // UnrealBuildTool.exe generates

            foreach (var CurProject in GeneratedProjectFiles)
            {
                KDevelopProjectFile KDevelopProject = CurProject as KDevelopProjectFile;
                if (KDevelopProject == null)
                {
                    System.Console.WriteLine("KDevelopProject == null");
                    continue;
                }

                foreach (var CurPath in KDevelopProject.IntelliSenseIncludeSearchPaths)
                {
                    string FullProjectPath = ProjectFileGenerator.MasterProjectPath.FullName;
                    string FullPath        = "";

                    // need to test to see if this in the project souce tree
                    if (CurPath.StartsWith("/") && !CurPath.StartsWith(FullProjectPath))
                    {
                        // Full path to a folder outside of project
                        FullPath = CurPath;
                    }
                    else
                    {
                        FullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(KDevelopProject.ProjectFilePath.FullName), CurPath));
                        FullPath = Utils.MakePathRelativeTo(FullPath, FullProjectPath);
                        FullPath = FullPath.TrimEnd('/');
                        FullPath = Path.Combine(UnrealEngineRootPath, FullPath);
                    }

                    if (!FullPath.Contains("FortniteGame/") && !FullPath.Contains("ThirdParty/"))
                    {
                        SystemIncludeDirectories.Add(String.Format("{0}", FullPath));
                        IncludeIndex++;
                    }
                }

                foreach (var CurPath in KDevelopProject.IntelliSenseSystemIncludeSearchPaths)
                {
                    string FullProjectPath = ProjectFileGenerator.MasterProjectPath.FullName;
                    string FullPath        = "";

                    if (CurPath.StartsWith("/") && !CurPath.StartsWith(FullProjectPath))
                    {
                        // Full path to a folder outside of project
                        FullPath = CurPath;
                    }
                    else
                    {
                        FullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(KDevelopProject.ProjectFilePath.FullName), CurPath));
                        FullPath = Utils.MakePathRelativeTo(FullPath, FullProjectPath);
                        FullPath = FullPath.TrimEnd('/');
                        FullPath = Path.Combine(UnrealEngineRootPath, FullPath);
                    }

                    if (!FullPath.Contains("FortniteGame/") && !FullPath.Contains("ThirdParty/"))                     // @todo: skipping Fortnite header paths to shorten clang command line for building UE4XcodeHelper
                    {
                        SystemIncludeDirectories.Add(String.Format("{0}", FullPath));
                        IncludeIndex++;
                    }
                }
            }

            // Remove duplicate paths from include dir and system include dir list
            List <string> Tmp  = new List <string>();
            List <string> Stmp = new List <string>();

            Tmp  = IncludeDirectories.Distinct().ToList();
            Stmp = SystemIncludeDirectories.Distinct().ToList();

            IncludeDirectories       = Tmp.ToList();
            SystemIncludeDirectories = Stmp.ToList();

            foreach (var CurPath in IncludeDirectories)
            {
                FileContent.Append(CurPath);
                FileContent.Append(" \n");
            }

            foreach (var CurPath in SystemIncludeDirectories)
            {
                FileContent.Append(CurPath);
                FileContent.Append(" \n");
            }
            FileContent.Append("\n");
        }
コード例 #3
0
        private bool WriteQMakePro()
        {
            // Some more stuff borrowed from Mac side of things.
            List <string> IncludeDirectories       = new List <string>();
            List <string> SystemIncludeDirectories = new List <string>();
            List <string> DefinesAndValues         = new List <string>();

            // DefineList.Add ("");

            var QMakeIncludesFileName       = MasterProjectName + "Includes.pri";
            var QMakeIncludesPriFileContent = new StringBuilder();

            var QMakeDefinesFileName       = MasterProjectName + "Defines.pri";
            var QMakeDefinesPriFileContent = new StringBuilder();

            string GameProjectPath     = "";
            string GameProjectFile     = "";
            string GameProjectRootPath = "";

            string BuildCommand = "";

            string QMakeGameProjectFile = "";

            foreach (var CurProject in GeneratedProjectFiles)
            {
                QMakefileProjectFile QMakeProject = CurProject as QMakefileProjectFile;
                if (QMakeProject == null)
                {
                    System.Console.WriteLine("QMakeProject == null");
                    continue;
                }

                foreach (var CurPath in QMakeProject.IntelliSenseIncludeSearchPaths)
                {
                    AddIncludeDirectory(ref IncludeDirectories, CurPath, Path.GetDirectoryName(QMakeProject.ProjectFilePath.FullName));
                    // System.Console.WriteLine ("Not empty now? CurPath == ", CurPath);
                }
                foreach (var CurPath in QMakeProject.IntelliSenseSystemIncludeSearchPaths)
                {
                    AddIncludeDirectory(ref SystemIncludeDirectories, CurPath, Path.GetDirectoryName(QMakeProject.ProjectFilePath.FullName));
                }
            }

            // Remove duplicate paths from include dir and system include dir list
            IncludeDirectories       = IncludeDirectories.Distinct().ToList();
            SystemIncludeDirectories = SystemIncludeDirectories.Distinct().ToList();

            // Iterate through all the defines for the projects that are generated by
            // UnrealBuildTool.exe
            // !RAKE: move to seperate function
            QMakeDefinesPriFileContent.Append("DEFINES += \\\n");
            foreach (var CurProject in GeneratedProjectFiles)
            {
                QMakefileProjectFile QMakeProject = CurProject as QMakefileProjectFile;
                if (QMakeProject == null)
                {
                    System.Console.WriteLine("QMakeProject == null");
                    continue;
                }

                foreach (var CurDefine in QMakeProject.IntelliSensePreprocessorDefinitions)
                {
                    String define = "";
                    String value  = "";

                    SplitDefinitionAndValue(CurDefine, out define, out value);

                    if (!DefinesAndValues.Contains(define))
                    {
                        // System.Console.WriteLine (CurDefine);
                        if (string.IsNullOrEmpty(value))
                        {
                            DefinesAndValues.Add("\t");
                            DefinesAndValues.Add(String.Format("{0}=", define));
                            DefinesAndValues.Add(" \\\n");
                        }
                        else
                        {
                            DefinesAndValues.Add("\t");
                            DefinesAndValues.Add(define);
                            DefinesAndValues.Add("=");
                            DefinesAndValues.Add(value);
                            DefinesAndValues.Add(" \\\n");
                        }
                    }
                }
            }

            foreach (var Def in DefinesAndValues)
            {
                QMakeDefinesPriFileContent.Append(Def);
            }

            // Iterate through all the include paths that
            // UnrealBuildTool.exe generates
            // !RAKE: Move to seperate function
            QMakeIncludesPriFileContent.Append("INCLUDEPATH += \\\n");
            foreach (var CurPath in IncludeDirectories)
            {
                QMakeIncludesPriFileContent.Append("\t");
                QMakeIncludesPriFileContent.Append(CurPath);
                QMakeIncludesPriFileContent.Append(" \\\n");
            }

            foreach (var CurPath in SystemIncludeDirectories)
            {
                QMakeIncludesPriFileContent.Append("\t");
                QMakeIncludesPriFileContent.Append(CurPath);
                QMakeIncludesPriFileContent.Append(" \\\n");
            }
            QMakeIncludesPriFileContent.Append("\n");

            if (!String.IsNullOrEmpty(GameProjectName))
            {
                GameProjectPath      = OnlyGameProject.Directory.FullName;
                GameProjectFile      = OnlyGameProject.FullName;
                QMakeGameProjectFile = "gameProjectFile=" + GameProjectFile + "\n";
                BuildCommand         = "build=mono $$unrealRootPath/Engine/Binaries/DotNET/UnrealBuildTool.exe\n\n";
            }
            else
            {
                BuildCommand = "build=bash $$unrealRootPath/Engine/Build/BatchFiles/Linux/Build.sh\n";
            }

            var UnrealRootPath = Path.GetFullPath(ProjectFileGenerator.RootRelativePath);

            var FileName = MasterProjectName + ".pro";

            var QMakeSourcePriFileName = MasterProjectName + "Source.pri";
            var QMakeHeaderPriFileName = MasterProjectName + "Header.pri";
            var QMakeConfigPriFileName = MasterProjectName + "Config.pri";

            var QMakeFileContent = new StringBuilder();

            var QMakeSourcePriFileContent = new StringBuilder();
            var QMakeHeaderPriFileContent = new StringBuilder();
            var QMakeConfigPriFileContent = new StringBuilder();

            var QMakeSectionEnd = " \n\n";

            var QMakeSourceFilesList = "SOURCES += \\ \n";
            var QMakeHeaderFilesList = "HEADERS += \\ \n";
            var QMakeConfigFilesList = "OTHER_FILES += \\ \n";
            var QMakeTargetList      = "QMAKE_EXTRA_TARGETS += \\ \n";

            if (!String.IsNullOrEmpty(GameProjectName))
            {
                GameProjectRootPath = GameProjectName + "RootPath=" + GameProjectPath + "\n\n";
            }

            QMakeFileContent.Append(
                "# UnrealEngine.pro generated by QMakefileGenerator.cs\n" +
                "# *DO NOT EDIT*\n\n" +
                "TEMPLATE = aux\n" +
                "CONFIG += c++11\n" +
                "CONFIG -= console\n" +
                "CONFIG -= app_bundle\n" +
                "CONFIG -= qt\n\n" +
                "TARGET = UE4 \n\n" +
                "unrealRootPath=" + UnrealRootPath + "\n" +
                GameProjectRootPath +
                QMakeGameProjectFile +
                BuildCommand +
                "args=$(ARGS)\n\n" +
                "include(" + QMakeSourcePriFileName + ")\n" +
                "include(" + QMakeHeaderPriFileName + ")\n" +
                "include(" + QMakeConfigPriFileName + ")\n" +
                "include(" + QMakeIncludesFileName + ")\n" +
                "include(" + QMakeDefinesFileName + ")\n\n"
                );

            // Create SourceFiles, HeaderFiles, and ConfigFiles sections.
            var AllModuleFiles = DiscoverModules(FindGameProjects());

            foreach (FileReference CurModuleFile in AllModuleFiles)
            {
                var FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile);
                foreach (FileReference CurSourceFile in FoundFiles)
                {
                    string SourceFileRelativeToRoot = CurSourceFile.MakeRelativeTo(UnrealBuildTool.EngineDirectory);
                    // Exclude some directories that we don't compile (note that we still want Windows/Mac etc for code navigation)
                    if (!SourceFileRelativeToRoot.Contains("Source/ThirdParty/"))
                    {
                        if (SourceFileRelativeToRoot.EndsWith(".cpp"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                QMakeSourceFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    QMakeSourceFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n");
                                }
                                else if (!String.IsNullOrEmpty(GameProjectName))
                                {
                                    QMakeSourceFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath) + "\" \\\n");
                                }
                                else
                                {
                                    System.Console.WriteLine("Error!, you should not be here.");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".h"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                QMakeHeaderFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    QMakeHeaderFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n");
                                }
                                else if (!String.IsNullOrEmpty(GameProjectName))
                                {
                                    QMakeHeaderFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath) + "\" \\\n");
                                }
                                else
                                {
                                    System.Console.WriteLine("Error!, you should not be here.");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".cs"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                QMakeConfigFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    QMakeConfigFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n");
                                }
                                else if (!String.IsNullOrEmpty(GameProjectName))
                                {
                                    QMakeConfigFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath) + "\" \\\n");
                                }
                                else
                                {
                                    System.Console.WriteLine("Error!, you should not be here.");
                                }
                            }
                        }
                    }
                }
            }

            // Add section end to section strings;
            QMakeSourceFilesList += QMakeSectionEnd;
            QMakeHeaderFilesList += QMakeSectionEnd;
            QMakeConfigFilesList += QMakeSectionEnd;

            // Append sections to the QMakeLists.txt file
            QMakeSourcePriFileContent.Append(QMakeSourceFilesList);
            QMakeHeaderPriFileContent.Append(QMakeHeaderFilesList);
            QMakeConfigPriFileContent.Append(QMakeConfigFilesList);

            string QMakeProjectCmdArg = "";

            foreach (var Project in GeneratedProjectFiles)
            {
                foreach (var TargetFile in Project.ProjectTargets)
                {
                    if (TargetFile.TargetFilePath == null)
                    {
                        continue;
                    }

                    var TargetName = TargetFile.TargetFilePath.GetFileNameWithoutAnyExtensions();                               // Remove both ".cs" and ".

                    foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                    {
                        if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development)
                        {
                            if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                            {
                                if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                                {
                                    QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\"";
                                }
                                var ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration);
                                QMakeFileContent.Append(String.Format("{0}-Linux-{1}.commands = $$build {0} Linux {1} {2} $$args\n", TargetName, ConfName, QMakeProjectCmdArg));
                                QMakeTargetList += "\t" + TargetName + "-Linux-" + ConfName + " \\\n";                                 // , TargetName, ConfName);
                            }
                        }
                    }

                    if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                    {
                        QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\"";
                    }

                    QMakeFileContent.Append(String.Format("{0}.commands = $$build {0} Linux Development {1} $$args\n\n", TargetName, QMakeProjectCmdArg));
                    QMakeTargetList += "\t" + TargetName + " \\\n";
                }
            }

            QMakeFileContent.Append(QMakeTargetList.TrimEnd('\\'));

            var FullFileName = Path.Combine(MasterProjectPath.FullName, FileName);

            var FullQMakeDefinesFileName   = Path.Combine(MasterProjectPath.FullName, QMakeDefinesFileName);
            var FullQMakeIncludesFileName  = Path.Combine(MasterProjectPath.FullName, QMakeIncludesFileName);
            var FullQMakeSourcePriFileName = Path.Combine(MasterProjectPath.FullName, QMakeSourcePriFileName);
            var FullQMakeHeaderPriFileName = Path.Combine(MasterProjectPath.FullName, QMakeHeaderPriFileName);
            var FullQMakeConfigPriFileName = Path.Combine(MasterProjectPath.FullName, QMakeConfigPriFileName);

            WriteFileIfChanged(FullQMakeDefinesFileName, QMakeDefinesPriFileContent.ToString());
            WriteFileIfChanged(FullQMakeIncludesFileName, QMakeIncludesPriFileContent.ToString());
            WriteFileIfChanged(FullQMakeSourcePriFileName, QMakeSourcePriFileContent.ToString());

            WriteFileIfChanged(FullQMakeHeaderPriFileName, QMakeHeaderPriFileContent.ToString());
            WriteFileIfChanged(FullQMakeConfigPriFileName, QMakeConfigPriFileContent.ToString());

            return(WriteFileIfChanged(FullFileName, QMakeFileContent.ToString()));
        }
コード例 #4
0
ファイル: XcodeProject.cs プロジェクト: emperor-katax/unreal
        /**
         * Returns a project navigator group to which the file should belong based on its path.
         * Creates a group tree if it doesn't exist yet.
         */
        public XcodeFileGroup FindGroupByFullPath(ref Dictionary <string, XcodeFileGroup> Groups, string FullPath)
        {
            string RelativePath = (FullPath == XcodeProjectFileGenerator.MasterProjectRelativePath) ? "" : Utils.MakePathRelativeTo(FullPath, XcodeProjectFileGenerator.MasterProjectRelativePath);

            if (RelativePath.StartsWith(".."))
            {
                string UE4Dir = Path.GetFullPath(Directory.GetCurrentDirectory() + "../../..");
                RelativePath = Utils.MakePathRelativeTo(FullPath, UE4Dir);
            }

            string[] Parts       = RelativePath.Split(Path.DirectorySeparatorChar);
            string   CurrentPath = "";
            Dictionary <string, XcodeFileGroup> CurrentParent = Groups;

            foreach (string Part in Parts)
            {
                XcodeFileGroup CurrentGroup;

                if (CurrentPath != "")
                {
                    CurrentPath += Path.DirectorySeparatorChar;
                }

                CurrentPath += Part;

                if (!CurrentParent.ContainsKey(CurrentPath))
                {
                    CurrentGroup = new XcodeFileGroup(Path.GetFileName(CurrentPath), CurrentPath);
                    CurrentParent.Add(CurrentPath, CurrentGroup);
                }
                else
                {
                    CurrentGroup = CurrentParent[CurrentPath];
                }

                if (CurrentPath == RelativePath)
                {
                    return(CurrentGroup);
                }

                CurrentParent = CurrentGroup.Children;
            }

            return(null);
        }
コード例 #5
0
        private bool WriteCMakeLists()
        {
            string BuildCommand     = "";
            var    FileName         = "CMakeLists.txt";
            var    CMakefileContent = new StringBuilder();

            var CMakeSectionEnd = " )\n\n";

            var CMakeSourceFilesList = "set(SOURCE_FILES \n";
            var CMakeHeaderFilesList = "set(HEADER_FILES \n";
            var CMakeConfigFilesList = "set(CONFIG_FILES \n";

            var CMakeGameRootPath = "";
            var CMakeUE4RootPath  = "set(UE4_ROOT_PATH " + Path.GetFullPath(ProjectFileGenerator.RootRelativePath) + ")\n";

            string GameProjectPath = "";
            string GameProjectFile = "";

            string CMakeGameProjectFile = "";

            if (!String.IsNullOrEmpty(GameProjectName))
            {
                CMakeGameRootPath = "set(GAME_ROOT_PATH \"" + UnrealBuildTool.GetUProjectPath() + "\")\n";

                GameProjectPath = UnrealBuildTool.GetUProjectPath();
                GameProjectFile = UnrealBuildTool.GetUProjectFile();

                CMakeGameProjectFile = "set(GAME_PROJECT_FILE \"" + GameProjectFile + "\")\n";

                BuildCommand = "set(BUILD mono ${UE4_ROOT_PATH}/Engine/Binaries/DotNET/UnrealBuildTool.exe )\n";                 // -project=\"\\\"" + UnrealBuildTool.GetUProjectPath () + "/" + GameProjectName + ".uproject\\\"\")\n";
            }
            else
            {
                BuildCommand = "set(BUILD bash ${UE4_ROOT_PATH}/Engine/Build/BatchFiles/Linux/Build.sh)\n";
            }

            CMakefileContent.Append(
                "# Makefile generated by CMakefileGenerator.cs\n" +
                "# *DO NOT EDIT*\n\n" +
                "cmake_minimum_required (VERSION 2.6)\n" +
                "project (UE4)\n\n" +
                CMakeUE4RootPath +
                CMakeGameProjectFile +
                BuildCommand +
                CMakeGameRootPath + "\n"
                );

            // Create SourceFiles, HeaderFiles, and ConfigFiles sections.
            var AllModuleFiles = DiscoverModules();

            foreach (string CurModuleFile in AllModuleFiles)
            {
                var FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile, ExcludeNoRedistFiles: bExcludeNoRedistFiles);
                foreach (string CurSourceFile in FoundFiles)
                {
                    string SourceFileRelativeToRoot = Utils.MakePathRelativeTo(CurSourceFile, Path.Combine(EngineRelativePath));
                    // Exclude Windows, Mac, and iOS only files/folders.
                    // This got ugly quick.
                    if (!SourceFileRelativeToRoot.Contains("Source/ThirdParty/") &&
                        !SourceFileRelativeToRoot.Contains("/Windows/") &&
                        !SourceFileRelativeToRoot.Contains("/Mac/") &&
                        !SourceFileRelativeToRoot.Contains("/IOS/") &&
                        !SourceFileRelativeToRoot.Contains("/iOS/") &&
                        !SourceFileRelativeToRoot.Contains("/VisualStudioSourceCodeAccess/") &&
                        !SourceFileRelativeToRoot.Contains("/XCodeSourceCodeAccess/") &&
                        !SourceFileRelativeToRoot.Contains("/WmfMedia/") &&
                        !SourceFileRelativeToRoot.Contains("/IOSDeviceProfileSelector/") &&
                        !SourceFileRelativeToRoot.Contains("/WindowsDeviceProfileSelector/") &&
                        !SourceFileRelativeToRoot.Contains("/WindowsMoviePlayer/") &&
                        !SourceFileRelativeToRoot.Contains("/AppleMoviePlayer/") &&
                        !SourceFileRelativeToRoot.Contains("/MacGraphicsSwitching/") &&
                        !SourceFileRelativeToRoot.Contains("/Apple/") &&
                        !SourceFileRelativeToRoot.Contains("/WinRT/")
                        )
                    {
                        if (SourceFileRelativeToRoot.EndsWith(".cpp"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                CMakeSourceFilesList += ("\t\"${UE4_ROOT_PATH}/Engine/" + SourceFileRelativeToRoot + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    CMakeSourceFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\"\n");
                                }
                                else
                                {
                                    CMakeSourceFilesList += ("\t\"${GAME_ROOT_PATH}/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\"\n");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".h"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                CMakeHeaderFilesList += ("\t\"${UE4_ROOT_PATH}/Engine/" + SourceFileRelativeToRoot + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    CMakeHeaderFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\"\n");
                                }
                                else
                                {
                                    CMakeHeaderFilesList += ("\t\"${GAME_ROOT_PATH}/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\"\n");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".cs"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                CMakeConfigFilesList += ("\t\"${UE4_ROOT_PATH}/Engine/" + SourceFileRelativeToRoot + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    CMakeConfigFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\"\n");
                                }
                                else
                                {
                                    CMakeConfigFilesList += ("\t\"${GAME_ROOT_PATH}/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\"\n");
                                };
                            }
                        }
                    }
                }
            }

            // Add section end to section strings;
            CMakeSourceFilesList += CMakeSectionEnd;
            CMakeHeaderFilesList += CMakeSectionEnd;
            CMakeConfigFilesList += CMakeSectionEnd;

            // Append sections to the CMakeLists.txt file
            CMakefileContent.Append(CMakeSourceFilesList);
            CMakefileContent.Append(CMakeHeaderFilesList);
            CMakefileContent.Append(CMakeConfigFilesList);

            string CMakeProjectCmdArg = "";

            foreach (string TargetFilePath in DiscoverTargets())
            {
                var TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFilePath);                         // Remove both ".cs" and ".

                foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                {
                    if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development)
                    {
                        if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                        {
                            if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                            {
                                CMakeProjectCmdArg = " -project=\"\\\"${GAME_PROJECT_FILE}\\\"\"";
                            }
                            var ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration);
                            CMakefileContent.Append(String.Format("add_custom_target({0}-Linux-{1} ${{BUILD}} {2} {0} Linux {1} $(ARGS))\n", TargetName, ConfName, CMakeProjectCmdArg));
                        }
                    }
                }

                if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                {
                    CMakeProjectCmdArg = " -project=\"\\\"${GAME_PROJECT_FILE}\\\"\"";
                }
                CMakefileContent.Append(String.Format("add_custom_target({0} ${{BUILD}} {1} {0} Linux Development $(ARGS) SOURCES ${{SOURCE_FILES}} ${{HEADER_FILES}} ${{CONFIG_FILES}})\n\n", TargetName, CMakeProjectCmdArg));
            }

            var FullFileName = Path.Combine(MasterProjectRelativePath, FileName);

            return(WriteFileIfChanged(FullFileName, CMakefileContent.ToString()));
        }
コード例 #6
0
ファイル: RemoteToolChain.cs プロジェクト: wenjie891/UnrealVN
        public override void PreBuildSync()
        {
            // no need to sync on the Mac!
            if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
            {
                return;
            }

            if (bUseRPCUtil)
            {
                string ExtString = "";

                // look only for useful extensions
                foreach (string Ext in RsyncExtensions)
                {
                    // for later ls
                    ExtString += Ext.StartsWith(".") ? ("*" + Ext) : Ext;
                    ExtString += " ";
                }

                List <string> BatchUploadCommands = new List <string>();
                // for each directory we visited, add all the files in that directory
                foreach (string Dir in RsyncDirs)
                {
                    List <string> LocalFilenames = new List <string>();

                    // look only for useful extensions
                    foreach (string Ext in RsyncExtensions)
                    {
                        string[] Files = Directory.GetFiles(Dir, "*" + Ext);
                        foreach (string SyncFile in Files)
                        {
                            // remember all local files
                            LocalFilenames.Add(Path.GetFileName(SyncFile));

                            string RemoteFilePath = ConvertPath(SyncFile);
                            // an upload command is local name and remote name
                            BatchUploadCommands.Add(SyncFile + ";" + RemoteFilePath);
                        }
                    }
                }

                // batch upload
                RPCUtilHelper.BatchUpload(BatchUploadCommands.ToArray());
            }
            else
            {
                List <string> RelativeRsyncDirs = new List <string>();
                foreach (string Dir in RsyncDirs)
                {
                    RelativeRsyncDirs.Add(Utils.CleanDirectorySeparators(Utils.MakePathRelativeTo(Dir, "../.."), '/') + "/");
                }

                // write out directories to copy
                string RSyncPathsFile  = Path.GetTempFileName();
                string IncludeFromFile = Path.GetTempFileName();
                File.WriteAllLines(RSyncPathsFile, RelativeRsyncDirs.ToArray());
                File.WriteAllLines(IncludeFromFile, RsyncExtensions);

                // source and destination paths in the format rsync wants
                string CygRootPath = ConvertPathToCygwin(Path.GetFullPath("../../"));
                string RemotePath  = ConvertPath(Path.GetFullPath("../../")).Replace(" ", "\\ ");

                // get the executable dir for SSH, so Rsync can call it easily
                string ExeDir = Path.GetDirectoryName(ResolvedSSHExe);

                Process RsyncProcess = new Process();
                if (ExeDir != "")
                {
                    RsyncProcess.StartInfo.WorkingDirectory = ExeDir;
                }

                // --exclude='*'  ??? why???
                RsyncProcess.StartInfo.FileName  = ResolvedRSyncExe;
                RsyncProcess.StartInfo.Arguments = string.Format(
                    "-vzae \"{0}\" --rsync-path=\"mkdir -p {2} && rsync\" --chmod=ug=rwX,o=rxX --delete --files-from=\"{4}\" --include-from=\"{5}\" --include='*/' --exclude='*.o' --exclude='Timestamp' {1} {6}@{3}:'{2}'",
                    ResolvedRsyncAuthentication,
                    CygRootPath,
                    RemotePath,
                    RemoteServerName,
                    ConvertPathToCygwin(RSyncPathsFile),
                    ConvertPathToCygwin(IncludeFromFile),
                    RSyncUsername);

                RsyncProcess.OutputDataReceived += new DataReceivedEventHandler(OutputReceivedForRsync);
                RsyncProcess.ErrorDataReceived  += new DataReceivedEventHandler(OutputReceivedForRsync);

                // run rsync
                Utils.RunLocalProcess(RsyncProcess);

                File.Delete(IncludeFromFile);
                File.Delete(RSyncPathsFile);
            }

            // we can now clear out the set of files
            RsyncDirs.Clear();
            RsyncExtensions.Clear();
        }
コード例 #7
0
ファイル: UProjectInfo.cs プロジェクト: kidaa/UnrealEngineVR
        /// <summary>
        /// Discover and fill in the project info
        /// </summary>
        public static void FillProjectInfo()
        {
            DateTime StartTime = DateTime.Now;

            List <string> DirectoriesToSearch = new List <string>();

            // Find all the .uprojectdirs files contained in the root folder and add their entries to the search array
            string RootDirectory         = Path.Combine(Utils.GetExecutingAssemblyDirectory(), "..", "..", "..");
            string EngineSourceDirectory = Path.GetFullPath(Path.Combine(RootDirectory, "Engine", "Source"));

            foreach (var File in Directory.EnumerateFiles(RootDirectory, "*.uprojectdirs", SearchOption.TopDirectoryOnly))
            {
                string FilePath = Path.GetFullPath(File);
                Log.TraceVerbose("\tFound uprojectdirs file {0}", FilePath);

                using (StreamReader Reader = new StreamReader(FilePath))
                {
                    string LineRead;
                    while ((LineRead = Reader.ReadLine()) != null)
                    {
                        string ProjDirEntry = LineRead.Trim();
                        if (String.IsNullOrEmpty(ProjDirEntry) == false)
                        {
                            if (ProjDirEntry.StartsWith(";"))
                            {
                                // Commented out line... skip it
                                continue;
                            }
                            else
                            {
                                string DirPath = Path.GetFullPath(Path.Combine(RootDirectory, ProjDirEntry));
                                DirectoriesToSearch.Add(DirPath);
                            }
                        }
                    }
                }
            }

            Log.TraceVerbose("\tFound {0} directories to search", DirectoriesToSearch.Count);

            // Initialize the target finding time to 0
            TimeSpan TotalTargetTime = DateTime.Now - DateTime.Now;

            foreach (string DirToSearch in DirectoriesToSearch)
            {
                Log.TraceVerbose("\t\tSearching {0}", DirToSearch);
                if (Directory.Exists(DirToSearch))
                {
                    foreach (string SubDir in Directory.EnumerateDirectories(DirToSearch, "*", SearchOption.TopDirectoryOnly))
                    {
                        Log.TraceVerbose("\t\t\tFound subdir {0}", SubDir);
                        string[] SubDirFiles = Directory.GetFiles(SubDir, "*.uproject", SearchOption.TopDirectoryOnly);
                        foreach (string UProjFile in SubDirFiles)
                        {
                            string RelativePath = Utils.MakePathRelativeTo(UProjFile, EngineSourceDirectory);
                            Log.TraceVerbose("\t\t\t\t{0}", RelativePath);
                            if (!ProjectInfoDictionary.ContainsKey(RelativePath))
                            {
                                DateTime TargetStartTime = DateTime.Now;

                                string SourceFolder   = Path.Combine(Path.GetDirectoryName(UProjFile), "Source");
                                bool   bIsCodeProject = Directory.Exists(SourceFolder);

                                AddProject(RelativePath, bIsCodeProject);

                                if (bIsCodeProject)
                                {
                                    // Find all Target.cs files
                                    bool bFoundTargetFiles = false;
                                    if (!FindTargetFiles(SourceFolder, ref bFoundTargetFiles))
                                    {
                                        Log.TraceVerbose("No target files found under " + SourceFolder);
                                    }
                                }

                                DateTime TargetStopTime = DateTime.Now;

                                TotalTargetTime += TargetStopTime - TargetStartTime;
                            }
                        }
                    }
                }
                else
                {
                    Log.TraceVerbose("ProjectInfo: Skipping directory {0} from .uprojectdirs file as it doesn't exist.", DirToSearch);
                }
            }

            DateTime StopTime = DateTime.Now;

            if (BuildConfiguration.bPrintPerformanceInfo)
            {
                TimeSpan TotalProjectInfoTime = StopTime - StartTime;
                Log.TraceInformation("FillProjectInfo took {0} milliseconds (AddTargetInfo {1} ms)",
                                     TotalProjectInfoTime.Milliseconds, TotalTargetTime.Milliseconds);
            }

            if (UnrealBuildTool.CommandLineContains("-dumpprojectinfo"))
            {
                UProjectInfo.DumpProjectInfo();
            }
        }
コード例 #8
0
        public override CPPOutput CompileCPPFiles(UEBuildTarget Target, CPPEnvironment CompileEnvironment, List <FileItem> SourceFiles, string ModuleName)
        {
            var EnvVars = VCEnvironment.SetEnvironment(CompileEnvironment.Config.Target.Platform);

            StringBuilder Arguments = new StringBuilder();

            AppendCLArguments_Global(CompileEnvironment, EnvVars, Arguments);

            // Add include paths to the argument list.
            foreach (string IncludePath in CompileEnvironment.Config.CPPIncludeInfo.IncludePaths)
            {
                string IncludePathRelative = Utils.CleanDirectorySeparators(Utils.MakePathRelativeTo(IncludePath, Path.Combine(ProjectFileGenerator.RootRelativePath, "Engine/Source")), '/');
                Arguments.AppendFormat(" /I \"{0}\"", IncludePathRelative);
            }
            foreach (string IncludePath in CompileEnvironment.Config.CPPIncludeInfo.SystemIncludePaths)
            {
                string IncludePathRelative = Utils.CleanDirectorySeparators(Utils.MakePathRelativeTo(IncludePath, Path.Combine(ProjectFileGenerator.RootRelativePath, "Engine/Source")), '/');
                Arguments.AppendFormat(" /I \"{0}\"", IncludePathRelative);
            }


            if (CompileEnvironment.Config.CLRMode == CPPCLRMode.CLREnabled)
            {
                // Add .NET framework assembly paths.  This is needed so that C++/CLI projects
                // can reference assemblies with #using, without having to hard code a path in the
                // .cpp file to the assembly's location.
                foreach (string AssemblyPath in CompileEnvironment.Config.SystemDotNetAssemblyPaths)
                {
                    Arguments.AppendFormat(" /AI \"{0}\"", AssemblyPath);
                }

                // Add explicit .NET framework assembly references
                foreach (string AssemblyName in CompileEnvironment.Config.FrameworkAssemblyDependencies)
                {
                    Arguments.AppendFormat(" /FU \"{0}\"", AssemblyName);
                }

                // Add private assembly references
                foreach (PrivateAssemblyInfo CurAssemblyInfo in CompileEnvironment.PrivateAssemblyDependencies)
                {
                    Arguments.AppendFormat(" /FU \"{0}\"", CurAssemblyInfo.FileItem.AbsolutePath);
                }
            }


            // Add preprocessor definitions to the argument list.
            foreach (string Definition in CompileEnvironment.Config.Definitions)
            {
                // Escape all quotation marks so that they get properly passed with the command line.
                var DefinitionArgument = Definition.Contains("\"") ? Definition.Replace("\"", "\\\"") : Definition;
                Arguments.AppendFormat(" /D\"{0}\"", DefinitionArgument);
            }

            var BuildPlatform = UEBuildPlatform.GetBuildPlatformForCPPTargetPlatform(CompileEnvironment.Config.Target.Platform);

            // Create a compile action for each source file.
            CPPOutput Result = new CPPOutput();

            foreach (FileItem SourceFile in SourceFiles)
            {
                Action CompileAction = new Action(ActionType.Compile);
                CompileAction.CommandDescription = "Compile";

                StringBuilder FileArguments = new StringBuilder();
                bool          bIsPlainCFile = Path.GetExtension(SourceFile.AbsolutePath).ToUpperInvariant() == ".C";

                // Add the C++ source file and its included files to the prerequisite item list.
                AddPrerequisiteSourceFile(Target, BuildPlatform, CompileEnvironment, SourceFile, CompileAction.PrerequisiteItems);

                // If this is a CLR file then make sure our dependent assemblies are added as prerequisites
                if (CompileEnvironment.Config.CLRMode == CPPCLRMode.CLREnabled)
                {
                    foreach (PrivateAssemblyInfo CurPrivateAssemblyDependency in CompileEnvironment.PrivateAssemblyDependencies)
                    {
                        CompileAction.PrerequisiteItems.Add(CurPrivateAssemblyDependency.FileItem);
                    }
                }

                bool bEmitsObjectFile = true;
                if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Create)
                {
                    // Generate a CPP File that just includes the precompiled header.
                    string   PCHCPPFilename = "PCH." + ModuleName + "." + Path.GetFileName(CompileEnvironment.Config.PrecompiledHeaderIncludeFilename) + ".cpp";
                    string   PCHCPPPath     = Path.Combine(CompileEnvironment.Config.OutputDirectory, PCHCPPFilename);
                    FileItem PCHCPPFile     = FileItem.CreateIntermediateTextFile(
                        PCHCPPPath,
                        string.Format("#include \"{0}\"\r\n", CompileEnvironment.Config.PrecompiledHeaderIncludeFilename)
                        );

                    // Make sure the original source directory the PCH header file existed in is added as an include
                    // path -- it might be a private PCH header and we need to make sure that its found!
                    string OriginalPCHHeaderDirectory = Path.GetDirectoryName(SourceFile.AbsolutePath);
                    FileArguments.AppendFormat(" /I \"{0}\"", OriginalPCHHeaderDirectory);

                    var PrecompiledFileExtension = UEBuildPlatform.BuildPlatformDictionary[UnrealTargetPlatform.UWP].GetBinaryExtension(UEBuildBinaryType.PrecompiledHeader);
                    // Add the precompiled header file to the produced items list.
                    FileItem PrecompiledHeaderFile = FileItem.GetItemByPath(
                        Path.Combine(
                            CompileEnvironment.Config.OutputDirectory,
                            Path.GetFileName(SourceFile.AbsolutePath) + PrecompiledFileExtension
                            )
                        );
                    CompileAction.ProducedItems.Add(PrecompiledHeaderFile);
                    Result.PrecompiledHeaderFile = PrecompiledHeaderFile;

                    // Add the parameters needed to compile the precompiled header file to the command-line.
                    FileArguments.AppendFormat(" /Yc\"{0}\"", CompileEnvironment.Config.PrecompiledHeaderIncludeFilename);
                    FileArguments.AppendFormat(" /Fp\"{0}\"", PrecompiledHeaderFile.AbsolutePath);

                    // If we're creating a PCH that will be used to compile source files for a library, we need
                    // the compiled modules to retain a reference to PCH's module, so that debugging information
                    // will be included in the library.  This is also required to avoid linker warning "LNK4206"
                    // when linking an application that uses this library.
                    if (CompileEnvironment.Config.bIsBuildingLibrary)
                    {
                        // NOTE: The symbol name we use here is arbitrary, and all that matters is that it is
                        // unique per PCH module used in our library
                        string FakeUniquePCHSymbolName = Path.GetFileNameWithoutExtension(CompileEnvironment.Config.PrecompiledHeaderIncludeFilename);
                        FileArguments.AppendFormat(" /Yl{0}", FakeUniquePCHSymbolName);
                    }

                    FileArguments.AppendFormat(" \"{0}\"", PCHCPPFile.AbsolutePath);

                    CompileAction.StatusDescription = PCHCPPFilename;
                }
                else
                {
                    if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Include)
                    {
                        CompileAction.bIsUsingPCH = true;
                        CompileAction.PrerequisiteItems.Add(CompileEnvironment.PrecompiledHeaderFile);

                        FileArguments.AppendFormat(" /Yu\"{0}\"", CompileEnvironment.Config.PCHHeaderNameInCode);
                        FileArguments.AppendFormat(" /Fp\"{0}\"", CompileEnvironment.PrecompiledHeaderFile.AbsolutePath);

                        // Is it unsafe to always force inclusion?  Clang is doing it, and .generated.cpp files
                        // won't work otherwise, because they're not located in the context of the module,
                        // so they can't access the module's PCH without an absolute path.
                        //if( CompileEnvironment.Config.bForceIncludePrecompiledHeader )
                        {
                            // Force include the precompiled header file.  This is needed because we may have selected a
                            // precompiled header that is different than the first direct include in the C++ source file, but
                            // we still need to make sure that our precompiled header is the first thing included!
                            FileArguments.AppendFormat(" /FI\"{0}\"", CompileEnvironment.Config.PCHHeaderNameInCode);
                        }
                    }

                    // Add the source file path to the command-line.
                    FileArguments.AppendFormat(" \"{0}\"", SourceFile.AbsolutePath);

                    CompileAction.StatusDescription = Path.GetFileName(SourceFile.AbsolutePath);
                }

                if (bEmitsObjectFile)
                {
                    var ObjectFileExtension = UEBuildPlatform.BuildPlatformDictionary[UnrealTargetPlatform.UWP].GetBinaryExtension(UEBuildBinaryType.Object);
                    // Add the object file to the produced item list.
                    FileItem ObjectFile = FileItem.GetItemByPath(
                        Path.Combine(
                            CompileEnvironment.Config.OutputDirectory,
                            Path.GetFileName(SourceFile.AbsolutePath) + ObjectFileExtension
                            )
                        );
                    CompileAction.ProducedItems.Add(ObjectFile);
                    Result.ObjectFiles.Add(ObjectFile);
                    FileArguments.AppendFormat(" /Fo\"{0}\"", ObjectFile.AbsolutePath);
                }

                // Create PDB files if we were configured to do that.
                //
                // Also, when debug info is off and XGE is enabled, force PDBs, otherwise it will try to share
                // a PDB file, which causes PCH creation to be serial rather than parallel (when debug info is disabled)
                //		--> See https://udn.epicgames.com/lists/showpost.php?id=50619&list=unprog3
                if (BuildConfiguration.bUsePDBFiles ||
                    (BuildConfiguration.bAllowXGE && !CompileEnvironment.Config.bCreateDebugInfo))
                {
                    string PDBFileName;
                    bool   bActionProducesPDB = false;

                    // All files using the same PCH are required to share the same PDB that was used when compiling the PCH
                    if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Include)
                    {
                        PDBFileName = "PCH." + ModuleName + "." + Path.GetFileName(CompileEnvironment.Config.PrecompiledHeaderIncludeFilename);
                    }
                    // Files creating a PCH use a PDB per file.
                    else if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Create)
                    {
                        PDBFileName        = "PCH." + ModuleName + "." + Path.GetFileName(CompileEnvironment.Config.PrecompiledHeaderIncludeFilename);
                        bActionProducesPDB = true;
                    }
                    // Ungrouped C++ files use a PDB per file.
                    else if (!bIsPlainCFile)
                    {
                        PDBFileName        = Path.GetFileName(SourceFile.AbsolutePath);
                        bActionProducesPDB = true;
                    }
                    // Group all plain C files that doesn't use PCH into the same PDB
                    else
                    {
                        PDBFileName = "MiscPlainC";
                    }

                    // Specify the PDB file that the compiler should write to.
                    FileItem PDBFile = FileItem.GetItemByPath(
                        Path.Combine(
                            CompileEnvironment.Config.OutputDirectory,
                            PDBFileName + ".pdb"
                            )
                        );
                    FileArguments.AppendFormat(" /Fd\"{0}\"", PDBFile.AbsolutePath);

                    // Only use the PDB as an output file if we want PDBs and this particular action is
                    // the one that produces the PDB (as opposed to no debug info, where the above code
                    // is needed, but not the output PDB, or when multiple files share a single PDB, so
                    // only the action that generates it should count it as output directly)
                    if (BuildConfiguration.bUsePDBFiles && bActionProducesPDB)
                    {
                        CompileAction.ProducedItems.Add(PDBFile);
                        Result.DebugDataFiles.Add(PDBFile);
                    }
                }

                // Add C or C++ specific compiler arguments.
                if (bIsPlainCFile)
                {
                    AppendCLArguments_C(FileArguments);
                }
                else
                {
                    AppendCLArguments_CPP(CompileEnvironment, FileArguments);
                }

                CompileAction.WorkingDirectory = Path.GetFullPath(".");
                CompileAction.CommandPath      = EnvVars.CompilerPath;
                CompileAction.CommandArguments = Arguments.ToString() + FileArguments.ToString() + CompileEnvironment.Config.AdditionalArguments;

                if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Create)
                {
                    Log.TraceVerbose("Creating PCH: " + CompileEnvironment.Config.PrecompiledHeaderIncludeFilename);
                    Log.TraceVerbose("     Command: " + CompileAction.CommandArguments);
                }
                else
                {
                    Log.TraceVerbose("   Compiling: " + CompileAction.StatusDescription);
                    Log.TraceVerbose("     Command: " + CompileAction.CommandArguments);
                }

                // VC++ always outputs the source file name being compiled, so we don't need to emit this ourselves
                CompileAction.bShouldOutputStatusDescription = false;

                // Don't farm out creation of precompiled headers as it is the critical path task.
                CompileAction.bCanExecuteRemotely =
                    CompileEnvironment.Config.PrecompiledHeaderAction != PrecompiledHeaderAction.Create ||
                    BuildConfiguration.bAllowRemotelyCompiledPCHs
                ;

                // @todo: XGE has problems remote compiling C++/CLI files that use .NET Framework 4.0
                if (CompileEnvironment.Config.CLRMode == CPPCLRMode.CLREnabled)
                {
                    CompileAction.bCanExecuteRemotely = false;
                }
            }
            return(Result);
        }
コード例 #9
0
        private bool WriteQMakePro()
        {
            string GameProjectPath     = "";
            string GameProjectFile     = "";
            string GameProjectRootPath = "";

            string BuildCommand = "";

            string QMakeGameProjectFile = "";

            if (!String.IsNullOrEmpty(GameProjectName))
            {
                GameProjectPath      = UnrealBuildTool.GetUProjectPath();
                GameProjectFile      = UnrealBuildTool.GetUProjectFile();
                QMakeGameProjectFile = "gameProjectFile=" + GameProjectFile + "\n";
                BuildCommand         = "build=mono $$unrealRootPath/Engine/Binaries/DotNET/UnrealBuildTool.exe\n\n";
            }
            else
            {
                BuildCommand = "build=bash $$unrealRootPath/Engine/Build/BatchFiles/Linux/Build.sh\n";
            }

            var UnrealRootPath = Path.GetFullPath(ProjectFileGenerator.RootRelativePath);

            var FileName         = MasterProjectName + ".pro";
            var QMakeFileContent = new StringBuilder();

            var QMakeSectionEnd = " \n\n";

            var QMakeSourceFilesList = "SOURCES += \\ \n";
            var QMakeHeaderFilesList = "HEADERS += \\ \n";
            var QMakeConfigFilesList = "OTHER_FILES += \\ \n";
            var QMakeTargetList      = "QMAKE_EXTRA_TARGETS += \\ \n";

            if (!String.IsNullOrEmpty(GameProjectName))
            {
                GameProjectRootPath = GameProjectName + "RootPath=" + GameProjectPath + "\n\n";
            }

            QMakeFileContent.Append(
                "# UnrealEngine.pro generated by QMakefileGenerator.cs\n" +
                "# *DO NOT EDIT*\n\n" +
                "TEMPLATE = aux\n" +
                "CONFIG -= console\n" +
                "CONFIG -= app_bundle\n" +
                "CONFIG -= qt\n\n" +
                "TARGET = UE4 \n\n" +
                "unrealRootPath=" + UnrealRootPath + "\n" +
                GameProjectRootPath +
                QMakeGameProjectFile +
                BuildCommand +
                "args=$(ARGS)\n\n"
                );

            // Create SourceFiles, HeaderFiles, and ConfigFiles sections.
            var AllModuleFiles = DiscoverModules();

            foreach (string CurModuleFile in AllModuleFiles)
            {
                var FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile, ExcludeNoRedistFiles: bExcludeNoRedistFiles);
                foreach (string CurSourceFile in FoundFiles)
                {
                    string SourceFileRelativeToRoot = Utils.MakePathRelativeTo(CurSourceFile, Path.Combine(EngineRelativePath));
                    // Exclude Windows, Mac, and iOS only files/folders.
                    // This got ugly quick.
                    if (!SourceFileRelativeToRoot.Contains("Source/ThirdParty/") &&
                        !SourceFileRelativeToRoot.Contains("/Windows/") &&
                        !SourceFileRelativeToRoot.Contains("/Mac/") &&
                        !SourceFileRelativeToRoot.Contains("/IOS/") &&
                        !SourceFileRelativeToRoot.Contains("/iOS/") &&
                        !SourceFileRelativeToRoot.Contains("/VisualStudioSourceCodeAccess/") &&
                        !SourceFileRelativeToRoot.Contains("/XCodeSourceCodeAccess/") &&
                        !SourceFileRelativeToRoot.Contains("/WmfMedia/") &&
                        !SourceFileRelativeToRoot.Contains("/IOSDeviceProfileSelector/") &&
                        !SourceFileRelativeToRoot.Contains("/WindowsDeviceProfileSelector/") &&
                        !SourceFileRelativeToRoot.Contains("/WindowsMoviePlayer/") &&
                        !SourceFileRelativeToRoot.Contains("/AppleMoviePlayer/") &&
                        !SourceFileRelativeToRoot.Contains("/MacGraphicsSwitching/") &&
                        !SourceFileRelativeToRoot.Contains("/Apple/") &&
                        !SourceFileRelativeToRoot.Contains("/WinRT/")
                        )
                    {
                        if (SourceFileRelativeToRoot.EndsWith(".cpp"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                QMakeSourceFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    QMakeSourceFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n");
                                }
                                else if (!String.IsNullOrEmpty(GameProjectName))
                                {
                                    QMakeSourceFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\" \\\n");
                                }
                                else
                                {
                                    System.Console.WriteLine("Error!, you should not be here.");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".h"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                QMakeHeaderFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    QMakeHeaderFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n");
                                }
                                else if (!String.IsNullOrEmpty(GameProjectName))
                                {
                                    QMakeHeaderFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\" \\\n");
                                }
                                else
                                {
                                    System.Console.WriteLine("Error!, you should not be here.");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".cs"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                QMakeConfigFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    QMakeConfigFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n");
                                }
                                else if (!String.IsNullOrEmpty(GameProjectName))
                                {
                                    QMakeConfigFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\" \\\n");
                                }
                                else
                                {
                                    System.Console.WriteLine("Error!, you should not be here.");
                                }
                            }
                        }
                    }
                }
            }

            // Add section end to section strings;
            QMakeSourceFilesList += QMakeSectionEnd;
            QMakeHeaderFilesList += QMakeSectionEnd;
            QMakeConfigFilesList += QMakeSectionEnd;

            // Append sections to the QMakeLists.txt file
            QMakeFileContent.Append(QMakeSourceFilesList);
            QMakeFileContent.Append(QMakeHeaderFilesList);
            QMakeFileContent.Append(QMakeConfigFilesList);

            string QMakeProjectCmdArg = "";

            foreach (string TargetFilePath in DiscoverTargets())
            {
                var TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFilePath);                         // Remove both ".cs" and ".

                foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                {
                    if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development)
                    {
                        if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                        {
                            if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                            {
                                QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\"";
                            }
                            var ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration);
                            QMakeFileContent.Append(String.Format("{0}-Linux-{1}.commands = $$build {2} {0} Linux {1} $$args\n", TargetName, ConfName, QMakeProjectCmdArg));
                            QMakeTargetList += "\t" + TargetName + "-Linux-" + ConfName + " \\\n";                             // , TargetName, ConfName);
                        }
                    }
                }

                if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                {
                    QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\"";
                }

                QMakeFileContent.Append(String.Format("{0}.commands = $$build {1} {0} Linux Development $$args\n\n", TargetName, QMakeProjectCmdArg));
                QMakeTargetList += "\t" + TargetName + " \\\n";
            }

            QMakeFileContent.Append(QMakeTargetList.TrimEnd('\\'));

            var FullFileName = Path.Combine(MasterProjectRelativePath, FileName);

            return(WriteFileIfChanged(FullFileName, QMakeFileContent.ToString()));
        }
        private bool WriteCMakeLists()
        {
            string       BuildCommand;
            const string CMakeSectionEnd = " )\n\n";

            var CMakefileContent = new StringBuilder();

            StringBuilder CMakeSourceFilesList        = new StringBuilder("set(SOURCE_FILES \n");
            StringBuilder CMakeHeaderFilesList        = new StringBuilder("set(HEADER_FILES \n");
            StringBuilder CMakeConfigFilesList        = new StringBuilder("set(CONFIG_FILES \n");
            StringBuilder IncludeDirectoriesList      = new StringBuilder("include_directories( \n");
            StringBuilder PreprocessorDefinitionsList = new StringBuilder("add_definitions( \n");

            var CMakeGameRootPath = "";
            var CMakeUE4RootPath  = "set(UE4_ROOT_PATH " + Utils.CleanDirectorySeparators(Path.GetFullPath(ProjectFileGenerator.RootRelativePath), '/') + ")\n";

            string GameProjectPath      = "";
            string CMakeGameProjectFile = "";

            string HostArchitecture;

            switch (BuildHostPlatform.Current.Platform)
            {
            case UnrealTargetPlatform.Win64:
            {
                HostArchitecture = "Win64";
                BuildCommand     = "set(BUILD cmd /c \"${UE4_ROOT_PATH}/Engine/Build/BatchFiles/Build.bat\")\n";
                break;
            }

            case UnrealTargetPlatform.Mac:
            {
                HostArchitecture = "Mac";
                BuildCommand     = "set(BUILD cd \"${UE4_ROOT_PATH}\" && bash \"${UE4_ROOT_PATH}/Engine/Build/BatchFiles/" + HostArchitecture + "/Build.sh\")\n";
                break;
            }

            case UnrealTargetPlatform.Linux:
            {
                HostArchitecture = "Linux";
                BuildCommand     = "set(BUILD cd \"${UE4_ROOT_PATH}\" && bash \"${UE4_ROOT_PATH}/Engine/Build/BatchFiles/" + HostArchitecture + "/Build.sh\")\n";
                break;
            }

            default:
            {
                throw new BuildException("ERROR: CMakefileGenerator does not support this platform");
            }
            }

            if (!String.IsNullOrEmpty(GameProjectName))
            {
                GameProjectPath = OnlyGameProject.Directory.FullName;

                CMakeGameRootPath    = "set(GAME_ROOT_PATH \"" + Utils.CleanDirectorySeparators(OnlyGameProject.Directory.FullName, '/') + "\")\n";
                CMakeGameProjectFile = "set(GAME_PROJECT_FILE \"" + Utils.CleanDirectorySeparators(OnlyGameProject.FullName, '/') + "\")\n";
            }

            CMakefileContent.Append(
                "# Makefile generated by CMakefileGenerator.cs (v1.1)\n" +
                "# *DO NOT EDIT*\n\n" +
                "cmake_minimum_required (VERSION 2.6)\n" +
                "project (UE4)\n\n" +
                CMakeUE4RootPath +
                CMakeGameProjectFile +
                BuildCommand +
                CMakeGameRootPath + "\n"
                );

            List <string> IncludeDirectories      = new List <string>();
            List <string> PreprocessorDefinitions = new List <string>();

            foreach (var CurProject in GeneratedProjectFiles)
            {
                foreach (var IncludeSearchPath in CurProject.IntelliSenseIncludeSearchPaths)
                {
                    string IncludeDirectory = GetIncludeDirectory(IncludeSearchPath, Path.GetDirectoryName(CurProject.ProjectFilePath.FullName));
                    if (IncludeDirectory != null && !IncludeDirectories.Contains(IncludeDirectory))
                    {
                        if (IncludeDirectory.Contains(Path.GetFullPath(RootRelativePath)))
                        {
                            IncludeDirectories.Add(IncludeDirectory.Replace(Path.GetFullPath(RootRelativePath), "${UE4_ROOT_PATH}"));
                        }
                        else
                        {
                            IncludeDirectories.Add("${GAME_ROOT_PATH}/" + IncludeDirectory);
                        }
                    }
                }

                foreach (var PreProcessorDefinition in CurProject.IntelliSensePreprocessorDefinitions)
                {
                    string Definition          = PreProcessorDefinition;
                    string AlternateDefinition = Definition.Contains("=0") ? Definition.Replace("=0", "=1") : Definition.Replace("=1", "=0");

                    if (Definition.Equals("WITH_EDITORONLY_DATA=0") || Definition.Equals("WITH_DATABASE_SUPPORT=1"))
                    {
                        Definition = AlternateDefinition;
                    }

                    if (!PreprocessorDefinitions.Contains(Definition) &&
                        !PreprocessorDefinitions.Contains(AlternateDefinition) &&
                        !Definition.StartsWith("UE_ENGINE_DIRECTORY") &&
                        !Definition.StartsWith("ORIGINAL_FILE_NAME"))
                    {
                        PreprocessorDefinitions.Add(Definition);
                    }
                }
            }

            // Create SourceFiles, HeaderFiles, and ConfigFiles sections.
            var AllModuleFiles = DiscoverModules(FindGameProjects());

            foreach (FileReference CurModuleFile in AllModuleFiles)
            {
                var FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile);
                foreach (FileReference CurSourceFile in FoundFiles)
                {
                    string SourceFileRelativeToRoot = CurSourceFile.MakeRelativeTo(UnrealBuildTool.EngineDirectory);

                    // Exclude files/folders on a per-platform basis.
                    if (!IsPathExcludedOnPlatform(SourceFileRelativeToRoot, BuildHostPlatform.Current.Platform))
                    {
                        if (SourceFileRelativeToRoot.EndsWith(".cpp"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                CMakeSourceFilesList.Append("\t\"${UE4_ROOT_PATH}/Engine/" + Utils.CleanDirectorySeparators(SourceFileRelativeToRoot, '/') + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    CMakeSourceFilesList.Append("\t\"" + Utils.CleanDirectorySeparators(SourceFileRelativeToRoot, '/').Substring(3) + "\"\n");
                                }
                                else
                                {
                                    string RelativeGameSourcePath = Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath);
                                    CMakeSourceFilesList.Append("\t\"${GAME_ROOT_PATH}/" + Utils.CleanDirectorySeparators(RelativeGameSourcePath, '/') + "\"\n");
                                }
                            }
                        }
                        else if (SourceFileRelativeToRoot.EndsWith(".h"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                CMakeHeaderFilesList.Append("\t\"${UE4_ROOT_PATH}/Engine/" + Utils.CleanDirectorySeparators(SourceFileRelativeToRoot, '/') + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    CMakeHeaderFilesList.Append("\t\"" + Utils.CleanDirectorySeparators(SourceFileRelativeToRoot, '/').Substring(3) + "\"\n");
                                }
                                else
                                {
                                    string relativeGameSourcePath = Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath);
                                    CMakeHeaderFilesList.Append("\t\"${GAME_ROOT_PATH}/" + Utils.CleanDirectorySeparators(relativeGameSourcePath, '/') + "\"\n");
                                }
                            }
                        }
                        else if (SourceFileRelativeToRoot.EndsWith(".cs"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                CMakeConfigFilesList.Append("\t\"${UE4_ROOT_PATH}/Engine/" + Utils.CleanDirectorySeparators(SourceFileRelativeToRoot, '/') + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    CMakeConfigFilesList.Append("\t\"" + Utils.CleanDirectorySeparators(SourceFileRelativeToRoot, '/').Substring(3) + "\"\n");
                                }
                                else
                                {
                                    string relativeGameSourcePath = Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath);
                                    CMakeConfigFilesList.Append("\t\"${GAME_ROOT_PATH}/" + Utils.CleanDirectorySeparators(relativeGameSourcePath, '/') + "\"\n");
                                }
                            }
                        }
                    }
                }
            }

            foreach (string IncludeDirectory in IncludeDirectories)
            {
                IncludeDirectoriesList.Append("\t\"" + Utils.CleanDirectorySeparators(IncludeDirectory, '/') + "\"\n");
            }

            foreach (string PreprocessorDefinition in PreprocessorDefinitions)
            {
                PreprocessorDefinitionsList.Append("\t-D" + PreprocessorDefinition + "\n");
            }

            // Add section end to section strings;
            CMakeSourceFilesList.Append(CMakeSectionEnd);
            CMakeHeaderFilesList.Append(CMakeSectionEnd);
            CMakeConfigFilesList.Append(CMakeSectionEnd);
            IncludeDirectoriesList.Append(CMakeSectionEnd);
            PreprocessorDefinitionsList.Append(CMakeSectionEnd);

            // Append sections to the CMakeLists.txt file
            CMakefileContent.Append(CMakeSourceFilesList);
            CMakefileContent.Append(CMakeHeaderFilesList);
            CMakefileContent.Append(CMakeConfigFilesList);
            CMakefileContent.Append(IncludeDirectoriesList);
            CMakefileContent.Append(PreprocessorDefinitionsList);

            string CMakeProjectCmdArg = "";

            foreach (var Project in GeneratedProjectFiles)
            {
                foreach (var TargetFile in Project.ProjectTargets)
                {
                    if (TargetFile.TargetFilePath == null)
                    {
                        continue;
                    }

                    var TargetName = TargetFile.TargetFilePath.GetFileNameWithoutAnyExtensions();                               // Remove both ".cs" and ".

                    foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                    {
                        if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development)
                        {
                            if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                            {
                                if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                                {
                                    CMakeProjectCmdArg = "-project=\"${GAME_PROJECT_FILE}\"";
                                }

                                string ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration);
                                CMakefileContent.Append(String.Format("add_custom_target({0}-{3}-{1} ${{BUILD}} {0} {3} {1} {2} $(ARGS))\n", TargetName, ConfName, CMakeProjectCmdArg, HostArchitecture));
                            }
                        }
                    }

                    if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                    {
                        CMakeProjectCmdArg = "-project=\"${GAME_PROJECT_FILE}\"";
                    }

                    if (!String.IsNullOrEmpty(HostArchitecture))
                    {
                        CMakefileContent.Append(String.Format("add_custom_target({0} ${{BUILD}} {0} {2} Development {1} $(ARGS) SOURCES ${{SOURCE_FILES}} ${{HEADER_FILES}} ${{CONFIG_FILES}})\n\n", TargetName, CMakeProjectCmdArg, HostArchitecture));
                    }
                }
            }

            // Append a dummy executable target
            CMakefileContent.AppendLine("add_executable(FakeTarget ${SOURCE_FILES})");

            var FullFileName = Path.Combine(MasterProjectPath.FullName, ProjectFileName);

            bool writeSuccess = WriteFileIfChanged(FullFileName, CMakefileContent.ToString());

            return(writeSuccess);
        }
コード例 #11
0
        /// <summary>
        /// Return any custom paths for VisualStudio this platform requires
        /// This include ReferencePath, LibraryPath, LibraryWPath, IncludePath and ExecutablePath.
        /// </summary>
        /// <param name="InPlatform">The UnrealTargetPlatform being built</param>
        /// <param name="InConfiguration">The configuration being built</param>
        /// <param name="TargetType">The type of target (game or program)</param>
        /// <param name="TargetRulesPath">Path to the target.cs file</param>
        /// <param name="ProjectFilePath">Path to the project file</param>
        /// <param name="NMakeOutputPath"></param>
        /// <param name="InProjectFileFormat">Format for the generated project files</param>
        /// <param name="ProjectFileBuilder">The project file content</param>
        /// <returns>The custom path lines for the project file; Empty string if it doesn't require one</returns>
        public override void GetVisualStudioPathsEntries(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath, FileReference NMakeOutputPath, VCProjectFileFormat InProjectFileFormat, StringBuilder ProjectFileBuilder)
        {
            base.GetVisualStudioPathsEntries(InPlatform, InConfiguration, TargetType, TargetRulesPath, ProjectFilePath, NMakeOutputPath, InProjectFileFormat, ProjectFileBuilder);

            if (IsVSLuminSupportInstalled(InProjectFileFormat) && TargetType == TargetType.Game && InPlatform == UnrealTargetPlatform.Lumin)
            {
                // When generating for a blueprint only project, use the blueprint only project's path to generate the visual studio path entries
                bool bGetEntriesForBlueprintOnlyProject = BPOnlyProjectPath != null;

                string MLSDK = Utils.CleanDirectorySeparators(Environment.GetEnvironmentVariable("MLSDK"), '\\');

                string GameName = bGetEntriesForBlueprintOnlyProject ? BPOnlyProjectPath.GetFileNameWithoutExtension() : TargetRulesPath.GetFileNameWithoutExtension();
                GameName = Path.GetFileNameWithoutExtension(GameName);

                string PackagePath = bGetEntriesForBlueprintOnlyProject ? BPOnlyProjectPath.Directory.FullName + "\\Binaries\\Lumin" : Utils.MakePathRelativeTo(NMakeOutputPath.Directory.FullName, ProjectFilePath.Directory.FullName);
                string PackageFile = PackagePath;
                string PackageName = GameName;
                if (InConfiguration != UnrealTargetConfiguration.Development)
                {
                    PackageName = GameName + "-" + InPlatform.ToString() + "-" + InConfiguration.ToString();
                }
                PackageFile = Path.Combine(PackageFile, PackageName + ".mpk");

                // Can't use $(NMakeOutput) directly since that is defined after <ELFFile> tag and thus ends up being translated as an empty string.
                string ELFFile = bGetEntriesForBlueprintOnlyProject ? PackagePath : Utils.MakePathRelativeTo(NMakeOutputPath.Directory.FullName, ProjectFilePath.Directory.FullName);
                // Provide path to stripped executable so all symbols are resolved from the external sym file instead.
                ELFFile = Path.Combine(ELFFile, "..\\..\\Intermediate\\Lumin\\Mabu\\Binaries", GetElfName(NMakeOutputPath));
                string DebuggerFlavor = "MLDebugger";

                string SymFile = Utils.MakePathRelativeTo(NMakeOutputPath.Directory.FullName, ProjectFilePath.Directory.FullName);
                SymFile = Path.Combine(SymFile, "..\\..\\Intermediate\\Lumin\\Mabu\\Binaries", Path.ChangeExtension(GetElfName(NMakeOutputPath), ".sym"));

                // following are defaults for debugger options
                string Attach               = "false";
                string EnableAutoStop       = "true";
                string AutoStopAtFunction   = "main";
                string EnablePrettyPrinting = "true";
                string MLDownloadOnStart    = "true";

                string CustomPathEntriesTemplate = "<MLSDK>{0}</MLSDK>" + ProjectFileGenerator.NewLine +
                                                   "<PackageFile>{1}</PackageFile>" + ProjectFileGenerator.NewLine +
                                                   "<ELFFile>{2}</ELFFile>" + ProjectFileGenerator.NewLine +
                                                   "<DebuggerFlavor>{3}</DebuggerFlavor>" + ProjectFileGenerator.NewLine +
                                                   "<Attach>{4}</Attach>" + ProjectFileGenerator.NewLine +
                                                   "<EnableAutoStop>{5}</EnableAutoStop>" + ProjectFileGenerator.NewLine +
                                                   "<AutoStopAtFunction>{6}</AutoStopAtFunction>" + ProjectFileGenerator.NewLine +
                                                   "<EnablePrettyPrinting>{7}</EnablePrettyPrinting>" + ProjectFileGenerator.NewLine +
                                                   "<MLDownloadOnStart>{8}</MLDownloadOnStart>" + ProjectFileGenerator.NewLine;
                // No need to provide SymFile path. The file is automatically picked up when it resides in the same folder and has the same name as the ElfFile
                // "<SymFile>{9}</SymFile>" + ProjectFileGenerator.NewLine;
                ProjectFileBuilder.Append(ProjectFileGenerator.NewLine + string.Format(CustomPathEntriesTemplate, MLSDK, PackageFile, ELFFile, DebuggerFlavor, Attach, EnableAutoStop, AutoStopAtFunction, EnablePrettyPrinting, MLDownloadOnStart));
            }
        }
コード例 #12
0
        private bool WriteCMakeLists()
        {
            string BuildCommand     = "";
            var    FileName         = "CMakeLists.txt";
            var    CMakefileContent = new StringBuilder();

            var CMakeSectionEnd = " )\n\n";

            var CMakeSourceFilesList        = "set(SOURCE_FILES \n";
            var CMakeHeaderFilesList        = "set(HEADER_FILES \n";
            var CMakeConfigFilesList        = "set(CONFIG_FILES \n";
            var IncludeDirectoriesList      = "include_directories( \n";
            var PreprocessorDefinitionsList = "add_definitions( \n";

            var CMakeGameRootPath = "";
            var CMakeUE4RootPath  = "set(UE4_ROOT_PATH " + Path.GetFullPath(ProjectFileGenerator.RootRelativePath) + ")\n";

            string GameProjectPath = "";
            string GameProjectFile = "";

            string CMakeGameProjectFile = "";

            bool bIsMac   = BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac;
            bool bIsLinux = BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Linux;
            bool bIsWin64 = BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64;

            String HostArchitecture = null;

            if (bIsLinux)
            {
                HostArchitecture = "Linux";
            }
            else if (bIsMac)
            {
                HostArchitecture = "Mac";
            }
            else if (bIsWin64)
            {
                HostArchitecture = "Win64";
            }
            else
            {
                throw new BuildException("ERROR: CMakefileGenerator does not support this platform");
            }

            if (!String.IsNullOrEmpty(GameProjectName))
            {
                CMakeGameRootPath = "set(GAME_ROOT_PATH \"" + UnrealBuildTool.GetUProjectPath() + "\")\n";

                GameProjectPath = UnrealBuildTool.GetUProjectPath();
                GameProjectFile = UnrealBuildTool.GetUProjectFile();

                CMakeGameProjectFile = "set(GAME_PROJECT_FILE \"" + GameProjectFile + "\")\n";

                BuildCommand = "set(BUILD mono ${UE4_ROOT_PATH}/Engine/Binaries/DotNET/UnrealBuildTool.exe )\n";
            }
            else if (bIsLinux || bIsMac)
            {
                BuildCommand = String.Format("set(BUILD cd ${{UE4_ROOT_PATH}} && bash ${{UE4_ROOT_PATH}}/Engine/Build/BatchFiles/{0}/Build.sh)\n", HostArchitecture);
            }
            else if (bIsWin64)
            {
                BuildCommand = "set(BUILD bash ${{UE4_ROOT_PATH}}/Engine/Build/BatchFiles/Build.bat)\n";
            }

            CMakefileContent.Append(
                "# Makefile generated by CMakefileGenerator.cs\n" +
                "# *DO NOT EDIT*\n\n" +
                "cmake_minimum_required (VERSION 2.6)\n" +
                "project (UE4)\n\n" +
                CMakeUE4RootPath +
                CMakeGameProjectFile +
                BuildCommand +
                CMakeGameRootPath + "\n"
                );

            List <String> IncludeDirectories      = new List <String>();
            List <String> PreprocessorDefinitions = new List <String>();

            foreach (var CurProject in GeneratedProjectFiles)
            {
                foreach (var CurPath in CurProject.IntelliSenseIncludeSearchPaths)
                {
                    string IncludeDirectory = GetIncludeDirectory(CurPath, Path.GetDirectoryName(CurProject.ProjectFilePath));
                    if (IncludeDirectory != null && !IncludeDirectories.Contains(IncludeDirectory))
                    {
                        IncludeDirectories.Add(IncludeDirectory);
                    }
                }

                foreach (var CurDefinition in CurProject.IntelliSensePreprocessorDefinitions)
                {
                    string Definition          = CurDefinition;
                    string AlternateDefinition = Definition.Contains("=0") ? Definition.Replace("=0", "=1") : Definition.Replace("=1", "=0");
                    if (Definition.Equals("WITH_EDITORONLY_DATA=0") || Definition.Equals("WITH_DATABASE_SUPPORT=1"))
                    {
                        Definition = AlternateDefinition;
                    }
                    if (!PreprocessorDefinitions.Contains(Definition) && !PreprocessorDefinitions.Contains(AlternateDefinition) && !Definition.StartsWith("UE_ENGINE_DIRECTORY") && !Definition.StartsWith("ORIGINAL_FILE_NAME"))
                    {
                        PreprocessorDefinitions.Add(Definition);
                    }
                }
            }

            // Create SourceFiles, HeaderFiles, and ConfigFiles sections.
            var AllModuleFiles = DiscoverModules();

            foreach (string CurModuleFile in AllModuleFiles)
            {
                var FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile, ExcludeNoRedistFiles: bExcludeNoRedistFiles);
                foreach (string CurSourceFile in FoundFiles)
                {
                    string SourceFileRelativeToRoot = Utils.MakePathRelativeTo(CurSourceFile, Path.Combine(EngineRelativePath));
                    // Exclude files/folders on a per-platform basis.
                    if ((bIsLinux && IsLinuxFiltered(SourceFileRelativeToRoot)) || (bIsMac && IsMacFiltered(SourceFileRelativeToRoot)) ||
                        (bIsWin64 && IsWinFiltered(SourceFileRelativeToRoot))
                        )
                    {
                        if (SourceFileRelativeToRoot.EndsWith(".cpp"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                CMakeSourceFilesList += ("\t\"${UE4_ROOT_PATH}/Engine/" + SourceFileRelativeToRoot + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    CMakeSourceFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\"\n");
                                }
                                else
                                {
                                    CMakeSourceFilesList += ("\t\"${GAME_ROOT_PATH}/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\"\n");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".h"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                CMakeHeaderFilesList += ("\t\"${UE4_ROOT_PATH}/Engine/" + SourceFileRelativeToRoot + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    CMakeHeaderFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\"\n");
                                }
                                else
                                {
                                    CMakeHeaderFilesList += ("\t\"${GAME_ROOT_PATH}/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\"\n");
                                }
                            }
                        }
                        if (SourceFileRelativeToRoot.EndsWith(".cs"))
                        {
                            if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot))
                            {
                                // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot;
                                CMakeConfigFilesList += ("\t\"${UE4_ROOT_PATH}/Engine/" + SourceFileRelativeToRoot + "\"\n");
                            }
                            else
                            {
                                if (String.IsNullOrEmpty(GameProjectName))
                                {
                                    // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3);
                                    CMakeConfigFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\"\n");
                                }
                                else
                                {
                                    CMakeConfigFilesList += ("\t\"${GAME_ROOT_PATH}/" + Utils.MakePathRelativeTo(CurSourceFile, GameProjectPath) + "\"\n");
                                };
                            }
                        }
                    }
                }
            }

            foreach (string IncludeDirectory in IncludeDirectories)
            {
                IncludeDirectoriesList += ("\t\"" + IncludeDirectory + "\"\n");
            }

            foreach (string PreprocessorDefinition in PreprocessorDefinitions)
            {
                PreprocessorDefinitionsList += ("\t-D" + PreprocessorDefinition + "\n");
            }

            // Add section end to section strings;
            CMakeSourceFilesList        += CMakeSectionEnd;
            CMakeHeaderFilesList        += CMakeSectionEnd;
            CMakeConfigFilesList        += CMakeSectionEnd;
            IncludeDirectoriesList      += CMakeSectionEnd;
            PreprocessorDefinitionsList += CMakeSectionEnd;

            // Append sections to the CMakeLists.txt file
            CMakefileContent.Append(CMakeSourceFilesList);
            CMakefileContent.Append(CMakeHeaderFilesList);
            CMakefileContent.Append(CMakeConfigFilesList);
            CMakefileContent.Append(IncludeDirectoriesList);
            CMakefileContent.Append(PreprocessorDefinitionsList);

            string CMakeProjectCmdArg = "";

            foreach (var Project in GeneratedProjectFiles)
            {
                foreach (var TargetFile in Project.ProjectTargets)
                {
                    if (TargetFile.TargetFilePath == null)
                    {
                        continue;
                    }

                    var TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFile.TargetFilePath);                                  // Remove both ".cs" and ".

                    foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                    {
                        if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development)
                        {
                            if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                            {
                                if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                                {
                                    CMakeProjectCmdArg = " -project=\"\\\"${GAME_PROJECT_FILE}\\\"\"";
                                }
                                var ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration);
                                CMakefileContent.Append(String.Format("add_custom_target({0}-{3}-{1} ${{BUILD}} {2} {0} {3} {1} $(ARGS))\n", TargetName, ConfName, CMakeProjectCmdArg, HostArchitecture));
                            }
                        }
                    }

                    if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor"))
                    {
                        CMakeProjectCmdArg = " -project=\"\\\"${GAME_PROJECT_FILE}\\\"\"";
                    }
                    if (HostArchitecture != null)
                    {
                        CMakefileContent.Append(String.Format("add_custom_target({0} ${{BUILD}} {1} {0} {2} Development $(ARGS) SOURCES ${{SOURCE_FILES}} ${{HEADER_FILES}} ${{CONFIG_FILES}})\n\n", TargetName, CMakeProjectCmdArg, HostArchitecture));
                    }
                }
            }

            var FullFileName = Path.Combine(MasterProjectRelativePath, FileName);

            return(WriteFileIfChanged(FullFileName, CMakefileContent.ToString()));
        }