可可西

UE4之宏与预编译指令定义

在UBT中添加宏定义

UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Configuration\ModuleRules.cs

 

UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildPlatform.cs

 

UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildTarget.cs

 

 

UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Platform\Android\UEBuildAndroid.cs

 

UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Platform\IOS\UEBuildIOS.cs

 

UnrealEngine\Engine\Source\Runtime\Core\Core.Build.cs

 

Definitions文件

Definitions文件是编译时存放所有定义的宏

编译编辑器(Debug)时,这些宏会被写入Intermediate\Build\Win64\UE4Editor\Debug\<Module>\Definitions.<Module>.h中

编译win64的cook版本(Debug)时,这些宏会被写入Intermediate\Build\Win64\<MyGame>\Debug\<Module>\Definitions.<Module>.h中

编译Android的cook版本(Debug)时,这些宏会被写入Intermediate\Build\Android\<MyGame>\Debug\<Module>\Definitions.<Module>.h中

编译IOS的cook版本(Debug)时,这些宏会被写入Intermediate\Build\IOS\<MyGame>\Debug\<Module>\Definitions.<Module>.h中

 

ue4.26在vs2019缺省用c++14编译

 

注:Intermediate\ProjectFiles\*vcxproj工程文件的生成代码在G:\svn\UnrealEngine\Engine\Source\Programs\UnrealBuildTool\ProjectFiles\VisualStudio\VCProject.cs

 

 

使用__cplusplus宏在代码中判断c++标准库版本:

if (__cplusplus == 201703L)
{
    UE_LOG(LogTemp, Log, TEXT("C++17."));
}
else if (__cplusplus == 201402L)
{
    UE_LOG(LogTemp, Log, TEXT("C++14."));
}
else if (__cplusplus == 201103L)
{
    UE_LOG(LogTemp, Log, TEXT("C++11."));
}    
else if (__cplusplus == 199711L)
{
    UE_LOG(LogTemp, Log, TEXT("C++98."));
}
else
{
    UE_LOG(LogTemp, Log, TEXT("pre-standard C++."));
}

 

基础宏

UnrealEngine\Engine\Source\Runtime\Core\Public\HAL\PreprocessorHelpers.h

UnrealEngine\Engine\Source\Runtime\Core\Public\Misc\Build.h

UnrealEngine\Engine\Source\Runtime\Core\Public\HAL\Platform.h

说明
ENGINE_MAJOR_VERSION UE4.26.1下,该宏为4
ENGINE_MINOR_VERSION UE4.26.1下,该宏为26
ENGINE_PATCH_VERSION UE4.26.1下,该宏为1
WITH_EDITOR 编辑器中或Standalone,该宏都为1
WITH_EDITORONLY_DATA

在windows、macos、unix平台的编辑器、Client下该宏为1,DS下该宏为0

其他Android、IOS等平台,该宏为0

与WITH_EDITOR相比,能被UHT识别,可用来包裹UPROPERTY成员变量和UFUNCTION成员函数。

 

UHT在针对WITH_EDITOR、WITH_EDITORONLY_DATA也做了一些特殊处理。详见:UHT里的条件宏处理逻辑

WITH_ENGINE 是否需要编译引擎代码
UE_SERVER

TargetType为Server

cook DS版本,该宏为1。编辑器中,该宏为0

宏UE_SERVER为1时,宏USE_NULL_RHI也为1

UE_GAME

TargetType为Client或Game

cook 游戏版本,该宏为1。编辑器中,该宏为0

UE_CLIENT

TargetType为Client

UE_EDITOR TargetType为Editor
UE_APP_NAME 当前App的名称  如:#define UE_APP_NAME "MyTest1"
PLATFORM_WINDOWS 在windows开发机上,编辑器、standalone、cook win64版本,该宏都为1
PLATFORM_HOLOLENS Hololens平台
PLATFORM_DESKTOP 在桌面开发机(windows、mac、linux)上,编辑器、standalone、cook pc版本,该宏都为1
PLATFORM_ANDROID 编译Android版本时,该宏为1
PLATFORM_ANDROID_ARM64 编译Android ARM64版本时,该宏为1
PLATFORM_APPLE 是否为苹果平台,mac、ios该宏为1
PLATFORM_IOS 编译IOS版本时,该宏为1

PLATFORM_LINUX

PLATFORM_UNIX

编译Linux/Unix DS版本时,该宏为1

注:这2个宏等价

PLATFORM_MAC 在macos开发机上,该宏为1
PLATFROM_SWITCH Switch平台
SWITCHRHI 使用SwitchRHI来作为渲染
PLATFORM_SUPPORTS_MULTITHREADED_GC 是否支持多线程GC。在HoloLen平台该宏为0,其他平台为1
PLATFORM_CAN_SUPPORT_EDITORONLY_DATA 平台是否支持编辑器数据。在windows、macos、unix平台该宏为1,其他平台为0
WITH_EDITORONLY_DATA

在windows、macos、unix平台的编辑器、Client下该宏为1,DS下该宏为0

其他Android、IOS等平台,该宏为0

PLATFORM_IS_ANSI_MALLOC_THREADSAFE Ansi Malloc线程安全。在windows、macos、unix、ios平台该宏为1,其他平台为0
PLATFORM_ALLOW_NULL_RHI IOS平台该宏为1,其他平台为0
IS_MONOLITHIC

宏为1,即:代码会编译到一个模块中 如:cook后的pc和手机版本

宏为0,即:代码会编译到多个dll或dylib中 如:在编辑器或standalone下

IS_PROGRAM

TargetType为TargetType.Program

是否为一个独立的可执行程序(如:ShaderCompileWorker、UnrealPak等)。

编译Android/IOS时,该宏为0

UE_BUILD_DEBUG 编译Debug版本
UE_BUILD_DEVELOPMENT 编译Development版本
UE_BUILD_TEST 编译Test版本
UE_BUILD_SHIPPING 编译Shipping版本
NO_LOGGING 

是否打印log。Debug/Development该宏为0,Shipping/Test版下该宏为!USE_LOGGING_IN_SHIPPING

注:USE_LOGGING_IN_SHIPPING的开启可通过Target.cs中的bUseLoggingInShipping控制

ALLOW_CONSOLE

是否能输出到Console上。Debug/Development/Test该宏为1,Shipping版下该宏为ALLOW_CONSOLE_IN_SHIPPING

ALLOW_DEBUG_FILES

是否允许输出各种调试相关的文件(如:DumpFPSChart、DumpMaterialStats、DumpShaderStats、DumpMemReport等)到磁盘。

Debug/Development/Test该宏为1,Shipping版下该宏为0

WITH_PROFILEGPU

是否允许GPU Profile。Debug/Development该宏为1。

Test需要再额外开启ALLOW_PROFILEGPU_IN_TEST宏,该宏才为1。

Shipping需要再额外开启ALLOW_PROFILEGPU_IN_SHIPPING宏,该宏才为1。

WITH_RPC_REGISTRY

是否允许RPC Registry。Debug/Development/Test该宏为1。

Shipping需要再额外开启USE_RPC_REGISTRY_IN_SHIPPING宏,该宏才为1。

CSV_PROFILER

是否启用CSV Profiler。Debug/Development/Test该宏为1。

Shipping需要再额外开启CSV_PROFILER_ENABLE_IN_SHIPPING宏,该宏才为1。

ENABLE_METAL_GPUEVENTS

是否开启Metal GPU Event。Debug/Development该宏为1,Shipping该宏为0。

Test需要再额外开启ENABLE_METAL_GPUEVENTS_IN_TEST宏,该宏才为1。

ENABLE_METAL_GPUPROFILE

宏ENABLE_METAL_GPUEVENTS开启时,该宏也会对应开启。

USE_CHECKS_IN_SHIPPING

是否在Shipping中使用check。缺省为0

USE_ENSURES_IN_SHIPPING 是否在Shipping中使用ensure。缺省为0
PRESERVE_LOG_BACKUPS_IN_SHIPPING 是否在Shipping中启用log备份(注:Debug/Development/Test会一直启用log备份)。缺省为1
USE_NETWORK_PROFILER 是否允许网络Profiler。Debug/Development该宏为1,Test/Shipping版下该宏为0
FORCE_USE_STATS 强制开启STATS宏。缺省为0。在编译shipping时,可将该宏设为1,让shipping包拥有STATS能力。
ENABLE_STATNAMEDEVENTS 使用系统的埋点
ENABLE_STATNAMEDEVENTS_UOBJECT 为UObject对象使用系统的埋点
ENABLE_RHI_VALIDATION 启用RHI有效性检查。Debug/Development该宏为1,Test/Shipping版下该宏为0
DISABLE_CHEAT_CVARS

是否禁用Cheat变量。注:开启Cheat变量,可方便开发者对功能进行快速测试。

Debug/Development该宏为0,Shipping该宏为1。

Test该宏缺省为0,开启ALLOW_CHEAT_CVARS_IN_TEST宏,该宏才为0。

USE_HANG_DETECTION

启用时,会使用FThreadHeartBeat线程进行挂起检测。

Android/IOS平台不支持检测,具体详见:AllowThreadHeartBeat()函数

USE_HITCH_DETECTION 卡顿检测
AGGRESSIVE_MEMORY_SAVING 是否开启激进内存节省。缺省为0
PSO_TRACK_CACHE_STATS 开启pso追踪统计
GET_DEVICE_ID_UNAVAILABLE

是否允许获取Device ID(该宏为1,会始终返回一个空的Device ID字符串)。缺省为0

WITH_PHYSX

为1,表示使用PhysX引擎

PHYSICS_INTERFACE_PHYSX

为1,表示使用PhysX引擎

WITH_IMMEDIATE_PHYSX

是否启用Immediate PhysX。缺省该宏为0

WITH_APEX

为1,表示使用Apex框架

WITH_APEX_CLOTHING

为1,表示使用Apex Clothing

WITH_CLOTH_COLLISION_DETECTION

为1,表示使用布料碰撞检测

WITH_PHYSX_COOKING

为1,表示使用PhysX Cooking。注:即使在运行时,Apex也需要PhysX Cooking

WITH_NVCLOTH

为1,表示使用NvCloth库

WITH_CHAOS

为1,表示使用Chaos引擎

WITH_CHAOS_CLOTHING

为1,表示使用Chaos Clothing

UE_ENABLE_ICU

为1,表示使用ICU(International Components for Unicode)库。

ICU库提供了处理Unicode字符、字符串和文本的功能,包括字符集转换、字符串比较、正则表达式、日期和时间格式化等

为0,表示使用操作系统提供的Unicode支持。

这可能会导致一些Unicode相关的问题,例如无法正确处理某些字符集、无法正确比较字符串等。

 

预编译相关的宏

说明
DISABLE_DEPRECATION 不打印如下信息:The DEPRECATED macro has been deprecated in favor of UE_DEPRECATED().
PRAGMA_POP #pragma warning (pop)
EMIT_CUSTOM_WARNING_AT_LINE 在某行打印一句警告

PRAGMA_DISABLE_DEPRECATION_WARNINGS

PRAGMA_ENABLE_DEPRECATION_WARNINGS

禁止c/c++ deprecation警告

PRAGMA_DISABLE_SHADOW_VARIABLE_WARNINGS

PRAGMA_ENABLE_SHADOW_VARIABLE_WARNINGS

禁止影子变量警告

PRAGMA_DISABLE_UNSAFE_TYPECAST_WARNINGS

PRAGMA_ENABLE_UNSAFE_TYPECAST_WARNINGS

禁止不安全类型转换警告

PRAGMA_DISABLE_UNDEFINED_IDENTIFIER_WARNINGS

PRAGMA_ENABLE_UNDEFINED_IDENTIFIER_WARNINGS

禁止未定义宏警告

PRAGMA_DISABLE_MISSING_VIRTUAL_DESTRUCTOR_WARNINGS

PRAGMA_ENABLE_MISSING_VIRTUAL_DESTRUCTOR_WARNINGS

禁止非虚析构函数警告

PRAGMA_DISABLE_REORDER_WARNINGS

PRAGMA_ENABLE_REORDER_WARNINGS

禁止成员变量按声明顺序依次初始化警告

PRAGMA_DISABLE_REGISTER_WARNINGS

PRAGMA_ENABLE_REGISTER_WARNINGS

禁止使用register存储类关键字警告

注:C++ 语言中已弃用或删除 auto 和 register 存储类关键字

PRAGMA_PUSH_PLATFORM_DEFAULT_PACKING

PRAGMA_POP_PLATFORM_DEFAULT_PACKING

恢复系统平台默认对齐字节数

THIRD_PARTY_INCLUDES_START

THIRD_PARTY_INCLUDES_END

包含第三方头文件

注:会disable很多warning

不同平台下,该宏的实现详见如下文件

UnrealEngine\Engine\Source\Runtime\Core\Public\Android\AndroidPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\Apple\ApplePlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\Clang\ClangPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\GenericPlatform\GenericPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\HoloLens\HoloLensPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\IOS\IOSPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\Linux\LinuxPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\Lumin\LuminPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\Mac\MacPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\Unix\UnixPlatformCompilerPreSetup.h
UnrealEngine\Engine\Source\Runtime\Core\Public\Windows\WindowsPlatformCompilerPreSetup.h

 

编译用命令行文件

TargetCode.response内容如下:

/D_CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1
/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1
/D_WINDLL
/D_DISABLE_EXTENDED_ALIGNED_STORAGE

。。。 。。。

/DUE_BUILD_DEBUG=1
/DWITH_EDITOR=1
/DWITH_ENGINE=1
/DWITH_UNREAL_DEVELOPER_TOOLS=0
/DWITH_PLUGIN_SUPPORT=0
/DUE_BUILD_MINIMAL=0
/DIS_MONOLITHIC=0
/DIS_PROGRAM=0
/DPLATFORM_WINDOWS=1
/DOVERRIDE_PLATFORM_HEADER_NAME=Windows

/source-charset:utf-8
/execution-charset:utf-8
/I .
/I D:\svn\ThirdParty

/I ... ... 
/I D:\svn\TPSProject\Private

/EP
"D:\svn\TPSProject\Private\TargetCode.cpp"

 

x64 Native Tools Command Prompt for VS2019

cd /d %EngineDir%\Engine\Source

cl.exe @"G:\TargetCode.response" > "G:\TargetCode.i.cpp"

 

#include头文件

包括外部模块的头文件时,只用写Public、Classes文件夹之后的相对目录。

包含内部模块的头文件时,除了写Public、Classes文件夹之后的相对目录,还可以只用写Private文件夹之后的相对目录。

具体逻辑详见:UnrealEngine\Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildModuleCPP.cs的AddDefaultIncludePaths函数

private void AddDefaultIncludePaths()
{
    // Add the module's parent directory to the public include paths, so other modules may include headers from it explicitly.
    foreach (DirectoryReference ModuleDir in ModuleDirectories)
    {
        PublicIncludePaths.Add(ModuleDir.ParentDirectory);

        // Add the base directory to the legacy include paths.
        LegacyPublicIncludePaths.Add(ModuleDir);

        // Add the 'classes' directory, if it exists
        DirectoryReference ClassesDirectory = DirectoryReference.Combine(ModuleDir, "Classes");
        if (DirectoryLookupCache.DirectoryExists(ClassesDirectory))
        {
            PublicIncludePaths.Add(ClassesDirectory);
        }

        // Add all the public directories
        DirectoryReference PublicDirectory = DirectoryReference.Combine(ModuleDir, "Public");
        if (DirectoryLookupCache.DirectoryExists(PublicDirectory))
        {
            PublicIncludePaths.Add(PublicDirectory);

            ReadOnlyHashSet<string> ExcludeNames = UEBuildPlatform.GetBuildPlatform(Rules.Target.Platform).GetExcludedFolderNames();
            EnumerateLegacyIncludePaths(DirectoryItem.GetItemByDirectoryReference(PublicDirectory), ExcludeNames, LegacyPublicIncludePaths);
        }

        // Add the base private directory for this module
        DirectoryReference PrivateDirectory = DirectoryReference.Combine(ModuleDir, "Private");
        if (DirectoryLookupCache.DirectoryExists(PrivateDirectory))
        {
            PrivateIncludePaths.Add(PrivateDirectory);
        }
    }
}

如:UnrealEngine\Engine\Source\Runtime\Engine\Public\SceneManagement.h  写成

#include "SceneManagement.h"

如:UnrealEngine\Engine\Source\Runtime\Engine\Classes\GameFramework\Actor.h  写成

#include "GameFramework/Actor.h"

 

如果只想用GEngine,只需要#include "Engine/Engine.h"就行,不要用#include "Engine.h"(#include "Engine.h"里面加了一大堆其他头文件,非常容易与windows sdk发生冲突,导致一些奇怪的编译错误)

UnrealEngine\Engine\Source\Runtime\Engine\Classes\Engine\Engine.h  // #include "Engine.h"

UnrealEngine\Engine\Source\Runtime\Engine\Public\Engine.h  // #include "Engine/Engine.h"

 

跨平台目录说明

注1:Lumin是Magic Leap公司基于Linux和Android开发的穿戴式设备操作系统,目前已用在自家产品Magic Leap One AR头盔中

注2:HoloLens是Microsoft公司基于win10开发的混合现实的穿戴式设备操作系统,目前已用在自家产品HoloLens AR头盔中

注3:GenericPlatform提供公共基类,Windows、Linux、Unix、Mac、Apple、HoloLens、Lumin、Android、IOS从GenericPlatform上派生来实现各平台的功能

注4:通过HAL来对外提供统一的接口。其他模块仅需要include HAL目录下的头文件即可

 

posted on 2024-05-25 16:53  可可西  阅读(220)  评论(0编辑  收藏  举报

导航