public override CPPOutput CompileCPPFiles(CPPEnvironment CompileEnvironment, List<FileItem> SourceFiles, string ModuleName) { string Arguments = GetCLArguments_Global(CompileEnvironment); string PCHArguments = ""; if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Include) { // Add the precompiled header file's path to the include path so Clang can find it. // This needs to be before the other include paths to ensure Clang uses it instead of the source header file. PCHArguments += string.Format(" -include \"{0}\"", CompileEnvironment.PrecompiledHeaderFile.AbsolutePath.Replace(".gch", "")); } // Add include paths to the argument list. foreach (string IncludePath in CompileEnvironment.Config.IncludePaths) { Arguments += string.Format(" -I\"{0}\"", IncludePath); } foreach (string IncludePath in CompileEnvironment.Config.SystemIncludePaths) { Arguments += string.Format(" -I\"{0}\"", IncludePath); } // Add preprocessor definitions to the argument list. foreach (string Definition in CompileEnvironment.Config.Definitions) { Arguments += string.Format(" -D \"{0}\"", Definition); } // Create a compile action for each source file. CPPOutput Result = new CPPOutput(); foreach (FileItem SourceFile in SourceFiles) { Action CompileAction = new Action(ActionType.Compile); string FileArguments = ""; string Extension = Path.GetExtension(SourceFile.AbsolutePath).ToUpperInvariant(); // Add C or C++ specific compiler arguments. if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Create) { FileArguments += GetCompileArguments_PCH(); } else if (Extension == ".C") { // Compile the file as C code. FileArguments += GetCompileArguments_C(); } else if (Extension == ".CC") { // Compile the file as C++ code. FileArguments += GetCompileArguments_CPP(); } else if (Extension == ".MM") { // Compile the file as Objective-C++ code. FileArguments += GetCompileArguments_MM(); } else if (Extension == ".M") { // Compile the file as Objective-C code. FileArguments += GetCompileArguments_M(); } else { FileArguments += GetCompileArguments_CPP(); // only use PCH for .cpp files FileArguments += PCHArguments; } // Add the C++ source file and its included files to the prerequisite item list. CompileAction.PrerequisiteItems.Add(SourceFile); foreach (FileItem IncludedFile in CompileEnvironment.GetIncludeDependencies(SourceFile)) { CompileAction.PrerequisiteItems.Add(IncludedFile); } if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Create) { // Add the precompiled header file to the produced item list. FileItem PrecompiledHeaderFile = FileItem.GetItemByPath( Path.Combine( CompileEnvironment.Config.OutputDirectory, Path.GetFileName(SourceFile.AbsolutePath) + ".gch" ) ); CompileAction.ProducedItems.Add(PrecompiledHeaderFile); Result.PrecompiledHeaderFile = PrecompiledHeaderFile; // Add the parameters needed to compile the precompiled header file to the command-line. FileArguments += string.Format(" -o \"{0}\"", PrecompiledHeaderFile.AbsolutePath, false); } else { if (CompileEnvironment.Config.PrecompiledHeaderAction == PrecompiledHeaderAction.Include) { CompileAction.bIsUsingPCH = true; CompileAction.PrerequisiteItems.Add(CompileEnvironment.PrecompiledHeaderFile); } // Add the object file to the produced item list. FileItem ObjectFile = FileItem.GetItemByPath( Path.Combine( CompileEnvironment.Config.OutputDirectory, Path.GetFileName(SourceFile.AbsolutePath) + ".o" ) ); CompileAction.ProducedItems.Add(ObjectFile); Result.ObjectFiles.Add(ObjectFile); FileArguments += string.Format(" -o \"{0}\"", ObjectFile.AbsolutePath, false); } // Add the source file path to the command-line. FileArguments += string.Format(" \"{0}\"", SourceFile.AbsolutePath); CompileAction.WorkingDirectory = Path.GetFullPath("."); CompileAction.CommandPath = ClangPath; CompileAction.CommandArguments = Arguments + FileArguments + CompileEnvironment.Config.AdditionalArguments; CompileAction.StatusDescription = string.Format("{0}", Path.GetFileName(SourceFile.AbsolutePath)); CompileAction.StatusDetailedDescription = SourceFile.Description; CompileAction.bIsGCCCompiler = true; // Don't farm out creation of pre-compiled headers as it is the critical path task. CompileAction.bCanExecuteRemotely = CompileEnvironment.Config.PrecompiledHeaderAction != PrecompiledHeaderAction.Create || BuildConfiguration.bAllowRemotelyCompiledPCHs; CompileAction.OutputEventHandler = new DataReceivedEventHandler(CompileOutputReceivedDataEventHandler); } return Result; }
static string GetCLArguments_Global(CPPEnvironment CompileEnvironment) { string Result = ""; // build up the commandline common to C and C++ Result += " -c"; Result += " -pipe"; Result += " -fomit-frame-pointer"; Result += " -fno-exceptions"; // no exceptions Result += " -funwind-tables"; // generate unwind tables as they seem to be needed for stack tracing (why??) Result += " -Wall -Werror"; Result += " -Wsequence-point"; // additional warning not normally included in Wall: warns if order of operations is ambigious //Result += " -Wunreachable-code"; // additional warning not normally included in Wall: warns if there is code that will never be executed - not helpful due to bIsGCC and similar //Result += " -Wshadow"; // additional warning not normally included in Wall: warns if there variable/typedef shadows some other variable - not helpful because we have gobs of code that shadows variables Result += " -mmmx -msse -msse2"; // allows use of SIMD intrinsics Result += " -fno-math-errno"; // do not assume that math ops have side effects Result += " -fdiagnostics-format=msvc"; // make diagnostics compatible with MSVC Result += " -Wno-unused-variable"; // this will hide the warnings about static functions in headers that aren't used in every single .cpp file Result += " -Wno-unused-function"; // this hides the "enumeration value 'XXXXX' not handled in switch [-Wswitch]" warnings - we should maybe remove this at some point and add UE_LOG(, Fatal, ) to default cases Result += " -Wno-switch"; // this hides the "warning : comparison of unsigned expression < 0 is always false" type warnings due to constant comparisons, which are possible with template arguments Result += " -Wno-tautological-compare"; Result += " -Wno-unknown-pragmas"; // Slate triggers this (with its optimize on/off pragmas) Result += " -Wno-unused-private-field"; // MultichannelTcpSocket.h triggers this, possibly more Result += " -Wno-invalid-offsetof"; // needed to suppress warnings about using offsetof on non-POD types. //Result += " -DOPERATOR_NEW_INLINE=FORCENOINLINE"; // shipping builds will cause this warning with "ensure", so disable only in those case if (CompileEnvironment.Config.TargetConfiguration == CPPTargetConfiguration.Shipping) { Result += " -Wno-unused-value"; } // debug info if (CompileEnvironment.Config.bCreateDebugInfo) { Result += " -g3"; } else if (CompileEnvironment.Config.TargetConfiguration < CPPTargetConfiguration.Shipping) { Result += " -gline-tables-only"; // include debug info for meaningful callstacks } else { // in shipping, strip as much info as possible Result += " -g0"; Result += " -fvisibility=hidden"; // prevents from exporting all symbols (reduces the size of the binary) } // optimization level if (CompileEnvironment.Config.TargetConfiguration == CPPTargetConfiguration.Debug) { Result += " -O0"; } else { Result += " -O3"; } //Result += " -v"; // for better error diagnosis Result += " -target x86_64-unknown-linux-gnu"; // Set target triple Result += " -D _LINUX64"; Result += String.Format(" --sysroot={0}", BaseLinuxPath); return Result; }