[Linux] Trying to find out why I'm getting failure to load plugin binaries

I’ve got a project which we’ve structured to have a few in-house plugins. This is a pretty long-standing project that was originally built on 4.27, has been upgraded through 5.0 and now on to 5.1. And the crux of my problem is also new in the sense that this was actually working as recently as 3 weeks ago. Yes, there have been meaningful code changes, but no changes to the *.Target.cs or *.Build.cs files in that time. We do use a number of Unreal built-in plugins and they work fine.

The oddity here is that when I do either a Build and Cook with RunUAT or try to open the project in the Editor, I get two specific dlopen failures to load shared object files.

One is for a shared library to which is a core dependency for our C++ code and is built separately from the Unreal project. This is particularly weird because in my Build.cs files (for the main project and the plugins), that dependency is added to my PublicAdditionalLibraries with an absolute path to the build artifact. Granted, I can copy that artifact to the xxxxProject/Binaries/Linux directory and it loads fine. That said, this shouldn’t be necessary, and a few weeks ago, it wasn’t.

The other one is one of the plugins located within my project. No surprises here that it compiles and builds just fine. And yet, I get dlopen errors that it cannot open libUnrealEditor-yyyyyPlugin.so because the file apparently does not exist. This is in spite of the fact that the built object file is plainly located in Plugins/yyyyyPlugin/Binaries/Linux. I thought maybe it might be a timing flaw in when it’s trying to load the file, in which case, it should succeed on a second attempt. This is not the case; the failure to locate the file is absolute. If I try copying the binary .so file to the xxxxProject/Binaries/Linux, then I get errors because it now somehow finds both binaries, and complains about ambiguity. Try to delete either one of the two copies, and the shared object file is no longer found. No amount of cleaning and rebuilding or anything of the sort actually changes the result. If I try to test deliberately removing the dependency, then I get expected failures that the code in my main project cannot find the header files – which makes sense.

Again, a fix for this either setting the LD_LIBRARY_PATH or by adding a config file to /etc/ld.so.conf.d/. This is still strange to me, and really, by all measures, this shouldn’t be necessary. Build systems in general, when explicit dependencies are provided and/or are local to the project should be able to manage this. It clearly appears to do it just fine for the other plugins I have in the project. Not even reverting to the changeset where it originally worked has any effect on the result, so something is broken in a way involving something hidden or cached outside of the immediate environment that embodies Murphy’s Law. Either that, or something tremendously innocuous and stupid that I’m missing and the fact that it ever worked at all is the real mystery.

Based on this experience, I’m presuming that this is not new and has been experienced by others before, so I’m looking to see if anyone else has hit something similar and remembered the fix.