I have a plugin in my project that links to third-party library. Everything builds, but when I package my project for macOS, I can see the library as a dependency in otool output:
otool -L <...>/MacNoEditor/game.app/Contents/MacOS/game
However, Unreal does not create proper rpath that points to it and as a result when trying to start the game, it crashes because it can’t find the library.
All I see are rpaths for UE’s thirdparty libraries:
otool -l <..>/MacNoEditor/game.app/Contents/MacOS/game | grep RPATH -A2
cmd LC_RPATH
cmdsize 32
path @loader_path/ (offset 12)
--
cmd LC_RPATH
cmdsize 32
path @executable_path/ (offset 12)
--
cmd LC_RPATH
cmdsize 72
path @loader_path/../UE4/Engine/Binaries/ThirdParty/PhysX3/Mac (offset 12)
--
cmd LC_RPATH
cmdsize 88
path @loader_path/../UE4/Engine/Binaries/ThirdParty/OpenVR/OpenVRv1_5_17/osx32 (offset 12)
--
cmd LC_RPATH
cmdsize 72
path @loader_path/../UE4/Engine/Binaries/ThirdParty/Ogg/Mac (offset 12)
--
cmd LC_RPATH
cmdsize 72
path @loader_path/../UE4/Engine/Binaries/ThirdParty/Vorbis/Mac (offset 12)
I’d expect there be an rpath that points to the library inside the app bundle, game.app (and I can verify that the library has been copied inside the app bundle properly).
How can I fix RPATH for thirdparty dependencies?
I wrote a patch for UnrealBuildSystem that fixes RPATHs automatically, if the library is from “Plugins”. Since I can’t share the forked repo of UnrealEngine (it’s private), here is the patch:
diff --git a/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs b/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs
index f1781826290..f96a5b938ff 100644
--- a/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs
+++ b/Engine/Source/Programs/UnrealBuildTool/Platform/Mac/MacToolChain.cs
@@ -643,6 +643,20 @@ namespace UnrealBuildTool
string BundleRelativeDir = Utils.MakePathRelativeTo(BundleLibraryDir, ExeDir).Replace("\\", "/");
LinkCommand += " -rpath \"@loader_path/" + BundleRelativeDir + "\"";
+ if (LibraryFullPath.Contains("Plugins") || LibraryFullPath.Contains("ThirdParty"))
+ {
+ string ProjectDir = Path.GetDirectoryName(ProjectFile.ToString());
+ string GameName = Path.GetFileName(ExeAbsolutePath);
+ string BundleGameDir = Path.GetFullPath(BundleUE4Dir + "/" + GameName);
+ string PackagedLibPath = BundleGameDir + LibraryDir.Replace(ProjectDir, "");
+ string PackagedLibRpath = Utils.MakePathRelativeTo(PackagedLibPath, ExeDir).Replace("\\", "/");
+
+ LinkCommand += " -rpath \"@executable_path/" + PackagedLibRpath + "\"";
+
+ Log.TraceInformation("Fixing library RPATH for app bundle: {0} -> @executable_path/{1}",
+ PackagedLibPath, PackagedLibRpath);
+ }
+
// For staged code-based games we need additional entry if the game is not stored directly in the engine's root directory
if (bCanUseMultipleRPATHs)
{
You will then need to open the “UnrealBuildTool.sln” VS solution in “Engine/Source/Programs/UnrealBuildTool” and re-compile it.
I followed your steps, but I do not know where exactly should your code go in the UnrealBuildTool.sln.