Unresolved External Symbols

There 3 most common reasons why can have Unresolved External Symbols linker error:

1.You declared non-virtual function (standard function) but you didn’t define code for it

2.The function is in different module and you didn’t add dependency of that module in build script (*.build.cs file)

3.Class you trying to use is declared as MinimalAPI or missing extern (MODULENAME_API macro) and can not be used outside of it’s module (in this case you would need to modify engine and rebuild it, possible for game projects no go for plugins)

Number 2 and 3 are UE4 specific, related to UE4 build system and it’s configuration.

Your case is probably number 2, you probably missing module decency and you need to add module you using in to build script of your module. Start by checking from which module, functions or classes you using belong to, you can easily do this by searching API reference (just google class or function name and add “UE4 API”, it most effective way of searching thru API reference now days). But in this case i did that for you:

Now look below of the page you should have information in which module class is declered and in which header file, so in ourr case it is “NavigationSystem”

go to *.Build.cs file in you module inside oyur project and you will find something like this:

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

Build scripts are written in C# and this line adds decencies to the your module build rules, “Core” module contains most basic functions that you use in C++ inside UE4, “CoreUObject” contains module UObject system, root of class tree in UE4 and “Engine” is core of engine it self. Engine is divided in to more modules (“Engine” module only contains core things), you can see them as dlls in binary folder in the engine and you need to add decency if you referenceing anything from that specific module, this way UnrealBuidTool knows what to build during packaging and properly configures compilation environment for your module, so build is fully optimized.

So all you need to do is just add “NavigationSystem” to that list like this:

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

And in future oyu just add up more to this, depending what you are using, if you remove usage of some module in your module you remove it’s entry here too.

33 Likes

I’ve had this problem for a couple of days now, been trying to fix it for ages, but I couldnt find anything online. Here is the .h file:

#pragma once

#include "CoreMinimal.h"
#include "AIController.h"
#include "Runtime/AIModule/Classes/Navigation/PathFollowingComponent.h"
#include "PacmanGhostController.generated.h"

/**
 * 
 */
UCLASS()
class ARCADEGAMES_API APacmanGhostController : public AAIController
{
	GENERATED_BODY()
	
public:
	
	APacmanGhostController();

	void Possess(class APawn* InPawn) override;

	void OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult & Result);
	
	void SearchNewPoint();
	void GoHome();
	void Rearm();
	void StopMove();

private:
	class APacmanGhost* Bot;
	FVector HomeLocation;
	FTimerHandle TimerDead;
	
};

.cpp:
#include “PacmanGhostController.h”
#include “PacmanGhost.h”
#include “AIController.h”
#include “TimerManager.h”
#include “Runtime/NavigationSystem/Public/AbstractNavData.h”
#include “NavigationSystem.h”

APacmanGhostController::APacmanGhostController() {};

void APacmanGhostController::Possess(class APawn* InPawn)
{
	Super::Possess(InPawn);

	Bot = Cast<APacmanGhost>(InPawn);

	HomeLocation = Bot->GetActorLocation();
	SearchNewPoint();
}


void APacmanGhostController::GoHome()
{
	MoveToLocation(HomeLocation);
	GetWorldTimerManager().SetTimer(TimerDead, this, &APacmanGhostController::Rearm, 5.0f, false);
}

void APacmanGhostController::Rearm()
{

	GetWorldTimerManager().ClearTimer(TimerDead);
	Bot->Rearm();

}

void APacmanGhostController::OnMoveCompleted(FAIRequestID RequestID, const FPathFollowingResult & Result)
{

	if (!Bot->bIsDead) 
	{ 
		SearchNewPoint();
	}

}

void APacmanGhostController::StopMove()
{

	StopMovement();

}

void APacmanGhostController::SearchNewPoint()
{
	UNavigationSystemV1* NavMesh = UNavigationSystemV1::GetCurrent(());
	if (NavMesh)
	{
		const float SearchRadius = 10000.0f;
		FVector RandomPt;
		bool bFound = NavMesh->K2_GetRandomReachablePointInRadius(this, Bot->GetActorLocation(), RandomPt, SearchRadius);
		if (bFound)
		{
			MoveToLocation(RandomPt);
		}
	}
}

Output:

1>------ Build started: Project: ArcadeGames, Configuration: Development_Editor x64 ------
1>Creating makefile for hot reloading ArcadeGamesEditor (modules to compile have changed)
1>Compiling game modules for hot reload
1>Using Visual Studio 2017 14.15.26726 toolchain (C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.15.26726) and Windows 10.0.16299.0 SDK (C:\Program Files (x86)\Windows Kits\10).
1>Building 1 action with 4 processes...
1>  [1/1] UE4Editor-ArcadeGames-1823.dll
1>     Creating library E:\FunStuff\Unreal Engine\4Projects\1C++\ArcadeGames\Intermediate\Build\Win64\UE4Editor\Development\ArcadeGames\UE4Editor-ArcadeGames-1823.suppressed.lib and object E:\FunStuff\Unreal Engine\4Projects\1C++\ArcadeGames\Intermediate\Build\Win64\UE4Editor\Development\ArcadeGames\UE4Editor-ArcadeGames-1823.suppressed.exp
1>PacmanGhostController.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static bool __cdecl UNavigationSystemV1::K2_GetRandomReachablePointInRadius(class UObject *,struct FVector const &,struct FVector &,float,class ANavigationData *,class TSubclassOf)" (__imp_?K2_GetRandomReachablePointInRadius@UNavigationSystemV1@@SA_NPEAVUObject@@AEBUFVector@@AEAU3@MPEAVANavigationData@@anonymous_user_e71e0d8a?$TSubclassOf@VUNavigationQueryFilter@@@@@Z) referenced in function "public: void __cdecl APacmanGhostController::SearchNewPoint(void)" (?SearchNewPoint@APacmanGhostController@@QEAAXXZ)
1>PacmanGhostController.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class UNavigationSystemV1 * __cdecl UNavigationSystemV1::GetCurrent(class UWorld *)" (__imp_?GetCurrent@UNavigationSystemV1@@SAPEAV1@PEAVUWorld@@@Z) referenced in function "public: void __cdecl APacmanGhostController::SearchNewPoint(void)" (?SearchNewPoint@APacmanGhostController@@QEAAXXZ)
1>E:\FunStuff\Unreal Engine\4Projects\1C++\ArcadeGames\Binaries\Win64\UE4Editor-ArcadeGames-1823.dll : fatal error LNK1120: 2 unresolved externals
1>UnrealBuildTool : error : UBT ERROR: Failed to produce item: E:\FunStuff\Unreal Engine\4Projects\1C++\ArcadeGames\Binaries\Win64\UE4Editor-ArcadeGames-1823.dll
1>                        (see ../Programs/UnrealBuildTool/Log.txt for full exception trace)
1>Total build time: 89.64 seconds (Parallel executor: 0.00 seconds)
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.MakeFile.Targets(44,5): error MSB3075: The command ""E:\FunStuff\Unreal Engine\5Engine\UE_4.20\Engine\Build\BatchFiles\Build.bat" ArcadeGamesEditor Win64 Development "E:\FunStuff\Unreal Engine\4Projects\1C++\ArcadeGames\ArcadeGames.uproject" -WaitMutex -FromMsBuild" exited with code 5. Please verify that you have sufficient rights to run this command.
1>Done building project "ArcadeGames.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

P.S. This is my first question, so if I should’ve included something else or left something out please tell me. Also, the reason I put all of the code in is because i’m relatively new to C++, so I’m not sure which part of the code created the error

Thanks for your time!

1 Like

Thank you soooo much! Just wondering, how do I know which problem I have in the future?

1 is obviues as it will mention your function in linker error, InteliSense also will mark that function with green line in header file, if not then it most likely 2, if solution mention don’t work it most likely MinimalAPI, you can confirm it by looking on header file that declares the function you use and if you sse UCLASS(…) with MinimalAPI inside then it is MinimalAPI (note that just removing that in header files is not enough you need to rebuild engine for this to take effect). But you most likely don’t encounter MinimalAPI or else you gonna try to do something deeper in to engine, most actors should not lead to any of such classes, i know rendering system is full of MinimalAPI classes.

Sorry for necro, but this is the first hit in google, so someone could find it useful:
I’m on UE5.0 and extended an inline method in the cpp and forgot to remove FORCEINLINE (removing it fixed the error)

2 Likes

I want to expand a bit on point 3. from the accepted answer.

If you want to inherit from a class that is marked with MinimalAPI that means you have two options:

  1. Modify the engine source code so that all methods are exported for linking. That means you have to prepend the ENGINE_API macro at the start of each method declaration (see example below). You would need to compile the engine in that case.
  2. Provide your own implementation of the methods. You can copy-paste the implementation of the methods from the engine code into your own implementation (which is a bit dirty)

— Example for the second approach —
I had to inherit from UPostProcessComponent which is marked as MinimalAPI. Most of the methods have the ENGINE_API macro at the start of their declaration. When compiling, the linker complained about 3 methods that do not have the ENGINE_API macro at the start of their declaration. Those were OnRegister, OnUnregister, Serialize. I had to provide my custom implementation for those in my class. I pretty much copy-pasted the implementation for them from UPostProcessComponent.

WARNING: This approach seems sketchy (involves code duplication) but so far I don’t know any other way of extending classes marked as MinimalAPI.

1 Like

Im having a similar name mangling issue as stated above but I dont see why. I have thoroughly checked the 3 common rules for name mangling.

I am trying to access the AssetManagerEditorModule. I have added the module to my build.cs. This showed immediate results of letting me even include the header for this module and compile. But, if I try to call IAssetManagerEditorModule::Get(), I get a declspec linker error.
I can use IAssetManagerEditorModule::DiskSizeName and read that value. This is a bit confusing because it is declared in the cpp. It is in the global scope, though.
I also attempted to just recreate the single line of code that the Get function does. This is fine, but I can’t use this newly created AssetManager object to do anything.

As far as I can tell I have passed all requirements for using this object. It is included in my cpp. It is declared in my build.cs. I re-ran the build.bat to recreate my vs project.

All I can figure is that the dll for this module has a function implementation and the compiler cant differentiate which implementation I want to use. The class isn’t in a namespace or anything and I don’t see a way to further scope in this particular function over another.

As usual, you work on something for days and after you ask a question you answer it yourself.
Well, I would love a real explanation as to why this works:
The original class type that I was trying to use, to use the functionality of the IAssetManagerEditorModule, was deriving from UAssetManager. I made the class with the Unreal C++ class maker and it seemed to make sense to me.
Well, I tried to implement the same functionality with a class derived from UEditorAssetLibrary, and it is able to call the Get function without name mangling.
I have no idea why one class works and another does not.

To add to this, I’ve added a guide using images on how to solve this error 99% of the time.
I’ll keep improving the tutorial from time to time but i thought an image-based tutorial would help
https://store.algosyntax.com/tutorials/unreal-engine/ue5-lnk2001-unresolved-external-symbol-solution/

1 Like

I was getting this error (LNK2019) because I had copied the Build.cs file from another module I had which was using binaries. It included Type = ModuleType.External which tells the compiler to ignore the source files. If you are using any code in the module’s .cpp files, it will throw this error because the compiler can’t find that code. Just remove the line to fix it.
UE 5.1 Module Setup

UPackage * __cdecl UPackageTools::LoadPackage(class FString) is undeclared but it is part of CoreUObject

FString PackageName = "SomePackage";
UPackage* Package = UPackageTools::LoadPackage(PackageName);

how would this be possible ?

That’s in an editor module called UnrealEd, not CoreUObject. Not only you need that dependency, you’ll also get errors if you try to use it in non-editor builds (like packaging).

I just fixed a number 4 today for the list of possibilities. I had no idea about this one :open_mouth:

Functions from a class won’t be exported in the module’s dll, even with the MODULE_API macro, if they reside in a header-only class that’s not a USTRUCT or UCLASS and nothing uses the class in its module. With no .cpp file in the module including the code, there won’t be a compilation unit to compile that function. Then, other modules trying to use the class will have linking errors complaining that its function definitions couldn’t be found. The solution is to add an empty .cpp file that includes the offending header.

This issue doesn’t occur when using unreal reflection macros because generated .cpp files will include the header.

It might also not happen when building with unity on.

The MODULENAME_API macro worked for me. I prefaced individual functions with the MODULENAME_API macro and not the entire class.

what about these:
unresolved external symbol “__declspec(dllimport) bool __cdecl UE::Net::WriteQuantizedVector(int,struct UE::Math::TVector const &,class FArchive &)”
unresolved external symbol “__declspec(dllimport) bool __cdecl UE::Net::ReadQuantizedVector(int,struct UE::Math::TVector &,class FArchive &)”

i can’t find the declaration, i added CoreNet module but doesn’t work

in the source code, or in your plugin ?