Linking with FBX SDK in packaged UE4 Builds

Unreal Engine 4.21 ships with version 2018.1.1 of Autodesk’s FBXSDK. It’s used when importing or exporting FBX 3D data into your project using Unreal Editor. Sometimes it may be necessary to load or save 3D meshes at runtime. It’s mostly pretty straight forward to integrate third-party software into your packaged builds, but linking with the shipping FBX tends not to be.

The shipped version of the SDK coming along with UE4 is located under $UE_PATH/Engine/Source/ThirdParty/FBX in form of an engine module. Adding the dependency is usually done in the build script, e.g. in YourModule.Build.cs for your module, either statically via PublicDependencyModuleNames or PrivateDependencyModuleNames respectivly, or DynamicallyLoadedModuleNames to link dynamically.

This works well for editor builds, but when packaging your project with stock 4.21 obtained through the launcher, you’re presented with a slue of errors. If you try to link statically, you are likely to encounter ‘LINK : fatal error LNK1181: cannot open input file 'libfbxsdk-md.lib'‘. This is caused by the module’s build script trying to pull in ‘libfbxsdk-md.lib’, which is not included in the third party distribution. Introduced with 4.21, there is however a prebuilt DLL packaged with the engine.

If you try to build your module by linking dynamically via adding the dependency to DynamicallyLoadedModuleNames, you’ll likely encounter ‘fatal error C1083: Cannot open include file: 'fbxsdk/fbxsdk_def.h': No such file or directory‘.

I ended up adding the library dependency manually. For this I created the necessary path, library and symbol names with these properties in YourModule.Build.cs:

string EnginePath {
    get { return Path.GetFullPath(Target.RelativeEnginePath); }
}

string EngineThirdPartyPath {
    get { return Path.GetFullPath(Path.Combine(EnginePath, "Source/ThirdParty/")); }
}

string FBXModuleIncludePath {
    get { return Path.Combine(EngineThirdPartyPath, "FBX/2018.1.1/include/"); }
}

string FBXModuleLibraryPath {
    get { return Path.Combine(EngineThirdPartyPath, "FBX/2018.1.1/lib/vs2015/x64/release/"); }   
}

string FBXStubLibraryName {
    get { return "libfbxsdk.lib"; }
}

string FBXRuntimeLibraryName {
    get { return "libfbxsdk.dll"; }
}

string FBXSharedLibrarySymbol {
    get { return "FBXSDK_SHARED"; }
}

And then pulling in the dependency differentiated on whether it’s an editor build or packaged build.

// For editor builds, use it as a public module dependency.
if (Target.Type == TargetType.Editor)
{
    PublicDependencyModuleNames.Add("FBX");
}
// Else just add dynamic depency for FBX manually.
else
{
    PublicIncludePaths.Add(FBXModuleIncludePath);

    // Setup stub library for build.
    PublicLibraryPaths.Add(FBXModuleLibraryPath);
    PublicAdditionalLibraries.Add(FBXStubLibraryName);

    // Tell UBT to use DLL version of the FBXSDK at runtime.
    PublicDefinitions.Add(FBXSharedLibrarySymbol);
    // Copy DLL to output directory on build.
    RuntimeDependencies.Add(
        "$(TargetOutputDir)/" + FBXRuntimeLibraryName,
        Path.Combine(FBXModuleLibraryPath, FBXRuntimeLibraryName)
    );
}