Linker error when trying to use FGameplayTagContainer

Hiya, I’m getting the below linker error when I try to use FGameplayTagContainer. I’ve created a new project in 4.21, created two gameplay tags in project settings > GameplayTags and created a new .cpp Actor class. This is my header file and I haven’t made any changes to the .cpp file. Exactly the same thing happens in 4.20 with a fresh project and in my existing 4.20 project. Can anyone else reproduce this or have I just messed up my UE4 installation somehow?:

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GameplayTagContainer.h"
#include "MyActor.generated.h"

UCLASS()
class TAGTEST_API AMyActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMyActor();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	UPROPERTY()
	FGameplayTagContainer MyContainer;

};

MyActor.cpp.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: __cdecl FGameplayTagContainer::FGameplayTagContainer(void)” (_imp??0FGameplayTagContainer@@QEAA@XZ) referenced in function “public: __cdecl AMyActor::AMyActor(void)” (??0AMyActor@@QEAA@XZ)
MyActor.gen.cpp.obj : error LNK2001: unresolved external symbol “__declspec(dllimport) public: __cdecl FGameplayTagContainer::FGameplayTagContainer(void)” (_imp??0FGameplayTagContainer@@QEAA@XZ)
MyActor.cpp.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) public: __cdecl FGameplayTagContainer::~FGameplayTagContainer(void)” (_imp??1FGameplayTagContainer@@QEAA@XZ) referenced in function “public: virtual __cdecl AMyActor::~AMyActor(void)” (??1AMyActor@@UEAA@XZ)
MyActor.gen.cpp.obj : error LNK2001: unresolved external symbol “__declspec(dllimport) public: __cdecl FGameplayTagContainer::~FGameplayTagContainer(void)” (_imp??1FGameplayTagContainer@@QEAA@XZ)
MyActor.gen.cpp.obj : error LNK2019: unresolved external symbol “__declspec(dllimport) class UScriptStruct * __cdecl Z_Construct_UScriptStruct_FGameplayTagContainer(void)” (_imp?Z_Construct_UScriptStruct_FGameplayTagContainer@@YAPEAVUScriptStruct@@anonymous_user_9674a66c) referenced in function “void __cdecl `dynamic initializer for ‘public: static struct UE4CodeGen_Private::FStructPropertyParams const Z_Construct_UClass_AMyActor_Statics::NewProp_MyContainer’’(void)” (??__E?NewProp_MyContainer@Z_Construct_UClass_AMyActor_Statics@@2UFStructPropertyParams@UE4CodeGen_Private@@anonymous_user_31e84eb0@@YAXXZ)
C:\Users\riche\Documents\TagTest\Binaries\Win64\UE4Editor-TagTest-1661.dll : fatal error LNK1120: 3 unresolved externals
UnrealBuildTool : error : UBT ERROR: Failed to produce item: C:\Users\riche\Documents\TagTest\Binaries\Win64\UE4Editor-TagTest-1661.dll
(see …/Programs/UnrealBuildTool/Log.txt for full exception trace)

2 Likes

You most likely forgot to add module dependency to your module.

UE4 is modular, and what you really doing by making C++ project (or even a plugin) is adding module to the existing once in engine. The functions you calling in your code (except once that are outside UE4 APIs) exist in other modules and in order for UBT to properly link them it needs information on which modules you using, as well information for engine which modules to load first when your module is load. So when you use function or type in specific module you need to add dependency to your module build script (*.build.cs file).

First to check which module to add you need to look in to API reference of type or function you use:

You can see on bottom module and header file in which type is declered, in this case module name is “GameplayTags”. You can also check module name by looking on header file path, it usually 2nd directory name after “Source”:

Runtime/GameplayTags/Classes/GameplayTagContainer.h

So open *.build.cs file in your module source files and search for this line:

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

And add module to that array by adding comma and module name in quatation marks after last dependent module declared

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

Yay! Thankyou. I hadn’t clocked it was a separate module. I’ll know to keep an eye out for that in future :slight_smile:

Thank you!