I’m going to take the renewed interest here to be about linking libraries and not addressing anything involving the source code/header inclusion from third party libraries. Consequently, this is just going to address linking to third party libraries compiled outside of UE.
The best way I’ve found to do this to support both editor and game builds (e.g., packaging) so far is shown in the following plugin build file:
For Windows with dlls, I do three things:
- Add the .lib file to PublicAdditionalLibraries
- Add the dll PublicDelayLoadDLLs
- Copy the dll to the Binaries/Win64 directory in your project root directory
You can see an example of this in the following code segment:
string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory,
"..", "..", "..", "..", ".."));
string BaseLibDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory,
"..", "..", ".."));
string MadaraLibDirectory = Path.Combine(BaseLibDirectory, "ThirdParty",
"madara", Target.Platform.ToString());
if (Target.Platform == UnrealTargetPlatform.Win64)
{
string BinariesDir = Path.Combine(BaseDirectory, "Binaries", "Win64");
System.IO.File.Copy(Path.Combine(MadaraLibDirectory, "MADARA.dll"),
Path.Combine(BinariesDir, "MADARA.dll"), true);
PublicAdditionalLibraries.Add(Path.Combine(MadaraLibDirectory, "MADARA.lib"));
PublicDelayLoadDLLs.Add(Path.Combine(MadaraLibDirectory, "MADARA.dll"));
}
Is this documented in the Engine, wiki, and blogs accurately? No, absolutely not. It took me a long time to debug what was going on. So, let me explain why these steps are necessary (I’ve been working primarily in 4.21-4.24, but these steps should work for earlier versions as well).
- You have to add the .lib to PublicAdditionalLibraries, regardless of the fact that you usually don’t need the .lib file with DLL loading in C++ linking in general. This appears to be an issue with linking in the editor mode. I’m only copying the dll over to the binaries folders for packaging and it seems to work, as you would expect with normal DLL loading.
- DLLs are best put in PublicDelayLoadDLLs. It may work in other places, but I know it works in this array on Windows as you would expect it to.
- To package the library with the game, you need to tell the build system to copy the .dll to the Binaries directory and the appropriate folder. If you don’t copy this to the Binaries folder, it won’t be packaged. However, if you do copy this as I’m doing here, you will have a strange side effect to keep in mind. This System.IO.File.Copy command needs to overwrite the destination file (the dll in the Binaries directory). If it can’t, it will fail the build. This is a problem in the editor after you package a build. If you try to run in the editor or build while the editor is still up, it is likely to have locked the dll if your plugin is opening the dll (mine does during the startup method). So, if you get failure messages after packaging, close the editor, and then try deleting the .dll files in your Binaries/Win64 directory. It should work after that. I’ve seen other methods of potentially packaging libs (i.e., you don’t necessarily have to use System.IO.File.Copy), but this is the method I’m currently using to include the libs in packaging.
Linux and Mac should be a bit simpler to debug. Here’s the process I’m currently using and how the code looks in one of my current third party libs.
For Linux so, I do the following:
- Add the lib*.so files to PublicAdditionalLibraries
- Copy the .so to the Binaries/Linux directory
string BaseDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory,
"..", "..", "..", "..", ".."));
string BaseLibDirectory = Path.GetFullPath(Path.Combine(ModuleDirectory,
"..", "..", ".."));
string MadaraLibDirectory = Path.Combine(BaseLibDirectory, "ThirdParty",
"madara", Target.Platform.ToString());
if (Target.Platform == UnrealTargetPlatform.Linux)
{
string BinariesDir = Path.Combine(BaseDirectory, "Binaries", "Linux");
System.IO.File.Copy(Path.Combine(MadaraLibDirectory, "libMADARA.so"),
Path.Combine(BinariesDir, "libMADARA.so"), true);
PublicAdditionalLibraries.Add(Path.Combine(MadaraLibDirectory, "libMADARA.so"));
}