Building a modular executable instead of a monolithic one

Hello, I tried to build a modular .exe so that instead of building a single exe with a big size, it is divided into multiple DLLs and a final .exe.
I set inside my Target.cs file:
LinkType = TargetLinkType.Modular;
BuildEnvironment = TargetBuildEnvironment.Unique;

but I’m getting some linker errors:

|Severity|Code|Description|Project|File|Line|Suppression State|
|---|---|---|---|---|---|---|
|Error|LNK2019|unresolved external symbol __declspec(dllimport) public: __cdecl UDeveloperSettings::UDeveloperSettings(class FObjectInitializer const &) (__imp_??0UDeveloperSettings@@QEAA@AEBVFObjectInitializer@@@Z) referenced in function public: __cdecl UGameplayTagsDeveloperSettings::UGameplayTagsDeveloperSettings(class FObjectInitializer const &) (??0UGameplayTagsDeveloperSettings@@QEAA@AEBVFObjectInitializer@@@Z)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.cpp.obj|1||
|Error|LNK2019|unresolved external symbol __declspec(dllimport) public: virtual __cdecl UDeveloperSettings::~UDeveloperSettings(void) (__imp_??1UDeveloperSettings@@UEAA@XZ) referenced in function int `public: __cdecl UGameplayTagsDeveloperSettings::UGameplayTagsDeveloperSettings(class FObjectInitializer const &)'::`1'::dtor$0 (?dtor$0@?0???0UGameplayTagsDeveloperSettings@@QEAA@AEBVFObjectInitializer@@@Z@4HA)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.cpp.obj|1||
|Error|LNK2001|unresolved external symbol __declspec(dllimport) public: virtual __cdecl UDeveloperSettings::~UDeveloperSettings(void) (__imp_??1UDeveloperSettings@@UEAA@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual __cdecl UDeveloperSettings::~UDeveloperSettings(void) (??1UDeveloperSettings@@UEAA@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual __cdecl UDeveloperSettings::~UDeveloperSettings(void) (??1UDeveloperSettings@@UEAA@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual class FName __cdecl UDeveloperSettings::GetContainerName(void)const  (?GetContainerName@UDeveloperSettings@@UEBA?AVFName@@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual class FName __cdecl UDeveloperSettings::GetContainerName(void)const  (?GetContainerName@UDeveloperSettings@@UEBA?AVFName@@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual class TSharedPtr<class SWidget,0> __cdecl UDeveloperSettings::GetCustomSettingsWidget(void)const  (?GetCustomSettingsWidget@UDeveloperSettings@@UEBA?AV?$TSharedPtr@VSWidget@@$0A@@@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual class TSharedPtr<class SWidget,0> __cdecl UDeveloperSettings::GetCustomSettingsWidget(void)const  (?GetCustomSettingsWidget@UDeveloperSettings@@UEBA?AV?$TSharedPtr@VSWidget@@$0A@@@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual class FName __cdecl UDeveloperSettings::GetSectionName(void)const  (?GetSectionName@UDeveloperSettings@@UEBA?AVFName@@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: virtual class FName __cdecl UDeveloperSettings::GetSectionName(void)const  (?GetSectionName@UDeveloperSettings@@UEBA?AVFName@@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK2019|unresolved external symbol __declspec(dllimport) public: static class UClass * __cdecl UDeveloperSettings::StaticClass(void) (__imp_?StaticClass@UDeveloperSettings@@SAPEAVUClass@@XZ) referenced in function private: static class UClass * __cdecl UGameplayTagsDeveloperSettings::GetPrivateStaticClass(void) (?GetPrivateStaticClass@UGameplayTagsDeveloperSettings@@CAPEAVUClass@@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK2019|unresolved external symbol __declspec(dllimport) public: __cdecl UDeveloperSettings::UDeveloperSettings(class FVTableHelper &) (__imp_??0UDeveloperSettings@@QEAA@AEAVFVTableHelper@@@Z) referenced in function public: __cdecl UGameplayTagsDeveloperSettings::UGameplayTagsDeveloperSettings(class FVTableHelper &) (??0UGameplayTagsDeveloperSettings@@QEAA@AEAVFVTableHelper@@@Z)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK2019|unresolved external symbol __declspec(dllimport) class UClass * __cdecl Z_Construct_UClass_UDeveloperSettings(void) (__imp_?Z_Construct_UClass_UDeveloperSettings@@YAPEAVUClass@@XZ) referenced in function void __cdecl `dynamic initializer for 'public: static class UObject * (__cdecl*const * const Z_Construct_UClass_UGameplayTagsDeveloperSettings_Statics::DependentSingletons)(void)''(void) (??__E?DependentSingletons@Z_Construct_UClass_UGameplayTagsDeveloperSettings_Statics@@2QBQ6APEAVUObject@@XZB@@YAXXZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.GameplayTags.gen.cpp.obj|1||
|Error|LNK1120|9 unresolved externals|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Binaries\Win64\UltimateArena-GameplayTags.dll|1||
|Error|LNK2019|unresolved external symbol __declspec(dllimport) public: __cdecl FUntypedBulkData2<struct FQuantizedDirectionalLightSample>::~FUntypedBulkData2<struct FQuantizedDirectionalLightSample>(void) (__imp_??1?$FUntypedBulkData2@UFQuantizedDirectionalLightSample@@@@QEAA@XZ) referenced in function public: virtual void __cdecl FLegacyLightMap1D::Serialize(class FArchive &) (?Serialize@FLegacyLightMap1D@@UEAAXAEAVFArchive@@@Z)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.Engine.23_of_49.cpp.obj|1||
|Error|LNK2019|unresolved external symbol __declspec(dllimport) public: __cdecl FUntypedBulkData2<struct FQuantizedSimpleLightSample>::~FUntypedBulkData2<struct FQuantizedSimpleLightSample>(void) (__imp_??1?$FUntypedBulkData2@UFQuantizedSimpleLightSample@@@@QEAA@XZ) referenced in function public: virtual void __cdecl FLegacyLightMap1D::Serialize(class FArchive &) (?Serialize@FLegacyLightMap1D@@UEAAXAEAVFArchive@@@Z)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.Engine.23_of_49.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: __cdecl FUntypedBulkData2<struct FQuantizedDirectionalLightSample>::~FUntypedBulkData2<struct FQuantizedDirectionalLightSample>(void) (??1?$FUntypedBulkData2@UFQuantizedDirectionalLightSample@@@@QEAA@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.Engine.23_of_49.cpp.obj|1||
|Error|LNK2001|unresolved external symbol public: __cdecl FUntypedBulkData2<struct FQuantizedSimpleLightSample>::~FUntypedBulkData2<struct FQuantizedSimpleLightSample>(void) (??1?$FUntypedBulkData2@UFQuantizedSimpleLightSample@@@@QEAA@XZ)|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Intermediate\ProjectFiles\Module.Engine.23_of_49.cpp.obj|1||
|Error|LNK1120|4 unresolved externals|UltimateArena|G:\Perforce\UltimateArena\dev-maps\Binaries\Win64\UltimateArena-Engine.dll|1||
|Error|MSB3073|The command G:\GitHub\UnrealEngine\Engine\Build\BatchFiles\Build.bat UltimateArena Win64 Development -Project=G:\Perforce\UltimateArena\dev-maps\UltimateArena.uproject -WaitMutex -FromMsBuild exited with code 6.|UltimateArena|C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.MakeFile.Targets|46||

this seems the only obstacle to my purpose.
Thanks in advance!

Hi. I had same issue. I have noted this problem in the UE4.26 when build a project with LinkType = TargetLinkType.Modular. I fixed it by comment line

if (Target.Type == TargetType.Editor)

in the Engine\Source\Runtime\GameplayTags\GameplayTags.Build.cs:
namespace UnrealBuildTool.Rules
{
	public class GameplayTags : ModuleRules
	{
		public GameplayTags(ReadOnlyTargetRules Target) : base(Target)
		{
			PrivateIncludePaths.AddRange(
				new string[] {
					"Runtime/GameplayTags/Private",
				}
				);

			PublicDependencyModuleNames.AddRange(
				new string[]
				{
					"Core",
					"CoreUObject",
					"Engine"
				}
				);

            //if (Target.Type == TargetType.Editor)
            {
                PrivateDependencyModuleNames.AddRange(
                new string[]
                {
                    "SlateCore",
                    "Slate",
					"DeveloperSettings"
				}
                );
            }
        }
	}
}

end recompile UE4 from source code

1 Like

Thank you! Honestly I didn’t think that someone would have answered my question, and after many tries to find out the cause of the problem, I surrended and used monolithic executables. Your solutions worked perfectly, but I still got the BulkData2 link errors, and I solved them editing BulkData.h and changing

#if WITH_EDITOR == 0 && WITH_EDITORONLY_DATA == 0 //Runtime
	#define USE_NEW_BULKDATA 1 // Set to 1 to enable 
#else
	#define USE_NEW_BULKDATA 0
#endif

to

#if WITH_EDITOR == 0 && WITH_EDITORONLY_DATA == 0 //Runtime
	#define USE_NEW_BULKDATA 0 // Set to 1 to enable 
#else
	#define USE_NEW_BULKDATA 0
#endif

after that everything compiled successfully, but I had some issues when packaging, due to Lumin plugins activated by default, so I disabled MLSDK and MagicLeap plugins inside my uproject file, and everything went well!
Thank you again for the help, I really appreciate it! :grinning: