/// <summary> /// Returns the common name of the current architecture /// </summary> /// <param name="arch">The architecture enum</param> /// <returns>String with the name</returns> public static string GetArchitectureSubpath(WindowsArchitecture arch) { return(WindowsPlatform.GetArchitectureSubpath(arch)); }
/// <summary> /// Gets a list of Windows Sdk installation directories, ordered by preference /// </summary> /// <returns>String with the name</returns> public static List <DirectoryReference> GetWindowsSdkDirs() { List <DirectoryReference> WindowsSdkDirs = new List <DirectoryReference>(); // Add the default directory first VersionNumber Version; DirectoryReference DefaultWindowsSdkDir; if (WindowsPlatform.TryGetWindowsSdkDir(null, out Version, out DefaultWindowsSdkDir)) { WindowsSdkDirs.Add(DefaultWindowsSdkDir); } // Add all the other directories sorted in reverse order IReadOnlyDictionary <VersionNumber, DirectoryReference> WindowsSdkDirPairs = WindowsPlatform.FindWindowsSdkDirs(); foreach (KeyValuePair <VersionNumber, DirectoryReference> Pair in WindowsSdkDirPairs.OrderByDescending(x => x.Key)) { if (!WindowsSdkDirs.Contains(Pair.Value)) { WindowsSdkDirs.Add(Pair.Value); } } return(WindowsSdkDirs); }
/// <summary> /// Tries to get the directory for an installed Visual Studio version /// </summary> /// <param name="Compiler">The compiler version</param> /// <param name="InstallDir">Receives the install directory on success</param> /// <returns>True if successful</returns> public static bool TryGetVSInstallDir(WindowsCompiler Compiler, out DirectoryReference InstallDir) { return(WindowsPlatform.TryGetVSInstallDir(Compiler, out InstallDir)); }
/// <summary> /// Gets the path to MSBuild.exe /// </summary> /// <returns>Path to MSBuild.exe</returns> public static string GetMSBuildToolPath() { return(WindowsPlatform.GetMsBuildToolPath().FullName); }
/// <summary> /// Sets up the standard compile environment for the toolchain /// </summary> private void SetupEnvironment(UnrealTargetPlatform Platform) { // Add the standard Visual C++ include paths IncludePaths.Add(DirectoryReference.Combine(ToolChainDir, "INCLUDE")); string ArchFolder = WindowsExports.GetArchitectureSubpath(Architecture); // Add the standard Visual C++ library paths if (ToolChain >= WindowsCompiler.VisualStudio2017) { if (Platform == UnrealTargetPlatform.HoloLens) { LibraryPaths.Add(DirectoryReference.Combine(ToolChainDir, "lib", ArchFolder, "store")); } else { LibraryPaths.Add(DirectoryReference.Combine(ToolChainDir, "lib", ArchFolder)); } } else { DirectoryReference LibsPath = DirectoryReference.Combine(ToolChainDir, "LIB"); if (Platform == UnrealTargetPlatform.HoloLens) { LibsPath = DirectoryReference.Combine(LibsPath, "store"); } if (Architecture == WindowsArchitecture.x64) { LibsPath = DirectoryReference.Combine(LibsPath, "amd64"); } else if (Architecture == WindowsArchitecture.ARM32) { LibsPath = DirectoryReference.Combine(LibsPath, "arm"); } LibraryPaths.Add(LibsPath); } // If we're on Visual Studio 2015 and using pre-Windows 10 SDK, we need to find a Windows 10 SDK and add the UCRT include paths if (ToolChain >= WindowsCompiler.VisualStudio2015_DEPRECATED && WindowsSdkVersion < new VersionNumber(10)) { KeyValuePair <VersionNumber, DirectoryReference> Pair = WindowsPlatform.FindUniversalCrtDirs().OrderByDescending(x => x.Key).FirstOrDefault(); if (Pair.Key == null || Pair.Key < new VersionNumber(10)) { throw new BuildException("{0} requires the Universal CRT to be installed.", WindowsPlatform.GetCompilerName(ToolChain)); } DirectoryReference IncludeRootDir = DirectoryReference.Combine(Pair.Value, "include", Pair.Key.ToString()); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "ucrt")); DirectoryReference LibraryRootDir = DirectoryReference.Combine(Pair.Value, "lib", Pair.Key.ToString()); LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "ucrt", ArchFolder)); } // Add the NETFXSDK include path. We need this for SwarmInterface. DirectoryReference NetFxSdkDir; if (WindowsPlatform.TryGetNetFxSdkInstallDir(out NetFxSdkDir)) { IncludePaths.Add(DirectoryReference.Combine(NetFxSdkDir, "include", "um")); LibraryPaths.Add(DirectoryReference.Combine(NetFxSdkDir, "lib", "um", ArchFolder)); } else { throw new BuildException("Could not find NetFxSDK install dir; this will prevent SwarmInterface from installing. Install a version of .NET Framework SDK at 4.6.0 or higher."); } // Add the Windows SDK paths if (WindowsSdkVersion >= new VersionNumber(10)) { DirectoryReference IncludeRootDir = DirectoryReference.Combine(WindowsSdkDir, "include", WindowsSdkVersion.ToString()); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "ucrt")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "shared")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "um")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "winrt")); DirectoryReference LibraryRootDir = DirectoryReference.Combine(WindowsSdkDir, "lib", WindowsSdkVersion.ToString()); LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "ucrt", ArchFolder)); LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "um", ArchFolder)); } else { DirectoryReference IncludeRootDir = DirectoryReference.Combine(WindowsSdkDir, "include"); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "shared")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "um")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "winrt")); DirectoryReference LibraryRootDir = DirectoryReference.Combine(WindowsSdkDir, "lib", "winv6.3"); LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "um", ArchFolder)); } }
/// <summary> /// Creates an environment with the given settings /// </summary> /// <param name="Compiler">The compiler version to use</param> /// <param name="Platform">The platform to target</param> /// <param name="Architecture">The Architecture to target</param> /// <param name="CompilerVersion">The specific toolchain version to use</param> /// <param name="WindowsSdkVersion">Version of the Windows SDK to use</param> /// <param name="SuppliedSdkDirectoryForVersion">If specified, this is the SDK directory to use, otherwise, attempt to look up via registry. If specified, the WindowsSdkVersion is used directly</param> /// <returns>New environment object with paths for the given settings</returns> public static VCEnvironment Create(WindowsCompiler Compiler, UnrealTargetPlatform Platform, WindowsArchitecture Architecture, string CompilerVersion, string WindowsSdkVersion, string SuppliedSdkDirectoryForVersion) { // Get the compiler version info VersionNumber SelectedCompilerVersion; DirectoryReference SelectedCompilerDir; if (!WindowsPlatform.TryGetToolChainDir(Compiler, CompilerVersion, out SelectedCompilerVersion, out SelectedCompilerDir)) { throw new BuildException("{0}{1} must be installed in order to build this target.", WindowsPlatform.GetCompilerName(Compiler), String.IsNullOrEmpty(CompilerVersion)? "" : String.Format(" ({0})", CompilerVersion)); } // Get the toolchain info WindowsCompiler ToolChain; VersionNumber SelectedToolChainVersion; DirectoryReference SelectedToolChainDir; if (Compiler == WindowsCompiler.Clang || Compiler == WindowsCompiler.Intel) { if (WindowsPlatform.TryGetToolChainDir(WindowsCompiler.VisualStudio2019, null, out SelectedToolChainVersion, out SelectedToolChainDir)) { ToolChain = WindowsCompiler.VisualStudio2019; } else if (WindowsPlatform.TryGetToolChainDir(WindowsCompiler.VisualStudio2017, null, out SelectedToolChainVersion, out SelectedToolChainDir)) { ToolChain = WindowsCompiler.VisualStudio2017; } else { throw new BuildException("{0} or {1} must be installed in order to build this target.", WindowsPlatform.GetCompilerName(WindowsCompiler.VisualStudio2019), WindowsPlatform.GetCompilerName(WindowsCompiler.VisualStudio2017)); } } else { ToolChain = Compiler; SelectedToolChainVersion = SelectedCompilerVersion; SelectedToolChainDir = SelectedCompilerDir; } // Get the actual Windows SDK directory VersionNumber SelectedWindowsSdkVersion; DirectoryReference SelectedWindowsSdkDir; if (SuppliedSdkDirectoryForVersion != null) { SelectedWindowsSdkDir = new DirectoryReference(SuppliedSdkDirectoryForVersion); SelectedWindowsSdkVersion = VersionNumber.Parse(WindowsSdkVersion); if (!DirectoryReference.Exists(SelectedWindowsSdkDir)) { throw new BuildException("Windows SDK{0} must be installed at {1}.", String.IsNullOrEmpty(WindowsSdkVersion) ? "" : String.Format(" ({0})", WindowsSdkVersion), SuppliedSdkDirectoryForVersion); } } else { if (!WindowsPlatform.TryGetWindowsSdkDir(WindowsSdkVersion, out SelectedWindowsSdkVersion, out SelectedWindowsSdkDir)) { throw new BuildException("Windows SDK{0} must be installed in order to build this target.", String.IsNullOrEmpty(WindowsSdkVersion) ? "" : String.Format(" ({0})", WindowsSdkVersion)); } } return(new VCEnvironment(Platform, Compiler, SelectedCompilerDir, SelectedCompilerVersion, Architecture, ToolChain, SelectedToolChainDir, SelectedToolChainVersion, SelectedWindowsSdkDir, SelectedWindowsSdkVersion)); }
private LinkEnvironment SetupBinaryLinkEnvironment(ReadOnlyTargetRules Target, UEToolChain ToolChain, LinkEnvironment LinkEnvironment, CppCompileEnvironment CompileEnvironment, List <PrecompiledHeaderTemplate> SharedPCHs, ISourceFileWorkingSet WorkingSet, DirectoryReference ExeDir, ActionGraph ActionGraph) { LinkEnvironment BinaryLinkEnvironment = new LinkEnvironment(LinkEnvironment); HashSet <UEBuildModule> LinkEnvironmentVisitedModules = new HashSet <UEBuildModule>(); List <UEBuildBinary> BinaryDependencies = new List <UEBuildBinary>(); CppCompileEnvironment BinaryCompileEnvironment = CreateBinaryCompileEnvironment(CompileEnvironment); foreach (UEBuildModule Module in Modules) { List <FileItem> LinkInputFiles; if (Module.Binary == null || Module.Binary == this) { // Compile each module. Log.TraceVerbose("Compile module: " + Module.Name); LinkInputFiles = Module.Compile(Target, ToolChain, BinaryCompileEnvironment, SharedPCHs, WorkingSet, ActionGraph); // NOTE: Because of 'Shared PCHs', in monolithic builds the same PCH file may appear as a link input // multiple times for a single binary. We'll check for that here, and only add it once. This avoids // a linker warning about redundant .obj files. foreach (FileItem LinkInputFile in LinkInputFiles) { if (!BinaryLinkEnvironment.InputFiles.Contains(LinkInputFile)) { BinaryLinkEnvironment.InputFiles.Add(LinkInputFile); } } } else { BinaryDependencies.Add(Module.Binary); } // Allow the module to modify the link environment for the binary. Module.SetupPrivateLinkEnvironment(this, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules, ExeDir); } // Allow the binary dependencies to modify the link environment. foreach (UEBuildBinary BinaryDependency in BinaryDependencies) { BinaryDependency.SetupDependentLinkEnvironment(BinaryLinkEnvironment); } // Remove the default resource file on Windows (PCLaunch.rc) if the user has specified their own if (BinaryLinkEnvironment.InputFiles.Select(Item => Path.GetFileName(Item.AbsolutePath).ToLower()).Any(Name => Name.EndsWith(".res") && !Name.EndsWith(".inl.res") && Name != "pclaunch.rc.res")) { BinaryLinkEnvironment.InputFiles.RemoveAll(x => Path.GetFileName(x.AbsolutePath).ToLower() == "pclaunch.rc.res"); } // Set the link output file. BinaryLinkEnvironment.OutputFilePaths = OutputFilePaths.ToList(); // Set whether the link is allowed to have exports. BinaryLinkEnvironment.bHasExports = bAllowExports; // Set the output folder for intermediate files BinaryLinkEnvironment.IntermediateDirectory = IntermediateDirectory; // Put the non-executable output files (PDB, import library, etc) in the same directory as the production BinaryLinkEnvironment.OutputDirectory = OutputFilePaths[0].Directory; // Setup link output type BinaryLinkEnvironment.bIsBuildingDLL = IsBuildingDll(Type); BinaryLinkEnvironment.bIsBuildingLibrary = IsBuildingLibrary(Type); // If we don't have any resource file, use the default or compile a custom one for this module if (BinaryLinkEnvironment.Platform == CppPlatform.Win32 || BinaryLinkEnvironment.Platform == CppPlatform.Win64) { if (!BinaryLinkEnvironment.InputFiles.Any(x => x.Location.HasExtension(".res"))) { if (BinaryLinkEnvironment.DefaultResourceFiles.Count > 0) { // Use the default resource file if possible BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.DefaultResourceFiles); } else { // Get the intermediate directory DirectoryReference ResourceIntermediateDirectory = ((UEBuildModuleCPP)Modules.First()).IntermediateDirectory; // Create a compile environment for resource files CppCompileEnvironment ResourceCompileEnvironment = new CppCompileEnvironment(BinaryCompileEnvironment); WindowsPlatform.SetupResourceCompileEnvironment(ResourceCompileEnvironment, ResourceIntermediateDirectory, Target); // @todo: This should be in some Windows code somewhere... // Set the original file name macro; used in PCLaunch.rc to set the binary metadata fields. string OriginalFilename = (OriginalOutputFilePaths != null) ? OriginalOutputFilePaths[0].GetFileName() : OutputFilePaths[0].GetFileName(); ResourceCompileEnvironment.Definitions.Add("ORIGINAL_FILE_NAME=\"" + OriginalFilename + "\""); // Set the other version fields ResourceCompileEnvironment.Definitions.Add(String.Format("BUILT_FROM_CHANGELIST={0}", Target.Version.Changelist)); ResourceCompileEnvironment.Definitions.Add(String.Format("BUILD_VERSION={0}", Target.BuildVersion)); // Otherwise compile the default resource file per-binary, so that it gets the correct ORIGINAL_FILE_NAME macro. FileItem DefaultResourceFile = FileItem.GetItemByFileReference(FileReference.Combine(UnrealBuildTool.EngineSourceDirectory, "Runtime", "Launch", "Resources", "Windows", "PCLaunch.rc")); CPPOutput DefaultResourceOutput = ToolChain.CompileRCFiles(ResourceCompileEnvironment, new List <FileItem> { DefaultResourceFile }, ResourceIntermediateDirectory, ActionGraph); BinaryLinkEnvironment.InputFiles.AddRange(DefaultResourceOutput.ObjectFiles); } } } // Add all the common resource files BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.CommonResourceFiles); return(BinaryLinkEnvironment); }
public static bool IsVisualStudioInstalled() { return(WindowsPlatform.HasAnyVSInstalled()); }
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()); }
/// <summary> /// Selects which platforms and build configurations we want in the project file /// </summary> /// <param name="IncludeAllPlatforms">True if we should include ALL platforms that are supported on this machine. Otherwise, only desktop platforms will be included.</param> /// <param name="SupportedPlatformNames">Output string for supported platforms, returned as comma-separated values.</param> protected override void SetupSupportedPlatformsAndConfigurations(bool IncludeAllPlatforms, out string SupportedPlatformNames) { // Call parent implementation to figure out the actual platforms base.SetupSupportedPlatformsAndConfigurations(IncludeAllPlatforms, out SupportedPlatformNames); // If we have a non-default setting for visual studio, check the compiler exists. If not, revert to the default. if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2015) { if (!WindowsPlatform.HasCompiler(WindowsCompiler.VisualStudio2015)) { Log.TraceWarning("Visual Studio C++ 2015 installation not found - ignoring preferred project file format."); ProjectFileFormat = VCProjectFileFormat.Default; } } else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2017) { if (!WindowsPlatform.HasCompiler(WindowsCompiler.VisualStudio2017)) { Log.TraceWarning("Visual Studio C++ 2017 installation not found - ignoring preferred project file format."); ProjectFileFormat = VCProjectFileFormat.Default; } } // Certain platforms override the project file format because their debugger add-ins may not yet support the latest // version of Visual Studio. This is their chance to override that. // ...but only if the user didn't override this via the command-line. if (ProjectFileFormat == VCProjectFileFormat.Default) { // Pick the best platform installed by default if (WindowsPlatform.HasCompiler(WindowsCompiler.VisualStudio2017) && WindowsPlatform.HasIDE(WindowsCompiler.VisualStudio2017)) { ProjectFileFormat = VCProjectFileFormat.VisualStudio2017; } else if (WindowsPlatform.HasCompiler(WindowsCompiler.VisualStudio2015) && WindowsPlatform.HasIDE(WindowsCompiler.VisualStudio2015)) { ProjectFileFormat = VCProjectFileFormat.VisualStudio2015; } // Allow the SDKs to override foreach (UnrealTargetPlatform SupportedPlatform in SupportedPlatforms) { UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(SupportedPlatform, true); if (BuildPlatform != null) { // Don't worry about platforms that we're missing SDKs for if (BuildPlatform.HasRequiredSDKsInstalled() == SDKStatus.Valid) { VCProjectFileFormat ProposedFormat = BuildPlatform.GetRequiredVisualStudioVersion(); if (ProposedFormat != VCProjectFileFormat.Default) { // Reduce the Visual Studio version to the max supported by each platform we plan to include. if (ProjectFileFormat == VCProjectFileFormat.Default || ProposedFormat < ProjectFileFormat) { ProjectFileFormat = ProposedFormat; } } } } } } }
private void WriteEnvironmentSetup() { VCEnvironment VCEnv = null; try { // This may fail if the caller emptied PATH; we try to ignore the problem since // it probably means we are building for another platform. if (BuildType == FBBuildType.Windows) { VCEnv = VCEnvironment.SetEnvironment(CppPlatform.Win64, WindowsPlatform.GetDefaultCompiler(null)); } else if (BuildType == FBBuildType.XBOne) { // If you have XboxOne source access, uncommenting the line below will be better for selecting the appropriate version of the compiler. // Translate the XboxOne compiler to the right Windows compiler to set the VC environment vars correctly... // WindowsCompiler windowsCompiler = XboxOnePlatform.GetDefaultCompiler() == XboxOneCompiler.VisualStudio2015 ? WindowsCompiler.VisualStudio2015 : WindowsCompiler.VisualStudio2017; VCEnv = VCEnvironment.SetEnvironment(CppPlatform.Win64, WindowsPlatform.GetDefaultCompiler(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"; switch (VCEnv.Compiler) { case WindowsCompiler.VisualStudio2015: platformVersionNumber = "140"; break; 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; default: string exceptionString = "Error: Unsupported Visual Studio Version."; Console.WriteLine(exceptionString); throw new BuildException(exceptionString); } AddText(string.Format(".WindowsSDKBasePath = '{0}'\n", VCEnv.WindowsSDKDir)); AddText("Compiler('UE4ResourceCompiler') \n{\n"); AddText("\t.Executable = '$WindowsSDKBasePath$/bin/x64/rc.exe'\n"); AddText("\t.CompilerFamily = 'custom'\n"); AddText("}\n\n"); AddText("Compiler('UE4Compiler') \n{\n"); AddText(string.Format("\t.Root = '{0}'\n", VCEnv.VCToolPath64)); 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(VCEnv.VCToolPath64 + "1033/clui.dll")) //Check English first... { AddText("\t\t'$Root$/1033/clui.dll'\n"); } else { var numericDirectories = Directory.GetDirectories(VCEnv.VCToolPath64.ToString()).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)); if (VCEnv.Compiler == WindowsCompiler.VisualStudio2015) { AddText(string.Format("\t\t'{0}/redist/x64/Microsoft.VC{1}.CRT/msvcp{2}.dll'\n", VCEnv.VCInstallDir, platformVersionNumber, platformVersionNumber)); AddText(string.Format("\t\t'{0}/redist/x64/Microsoft.VC{1}.CRT/vccorlib{2}.dll'\n", VCEnv.VCInstallDir, platformVersionNumber, platformVersionNumber)); } else { //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}/Redist/MSVC/14.12.25810/x64/Microsoft.VC141.CRT/msvcp{1}.dll'\n", VCEnv.VCInstallDir, platformVersionNumber)); AddText(string.Format("\t\t'{0}/Redist/MSVC/14.12.25810/x64/Microsoft.VC141.CRT/vccorlib{1}.dll'\n", VCEnv.VCInstallDir, 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("}\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}\",\n", VCEnv.VCInstallDir, VCEnv.VCToolPath64)); } 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 }
private VCEnvironment(CppPlatform InPlatform, WindowsCompiler InCompiler) { Platform = InPlatform; Compiler = InCompiler; // Get the Visual Studio install directory WindowsPlatform.TryGetVSInstallDir(Compiler, out VSInstallDir); // Get the Visual C++ compiler install directory. if (!WindowsPlatform.TryGetVCInstallDir(Compiler, out VCInstallDir)) { throw new BuildException(WindowsPlatform.GetCompilerName(Compiler) + " must be installed in order to build this target."); } // Figure out the default toolchain directory. VS15 separates this out into separate directories, with platforms as subdirectories under that. DirectoryReference VCToolChainDir = null; if (Compiler == WindowsCompiler.VisualStudio2017) { string Version = File.ReadAllText(FileReference.Combine(VCInstallDir, "Auxiliary", "Build", "Microsoft.VCToolsVersion.default.txt").FullName).Trim(); VCToolChainDir = DirectoryReference.Combine(VCInstallDir, "Tools", "MSVC", Version); } WindowsSDKDir = FindWindowsSDKInstallationFolder(Platform, Compiler); WindowsSDKLibVersion = FindWindowsSDKLibVersion(WindowsSDKDir); WindowsSDKExtensionDir = FindWindowsSDKExtensionInstallationFolder(Compiler); NetFxSDKExtensionDir = FindNetFxSDKExtensionInstallationFolder(Compiler); WindowsSDKExtensionHeaderLibVersion = FindWindowsSDKExtensionLatestVersion(WindowsSDKExtensionDir); FindUniversalCRT(Compiler, out UniversalCRTDir, out UniversalCRTVersion); VCToolPath32 = GetVCToolPath32(Compiler, VCInstallDir, VCToolChainDir); VCToolPath64 = GetVCToolPath64(Compiler, VCInstallDir, VCToolChainDir); // Compile using 64 bit tools for 64 bit targets, and 32 for 32. DirectoryReference CompilerDir = (Platform == CppPlatform.Win64) ? VCToolPath64 : VCToolPath32; // Regardless of the target, if we're linking on a 64 bit machine, we want to use the 64 bit linker (it's faster than the 32 bit linker and can handle large linking jobs) DirectoryReference LinkerDir = VCToolPath64; CompilerPath = GetCompilerToolPath(InPlatform, CompilerDir); CLExeVersion = FindCLExeVersion(CompilerPath.FullName); LinkerPath = GetLinkerToolPath(InPlatform, LinkerDir); LibraryManagerPath = GetLibraryLinkerToolPath(InPlatform, LinkerDir); ResourceCompilerPath = new FileReference(GetResourceCompilerToolPath(Platform)); // Make sure the base 32-bit VS tool path is in the PATH, regardless of which configuration we're using. The toolchain may need to reference support DLLs from this directory (eg. mspdb120.dll). string PathEnvironmentVariable = Environment.GetEnvironmentVariable("PATH") ?? ""; if (!PathEnvironmentVariable.Split(';').Any(x => String.Compare(x, VCToolPath32.FullName, true) == 0)) { PathEnvironmentVariable = VCToolPath32.FullName + ";" + PathEnvironmentVariable; Environment.SetEnvironmentVariable("PATH", PathEnvironmentVariable); } // Setup the INCLUDE environment variable List <string> IncludePaths = GetVisualCppIncludePaths(Compiler, VCInstallDir, VCToolChainDir, UniversalCRTDir, UniversalCRTVersion, NetFxSDKExtensionDir, WindowsSDKDir, WindowsSDKLibVersion); if (InitialIncludePaths != null) { IncludePaths.Add(InitialIncludePaths); } Environment.SetEnvironmentVariable("INCLUDE", String.Join(";", IncludePaths)); // Setup the LIB environment variable List <string> LibraryPaths = GetVisualCppLibraryPaths(Compiler, VCInstallDir, VCToolChainDir, UniversalCRTDir, UniversalCRTVersion, NetFxSDKExtensionDir, WindowsSDKDir, WindowsSDKLibVersion, Platform); if (InitialLibraryPaths != null) { LibraryPaths.Add(InitialLibraryPaths); } Environment.SetEnvironmentVariable("LIB", String.Join(";", LibraryPaths)); }
/// <summary> /// Creates an environment with the given settings /// </summary> /// <param name="Compiler">The compiler version to use</param> /// <param name="Platform">The platform to target</param> /// <param name="CompilerVersion">The specific toolchain version to use</param> /// <param name="WindowsSdkVersion">Version of the Windows SDK to use</param> /// <returns>New environment object with paths for the given settings</returns> public static VCEnvironment Create(WindowsCompiler Compiler, CppPlatform Platform, string CompilerVersion, string WindowsSdkVersion) { // Get the compiler version info VersionNumber SelectedCompilerVersion; DirectoryReference SelectedCompilerDir; if (!WindowsPlatform.TryGetToolChainDir(Compiler, CompilerVersion, out SelectedCompilerVersion, out SelectedCompilerDir)) { throw new BuildException("{0}{1} must be installed in order to build this target.", WindowsPlatform.GetCompilerName(Compiler), String.IsNullOrEmpty(CompilerVersion)? "" : String.Format(" ({0})", CompilerVersion)); } // Get the toolchain info WindowsCompiler ToolChain; VersionNumber SelectedToolChainVersion; DirectoryReference SelectedToolChainDir; if (Compiler == WindowsCompiler.Clang || Compiler == WindowsCompiler.Intel) { ToolChain = WindowsCompiler.VisualStudio2017; if (!WindowsPlatform.TryGetToolChainDir(ToolChain, CompilerVersion, out SelectedToolChainVersion, out SelectedToolChainDir)) { throw new BuildException("{0}{1} must be installed in order to build this target.", WindowsPlatform.GetCompilerName(Compiler), String.IsNullOrEmpty(CompilerVersion)? "" : String.Format(" ({0})", CompilerVersion)); } } else { ToolChain = Compiler; SelectedToolChainVersion = SelectedCompilerVersion; SelectedToolChainDir = SelectedCompilerDir; } // Get the actual Windows SDK directory VersionNumber SelectedWindowsSdkVersion; DirectoryReference SelectedWindowsSdkDir; if (!WindowsPlatform.TryGetWindowsSdkDir(WindowsSdkVersion, out SelectedWindowsSdkVersion, out SelectedWindowsSdkDir)) { throw new BuildException("Windows SDK{1} must be installed in order to build this target.", String.IsNullOrEmpty(WindowsSdkVersion)? "" : String.Format(" ({0})", WindowsSdkVersion)); } return(new VCEnvironment(Platform, Compiler, SelectedCompilerDir, SelectedCompilerVersion, ToolChain, SelectedToolChainDir, SelectedToolChainVersion, SelectedWindowsSdkDir, SelectedWindowsSdkVersion)); }
/// <summary> /// Sets up the standard compile environment for the toolchain /// </summary> private void SetupEnvironment(CppPlatform Platform) { // Add the standard Visual C++ include paths IncludePaths.Add(DirectoryReference.Combine(ToolChainDir, "INCLUDE")); // Add the standard Visual C++ library paths if (ToolChain >= WindowsCompiler.VisualStudio2017) { if (Platform == CppPlatform.Win32) { LibraryPaths.Add(DirectoryReference.Combine(ToolChainDir, "lib", "x86")); } else { LibraryPaths.Add(DirectoryReference.Combine(ToolChainDir, "lib", "x64")); } } else { if (Platform == CppPlatform.Win32) { LibraryPaths.Add(DirectoryReference.Combine(ToolChainDir, "LIB")); } else { LibraryPaths.Add(DirectoryReference.Combine(ToolChainDir, "LIB", "amd64")); } } // If we're on Visual Studio 2015 and using pre-Windows 10 SDK, we need to find a Windows 10 SDK and add the UCRT include paths if (ToolChain >= WindowsCompiler.VisualStudio2015 && WindowsSdkVersion < new VersionNumber(10)) { KeyValuePair <VersionNumber, DirectoryReference> Pair = WindowsPlatform.FindUniversalCrtDirs().OrderByDescending(x => x.Key).FirstOrDefault(); if (Pair.Key == null || Pair.Key < new VersionNumber(10)) { throw new BuildException("{0} requires the Universal CRT to be installed.", WindowsPlatform.GetCompilerName(ToolChain)); } DirectoryReference IncludeRootDir = DirectoryReference.Combine(Pair.Value, "include", Pair.Key.ToString()); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "ucrt")); DirectoryReference LibraryRootDir = DirectoryReference.Combine(Pair.Value, "lib", Pair.Key.ToString()); if (Platform == CppPlatform.Win64) { LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "ucrt", "x64")); } else { LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "ucrt", "x86")); } } // Add the NETFXSDK include path. We need this for SwarmInterface. DirectoryReference NetFxSdkDir; if (WindowsPlatform.TryGetNetFxSdkInstallDir(out NetFxSdkDir)) { IncludePaths.Add(DirectoryReference.Combine(NetFxSdkDir, "include", "um")); if (Platform == CppPlatform.Win32) { LibraryPaths.Add(DirectoryReference.Combine(NetFxSdkDir, "lib", "um", "x86")); } else { LibraryPaths.Add(DirectoryReference.Combine(NetFxSdkDir, "lib", "um", "x64")); } } // Add the Windows SDK paths if (WindowsSdkVersion >= new VersionNumber(10)) { DirectoryReference IncludeRootDir = DirectoryReference.Combine(WindowsSdkDir, "include", WindowsSdkVersion.ToString()); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "ucrt")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "shared")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "um")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "winrt")); DirectoryReference LibraryRootDir = DirectoryReference.Combine(WindowsSdkDir, "lib", WindowsSdkVersion.ToString()); if (Platform == CppPlatform.Win64) { LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "ucrt", "x64")); LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "um", "x64")); } else { LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "ucrt", "x86")); LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "um", "x86")); } } else { DirectoryReference IncludeRootDir = DirectoryReference.Combine(WindowsSdkDir, "include"); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "shared")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "um")); IncludePaths.Add(DirectoryReference.Combine(IncludeRootDir, "winrt")); DirectoryReference LibraryRootDir = DirectoryReference.Combine(WindowsSdkDir, "lib", "winv6.3"); if (Platform == CppPlatform.Win64) { LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "um", "x64")); } else { LibraryPaths.Add(DirectoryReference.Combine(LibraryRootDir, "um", "x86")); } } }
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 }