"ModuleManager: Unable to load module" during project startup

Look where symbol you’re referring to (_ZNK9Zeptomoby10OrbitTools7cEcBase8ToStringEv, or in a demangled form, Zeptomoby::OrbitTools::cEcBase::ToString() const) is defined (you can use nm to examine .a files). If it’s not defined in any of .a files you’re linking in but present in its sources, the visibility of the symbol may need to be changed.

As for “could not be loaded by the OS” - it is a generic message whenever dlopen() fails. The engine doesn’t (and cannot) analyze the details why dlopen() failed (it could be due to a missing system or a third party library or due to exhausting some system limit like DTV_SURPLUS etc) - from its POV it is an external error even if in your case it was caused by the user.

I get the error when starting the project

LogLinux: Warning: dlopen failed: …/Unreal_project/Binaries/Linux/libUE4Editor-Unreal_Project.so: undefined symbol: _ZNK9Zeptomoby10OrbitTools7cEcBase8ToStringEv
Warning: ModuleManager: Unable to load module …/Unreal_project/Binaries/Linux/libUE4Editor-Unreal_Project.so because the file couldn’t be loaded by the OS.

IMHO it’s not a OS error as the symbol referring to a ThirdParty library which obviously is not correctly loaded. Here’s the code of my Unreal_Project.build.cs

using UnrealBuildTool;
using System.IO;

public class Unreal_Project : ModuleRules
{
    private string ModulePath
    {
        get { return ModuleDirectory; }
    }

    private string ThirdPartyPath
    {
        get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }
    }
    
    public Unreal_Project(ReadOnlyTargetRules Target) : base (Target)
	{
	
	PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP", "UMG", "Slate", "SlateCore" });
        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore", "HTTP" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //		if (UEBuildConfiguration.bCompileSteamOSS == true)
        //		{
        //			DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //		}
        // }
        LoadLibraries(Target);
    }

    public bool LoadLibraries(ReadOnlyTargetRules Target)
    {
       bool isLibrarySupported = false;
       
        if (Target.Platform == UnrealTargetPlatform.Win64)
        {
	  isLibrarySupported = true;
        }
        
        if (Target.Platform == UnrealTargetPlatform.Linux)
        
        {
	  isLibrarySupported = true;
                  
        //CSpice
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "cspice/include"));
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "cspice/lib/cspice.a"));
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "cspice/lib/csupport.a"));
        
        //orbitTools
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "orbitTools/lib/libcore.a"));
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "orbitTools/lib/liborbit.a"));
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "orbitTools/core"));
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "orbitTools/orbit"));

        System.Console.WriteLine("ThirdParty Libraries for Linux loaded");
        }
        return isLibrarySupported;
    }
}

This specific symbol should be part of either the orbitTools/lib/libcore.a or orbitTools/lib/liborbit.a
The compiler works correctly and also the message “ThirdParty Libraries for Linux loaded” is shown at the log. So the compiler goes into the correct if loop. If I comment out either the PublicIncludePaths.Add or PublicAdditionalLibraries.Add the compiler will complain, so the libraries must be loaded when compiling. But as the symbol is refering to something from these additional libraries I guess it’s not correctly loaded.
The windows version works!!!

using UnrealBuildTool;
using System.IO;

public class Unreal_Project : ModuleRules
{
    private string ModulePath
    {
        get { return ModuleDirectory; }
    }

    private string ThirdPartyPath
    {
        get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }
    }
    
    public Unreal_Project(TargetInfo Target)
	{
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HTTP", "UMG", "Slate", "SlateCore" });

        // Uncomment if you are using Slate UI
        PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore", "HTTP" });

        // Uncomment if you are using online features
        // PrivateDependencyModuleNames.Add("OnlineSubsystem");
        // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
        // {
        //		if (UEBuildConfiguration.bCompileSteamOSS == true)
        //		{
        //			DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
        //		}
        // }

        LoadLibraries();
    }

    public void LoadLibraries()
    {
        //CSpice
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "cspice/include"));
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "cspice/lib/cspice.lib"));
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "cspice/lib/csupport.lib"));

        //orbitTools
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "orbitTools/x64/Release/orbitTools.core.lib"));
        PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "orbitTools/x64/Release/orbitTools.orbit.lib"));
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "orbitTools/core"));
        PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "orbitTools/orbit"));


        System.Console.WriteLine("Libraries loaded");
    }
}

I tried several thing, followed the instructions of Unreal Wiki and Transition to UE4.16 (btw. the windows code is working on UE4.16.3 even without these modifications.

I’m using Ubuntu 16.04 and UE4.17.2.

Many thanks that did the trick… actually it just came to my mind that I have commented this function from the thirdparty source of the library on the linux version as its using some code which is dedicated to windows only… Looks like I haven’t properly commented out this Zeptomoby::OrbitTools::cEcBase::ToString() so it was kinda still there but definitely not correctly defined. I remove it also from the .h file and now it works.

So actually it was not an issue of the loading/linking of additional libraries… which is good, mean the project .Build.cs is correct. Now I just need to adjust it to also run on windows :slight_smile: