Download

Help in compiling C++ code external to UE4 (it's a sort of library)

I’m trying to compile C++ code (pure C++11, no dependencies) in an UE project, without any luck. I’m struggling to understand how should I tell UE build system where to look for the code.

Basically, I’ve got this sort of library. It’s shared amongst other C++ projects (not related to UE4) and constantly evolving, so I don’t want to create a .lib or stuff like that. I just want to tell UE 4 “look, there are other C++ classes to compile, it’s just that they’re in another directory other than your project directory”. This way when I compile the UE4 project, it also compiles that code too. How do I do that?

I’ve managed let the compiler know of the C++ headers by adding this in the Build.cs file:

  PublicIncludePaths.Add("D:/Development/PathToMyExternalCode");

In the code, I’m simply creating a random object of a class that belongs to this library, but when I try to compile it throws me “Unresolved external symbols” related to the class methods, meaning it can find the definitions of the methods (in the header), but can’t find their implementation (i.e. the .cpp file). How can I tell the compilere where to look for the .cpp files (which are in the same folder of each corresponding .h)?

Can anyone save me from this nightmare?

1 Like

Anyone? I still didn’t manage… I can’t be the only one that has tried this, aren’t I? I couldn’t find anything on the web, but it doesn’t seem like something absurd…

1 Like

Your library needs to be part of an existing module or in its own module.
Copy your source folder to the right module folder, regenerate the project files and the build system should be aware of your library.
In order to access types and functions defined in your library from other modules, they need to be exported. You do that by adding the “MODULENAME_API” macro before the type/function name.
Example from the navmesh module :


class NAVMESH_API dtCrowd{...};

Now dtCrowd can be directly accessed by other modules.

Thank you for the explanation, I will consider it.

But it’s not exactly what I would like to do. I don’t want to copy the library code into my UE4 project folder. Instead, I would like to tell UE build system where the library code is located (meaning, outside the project folder: any other place in the filesystem). This would be very useful, since edits applied to the library code are automatically applied for every project that uses that code base. Do you have any idea on how to do that?

I see.
In your current setup, do you get unresolved externals while accessing the library from the same module ? Because otherwise, you can’t cross dll boundaries without an export.

I don’t think I understand, I’m probably not explaining myself correctly.

My folder structure is something like this:
[SPOILER]


[/SPOILER]

In the image, “MyUE4Project” is the (guess what) UE 4 project.
In the image, “OtherNotUE4Project” and “OtherNotUE4ProjectAgain” are plain C++ projects, completely unrelated to UE4.
In the image, “MyExternalSharedCode” is a sort of library containing C++ code. It’s my usage of “sort of library” that is probably misleading. I just mean that it’s a set of C++ code used among these other C++ projects.

In fact, inside “MyExternalSharedCode” it looks something like this:
[SPOILER]


[/SPOILER]

Just a “random” set of C++ classes. There are no “.dll” or “.lib” involved.

Now, what I would like to do is tell UE4 build system that when it compiles UE4 code, it also compiles the classes contained in “MyExternalSharedCode”, because they’re just plain C++ stuff, so why not compile it?

So, as of right now, I’ve only managed to tell the build system where to look for the headers, but I don’t know how to tell it where to look for the “.cpp” files

No, that much I understood.
But the way the engine works, is that it’s broken into modules which equate to separate dlls.
When you added the library’s path in ModuleXX.Build.cs, the definitions of your library became part of ModuleXX’s dll.
When you try to use your library types in a game project, your game code (which is located in your game’s generate dll) is trying to lookup types that exist in ModuleXX’s dll, and the linker doesn’t know where to find them.

First test you should do is create a variable using a type from library in the original module, ie. the module in whose Build.cs you added “PublicIncludePaths.Add(“D:/Development/PathToMyExternalCode”);”

If that code compiles then you only have a linker issue and you have 2 options to solve it :

1- add MODULEXX_API to the types/functions you want exported in your library. You can hide it behind a macro to make sure your code works with non ue4 projects.
or
2- create a wrapper/interface for your library in ModuleXX. And then access your library from other modules (other game projects) only through that wrapper/interface.

@FrancescoDeso did you figure it out? I have the same problem as you.

1 Like

Sorry for the late reply, but sadly no, I couldn’t find nothing that worked :frowning:

AFAIK you can’t have outside dependencies easily. When I have to have it, I sometimes use symbolic links (on Windows, at least) which will trick UE into believing the library is inside a module but it really is outside in another repository. Not very beautiful but it works.

1 Like

Could you do this the same way as having Boost compiled into the Engine? At one point I had Boost files compiled in.

Had directory “ThirdParty” at the same level of the “Source” directory, then the “boost” directory under “ThirdParty”

Also told VS project where to find the files.

In my Build.cs (I think I had both commented lines active. Been awhile since I had that setup.)


public class AW: ModuleRules
{
private string ThirdPartyPath
{
get { return Path.GetFullPath(Path.Combine(ModuleDirectory, "../../ThirdParty/")); }
}

public AW(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; //4.19.2

//PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "boost"));
//PublicSystemIncludePaths.Add(Path.Combine(ThirdPartyPath, "boost"));

...


1 Like

You can use symbolic links to accomplish this. With the folder structure below, I was able to get a project to compile using references to classes defined in files outside the normal project hierarchy. I used the command ‘mklink /J “C:\Users%USERNAME%\Documents\Unreal Projects\TestProject\Source\TestProject\cppfiles” “C:\Users%USERNAME%\Documents\cppfiles”’ in a command prompt to create the symbolic link. I also added the path string of the cppfiles folder to the PublicIncludePaths variable in the .Build.cs file. If your symbolic link is in the ‘Public’ subfolder under /Source/TestProject/, adding the path to PublicIncludePaths might not be required anymore for the current version of the engine, but I didn’t test that.



/Documents
    /cppfiles
        *.h
        *.cpp
    /Unreal Projects
        /TestProject
             /Source
                TestProject.Target.cs
                TestProjectEditor.Target.cs
                TestProject/
                    TestProject.Build.cs
                    *.h
                    *.cpp