Link to 3rd Party Libraries

What works:

I can write any type of source that I want (C++ language) and have Visual Studio include a third party header file (.h) and call a function defined in that header file by linking to the library properly in Visual Studio. This is all using the normal right clicking properties, adding the library and include directories, and #pragma comment(lib, ) in my .cpp / .h files. This works all fine and dandy, which I’m glad it does.

What doesn’t work:

The project is supposed to be deployed on the Android OS. (Mobile device). When I hit the export button, I’m getting a linker error when calling the function mentioned above (any function defined in my included third party library).

My opinion:

There are possibly a few things happening -
- A second compiler is running during export(clang++.exe from the ndk) that doesn’t know what / where the static libraries are (even with the #pragma comment(lib, ) in directly in the source.
- I’m using the incorrect library types. I know Android uses .so (Unix) libraries, should I be linking with those instead? Or continue to use .dll (Windows)

I’ve read through the (convoluted) third party library tutorial, but that’s not making very much sense to me. I’ve also searched for documentation on the “.Build.cs” files which was to no success. Which functions should I be calling in the “.Build.cs” file to say (in english):

“This is exactly where you will find your library Mr. Linker, oh and by the way, this is going onto the Android OS, so this is a .so file for you.”

That’s all I want to do. :slight_smile: Simple no wierd spaghetti code trying to link here, there and everywhere. Just one function call that’s implemented in a .so file for Android. :slight_smile: I’m trying to call the function but it can’t hear me! How do I tell the linker where my .so file is? Thanks in advance.

Have you tried following this tutorial : A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums

I haven’t deployed to Android myself. But just right clicking projects and setting dependencies there is not usually a good approach because every time you generate new project files all that information is lost. I would highly recommend following the tutorial above. I used it to link some libraries for my project and it works like a charm. I suspect your android woes can be dealt with a similar approach.

That’s exactly the tutorial that I don’t quite understand. Specifically the portion at the end about the folder structure. The problem is with that tutorial, there’s no mention of the Documentation on what the Path methods do. Albeit self explanatory (the method names) those don’t seem to be working well for me. :frowning: I’ve tried everyone that I’ve seen, with multiple different types of parameters.

Are you not able to find your build.cs file ?

I have one. :slight_smile: It’s in my project, it’s more of an issue of “How to correctly use it.” There’s not much documentation on the functions that are available for use in that context. For example, in openGL Documentation (un-related), it says something along the lines of “A Fragment Shader must at a minimum write to gl_FragColor.” That’s awesome! What’s the Build.cs file supposed to do? At a minimum? Or maximum? Lol. That’s what’s confusing. To me… It’s just there. Obviously for something but for what? :stuck_out_tongue: And how do I use it properly.

I understand, but you gotta use what you have :slight_smile: Now what exactly related to this change you are trying to make to the Build.cs file you don’t understand ? Can you be more specific ?

So I have a library file (.so for Android) that implements a function. I compile the project using VS which is successful, even with the function call implemented (VS is not complaining at all.) But when I go file->package project->Android ETC 2. Another compiler runs (which makes sense). So the compilation of the project starts again.

During this secondary compilation (clang++.exe) it’s not able to file the implementation of my function call (it’s inside of a .so file). So the export fails 100% of the time. All I need to be able to do is have clang++.exe link against this .so that I have. That’s it. :slight_smile:

Here’s my Log file: (The Error is on line 559).

Here’s my Log File from the UE4 Export process.

I too would like an answer to this. The “tutorial” is very incomplete.

I had quite an headhacke myself too following that tutorial, but got it work:

1- compiled the library as static for the needed source (in my case, PocketSphinx for win64 and OsX)
2- created his directories:
-MyProject
|

  • ThirdParty
    |
    • PocketSphinx
      |
      • include
      • lib
        |
        • Mac
        • x64

In x64 there are the 2 .lib files (windows static library), in Mac the two corresponding .a files (they are 2 in my case, they may be only 1 or more)

3- Edited the Build.cs this way:

using UnrealBuildTool;
using System.IO;    ////for the Path

public class MyProject : ModuleRules
{
///useful automations
    private string ModulePath
    {
        get { return Path.GetDirectoryName(RulesCompiler.GetModuleFilename(this.GetType().Name)); }
    }

    private string ThirdPartyPath
    {
        get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }
    }

	public MyProject (TargetInfo Target)
	{
///normal stuffs.....

		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

        PrivateDependencyModuleNames.AddRange(new string[] { "Voice", "OnlineSubsystemUtils", "OnlineSubsystem" });

		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// 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");
		//		}
		// }
///this is added
        LoadPocketSphinx(Target);
	}

//here we go
    public bool LoadPocketSphinx(TargetInfo Target)
    {
        bool isLibrarySupported = false;

/////where to pick the library if we're building for windows (32 or 64)
        if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
        {
            isLibrarySupported = true;
            string LibraryPath = Path.Combine(ThirdPartyPath, "PocketSphinx", "lib");
            //string LibraryName = "pocketsphinx";
            if (Target.Platform == UnrealTargetPlatform.Win64)
            {
                LibraryPath = Path.Combine(LibraryPath, "x64");
            }
            else if (Target.Platform == UnrealTargetPlatform.Win32)
            {
                LibraryPath = Path.Combine(LibraryPath, "Win32");
            }
            PublicLibraryPaths.Add(LibraryPath);
            PublicAdditionalLibraries.Add(Path.Combine(LibraryPath, "pocketsphinx.lib"));
            PublicAdditionalLibraries.Add(Path.Combine(LibraryPath, "sphinxbase.lib"));

            PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "PocketSphinx", "include"));
        }

///where to pick the library if we're building for mac
        else if (Target.Platform == UnrealTargetPlatform.Mac)
        {
            isLibrarySupported = true;
            string LibraryPath = Path.Combine(ThirdPartyPath, "PocketSphinx", "lib");
            //string LibraryName = "pocketsphinx";
            LibraryPath = Path.Combine(LibraryPath, "Mac");
            PublicLibraryPaths.Add(LibraryPath);
            PublicAdditionalLibraries.Add(Path.Combine(LibraryPath, "pocketsphinx.a"));
            PublicAdditionalLibraries.Add(Path.Combine(LibraryPath, "sphinxbase.a"));

            PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "PocketSphinx", "include"));
        }
//add other platforms if needed...

//and here we go.
        Definitions.Add(string.Format("WITH_SIXENSE_BINDING={0}", isLibrarySupported ? 1 : 0));
        return isLibrarySupported;
    }
}

Hope this helps :wink:

what dir are the log files stored?

Unfortunately, based on my current experience, I suspect that this doesn’t apply to Android… The Android NDK build tools seem to expect that all the libraries will be found in the “Intermediate\Android\APK\libs\armeabi-v7a” folder of the project.

So… methinks that you just need to copy the .so file there. I’m about to try that next.

Nice example!

does anybody have any success ?

Yea, i also would very much like to know how to do it properly on 4.16+
All documentation is outdated and doesn’t work any more.

+10 to this scenario. Exactly my case on UE 4.16