Example #1
0
        /**
         * Initializes environment variables required by toolchain. Different for 32 and 64 bit.
         */
        public static VCEnvironment SetEnvironment(CPPTargetPlatform Platform)
        {
            if (EnvVars != null && EnvVars.Platform == Platform)
            {
                return EnvVars;
            }

            EnvVars = new VCEnvironment(Platform);
            return EnvVars;
        }
Example #2
0
        static void AppendCLArguments_Global(CPPEnvironment CompileEnvironment, VCEnvironment EnvVars, StringBuilder Arguments)
        {
            // @todo fastubt: Use should be using StringBuilder instead of concatenation in all of these toolchain files.  On Mono, string builder is dramatically faster.

            // @todo fastubt: We can use '/showIncludes' to accelerate outdatedness checking, as the compiler will discover all indirect includes itself.  But, the spew is pretty noisy!
            //		-> If no files in source file chain have changed, even if the build product is outdated, we can skip using /showIncludes (relies on cache surviving)
            // Arguments.Append( " /showIncludes" );

            if (WindowsPlatform.bCompileWithClang)
            {
                // Arguments.Append( " -###" );	// @todo clang: Print Clang command-lines (instead of outputting compile results!)

                // @todo clang: We're impersonating the Visual C++ compiler by setting MSC_VER and _MSC_FULL_VER to values that MSVC would set
                string VersionString;
                switch (WindowsPlatform.Compiler)
                {
                    case WindowsCompiler.VisualStudio2012:
                        VersionString = "1700";
                        break;

                    case WindowsCompiler.VisualStudio2013:
                        VersionString = "1800";
                        break;

                    default:
                        throw new BuildException("Unexpected value for WindowsPlatform.Compiler: " + WindowsPlatform.Compiler.ToString());
                }
                Arguments.Append(" -fmsc-version=" + VersionString);
                Arguments.Append(" /D_MSC_FULL_VER=" + VersionString + "00000");
            }

            // @todo clang: Clang on Windows doesn't respect "#pragma warning (error: ####)", and we're not passing "/WX", so warnings are not
            // treated as errors when compiling on Windows using Clang right now.

            if (BuildConfiguration.bEnableCodeAnalysis)
            {
                Arguments.Append(" /analyze");

                // Don't cause analyze warnings to be errors
                Arguments.Append(" /analyze:WX-");

                // Report functions that use a LOT of stack space.  You can lower this value if you
                // want more aggressive checking for functions that use a lot of stack memory.
                Arguments.Append(" /analyze:stacksize81940");

                // Don't bother generating code, only analyze code (may report fewer warnings though.)
                //Arguments.Append(" /analyze:only");
            }

            // Prevents the compiler from displaying its logo for each invocation.
            Arguments.Append(" /nologo");

            // Enable intrinsic functions.
            Arguments.Append(" /Oi");

            if (WindowsPlatform.bCompileWithClang)
            {
                // Tell the Clang compiler whether we want to generate 32-bit code or 64-bit code
                if (CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win64)
                {
                    Arguments.Append(" --target=x86_64-pc-windows-msvc");
                }
                else
                {
                    Arguments.Append(" --target=x86-pc-windows-msvc");
                }
            }

            // Separate functions for linker.
            Arguments.Append(" /Gy");

            // Compile into an .obj file, and skip linking.
            Arguments.Append(" /c");

            // Allow 800% of the default memory allocation limit.
            Arguments.Append(" /Zm800");

            // Disable "The file contains a character that cannot be represented in the current code page" warning for non-US windows.
            Arguments.Append(" /wd4819");

            if (BuildConfiguration.bUseSharedPCHs)
            {
                // @todo SharedPCH: Disable warning about PCH defines not matching .cpp defines.  We "cheat" these defines a little
                // bit to make shared PCHs work.  But it's totally safe.  Trust us.
                Arguments.Append(" /wd4651");

                // @todo SharedPCH: Disable warning about redefining *API macros.  The PCH header is compiled with various DLLIMPORTs, but
                // when a module that uses that PCH header *IS* one of those imports, that module is compiled with EXPORTS, so the macro
                // is redefined on the command-line.  We need to clobber those defines to make shared PCHs work properly!
                Arguments.Append(" /wd4005");
            }

            // If compiling as a DLL, set the relevant defines
            if (CompileEnvironment.Config.bIsBuildingDLL)
            {
                Arguments.Append(" /D _WINDLL");
            }

            // When targeting Windows XP with Visual Studio 2012+, we need to tell the compiler to use the older Windows SDK that works
            // with Windows XP (http://blogs.msdn.com/b/vcblog/archive/2012/10/08/10357555.aspx)
            if (WindowsPlatform.IsWindowsXPSupported())
            {
                Arguments.Append(" /D_USING_V110_SDK71_");
            }

            // Handle Common Language Runtime support (C++/CLI)
            if (CompileEnvironment.Config.CLRMode == CPPCLRMode.CLREnabled)
            {
                Arguments.Append(" /clr");

                // Don't use default lib path, we override it explicitly to use the 4.0 reference assemblies.
                Arguments.Append(" /clr:nostdlib");
            }

            //
            //	Debug
            //
            if (CompileEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Debug)
            {
                // Disable compiler optimization.
                Arguments.Append(" /Od");

                // Favor code size (especially useful for embedded platforms).
                Arguments.Append(" /Os");

                // Allow inline method expansion unless E&C support is requested
                if (!BuildConfiguration.bSupportEditAndContinue)
                {
                    Arguments.Append(" /Ob2");
                }

                if ((CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win32) ||
                    (CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win64))
                {
                    // Runtime stack checks are not allowed when compiling for CLR
                    if (CompileEnvironment.Config.CLRMode == CPPCLRMode.CLRDisabled)
                    {
                        Arguments.Append(" /RTCs");
                    }
                }
            }
            //
            //	Development and LTCG
            //
            else
            {
                // Maximum optimizations if desired.
                if (CompileEnvironment.Config.OptimizeCode >= ModuleRules.CodeOptimization.InNonDebugBuilds)
                {
                    Arguments.Append(" /Ox");
                }

                // Favor code speed.
                Arguments.Append(" /Ot");

                // Only omit frame pointers on the PC (which is implied by /Ox) if wanted.
                if (BuildConfiguration.bOmitFramePointers == false
                && ((CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win32) ||
                    (CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win64)))
                {
                    Arguments.Append(" /Oy-");
                }

                // Allow inline method expansion
                Arguments.Append(" /Ob2");

                //
                // LTCG
                //
                if (CompileEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Shipping)
                {
                    if (BuildConfiguration.bAllowLTCG)
                    {
                        // Enable link-time code generation.
                        Arguments.Append(" /GL");
                    }
                }
            }

            //
            //	PC
            //
            if ((CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win32) ||
                (CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win64))
            {
                // SSE options are not allowed when using CLR compilation or the 64 bit toolchain
                // (both enable SSE2 automatically)
                if (CompileEnvironment.Config.CLRMode == CPPCLRMode.CLRDisabled &&
                    CompileEnvironment.Config.Target.Platform != CPPTargetPlatform.Win64)
                {
                    // Allow the compiler to generate SSE2 instructions.
                    Arguments.Append(" /arch:SSE2");
                }

                // Prompt the user before reporting internal errors to Microsoft.
                Arguments.Append(" /errorReport:prompt");

                if (CompileEnvironment.Config.CLRMode == CPPCLRMode.CLRDisabled)
                {
                    // Enable C++ exceptions when building with the editor or when building UHT.
                    if (!WindowsPlatform.bCompileWithClang &&	// @todo clang: C++ exceptions are not supported with Clang on Windows yet
                        (CompileEnvironment.Config.bEnableExceptions || STBuildConfiguration.bBuildEditor || STBuildConfiguration.bForceEnableExceptions))
                    {
                        // Enable C++ exception handling, but not C exceptions.
                        Arguments.Append(" /EHsc");
                    }
                    else
                    {
                        // This is required to disable exception handling in VC platform headers.
                        CompileEnvironment.Config.Definitions.Add("_HAS_EXCEPTIONS=0");
                    }
                }
                else
                {
                    // For C++/CLI all exceptions must be left enabled
                    Arguments.Append(" /EHa");
                }
            }

            // @todo - find a better place for this.
            if (CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.HTML5)
            {
                Arguments.Append(" /EHsc");
            }
            // If enabled, create debug information.
            if (CompileEnvironment.Config.bCreateDebugInfo)
            {
                // Store debug info in .pdb files.
                // @todo clang: PDB files are emited from Clang but do not fully work with Visual Studio yet (breakpoints won't hit due to "symbol read error")
                if (BuildConfiguration.bUsePDBFiles)
                {
                    // Create debug info suitable for E&C if wanted.
                    if (BuildConfiguration.bSupportEditAndContinue &&
                        // We only need to do this in debug as that's the only configuration that supports E&C.
                        CompileEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Debug)
                    {
                        Arguments.Append(" /ZI");
                    }
                    // Regular PDB debug information.
                    else
                    {
                        Arguments.Append(" /Zi");
                    }
                    // We need to add this so VS won't lock the PDB file and prevent synchronous updates. This forces serialization through MSPDBSRV.exe.
                    // See http://msdn.microsoft.com/en-us/library/dn502518.aspx for deeper discussion of /FS switch.
                    if (BuildConfiguration.bUseIncrementalLinking && WindowsPlatform.Compiler == WindowsCompiler.VisualStudio2013)
                    {
                        Arguments.Append(" /FS");
                    }
                }
                // Store C7-format debug info in the .obj files, which is faster.
                else
                {
                    Arguments.Append(" /Z7");
                }
            }

            // Specify the appropriate runtime library based on the platform and config.
            if (CompileEnvironment.Config.bUseStaticCRT)
            {
                if (CompileEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Debug && BuildConfiguration.bDebugBuildsActuallyUseDebugCRT)
                {
                    Arguments.Append(" /MTd");
                }
                else
                {
                    Arguments.Append(" /MT");
                }
            }
            else
            {
                if (CompileEnvironment.Config.Target.Configuration == CPPTargetConfiguration.Debug && BuildConfiguration.bDebugBuildsActuallyUseDebugCRT)
                {
                    Arguments.Append(" /MDd");
                }
                else
                {
                    Arguments.Append(" /MD");
                }
            }

            //
            // Options that aren't parsed by clang-cl yet
            //
            if (!WindowsPlatform.bCompileWithClang && !BuildConfiguration.bRunUnrealCodeAnalyzer)	// @todo clang: Not supported in clang-cl yet
            {
                // Allow large object files to avoid hitting the 2^16 section limit when running with -StressTestUnity.
                Arguments.Append(" /bigobj");

                // Relaxes floating point precision semantics to allow more optimization.
                Arguments.Append(" /fp:fast");

                if (CompileEnvironment.Config.OptimizeCode >= ModuleRules.CodeOptimization.InNonDebugBuilds)
                {
                    // Allow optimized code to be debugged more easily.  This makes PDBs a bit larger, but doesn't noticeably affect
                    // compile times.  The executable code is not affected at all by this switch, only the debugging information.
                    if (EnvVars.CLExeVersion >= new Version("18.0.30723"))
                    {
                        // VC2013 Update 3 has a new flag for doing this
                        Arguments.Append(" /Zo");
                    }
                    else
                    {
                        Arguments.Append(" /d2Zi+");
                    }
                }
            }

            //
            // Options skipped for UnrealCodeAnalyzer
            //
            if (!BuildConfiguration.bRunUnrealCodeAnalyzer)
            {
                if (CompileEnvironment.Config.Target.Platform == CPPTargetPlatform.Win64)
                {
                    // Pack struct members on 8-byte boundaries.
                    Arguments.Append(" /Zp8");
                }
                else if (!STBuildTool.CommandLineContains(@"UnrealCodeAnalyzer"))
                {
                    // Pack struct members on 4-byte boundaries.
                    // Disabled when compiling UnrealCodeAnalyzer as it breaks compilation (some structs in clang/llvm headers require 8-byte alignment in 32-bit compilation)
                    Arguments.Append(" /Zp4");
                }
            }

            //
            // Options required by UnrealCodeAnalyzer
            //
            if (BuildConfiguration.bRunUnrealCodeAnalyzer)
            {
                Arguments.Append(" /DUNREAL_CODE_ANALYZER");
            }
        }