public PVSToolChain(CppPlatform Platform, ReadOnlyTargetRules Target) : base(Platform)
        {
            EnvVars = VCEnvironment.Create(Target.WindowsPlatform.Compiler, Platform, Target.WindowsPlatform.CompilerVersion, Target.WindowsPlatform.WindowsSdkVersion);

            AnalyzerFile = FileReference.Combine(new DirectoryReference(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)), "PVS-Studio", "x64", "PVS-Studio.exe");
            if (!FileReference.Exists(AnalyzerFile))
            {
                FileReference EngineAnalyzerFile = FileReference.Combine(UnrealBuildTool.RootDirectory, "Engine", "Extras", "ThirdPartyNotUE", "NoRedist", "PVS-Studio", "PVS-Studio.exe");
                if (FileReference.Exists(EngineAnalyzerFile))
                {
                    AnalyzerFile = EngineAnalyzerFile;
                }
                else
                {
                    throw new BuildException("Unable to find PVS-Studio at {0} or {1}", AnalyzerFile, EngineAnalyzerFile);
                }
            }

            FileReference SettingsPath = FileReference.Combine(new DirectoryReference(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)), "PVS-Studio", "Settings.xml");

            if (FileReference.Exists(SettingsPath))
            {
                try
                {
                    XmlSerializer Serializer = new XmlSerializer(typeof(PVSApplicationSettings));
                    using (FileStream Stream = new FileStream(SettingsPath.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        ApplicationSettings = (PVSApplicationSettings)Serializer.Deserialize(Stream);
                    }
                }
                catch (Exception Ex)
                {
                    throw new BuildException(Ex, "Unable to read PVS-Studio settings file from {0}", SettingsPath);
                }
            }

            if (ApplicationSettings != null && !String.IsNullOrEmpty(ApplicationSettings.UserName) && !String.IsNullOrEmpty(ApplicationSettings.SerialNumber))
            {
                LicenseFile = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Intermediate", "PVS", "PVS-Studio.lic");
                FileItem.CreateIntermediateTextFile(LicenseFile, new string[] { ApplicationSettings.UserName, ApplicationSettings.SerialNumber });
            }
            else
            {
                FileReference DefaultLicenseFile = AnalyzerFile.ChangeExtension(".lic");
                if (FileReference.Exists(DefaultLicenseFile))
                {
                    LicenseFile = DefaultLicenseFile;
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Execute the command
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            Arguments.ApplyTo(this);

            // Create the build configuration object, and read the settings
            BuildConfiguration BuildConfiguration = new BuildConfiguration();

            XmlConfig.ApplyTo(BuildConfiguration);
            Arguments.ApplyTo(BuildConfiguration);

            // Parse the filter argument
            FileFilter FileFilter = null;

            if (FilterRules.Count > 0)
            {
                FileFilter = new FileFilter(FileFilterType.Exclude);
                foreach (string FilterRule in FilterRules)
                {
                    FileFilter.AddRules(FilterRule.Split(';'));
                }
            }

            // Parse all the target descriptors
            List <TargetDescriptor> TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, BuildConfiguration.bSkipRulesCompile);

            // Generate the compile DB for each target
            using (ISourceFileWorkingSet WorkingSet = new EmptySourceFileWorkingSet())
            {
                // Find the compile commands for each file in the target
                Dictionary <FileReference, string> FileToCommand = new Dictionary <FileReference, string>();
                foreach (TargetDescriptor TargetDescriptor in TargetDescriptors)
                {
                    // Disable PCHs and unity builds for the target
                    TargetDescriptor.AdditionalArguments = TargetDescriptor.AdditionalArguments.Append(new string[] { "-NoPCH", "-DisableUnity" });

                    // Create a makefile for the target
                    UEBuildTarget Target = UEBuildTarget.Create(TargetDescriptor, BuildConfiguration.bSkipRulesCompile, BuildConfiguration.bUsePrecompiled);

                    // Find the location of the compiler
                    VCEnvironment Environment = VCEnvironment.Create(WindowsCompiler.Clang, Target.Platform, Target.Rules.WindowsPlatform.Architecture, null, Target.Rules.WindowsPlatform.WindowsSdkVersion, null);
                    FileReference ClangPath   = FileReference.Combine(Environment.CompilerDir, "bin", "clang++.exe");

                    // Convince each module to output its generated code include path
                    foreach (UEBuildBinary Binary in Target.Binaries)
                    {
                        foreach (UEBuildModuleCPP Module in Binary.Modules.OfType <UEBuildModuleCPP>())
                        {
                            Module.bAddGeneratedCodeIncludePath = true;
                        }
                    }

                    // Create all the binaries and modules
                    CppCompileEnvironment GlobalCompileEnvironment = Target.CreateCompileEnvironmentForProjectFiles();
                    foreach (UEBuildBinary Binary in Target.Binaries)
                    {
                        CppCompileEnvironment BinaryCompileEnvironment = Binary.CreateBinaryCompileEnvironment(GlobalCompileEnvironment);
                        foreach (UEBuildModuleCPP Module in Binary.Modules.OfType <UEBuildModuleCPP>())
                        {
                            if (!Module.Rules.bUsePrecompiled)
                            {
                                UEBuildModuleCPP.InputFileCollection InputFileCollection = Module.FindInputFiles(Target.Platform, new Dictionary <DirectoryItem, FileItem[]>());

                                List <FileItem> InputFiles = new List <FileItem>();
                                InputFiles.AddRange(InputFileCollection.CPPFiles);
                                InputFiles.AddRange(InputFileCollection.CCFiles);

                                CppCompileEnvironment ModuleCompileEnvironment = Module.CreateModuleCompileEnvironment(Target.Rules, BinaryCompileEnvironment);

                                StringBuilder CommandBuilder = new StringBuilder();
                                CommandBuilder.AppendFormat("\"{0}\"", ClangPath.FullName);
                                foreach (FileItem ForceIncludeFile in ModuleCompileEnvironment.ForceIncludeFiles)
                                {
                                    CommandBuilder.AppendFormat(" -include \"{0}\"", ForceIncludeFile.FullName);
                                }
                                foreach (string Definition in ModuleCompileEnvironment.Definitions)
                                {
                                    CommandBuilder.AppendFormat(" -D\"{0}\"", Definition);
                                }
                                foreach (DirectoryReference IncludePath in ModuleCompileEnvironment.UserIncludePaths)
                                {
                                    CommandBuilder.AppendFormat(" -I\"{0}\"", IncludePath);
                                }
                                foreach (DirectoryReference IncludePath in ModuleCompileEnvironment.SystemIncludePaths)
                                {
                                    CommandBuilder.AppendFormat(" -I\"{0}\"", IncludePath);
                                }

                                foreach (FileItem InputFile in InputFiles)
                                {
                                    if (FileFilter == null || FileFilter.Matches(InputFile.Location.MakeRelativeTo(UnrealBuildTool.RootDirectory)))
                                    {
                                        FileToCommand[InputFile.Location] = String.Format("{0} \"{1}\"", CommandBuilder, InputFile.FullName);
                                    }
                                }
                            }
                        }
                    }
                }

                // Write the compile database
                FileReference DatabaseFile = FileReference.Combine(UnrealBuildTool.RootDirectory, "compile_commands.json");
                using (JsonWriter Writer = new JsonWriter(DatabaseFile))
                {
                    Writer.WriteArrayStart();
                    foreach (KeyValuePair <FileReference, string> FileCommandPair in FileToCommand.OrderBy(x => x.Key.FullName))
                    {
                        Writer.WriteObjectStart();
                        Writer.WriteValue("file", FileCommandPair.Key.FullName);
                        Writer.WriteValue("command", FileCommandPair.Value);
                        Writer.WriteValue("directory", UnrealBuildTool.EngineSourceDirectory.ToString());
                        Writer.WriteObjectEnd();
                    }
                    Writer.WriteArrayEnd();
                }
            }

            return(0);
        }
Пример #3
0
        public override void ValidateTarget(TargetRules Target)
        {
            // WindowsTargetRules are reused for HoloLens, so that build modules can keep the model that reuses "windows" configs for most cases
            // That means overriding those settings here that need to be adjusted for HoloLens

            // Compiler version and pix flags must be reloaded from the HoloLens hive

            // Currently BP-only projects don't load build-related settings from their remote ini when building UE4Game.exe
            // (see TargetRules.cs, where the possibly-null project directory is passed to ConfigCache.ReadSettings).
            // It's important for HoloLens that we *do* use the project-specific settings when building (VS 2017 vs 2015 and
            // retail Windows Store are both examples).  Possibly this should be done on all platforms?  But in the interest
            // of not changing behavior on other platforms I'm limiting the scope.

            DirectoryReference IniDirRef = DirectoryReference.FromFile(Target.ProjectFile);

            if (IniDirRef == null && !string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()))
            {
                IniDirRef = new DirectoryReference(UnrealBuildTool.GetRemoteIniPath());
            }

            // Stash the current compiler choice (accounts for command line) in case ReadSettings reverts it to default
            WindowsCompiler CompilerBeforeReadSettings = Target.HoloLensPlatform.Compiler;

            ConfigCache.ReadSettings(IniDirRef, Platform, Target.HoloLensPlatform);

            if (Target.HoloLensPlatform.Compiler == WindowsCompiler.Default)
            {
                if (CompilerBeforeReadSettings != WindowsCompiler.Default)
                {
                    // Previous setting was more specific, use that
                    Target.HoloLensPlatform.Compiler = CompilerBeforeReadSettings;
                }
                else
                {
                    Target.HoloLensPlatform.Compiler = WindowsPlatform.GetDefaultCompiler(Target.ProjectFile);
                }
            }

            if (!Target.bGenerateProjectFiles)
            {
                Log.TraceInformationOnce("Using {0} architecture for deploying to HoloLens device", Target.HoloLensPlatform.Architecture);
            }

            Target.WindowsPlatform.Compiler             = Target.HoloLensPlatform.Compiler;
            Target.WindowsPlatform.Architecture         = Target.HoloLensPlatform.Architecture;
            Target.WindowsPlatform.bPixProfilingEnabled = Target.HoloLensPlatform.bPixProfilingEnabled;
            Target.WindowsPlatform.bUseWindowsSDK10     = true;

            Target.bDeployAfterCompile = true;
            Target.bCompileNvCloth     = false;              // requires CUDA

            // Disable Simplygon support if compiling against the NULL RHI.
            if (Target.GlobalDefinitions.Contains("USE_NULL_RHI=1"))
            {
                Target.bCompileSpeedTree = false;
            }

            // Use shipping binaries to avoid dependency on nvToolsExt which fails WACK.
            if (Target.Configuration == UnrealTargetConfiguration.Shipping)
            {
                Target.bUseShippingPhysXLibraries = true;
            }

            // Be resilient to SDKs being uninstalled but still referenced in the INI file
            VersionNumber      SelectedWindowsSdkVersion;
            DirectoryReference SelectedWindowsSdkDir;

            if (!WindowsPlatform.TryGetWindowsSdkDir(Target.HoloLensPlatform.Win10SDKVersionString, out SelectedWindowsSdkVersion, out SelectedWindowsSdkDir))
            {
                Target.HoloLensPlatform.Win10SDKVersionString = "Latest";
            }

            // Initialize the VC environment for the target, and set all the version numbers to the concrete values we chose.
            VCEnvironment Environment = VCEnvironment.Create(Target.WindowsPlatform.Compiler, Platform, Target.WindowsPlatform.Architecture, Target.WindowsPlatform.CompilerVersion, Target.HoloLensPlatform.Win10SDKVersionString, null);

            Target.WindowsPlatform.Environment       = Environment;
            Target.WindowsPlatform.Compiler          = Environment.Compiler;
            Target.WindowsPlatform.CompilerVersion   = Environment.CompilerVersion.ToString();
            Target.WindowsPlatform.WindowsSdkVersion = Environment.WindowsSdkVersion.ToString();

            // Windows 10 SDK version
            // Auto-detect latest compatible by default (recommended), allow for explicit override if necessary
            // Validate that the SDK isn't too old, and that the combination of VS and SDK is supported.

            Target.HoloLensPlatform.Win10SDKVersion = new Version(Environment.WindowsSdkVersion.ToString());

            if (!Target.bGenerateProjectFiles)
            {
                Log.TraceInformationOnce("Building using Windows SDK version {0} for HoloLens", Target.HoloLensPlatform.Win10SDKVersion);

                if (Target.HoloLensPlatform.Win10SDKVersion < MinimumSDKVersionRecommended)
                {
                    Log.TraceWarning("Your Windows SDK version {0} is older than the minimum recommended version ({1}) for HoloLens.  Consider upgrading.", Target.HoloLensPlatform.Win10SDKVersion, MinimumSDKVersionRecommended);
                }
                else if (Target.HoloLensPlatform.Win10SDKVersion > MaximumSDKVersionTested)
                {
                    Log.TraceInformationOnce("Your Windows SDK version ({0}) for HoloLens is newer than the highest tested with this version of UBT ({1}).  This is probably fine, but if you encounter issues consider using an earlier SDK.", Target.HoloLensPlatform.Win10SDKVersion, MaximumSDKVersionTested);
                }
            }

            HoloLensExports.InitWindowsSdkToolPath(Target.HoloLensPlatform.Win10SDKVersion.ToString());
        }
Пример #4
0
        private void WriteEnvironmentSetup()
        {
            DirectoryReference VCInstallDir = null;
            string             VCToolPath64 = "";
            VCEnvironment      VCEnv        = null;

            try
            {
                VCEnv = VCEnvironment.Create(WindowsPlatform.GetDefaultCompiler(null), CppPlatform.Win64, null, null);
            }
            catch (Exception)
            {
                Console.WriteLine("Failed to get Visual Studio environment.");
            }

            // Copy environment into a case-insensitive dictionary for easier key lookups
            Dictionary <string, string> envVars = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
            {
                envVars[(string)entry.Key] = (string)entry.Value;
            }

            if (envVars.ContainsKey("CommonProgramFiles"))
            {
                AddText("#import CommonProgramFiles\n");
            }

            if (envVars.ContainsKey("DXSDK_DIR"))
            {
                AddText("#import DXSDK_DIR\n");
            }

            if (envVars.ContainsKey("DurangoXDK"))
            {
                AddText("#import DurangoXDK\n");
            }

            if (VCEnv != null)
            {
                string platformVersionNumber = "VSVersionUnknown";
                platformVersionNumber = "140";


                if (!WindowsPlatform.TryGetVSInstallDir(WindowsPlatform.GetDefaultCompiler(null), out VCInstallDir))
                {
                    string exceptionString = "Error: Cannot locate Visual Studio Installation.";
                    Console.WriteLine(exceptionString);
                    throw new BuildException(exceptionString);
                }

                VCToolPath64 = Environment.GetEnvironmentVariable("VC_COMPILER_DIR");

                AddText(string.Format(".WindowsSDKBasePath = '{0}'\n", VCEnv.WindowsSdkDir));

                AddText("Compiler('UE4ResourceCompiler') \n{\n");
                AddText(string.Format("\t.Executable = '{0}'\n", VCEnv.ResourceCompilerPath));
                AddText("\t.CompilerFamily  = 'custom'\n");
                AddText("}\n\n");


                AddText("Compiler('UE4Compiler') \n{\n");

                AddText(string.Format("\t.Root = '{0}'\n", VCEnv.CompilerPath.Directory));
                AddText("\t.Executable = '$Root$/cl.exe'\n");
                AddText("\t.ExtraFiles =\n\t{\n");
                AddText("\t\t'$Root$/c1.dll'\n");
                AddText("\t\t'$Root$/c1xx.dll'\n");
                AddText("\t\t'$Root$/c2.dll'\n");

                if (File.Exists(FileReference.Combine(VCEnv.CompilerPath.Directory, "1033/clui.dll").ToString()))                 //Check English first...
                {
                    AddText("\t\t'$Root$/1033/clui.dll'\n");
                }
                else
                {
                    var numericDirectories = Directory.GetDirectories(VCToolPath64).Where(d => Path.GetFileName(d).All(char.IsDigit));
                    var cluiDirectories    = numericDirectories.Where(d => Directory.GetFiles(d, "clui.dll").Any());
                    if (cluiDirectories.Any())
                    {
                        AddText(string.Format("\t\t'$Root$/{0}/clui.dll'\n", Path.GetFileName(cluiDirectories.First())));
                    }
                }
                AddText("\t\t'$Root$/mspdbsrv.exe'\n");
                AddText("\t\t'$Root$/mspdbcore.dll'\n");

                AddText(string.Format("\t\t'$Root$/mspft{0}.dll'\n", platformVersionNumber));
                AddText(string.Format("\t\t'$Root$/msobj{0}.dll'\n", platformVersionNumber));
                AddText(string.Format("\t\t'$Root$/mspdb{0}.dll'\n", platformVersionNumber));

                AddText(string.Format("\t\t'{0}/VC/Redist/MSVC/14.21.27702/x64/Microsoft.VC142.CRT/msvcp{1}.dll'\n", VCInstallDir.ToString(), platformVersionNumber));
                AddText(string.Format("\t\t'{0}/VC/Redist/MSVC/14.21.27702/x64/Microsoft.VC142.CRT/vccorlib{1}.dll'\n", VCInstallDir.ToString(), platformVersionNumber));


                AddText("\t}\n");                 //End extra files

                AddText("}\n\n");                 //End compiler
            }

            AddText("Settings \n{\n");

            //Start Environment
            AddText("\t.Environment = \n\t{\n");
            if (VCEnv != null)
            {
                AddText(string.Format("\t\t\"PATH={0}\\Common7\\IDE\\;{1}\",\n", VCInstallDir.ToString(), VCToolPath64));
                if (VCEnv.IncludePaths.Count() > 0)
                {
                    AddText(string.Format("\t\t\"INCLUDE={0}\",\n", String.Join(";", VCEnv.IncludePaths.Select(x => x))));
                }

                if (VCEnv.LibraryPaths.Count() > 0)
                {
                    AddText(string.Format("\t\t\"LIB={0}\",\n", String.Join(";", VCEnv.LibraryPaths.Select(x => x))));
                }
            }
            if (envVars.ContainsKey("TMP"))
            {
                AddText(string.Format("\t\t\"TMP={0}\",\n", envVars["TMP"]));
            }
            if (envVars.ContainsKey("SystemRoot"))
            {
                AddText(string.Format("\t\t\"SystemRoot={0}\",\n", envVars["SystemRoot"]));
            }
            if (envVars.ContainsKey("INCLUDE"))
            {
                AddText(string.Format("\t\t\"INCLUDE={0}\",\n", envVars["INCLUDE"]));
            }
            if (envVars.ContainsKey("LIB"))
            {
                AddText(string.Format("\t\t\"LIB={0}\",\n", envVars["LIB"]));
            }

            AddText("\t}\n");             //End environment
            AddText("}\n\n");             //End Settings
        }
Пример #5
0
        private void WriteEnvironmentSetup()
        {
            DirectoryReference VCInstallDir = null;
            string             VCToolPath64 = "";
            VCEnvironment      VCEnv        = null;

            try
            {
                VCEnv = VCEnvironment.Create(WindowsPlatform.GetDefaultCompiler(null), UnrealTargetPlatform.Win64, WindowsArchitecture.x64, null, null, null);
            }
            catch (Exception)
            {
                Log.TraceError("Failed to get Visual Studio environment.");
            }

            // Copy environment into a case-insensitive dictionary for easier key lookups
            Dictionary <string, string> envVars = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
            {
                envVars[(string)entry.Key] = (string)entry.Value;
            }

            if (envVars.ContainsKey("CommonProgramFiles"))
            {
                AddText("#import CommonProgramFiles\n");
            }

            if (envVars.ContainsKey("DXSDK_DIR"))
            {
                AddText("#import DXSDK_DIR\n");
            }

            if (envVars.ContainsKey("DurangoXDK"))
            {
                AddText("#import DurangoXDK\n");
            }

            if (VCEnv != null)
            {
                string platformVersionNumber = "VSVersionUnknown";

                switch (VCEnv.Compiler)
                {
                case WindowsCompiler.VisualStudio2017:
                    // For now we are working with the 140 version, might need to change to 141 or 150 depending on the version of the Toolchain you chose
                    // to install
                    platformVersionNumber = "140";
                    break;

                case WindowsCompiler.VisualStudio2019:
                    platformVersionNumber = "140";
                    break;

                default:
                    string exceptionString = "Error: Unsupported Visual Studio Version.";
                    Log.TraceError(exceptionString);
                    throw new BuildException(exceptionString);
                }


                if (!WindowsPlatform.TryGetVSInstallDir(WindowsPlatform.GetDefaultCompiler(null), out VCInstallDir))
                {
                    string exceptionString = "Error: Cannot locate Visual Studio Installation.";
                    Log.TraceError(exceptionString);
                    throw new BuildException(exceptionString);
                }

                VCToolPath64 = VCEnv.CompilerPath.Directory.ToString() + "\\";

                AddText(string.Format(".WindowsSDKBasePath = '{0}'\n", VCEnv.WindowsSdkDir));

                AddText("Compiler('UE4ResourceCompiler') \n{\n");
                AddText(string.Format("\t.Executable = '{0}'\n", VCEnv.ResourceCompilerPath));
                AddText("\t.CompilerFamily  = 'custom'\n");
                AddText("}\n\n");


                AddText("Compiler('UE4Compiler') \n{\n");

                AddText(string.Format("\t.Root = '{0}'\n", VCEnv.CompilerPath.Directory));
                AddText("\t.Executable = '$Root$/cl.exe'\n");
                AddText("\t.ExtraFiles =\n\t{\n");
                AddText("\t\t'$Root$/c1.dll'\n");
                AddText("\t\t'$Root$/c1xx.dll'\n");
                AddText("\t\t'$Root$/c2.dll'\n");


                if (File.Exists(FileReference.Combine(VCEnv.CompilerPath.Directory, "1033/clui.dll").ToString())) //Check English first...
                {
                    AddText("\t\t'$Root$/1033/clui.dll'\n");
                }
                else
                {
                    var numericDirectories = Directory.GetDirectories(VCToolPath64).Where(d => Path.GetFileName(d).All(char.IsDigit));
                    var cluiDirectories    = numericDirectories.Where(d => Directory.GetFiles(d, "clui.dll").Any());
                    if (cluiDirectories.Any())
                    {
                        AddText(string.Format("\t\t'$Root$/{0}/clui.dll'\n", Path.GetFileName(cluiDirectories.First())));
                    }
                }
                AddText("\t\t'$Root$/mspdbsrv.exe'\n");
                AddText("\t\t'$Root$/mspdbcore.dll'\n");



                AddText(string.Format("\t\t'$Root$/mspft{0}.dll'\n", platformVersionNumber));
                AddText(string.Format("\t\t'$Root$/msobj{0}.dll'\n", platformVersionNumber));
                AddText(string.Format("\t\t'$Root$/mspdb{0}.dll'\n", platformVersionNumber));


                var redistDirs = Directory.GetDirectories(VCInstallDir.ToString() + "\\VC\\Redist\\MSVC\\", "*", SearchOption.TopDirectoryOnly);



                if (redistDirs.Length > 0)
                {
                    Regex  regex     = new Regex(@"\d{2}\.\d{2}\.\d{5}$");
                    string redistDir = redistDirs.First((s) =>
                    {
                        return(regex.IsMatch(s));
                    });
                    if (VCEnv.Compiler == WindowsCompiler.VisualStudio2019)
                    {
                        AddText(string.Format("\t\t'{0}/x64/Microsoft.VC142.CRT/msvcp{1}.dll'\n", redistDir, platformVersionNumber));
                        AddText(string.Format("\t\t'{0}/x64/Microsoft.VC142.CRT/vccorlib{1}.dll'\n", redistDir, platformVersionNumber));
                        AddText("\t\t'$Root$/tbbmalloc.dll'\n");
                    }
                    else if (VCEnv.Compiler == WindowsCompiler.VisualStudio2017)
                    {
                        //VS 2017 is really confusing in terms of version numbers and paths so these values might need to be modified depending on what version of the tool chain you
                        // chose to install.
                        AddText(string.Format("\t\t'{0}/x64/Microsoft.VC141.CRT/msvcp{1}.dll'\n", redistDir, platformVersionNumber));
                        AddText(string.Format("\t\t'{0}/x64/Microsoft.VC141.CRT/vccorlib{1}.dll'\n", redistDir, platformVersionNumber));
                    }
                }

                AddText("\t}\n"); //End extra files

                AddText("}\n\n"); //End compiler
            }

            if (envVars.ContainsKey("SCE_ORBIS_SDK_DIR"))
            {
                AddText(string.Format(".SCE_ORBIS_SDK_DIR = '{0}'\n", envVars["SCE_ORBIS_SDK_DIR"]));
                AddText(string.Format(".PS4BasePath = '{0}/host_tools/bin'\n\n", envVars["SCE_ORBIS_SDK_DIR"]));
                AddText("Compiler('UE4PS4Compiler') \n{\n");
                AddText("\t.Executable = '$PS4BasePath$/orbis-clang.exe'\n");
                AddText("\t.ExtraFiles = '$PS4BasePath$/orbis-snarl.exe'\n");
                AddText("}\n\n");
            }

            AddText("Settings \n{\n");

            // Optional cachePath user setting
            if (bEnableCaching && CachePath != "")
            {
                AddText(string.Format("\t.CachePath = '{0}'\n", CachePath));
            }

            //Start Environment
            AddText("\t.Environment = \n\t{\n");
            if (VCEnv != null)
            {
                AddText(string.Format("\t\t\"PATH={0}\\Common7\\IDE\\;{1};{2}\",\n", VCInstallDir.ToString(), VCToolPath64, VCEnv.ResourceCompilerPath.Directory));
                if (VCEnv.IncludePaths.Count() > 0)
                {
                    AddText(string.Format("\t\t\"INCLUDE={0}\",\n", String.Join(";", VCEnv.IncludePaths.Select(x => x))));
                }

                if (VCEnv.LibraryPaths.Count() > 0)
                {
                    AddText(string.Format("\t\t\"LIB={0}\",\n", String.Join(";", VCEnv.LibraryPaths.Select(x => x))));
                }
            }
            if (envVars.ContainsKey("TMP"))
            {
                AddText(string.Format("\t\t\"TMP={0}\",\n", envVars["TMP"]));
            }
            if (envVars.ContainsKey("SystemRoot"))
            {
                AddText(string.Format("\t\t\"SystemRoot={0}\",\n", envVars["SystemRoot"]));
            }
            if (envVars.ContainsKey("INCLUDE"))
            {
                AddText(string.Format("\t\t\"INCLUDE={0}\",\n", envVars["INCLUDE"]));
            }
            if (envVars.ContainsKey("LIB"))
            {
                AddText(string.Format("\t\t\"LIB={0}\",\n", envVars["LIB"]));
            }

            AddText("\t}\n"); //End environment


            AddText("}\n\n"); //End Settings
        }