编译目标的 RuntimeLibrary 类型

与普通的 c++ 项目不一样,UE 的 Game 工程是不能在项目属性中设置 RuntimeLibrary 的,这部分有 UBT 代劳替我们处理。
其相关的代码在 UnrealBuildTool\Windows\VCToolchain.cs(UE_4.22) 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void AppendCLArguments_Global(CppCompileEnvironment CompileEnvironment, List<string> Arguments)
{
// ...
// Specify the appropriate runtime library based on the platform and config.
if (CompileEnvironment.bUseStaticCRT)
{
if (CompileEnvironment.bUseDebugCRT)
{
Arguments.Add("/MTd");
}
else
{
Arguments.Add("/MT");
}
}
else
{
if (CompileEnvironment.bUseDebugCRT)
{
Arguments.Add("/MDd");
}
else
{
Arguments.Add("/MD");
}
}
// ...
}

*.target.cs 中使用了 bUseStaticCRT=true 后(默认为 false),编译 Debug 版本是 /MTd,其他版本是MT
*.target.cs中不能直接控制 bUseDebugCRT, 但是可以控制bDebugBuildsActuallyUseDebugCRT(默认为 false), 它由我们在VS 选的 ConfigurationbDebugBuildsActuallyUseDebugCRT的值来控制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// UEBuildTarget.cs

// GetCppConfiguration
static CppConfiguration GetCppConfiguration(UnrealTargetConfiguration Configuration)
{
switch (Configuration)
{
case UnrealTargetConfiguration.Debug:
return CppConfiguration.Debug;
case UnrealTargetConfiguration.DebugGame:
case UnrealTargetConfiguration.Development:
return CppConfiguration.Development;
case UnrealTargetConfiguration.Shipping:
return CppConfiguration.Shipping;
case UnrealTargetConfiguration.Test:
return CppConfiguration.Shipping;
default:
throw new BuildException("Unhandled target configuration");
}
}

// CreateCompileEnvironmentForProjectFiles
public CppCompileEnvironment CreateCompileEnvironmentForProjectFiles()
{
CppPlatform CppPlatform = UEBuildPlatform.GetBuildPlatform(Platform).DefaultCppPlatform;
CppConfiguration CppConfiguration = GetCppConfiguration(Configuration);

SourceFileMetadataCache MetadataCache = SourceFileMetadataCache.CreateHierarchy(ProjectFile);

CppCompileEnvironment GlobalCompileEnvironment = new CppCompileEnvironment(CppPlatform, CppConfiguration, Architecture, MetadataCache);
LinkEnvironment GlobalLinkEnvironment = new LinkEnvironment(GlobalCompileEnvironment.Platform, GlobalCompileEnvironment.Configuration, GlobalCompileEnvironment.Architecture);

UEToolChain TargetToolChain = CreateToolchain(CppPlatform);
SetupGlobalEnvironment(TargetToolChain, GlobalCompileEnvironment, GlobalLinkEnvironment);

return GlobalCompileEnvironment;
}

// SetupGlobalEnvironment
private void SetupGlobalEnvironment(UEToolChain ToolChain, CppCompileEnvironment GlobalCompileEnvironment, LinkEnvironment GlobalLinkEnvironment)
{
// ...
GlobalCompileEnvironment.bUseDebugCRT = GlobalCompileEnvironment.Configuration == CppConfiguration.Debug && Rules.bDebugBuildsActuallyUseDebugCRT;
// ...
}

所以,总结上面的代码,只有当 VS 的编译选项选的是 Debug,并且在*.Target.csbDebugBuildsActuallyUseDebugCRT=true的时候,bUseDebugCRT才为true

情况一

  • bUseStaticCRT=true;
  • 以及bDebugBuildsActuallyUseDebugCRT=true;
  • 以及 VS 中的 Configuration 为Debug

以上三个条件全部满足的时候,编译的 Runtime Library 为/MTd

情况二

  • bUseStaticCRT=false;(默认)
  • 以及bDebugBuildsActuallyUseDebugCRT=true;
  • 以及 VS 中的 Configuration 为Debug

这三个条件,编译的 Runtime Library 为/MDd

情况三

情况二 基础上把下列条件改为:

  • 以及bDebugBuildsActuallyUseDebugCRT=false;(默认)

或者:

  • 以及 VS 中的 Configuration 不是Debug

则这种情况下,编译的 Runtime Library 都是/MD.