Packaging for macOS doesn't add correct RPATH for thirdparty dependencies

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.