debug ue4 completely

The default "Debug Editor" mode will produce a beast of UE4Editor that we can't debug it thoroughly, for vs2022 needs over 10G memory to load relative pdbs and retrieve debug information, eventually our computer is over burden, and vs2022 corrupts, so we never so much as trigger a debug point.

After several mends, vs2022 IDE still corrupts at beginning of debugging, so we have to seek help from WinDbg or QtCreator.

There are two main causes why UE4Editor is so big:

  • The original build tool action is 'Modular' which generates many dlls and every dll contains a portion of the same low level library code. So we change the action to 'Monolithic':

    ue\Engine\Source\Programs\UnrealBuildTool\Configuration\TargetRules.cs

    ...
    		public TargetLinkType LinkType
    		{
    			get
    			{
    //				return (LinkTypePrivate != TargetLinkType.Default) ? LinkTypePrivate : ((Type == global::UnrealBuildTool.TargetType.Editor) ? TargetLinkType.Modular : TargetLinkType.Monolithic);
    				return (LinkTypePrivate != TargetLinkType.Default) ? LinkTypePrivate : ((Type == global::UnrealBuildTool.TargetType.Editor) ? TargetLinkType.Monolithic : TargetLinkType.Monolithic);
    			}
    			set
    			{
    				LinkTypePrivate = value;
    			}
    		}
    ...
    

    But I have tried building in monolithic mode, it's a suicide, literately, there are many duplicated symbols generated which fail the building. We have to return to modular mode.

  • Every call on logging macro carves '__FILE__' or '__FUNCTION__' in the binary which will also inflate the executable. So we change these macros to nonsense:

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

    ...
    #define EUHAT_MINIMIZE 1
    
    #if UE_BUILD_DEBUG
    #if EUHAT_MINIMIZE
    	#ifndef DO_GUARD_SLOW
    		#define DO_GUARD_SLOW			0
    	#endif
    	#ifndef DO_CHECK
    		#define DO_CHECK			0
    	#endif
    	#ifndef DO_ENSURE
    		#define DO_ENSURE			0
    	#endif
    	#ifndef STATS
    		#define STATS				((WITH_UNREAL_DEVELOPER_TOOLS || !WITH_EDITORONLY_DATA || USE_STATS_WITHOUT_ENGINE || USE_MALLOC_PROFILER || FORCE_USE_STATS) && !ENABLE_STATNAMEDEVENTS)
    	#endif
    	#ifndef ALLOW_DEBUG_FILES
    		#define ALLOW_DEBUG_FILES		1
    	#endif
    	#ifndef ALLOW_CONSOLE
    		#define ALLOW_CONSOLE			0
    	#endif
    	#ifndef NO_LOGGING
    		#define NO_LOGGING			0
    	#endif
    #else
    	#ifndef DO_GUARD_SLOW
    ...
    

    We should notice NO_LOGGING is false, I attempted to set it true, but a lot of errors occured.

    At the end of ueDbg\Engine\Source\Runtime\Core\Public\Logging\LogMacros.h

    ...
    #if EUHAT_MINIMIZE
    	#undef UE_LOG
    	#undef UE_LOG_CLINKAGE
    	#undef UE_CLOG
    	#undef UE_SUPPRESS
    	#undef UE_SECURITY_LOG
    
    	#define UE_LOG(CategoryName, Verbosity, Format, ...) 
    	#define UE_LOG_CLINKAGE(CategoryName, Verbosity, Format, ...) 
    	#define UE_CLOG(Condition, CategoryName, Verbosity, Format, ...) 
    	#define UE_SUPPRESS(...) {}
    	#define UE_SECURITY_LOG(...)
    #endif
    

And if we wanna debug inline functions, modify this place:

ue\Engine\Saved\UnrealBuildTool\BuildConfiguration.xml

<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
	<BuildConfiguration>
		<bAllowXGE>true</bAllowXGE>
		<bUseInlining>0</bUseInlining>
	</BuildConfiguration>
</Configuration>

'bAllowXGE' means to turn on IncreBuild, while the prerequisite is we have very big memory.

There are still some nasty things to do:

  1. Invoking empty macro is considered as a warning 4390, existing unused variables is considered as warning 4101, they will cease ue4 compilation.

    ue\Engine\Source\Runtime\Core\Public\Windows\WindowsPlatformCompilerSetup.h

    #pragma warning (error: 4100      4102 4103                          4109           4112 4113 4114 4115 4116 4117      4119 4120 4121 4122 4123 4124 4125      4127      4129 4130 4131 4132 4133                4137 4138           4141 4142 4143 4144 4145 4146                4150      4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164      4166 4167 4168                4172      4174 4175 4176 4177 4178 4179 4180 4181 4182 4183      4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197      4199)
    
    #pragma warning (error:      4301 4302 4303           4306      4308 4309 4310           4313 4314 4315 4316      4318 4319      4321 4322 4323 4324 4325 4326 4327 4328 4329 4330           4333 4334 4335 4336 4337 4338      4340           4343 4344      4346      4348                4352 4353      4355 4356 4357 4358 4359           4362      4364      4366 4367 4368 4369                     4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384           4387      4389      4391 4392 4393 4394 4395 4396 4397 4398 4399)
    

    ue\Engine\Source\Programs\UnrealBuildTool\Platform\Windows\VCToolChain.cs

    ...
    			// Set warning level.
    			if (Target.WindowsPlatform.Compiler != WindowsCompiler.Intel)
    			{
    				// Restrictive during regular compilation.
    				// Euhat Modified
    				//Arguments.Add("/W4");
    				Arguments.Add("/wd4101");
    				Arguments.Add("/W0");
    			}
    ...
    			// Prevents the linker from displaying its logo for each invocation.
    			Arguments.Add("/NOLOGO");
    			// Euhat modified
    			Arguments.Add("/FORCE:MULTIPLE");
    ...
    

    'FORCE:MULTIPLE' means just to pick the first one of the same name symbols instead of complaining as a link error.

  2. ue\Engine\Plugins\Slate\SlateInsights\Source\SlateInsights\Private\SlateInsightsModule.cpp

    //IMPLEMENT_MODULE((UE::SlateInsights::FSlateInsightsModule), SlateInsights);
    
  3. ue\Engine\Source\Runtime\AudioMixer\Public\AudioMixerDevice.h

    		// make it public
    		FAudioPlatformDeviceInfo PlatformInfo;
    

    ue\Engine\Plugins\Media\BinkMedia\Source\BinkMediaPlayer\Private\BinkMediaPlayerPCH.h

    ...
    			//return mix->GetNumDeviceChannels();
    			return mix->PlatformInfo.NumChannels;
    ...
    //DECLARE_LOG_CATEGORY_EXTERN(LogBink, Log, All);
    ...
    

    ue\Engine\Plugins\Media\BinkMedia\Source\BinkMediaPlayer\Private\BinkMediaPlayerModule.cpp

    //DEFINE_LOG_CATEGORY(LogBink);
    
  4. ue\Engine\Plugins\Runtime\AR\Microsoft\HoloLensAR\Source\HoloLensTargetPlatform\HoloLensTargetPlatform.Build.cs

    bEnableUndefinedIdentifierWarnings = false;
    

The last thing kept in mind is don't build the whole resolution, for simultaneous compilations of projects can easily run out of memory. Just right click Engine/EU4 and build UE4Editor only.

ps: We use UnrealEngine-4.27.2-release.zip in this article.

build qt source in vs2022 win11

Don't download qt source in tar.xz format, for in Windows, if we unzip it using 7zip, some deep file paths may be truncated, for example, ECMFindModuleHelpersStub.cmake referred by FindEGL.cmake in qtbase\cmake\3rdparty\extra-cmake-modules\find-modules.

This time I download qt-everywhere-src-6.2.2.zip.

In preparation, as to README.md, ActivePerl must be installed, it sucks, we must have an account of it. However, we can find another perl alternative, Strawberry Perl portable edition.

When we build, qt source root path should be short enough like d:\qt.

bld.bat

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
set curpath=%CD%
set vspath=D:\cext\Program Files\Microsoft Visual Studio\2022\Enterprise
set perlpath=D:\work\open\strawberry-perl-5.32.1.1\perl\bin
set clangpath=D:\work\open\libclang
set installpath=D:\cext\Qt
 
call "%vspath%\VC\Auxiliary\Build\vcvars64.bat"
 
set oldpath=%path%
set path=%path%;%perlpath%
 
if not exist %curpath%\bld @mkdir %curpath%\bld
 
cd %curpath%\bld
 
cmake.exe ^
	-G "Ninja" ^
	-DCMAKE_INSTALL_PREFIX:PATH=%curpath%\bld ^
	-DCMAKE_BUILD_TYPE="Debug" ^
	-DFEATURE_clang="ON" ^
	-DCMAKE_PREFIX_PATH="%clangpath%" ^
	-DCMAKE_MAKE_PROGRAM="%vspath%\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\Ninja\ninja.exe" ..
 
cmake --build . --parallel
rem cmake --install . --prefix %installpath%
 
if 0 == 1 (
	rem if we build QtDoc, we must add clang path to system path, otherwise we will get exit code 0xc0000135.
	set path=%path%;%clangpath%\bin
	cmake --build . --target docs
)
 
set path=%oldpath%
cd ..

Modify paths at the beginning of above bld.bat and put the batch file in the qt source root directory, then execute it.

ps1: all in one release of qt is like below url, but we should know all in one is not available since Qt 5.15.
http://download.qt.io/archive/qt/5.9/5.9.2/qt-opensource-linux-x64-5.9.2.run
And we need download online installer for Qt above 5.15 if we don't want to build from scratch:
https://download.qt.io/official_releases/online_installers/

Refer to:
https://ninja-build.org/
https://strawberryperl.com/releases.html
https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-windows-x86_64.msi

https://download.qt.io/development_releases/prebuilt/libclang/
https://download.qt.io/archive/qt/6.2/6.2.2/single/qt-everywhere-src-6.2.2.zip
https://download.qt.io/official_releases/qtcreator/6.0/6.0.1/qt-creator-opensource-windows-x86_64-6.0.1.exe

https://stackoverflow.com/questions/14807294/how-to-install-cmake-c-compiler-and-cxx-compiler
https://www.cnblogs.com/gearslogy/p/7435202.html

custom widget in qt

TstUsrCtrl.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
 
#include <qwidget>
 
class TstUsrCtrl : public QWidget
{
	Q_OBJECT
 
	QPoint oldPos_;
	QPoint curPos_;
 
public:
	explicit TstUsrCtrl(QWidget *parent = nullptr);
	~TstUsrCtrl();
 
	void paintEvent(QPaintEvent* event);
	void mousePressEvent(QMouseEvent* event);
	void mouseMoveEvent(QMouseEvent* event);
	void mouseReleaseEvent(QMouseEvent* event);
	void mouseToPosition(QMouseEvent* event);
};
</qwidget>

Read more

Artists memo

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
		Medici
		乔托_迪_邦多纳
1452-1519	Leonardo da Vinci 达芬奇
			萨莱
1483-1520	Raffaello Sanzio da Urbino 拉斐尔
			披纱巾的少女
1475-1564	Michelangelo Buonarroti 米开朗基罗
		米开朗基罗_梅里西_达_卡拉瓦乔
			老千
			召唤使徒马太
		Benvenuto Cellini 切利尼
			珀尔修斯
		乔凡尼_洛伦佐_贝尼尼
			普鲁托和普洛塞尔皮娜
		提香_韦切利奥
 
1599-1660	Velasquez 委拉斯凯兹
			宫娥
1746-1828	弗朗西斯_戈雅/1808年拿破仑攻破西班牙
			查理四世一家
			The Execution of the Defenders of Madrid 1808
1881-1973	Pablo Picasso 毕加索
			格尔尼卡
 
		汉斯_荷尔拜因/英王亨利八世
1815-1905	阿道夫_冯_门采尔
			素描比照片有神
1836-1893	John Atkinson Grimshaw 格里姆肖
			The Sere and Yellow Leaf
 
		普桑
			The Abduction of the Sabine Women
		鲁本斯
			The Elevation of the Cross
		弗朗索瓦_布歇
		让_奥诺雷_弗拉戈纳尔
			The Happy Accidents of the Swing
		安格尔
			泉
		欧仁_德拉克罗瓦
			自由引导人民
		雅克_路易_大卫/neoclassic
			马拉之死
			加冕礼
 
1864-1943	卡密儿_克劳岱尔
		奥古斯特_罗丹
			思想者
		梵高
			星空
		高更
			我们从哪里来?我们是谁?我们到哪里去?
		让_弗朗索瓦_米勒/巴比松村
			The Cleaners 拾穗者
			晚祷
		享利_德_图克兹_劳特雷克
			红墨坊
		苏珊娜_瓦拉东
		雷诺阿
		卡米耶_毕沙罗
		爱德华_霍普
		乔治_修拉
			大碗岛的星期天下午
		爱德华_马奈
			草地上的午餐
		埃贡_席勒
		埃德加_德加
			芭蕾
		奥斯卡_克劳德_莫奈
			日出印象
			撑伞的女人
			睡莲
		保罗_塞尚
			苹果
 
		玛丽_路易斯_伊丽莎白_维瑞_勒布伦/玛丽皇后
		阿尔布雷特_丢勒
			selfie
 
1632-1675	Johannes Vermeer 维米尔/运用小孔成像作画
			Girl with a Pearl Earring 戴珍珠耳环的少女
		伦勃朗_梵_莱茵
			夜巡
		Jan Frederik Pieter Portielje 波蒂列耶
 
		巴尔蒂斯
		劳伦斯_阿尔玛_塔德玛
		奥蒂诺_雷东
 
		哈德逊河画派
			艾伯特 比尔兹塔德
		特伦特_古德姆森

refer to:
艺术八封说(美上美学)
https://www.mei-shu.com/famous/26944/artistic-171655.html

hollywood memo

1
2
3
4
5
6
7
8
9
1924-2004	Marlon Brando 马龙_白兰度/码头风云/教父/巴黎最后的探戈
1940-		Al Pacino 阿尔_帕西诺
1963-		Johnny Depp 约翰尼_德普
1972-		Jude Law 裘德_洛
1901-1960	Clark Gable 克拉克_盖博
1957-		Daniel Day Lewis 丹尼尔_戴_刘易斯
1937-		Anthony Hopkins 安东尼_霍普金斯
1956-		Tom Hanks 汤姆_汉克斯
1974-		Leonardo DiCaprio 莱昂纳多_迪卡普里奥

refer to:
小游说影星

Guitar memo

1
2
3
4
5
6
7
8
9
10
大三度:C F G
纯四度:除F
纯五度:除B
大六度:C D F G
大七度:C F
 
6	--4->		5
6	<-2--		4
6	-b3->		3
6	--5->		2

1
2
3
4
5
6
两音独一线
上线退一品
偶起空一格
 
二五三六四
用田九田曲




refer to:
freedom哈
丹尼尔-大胡子老师
https://www.jitashe.org/tab/1306156/

weird wildcards in format string argument of printf

to output in decimal notation of a char variable, we write like this

1
2
char a1 = 'a';
printf("a1 is [%d].\n", a1);

in the way we output an int variable.

but when we output a long variable, we must write like below reluctantly

1
2
3
#need to test in gcc.
long l1 = 123456789;
printf("l1 is [%ld].\n", l1);

don't say byte alignment.