Add initial support for Precompiled Header Files (PCH) in MSVC compilation
This commit is contained in:
25
Source/FlaxEngine.pch.h
Normal file
25
Source/FlaxEngine.pch.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Include common engine headers
|
||||
#include "Engine/Platform/Platform.h"
|
||||
#include "Engine/Platform/StringUtils.h"
|
||||
#include "Engine/Platform/CriticalSection.h"
|
||||
#include "Engine/Core/Delegate.h"
|
||||
#include "Engine/Core/Types/Guid.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Core/Types/StringView.h"
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Core/Math/Vector2.h"
|
||||
#include "Engine/Core/Math/Vector3.h"
|
||||
#include "Engine/Core/Math/Vector4.h"
|
||||
#include "Engine/Core/Math/Quaternion.h"
|
||||
#include "Engine/Core/Math/BoundingBox.h"
|
||||
#include "Engine/Core/Math/BoundingSphere.h"
|
||||
#include "Engine/Core/Math/Transform.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Scripting/ScriptingObject.h"
|
||||
#include "Engine/Serialization/SerializationFwd.h"
|
||||
@@ -35,6 +35,10 @@ namespace Flax.Build
|
||||
options.ScriptingAPI.Defines.Add("FLAX_GAME");
|
||||
}
|
||||
|
||||
// Use custom precompiled header file for the engine to boost compilation time
|
||||
options.CompileEnv.PrecompiledHeaderUsage = PrecompiledHeaderFileUsage.CreateManual;
|
||||
options.CompileEnv.PrecompiledHeaderSource = Utilities.NormalizePath(Path.Combine(Globals.EngineRoot, "Source/FlaxEngine.pch.h"));
|
||||
|
||||
BinaryModuleName = "FlaxEngine";
|
||||
options.ScriptingAPI.Defines.Add("FLAX");
|
||||
options.ScriptingAPI.Defines.Add("FLAX_ASSERTIONS");
|
||||
|
||||
@@ -23,6 +23,27 @@ namespace Flax.Build.NativeCpp
|
||||
GenerateProject = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Precompiled Headers Files (PCH) usage modes.
|
||||
/// </summary>
|
||||
public enum PrecompiledHeaderFileUsage
|
||||
{
|
||||
/// <summary>
|
||||
/// Precompiled Headers Files (PCH) feature is disabled.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Enables creation and usage of the header file. The input source PCH will be precompiled and included.
|
||||
/// </summary>
|
||||
CreateManual,
|
||||
|
||||
/// <summary>
|
||||
/// Enables usage of the header file. The input source PCH will be included in the build (assuming it exists).
|
||||
/// </summary>
|
||||
UseManual,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The nullable context type used with reference types (C#).
|
||||
/// </summary>
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Flax.Build
|
||||
public IGrouping<string, Module>[] BinaryModules;
|
||||
public BuildTargetInfo BuildInfo;
|
||||
public Dictionary<ProjectInfo, BuildData> ReferenceBuilds = new Dictionary<ProjectInfo, BuildData>();
|
||||
public Dictionary<string, string> PrecompiledHeaderFiles = new();
|
||||
|
||||
public BuildTargetBinaryModuleInfo FinReferenceBuildModule(string name)
|
||||
{
|
||||
@@ -484,6 +485,13 @@ namespace Flax.Build
|
||||
}
|
||||
}
|
||||
|
||||
// If the PCH was already created (eg. by other engine module) then simply reuse the same file
|
||||
if (moduleOptions.CompileEnv.PrecompiledHeaderUsage == PrecompiledHeaderFileUsage.CreateManual && buildData.PrecompiledHeaderFiles.TryGetValue(moduleOptions.CompileEnv.PrecompiledHeaderSource, out var pch))
|
||||
{
|
||||
moduleOptions.CompileEnv.PrecompiledHeaderUsage = PrecompiledHeaderFileUsage.UseManual;
|
||||
moduleOptions.CompileEnv.PrecompiledHeaderFile = pch;
|
||||
}
|
||||
|
||||
// Compile all source files
|
||||
var compilationOutput = buildData.Toolchain.CompileCppFiles(buildData.Graph, moduleOptions, cppFiles, moduleOptions.OutputFolder);
|
||||
foreach (var e in compilationOutput.ObjectFiles)
|
||||
@@ -493,6 +501,11 @@ namespace Flax.Build
|
||||
// TODO: find better way to add generated doc files to the target linker (module exports the output doc files?)
|
||||
buildData.TargetOptions.LinkEnv.DocumentationFiles.AddRange(compilationOutput.DocumentationFiles);
|
||||
}
|
||||
if (moduleOptions.CompileEnv.PrecompiledHeaderUsage == PrecompiledHeaderFileUsage.CreateManual && !string.IsNullOrEmpty(compilationOutput.PrecompiledHeaderFile))
|
||||
{
|
||||
// Cache PCH file to be used by other modules that reference the same file
|
||||
buildData.PrecompiledHeaderFiles.Add(moduleOptions.CompileEnv.PrecompiledHeaderSource, compilationOutput.PrecompiledHeaderFile);
|
||||
}
|
||||
|
||||
if (buildData.Target.LinkType != TargetLinkType.Monolithic)
|
||||
{
|
||||
|
||||
@@ -162,6 +162,21 @@ namespace Flax.Build.NativeCpp
|
||||
/// </summary>
|
||||
public readonly HashSet<string> CustomArgs = new HashSet<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The Precompiled Header File (PCH) usage.
|
||||
/// </summary>
|
||||
public PrecompiledHeaderFileUsage PrecompiledHeaderUsage = PrecompiledHeaderFileUsage.None;
|
||||
|
||||
/// <summary>
|
||||
/// The Precompiled Header File (PCH) binary path. Null if not created.
|
||||
/// </summary>
|
||||
public string PrecompiledHeaderFile;
|
||||
|
||||
/// <summary>
|
||||
/// The Precompiled Header File (PCH) source path. Null if not provided.
|
||||
/// </summary>
|
||||
public string PrecompiledHeaderSource;
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Clone()
|
||||
{
|
||||
@@ -184,7 +199,10 @@ namespace Flax.Build.NativeCpp
|
||||
StringPooling = StringPooling,
|
||||
IntrinsicFunctions = IntrinsicFunctions,
|
||||
BufferSecurityCheck = BufferSecurityCheck,
|
||||
TreatWarningsAsErrors = TreatWarningsAsErrors
|
||||
TreatWarningsAsErrors = TreatWarningsAsErrors,
|
||||
PrecompiledHeaderUsage = PrecompiledHeaderUsage,
|
||||
PrecompiledHeaderFile = PrecompiledHeaderFile,
|
||||
PrecompiledHeaderSource = PrecompiledHeaderSource,
|
||||
};
|
||||
clone.PreprocessorDefinitions.AddRange(PreprocessorDefinitions);
|
||||
clone.IncludePaths.AddRange(IncludePaths);
|
||||
|
||||
@@ -23,5 +23,10 @@ namespace Flax.Build.NativeCpp
|
||||
/// The result documentation files.
|
||||
/// </summary>
|
||||
public readonly List<string> DocumentationFiles = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The result precompiled header file (PCH) created during compilation. Can be used in other compilations (as shared).
|
||||
/// </summary>
|
||||
public string PrecompiledHeaderFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,6 +430,7 @@ namespace Flax.Build.Platforms
|
||||
var commonArgs = new List<string>();
|
||||
commonArgs.AddRange(options.CompileEnv.CustomArgs);
|
||||
SetupCompileCppFilesArgs(graph, options, commonArgs);
|
||||
var useSeparatePdb = true; //compileEnvironment.PrecompiledHeaderUsage == PrecompiledHeaderFileUsage.None;
|
||||
{
|
||||
// Suppress Startup Banner
|
||||
commonArgs.Add("/nologo");
|
||||
@@ -490,7 +491,10 @@ namespace Flax.Build.Platforms
|
||||
if (compileEnvironment.DebugInformation)
|
||||
{
|
||||
// Debug Information Format
|
||||
commonArgs.Add("/Zi");
|
||||
if (useSeparatePdb)
|
||||
commonArgs.Add("/Zi");
|
||||
else
|
||||
commonArgs.Add("/Z7");
|
||||
|
||||
// Enhance Optimized Debugging
|
||||
commonArgs.Add("/Zo");
|
||||
@@ -611,8 +615,65 @@ namespace Flax.Build.Platforms
|
||||
AddIncludePath(commonArgs, includePath);
|
||||
}
|
||||
|
||||
// Compile all C++ files
|
||||
var args = new List<string>();
|
||||
|
||||
// Create precompiled header
|
||||
string pchFile = null, pchSource = null;
|
||||
if (compileEnvironment.PrecompiledHeaderUsage == PrecompiledHeaderFileUsage.UseManual)
|
||||
{
|
||||
pchFile = compileEnvironment.PrecompiledHeaderFile;
|
||||
pchSource = compileEnvironment.PrecompiledHeaderSource;
|
||||
}
|
||||
else if (compileEnvironment.PrecompiledHeaderUsage == PrecompiledHeaderFileUsage.CreateManual)
|
||||
{
|
||||
// Use intermediate cpp file that includes the PCH path but also contains compiler info to properly recompile when it's modified
|
||||
pchSource = compileEnvironment.PrecompiledHeaderSource;
|
||||
var pchFilName = Path.GetFileName(pchSource);
|
||||
var pchSourceFile = Path.Combine(options.IntermediateFolder, Path.ChangeExtension(pchFilName, "cpp"));
|
||||
var contents = Bindings.BindingsGenerator.GetStringBuilder();
|
||||
contents.AppendLine("// This code was auto-generated. Do not modify it.");
|
||||
contents.Append("// Compiler: ").AppendLine(_compilerPath);
|
||||
contents.Append("#include \"").Append(pchSource).AppendLine("\"");
|
||||
Utilities.WriteFileIfChanged(pchSourceFile, contents.ToString());
|
||||
Bindings.BindingsGenerator.PutStringBuilder(contents);
|
||||
|
||||
// Compile intermediate cpp file into actual PCH (and obj+pdb files)
|
||||
pchFile = Path.Combine(options.IntermediateFolder, Path.ChangeExtension(pchFilName, "pch"));
|
||||
if (pchFile.EndsWith(".pch.pch"))
|
||||
pchFile = pchFile.Substring(0, pchFile.Length - 4);
|
||||
var pchPdbFile = Path.Combine(options.IntermediateFolder, Path.ChangeExtension(pchFilName, "pdb"));
|
||||
var pchObjFile = Path.Combine(options.IntermediateFolder, Path.ChangeExtension(pchFilName, "obj"));
|
||||
var task = graph.Add<Task>();
|
||||
task.PrerequisiteFiles.Add(pchSourceFile);
|
||||
task.PrerequisiteFiles.Add(pchSource);
|
||||
task.PrerequisiteFiles.AddRange(IncludesCache.FindAllIncludedFiles(pchSource));
|
||||
task.ProducedFiles.Add(pchFile);
|
||||
task.ProducedFiles.Add(pchObjFile);
|
||||
args.AddRange(commonArgs);
|
||||
args.Add(string.Format("/Yc\"{0}\"", pchSource));
|
||||
args.Add(string.Format("/Fp\"{0}\"", pchFile));
|
||||
args.Add(string.Format("/Fd\"{0}\"", pchPdbFile));
|
||||
args.Add(string.Format("/Fo\"{0}\"", pchObjFile));
|
||||
args.Add("/FS");
|
||||
args.Add(string.Format("\"{0}\"", pchSourceFile));
|
||||
task.WorkingDirectory = options.WorkingDirectory;
|
||||
task.CommandPath = _compilerPath;
|
||||
task.CommandArguments = string.Join(" ", args);
|
||||
task.Cost = int.MaxValue; // Run it before any other tasks
|
||||
|
||||
// Setup outputs
|
||||
output.PrecompiledHeaderFile = pchFile;
|
||||
output.ObjectFiles.Add(pchObjFile);
|
||||
}
|
||||
if (pchFile != null)
|
||||
{
|
||||
// Include PCH file
|
||||
commonArgs.Add(string.Format("/FI\"{0}\"", pchSource));
|
||||
commonArgs.Add(string.Format("/Yu\"{0}\"", pchSource));
|
||||
commonArgs.Add(string.Format("/Fp\"{0}\"", pchFile));
|
||||
}
|
||||
|
||||
// Compile all C++ files
|
||||
foreach (var sourceFile in sourceFiles)
|
||||
{
|
||||
var sourceFilename = Path.GetFileNameWithoutExtension(sourceFile);
|
||||
@@ -625,9 +686,25 @@ namespace Flax.Build.Platforms
|
||||
if (compileEnvironment.DebugInformation)
|
||||
{
|
||||
// Program Database File Name
|
||||
var pdbFile = Path.Combine(outputPath, sourceFilename + ".pdb");
|
||||
args.Add(string.Format("/Fd\"{0}\"", pdbFile));
|
||||
output.DebugDataFiles.Add(pdbFile);
|
||||
string pdbFile = null;
|
||||
if (pchFile != null)
|
||||
{
|
||||
// When using PCH we need to share the same PDB file that was used when building PCH
|
||||
pdbFile = pchFile + ".pdb";
|
||||
|
||||
// Turn on sync for file access to prevent issues when compiling on multiple threads at once
|
||||
if (useSeparatePdb)
|
||||
args.Add("/FS");
|
||||
}
|
||||
else if (useSeparatePdb)
|
||||
{
|
||||
pdbFile = Path.Combine(outputPath, sourceFilename + ".pdb");
|
||||
}
|
||||
if (pdbFile != null)
|
||||
{
|
||||
args.Add(string.Format("/Fd\"{0}\"", pdbFile));
|
||||
output.DebugDataFiles.Add(pdbFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (compileEnvironment.GenerateDocumentation)
|
||||
@@ -650,6 +727,10 @@ namespace Flax.Build.Platforms
|
||||
// Request included files to exist
|
||||
var includes = IncludesCache.FindAllIncludedFiles(sourceFile);
|
||||
task.PrerequisiteFiles.AddRange(includes);
|
||||
if (pchFile != null)
|
||||
{
|
||||
task.PrerequisiteFiles.Add(pchFile);
|
||||
}
|
||||
|
||||
// Compile
|
||||
task.WorkingDirectory = options.WorkingDirectory;
|
||||
@@ -853,6 +934,13 @@ namespace Flax.Build.Platforms
|
||||
task.PrerequisiteFiles.AddRange(linkEnvironment.InputFiles);
|
||||
foreach (var file in linkEnvironment.InputFiles)
|
||||
{
|
||||
if (file.EndsWith(".pch", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// PCH file
|
||||
args.Add(string.Format("/Yu:\"{0}\"", file));
|
||||
continue;
|
||||
}
|
||||
|
||||
args.Add(string.Format("\"{0}\"", file));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user