本文的目的:在项目代码中获知当前代码的自定义的版本号。
概览
Build.version文件(填写了版本号信息) → Definitions.h(包含了各种宏定义) → 各模块的Response文件(是否包含对应的 Definitions.h) → 该模块最终是否能够使用这个宏定义。
使用方法与最终效果
在MyActor.cpp .BeginPlay()中可以通过调用 FApp::GetBuildVersion() 来拿到这个版本号。
// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
Super::BeginPlay();
#ifndef BUILD_VERSION
#define BUILD_VERSION "UNDEFINED"
// 【MarkA】
#endif
// 第一种方式:直接使用 BUILD_VERSION // 【MarkA】
UE_LOG(LogTemp, Error, TEXT("watch the build_version: %s"), * FString( TEXT(BUILD_VERSION)));
// 第二种方式:用 FApp::GetBuildVersion() 接口,这个接口返回了 BUILD_VERSION // 【MarkB】
auto BuildVersion = FApp::GetBuildVersion();
UE_LOG(LogTemp, Error, TEXT("watch the build_version from BuildVersion : %s"), * FString(BuildVersion));
……
}
运行效果:
[2024.07.31-07.28.14:481][ 0]LogTemp: Error: watch the build_version: UNDEFINED
[2024.07.31-07.28.14:481][ 0]LogTemp: Error: watch the build_version from BuildVersion : 0.2.115.540
这个方法属于BuildSettings.build.cs模块。
好处:不需要从ini或者是别的什么地方获取,在引擎最开始运行时就能够使用版本号信息。接下来探讨原理。
Build.version是什么文件
在引擎中 G:\St\EngineSource\Engine\Build\Build.version 这个文件记录了引擎的版本信息,以及一个自定义的 BuildVersion,在其文件内容中没有体现,如下:
{ "MajorVersion": 4, "MinorVersion": 24, "PatchVersion": 2, "Changelist": 0, "CompatibleChangelist": 10570792, "IsLicenseeVersion": 0, "IsPromotedBuild": 0, "BranchName": "++UE4+Release-4.24" }
它对应的UI面板是:
参考:
在每次修改代码后,主动地修改这个Build.version文件,如下:
{"MajorVersion": 4, "MinorVersion": 24, "PatchVersion": 2, "Changelist": 0, "CompatibleChangelist": 10570792, "IsLicenseeVersion": 0, "IsPromotedBuild": 0, "BranchName": "++UE4+Release-4.24", "BuildVersion": "0.2.115.540"}
红色部分,就是自定义的版本号了。
它将会通过以下的堆栈所述的逻辑(没有细看),最终,将这个版本号,写到多个的 “BuildSettings\Definitions.h”。堆栈见“代码块1”,内容见“代码块2”,多个文件的明细见“代码块3”。
//代码块1
BuildVersion.GetDefaultFileName() at G:/St/EngineSource/Engine/Source/Programs/UnrealBuildTool/System/BuildVersion.cs:line 101
RulesAssembly.GetPreprocessorDefinitions() at G:/St/EngineSource/Engine/Source/Programs/UnrealBuildTool/System/RulesAssembly.cs:line 207
ProjectUtils.CompileAndLoadTargetsAssembly()
ProjectUtils.DetectTargetsForProject()
ProjectUtils.DetectProjectProperties()
ProjectUtils.GetProjectProperties()
ProjectParams.AutodetectSettings()
new ProjectParams()
BuildCookRun.SetupParams()
BuildCookRun.ExecuteBuild()
BuildCommand.Execute()
Automation.Execute()
Automation.Process()
Program.MainProc()
Program.<>c__DisplayClass1_0.<Main>b__2()
InternalUtils.RunSingleInstance()
Program.Main()
[External code: 2 frames]
Launcher.Main()
//代码块2
// 位于 {我的项目路径}\Intermediate\Build\Win64\{我的项名}\Development\BuildSettings\Definitions.h
……
#define BRANCH_NAME "++UE4+Release-4.24"
#define BUILD_VERSION "0.2.115.540"……
// 代码块3
Searching 5490 files for "#define BUILD_VERSION "0.2.115.540""
G:\我的项目\Tools\Develop\我的项目\Intermediate\Build\Win64\我的项目名\Development\BuildSettings\Definitions.h:
59 #define COMPATIBLE_CHANGELIST 0
60 #define BRANCH_NAME "++UE4+Release-4.24"
61: #define BUILD_VERSION "0.2.115.540"
62 #define UE_ENABLE_ICU 1
63 #define WITH_VS_PERF_PROFILER 0
G:\我的项目\Tools\Develop\我的项目\Intermediate\Build\Win64\UnrealPak\Development\BuildSettings\Definitions.h:
55 #define COMPATIBLE_CHANGELIST 0
56 #define BRANCH_NAME "++UE4+Release-4.24"
57: #define BUILD_VERSION "0.2.115.540"
58 #define UE_ENABLE_ICU 0
59 #define WITH_VS_PERF_PROFILER 0
2 matches across 2 files
Searching 80702 files for "#define BUILD_VERSION "0.2.115.540""
G:\St\EngineSource\Engine\Intermediate\Build\Win64\ShaderCompileWorker\Development\BuildSettings\Definitions.h:
57 #define COMPATIBLE_CHANGELIST 0
58 #define BRANCH_NAME "++UE4+Release-4.24"
59: #define BUILD_VERSION "0.2.115.540"
60 #define UE_ENABLE_ICU 0
61 #define WITH_VS_PERF_PROFILER 0
G:\St\EngineSource\Engine\Intermediate\Build\Win64\UE4Editor\Development\BuildSettings\Definitions.h:
55 #define COMPATIBLE_CHANGELIST 0
56 #define BRANCH_NAME "++UE4+Release-4.24"
57: #define BUILD_VERSION "0.2.115.540"
58 #define UE_ENABLE_ICU 1
59 #define WITH_VS_PERF_PROFILER 0
G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\Definitions.h:
57 #define COMPATIBLE_CHANGELIST 0
58 #define BRANCH_NAME "++UE4+Release-4.24"
59: #define BUILD_VERSION "0.2.115.540"
60 #define UE_ENABLE_ICU 0
61 #define WITH_VS_PERF_PROFILER 0
一共有五个相关的 Definitions.h 文件,Definitions.h 包含了各种各样的宏,它们是一些自动生成的头文件,用于存储编译时的宏定义和预处理指令。这些文件的作用是为项目提供一个集中管理的地方,用于定义编译时的宏和条件编译指令。在这些文件中,你可以定义各种编译时的开关,以控制代码的编译和行为。例如,你可以在这个文件中定义一些开关,用于启用或禁用特定的功能或模块。这样,你可以根据需要在不同的构建配置中切换功能的开启和关闭,而无需手动修改代码。
这些 Definitions.h 会分别被多个 Response 文件包含。Response文件的含义见: http://t.csdnimg.cn/q7zFwhttp://t.csdnimg.cn/q7zFw
还记得前面写的概览:“Build.version文件(填写了版本号信息) → Definitions.h(包含了各种宏定义) → 各模块的Response文件(是否包含对应的 Definitions.h) → 该模块最终是否能够使用这个宏定义”,接下来我们寻找Response文件。
寻找Response文件
打开“代码块3”里列出的其中一个Response文件,如下所示,它包含(/FI 编译参数,表示Force include)了 Definitions.h 。于是,BuildSettings.build.cs这个模块,就启用了 Definitions.h 里的所有宏定义。于是,BuildSettings.build.cs这个模块,就包含了 #define BUILD_VERSION "0.2.115.540" 。
G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\BuildSettings.cpp.obj.response:
46 /I "C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\winrt"
47 "G:\St\EngineSource\Engine\Source\Runtime\BuildSettings\Private\BuildSettings.cpp"
48: /FI"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\Definitions.h"
49 /Fo"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\BuildSettings.cpp.obj"
50 /TP
继续搜索 “所有包含代码块3中Definitions.h的response文件”,可以得到——所有能使用 #define BUILD_VERSION "0.2.115.540" ——的地方,如代码块4(↓)所示,并且,{我的项目}.build.cs 模块中,没有包含它,也就没有包含这个BUILD_VERSION定义。所以,前文【MarkA】处无法使用 BUILD_VERSION定义,而【MarkB】处可以使用。
// 代码块4
Searching 936 files for "BuildSettings\Definitions.h"
G:\我的项目\Intermediate\Build\Win64\我的项目名\Development\BuildSettings\BuildSettings.cpp.obj.response:
45 /D_HAS_EXCEPTIONS=0
46 "G:\St\EngineSource\Engine\Source\Runtime\BuildSettings\Private\BuildSettings.cpp"
47: /FI"G:\我的项目\Intermediate\Build\Win64\我的项目名\Development\BuildSettings\Definitions.h"
48 /Fo"G:\我的项目\Intermediate\Build\Win64\我的项目名\Development\BuildSettings\BuildSettings.cpp.obj"
49 /TP
G:\我的项目\Intermediate\Build\Win64\UnrealPak\Development\BuildSettings\BuildSettings.cpp.obj.response:
45 /D_HAS_EXCEPTIONS=0
46 "G:\St\EngineSource\Engine\Source\Runtime\BuildSettings\Private\BuildSettings.cpp"
47: /FI"G:\我的项目\Intermediate\Build\Win64\UnrealPak\Development\BuildSettings\Definitions.h"
48 /Fo"G:\我的项目\Intermediate\Build\Win64\UnrealPak\Development\BuildSettings\BuildSettings.cpp.obj"
49 /TP
2 matches across 2 files
Searching 5715 files for "UnrealHeaderTool\Development\BuildSettings\Definitions.h"
G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\BuildSettings.cpp.obj.response:
46 /I "C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\winrt"
47 "G:\St\EngineSource\Engine\Source\Runtime\BuildSettings\Private\BuildSettings.cpp"
48: /FI"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\Definitions.h"
49 /Fo"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\BuildSettings.cpp.obj"
50 /TP
1 match in 1 file
Searching 5715 files for "Build\Win64\UE4Editor\Development\BuildSettings\Definitions.h"
G:\St\EngineSource\Engine\Intermediate\Build\Win64\UE4Editor\Development\BuildSettings\BuildSettings.cpp.obj.response:
46 /I "C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\winrt"
47 "G:\St\EngineSource\Engine\Source\Runtime\BuildSettings\Private\BuildSettings.cpp"
48: /FI"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UE4Editor\Development\BuildSettings\Definitions.h"
49 /Fo"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UE4Editor\Development\BuildSettings\BuildSettings.cpp.obj"
50 /TP
1 match in 1 file
Searching 5715 files for "Build\Win64\UnrealHeaderTool\Development\BuildSettings\Definitions.h"
G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\BuildSettings.cpp.obj.response:
46 /I "C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\winrt"
47 "G:\St\EngineSource\Engine\Source\Runtime\BuildSettings\Private\BuildSettings.cpp"
48: /FI"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\Definitions.h"
49 /Fo"G:\St\EngineSource\Engine\Intermediate\Build\Win64\UnrealHeaderTool\Development\BuildSettings\BuildSettings.cpp.obj"
50 /TP
1 match in 1 file
继续探究 {我的项目}模块 的response文件( {我的项目路径}\Intermediate\Build\Win64\{我的项目名称}\Development\{我的项目名称}\{我的项目名称}.cpp.obj.response ),发现它包含的Definitions.h文件其实是这个:
/FI"{我的项目路径}\Intermediate\Build\Win64\{我的项目名称}\Development\{我的项目名称}\{我的项目名称}\Definitions.{我的项目名称}.h"
并且它其中是没有包含 BUILD_VERSION 的,至此,解释清楚了如何获取引擎Build.version版本号,以及相关原理。