Download

How do I include native libraries from a plugin?

Hello!

I have a plugin that is working great on Windows and Mac, and now is the time to also get it working on Android and iOS.
However I’m unable to get it to copy along the c++(c interface) library file. It does this fine for windows and mac.

The current code in the build.cs, (where I think the problem is).


else if (Target.Platform == UnrealTargetPlatform.Android)
{
		isLibrarySupported = true;
		string PlatformString = "armeabi-v7a";
		string LibrariesPath = Path.Combine(ThirdPartyPath, "elias", "android", PlatformString);

		string EliasDllFilepath = Path.Combine(LibrariesPath, "libelias.so");

		// @NOTE: Prefixed '/' seems to be important otherwise UAT constructs a bizarre invalid absolute path
		//string DllStagePath = "/libelias.so";
		//RuntimeDependencies.Add(new RuntimeDependency(EliasDllFilepath, DllStagePath));
		
		PublicAdditionalLibraries.Add(EliasDllFilepath);
		RuntimeDependencies.Add(new RuntimeDependency(EliasDllFilepath));

		string deployFilePath = System.IO.Path.Combine(ModuleDirectory, "../../Binaries", Target.Platform.ToString(), "deploy.txt");
		System.IO.File.WriteAllText(deployFilePath, "libelias.so");
		System.Console.WriteLine(EliasDllFilepath);
}


Any suggestions are welcome!
If you need more I can provide the entire plugin code + libraries to reproduce the problem.

Hi Zicandar,

Instead of writing the deploy.txt you will need to use an APL (AndroidPluginLanguage) XML file to copy the .so for packaging in the APK. Put this in your build.cs:


	string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, BuildConfiguration.RelativeEnginePath);
	AdditionalPropertiesForReceipt.Add(new ReceiptProperty("AndroidPlugin", Path.Combine(PluginPath, "Elias_APL.xml")));


Then put the Elias_APL.xml in same directory. This file should be something like this:


<?xml version="1.0" encoding="utf-8"?>
<!--Elias additions-->
<root xmlns:android="http://schemas.android.com/apk/res/android">
	<!-- init section is always evaluated once per architecture -->
	<init>
		<!-- currently only support armv7 -->
		<setBool result="bSupported" value="false"/>
		<isArch arch="armeabi-v7a">
			<setBool result="bSupported" value="true"/>
		</isArch>
		
		<if condition="bSupported">
			<false>
				<log text="WARNING: this architecture is not supported for libelias.so!"/>
			</false>
		</if>
	</init>

	<!-- optional files or directories to copy to Intermediate/Android/APK -->
	<resourceCopies>
		<isArch arch="armeabi-v7a">
			<copyFile src="$S(EngineDir)/Source/ThirdParty/elias/android/armeabi-v7a/libelias.so"
				dst="$S(BuildDir)/libs/armeabi-v7a/libelias.so" />
		</isArch>
	</resourceCopies>
</root>


Hello Chris,

Thanks a lot for the help!
However as the plugin I’m creating is not located in the engine installation currently, but in the game directories plugins, I’m guessing that the $S(EngineDir) won’t work?

Is there any documentation on this? If not, it would be great if you could add it to the official docs! To be honest, they are quite lacking in a lot of areas, one of the few reasons that are big enough to make using Unity worthwhile…
If there is good documentation on how to deploy plugins with native third party libraries please point me to them!

Download link to the testing project I’m using.

Best regards
Zicandar

There is documentation at the top of the AndroidPluginLanguage.cs inEngine\Source\Programs\UnrealBuildTool\Android. For the directory the XML is in you can use $S(PluginDir).

Thanks for the help, but I’m still not having any luck. :frowning:
This is the only part I find about it in the build log:
LogPlayLevel: CommandUtils.CopyFileIncremental: CopyFileIncremental Skipping F:\Unreal Projects\ELIAS\Saved\StagedBuilds\Android_ASTC\ELIAS\Plugins\ELIAS_UE4\Binaries\Android\libelias.so, up to date.
I’ll upload the project to dropbox and send you a pm with it. I’m probably doing something simple wrong, but I’m kinda out of ideas on what to test as my knowledge here is far to limited.

Is there some example I can base my code on / look at? I have tried looking at FMod, but theirs doesn’t seem to be working. (The deploy.txt method).

As for documentation I can’t find it.

I’m unable to find this directory in the 4.10 or 4.9 installations I have. Engine/Source only has Developer, Editor, Runtime and ThirdParty folders.
Engine/Programs/UnrealBuildTool only has BuildConfiguration.xml

Note that I’m using the “Launch” button from inside the editor if that matters?

The GearVR plugin is the best example at the moment.

Here is the AndroidPluginLanguage.cs on GitHub for 4.10: https://github.com/EpicGames/UnrealEngine/blob/4.10/Engine/Source/Programs/UnrealBuildTool/Android/AndroidPluginLanguage.cs

I’ll take a look at your project and get back to you.

Any progress on this? Any additional tips would be appreciated!

Sorry, I had a lot of last minute 4.11 issues to deal with and didn’t have time to do anything more.

No worries, but will you be able to look at it post 4.11? Or should I try finding a different way of getting a viable copy of the library?

I should get a chance to look at it early next week. The APL code I had above should work, though.

“Should work”, well, it seems like it should, as it’s even giving me logs from inside the xml file, but my .so file is not appearing.
I expect the .so file at: (/PROJECT/Binaries/Android/apk_name.apk/lib/armeabi-v7a/).
I did find these two things in the release notes, but no explanation on how to use them/what they mean:
“Added Third Party binaries folder to Build Plugin command”
“Bugfix: Use runtime dependencies from module files to determine what needs to be included in released builds”
“New: Added new prebuildCopies stage to Android plugins before ndk-build is run to allow copies to JavaLibs. Continue to use resourceCopies stage for .so or other assets to copy after ndk-build so they are not removed.”
Perhaps one of these two things could save me?

Thanks!

The .so put be placed in /PROJECT/Intermediate/Android/APK/libs/armeabi-v7a to be included in the APK. resourceCopies is the place you want to do the copy (libs can be removed during the ndk-build step).

The runtime dependencies note I believe had to due to dll files for Windows, not Android.

Sadly the XML when parsed for logging/init is telling me it should work, the problem is that it isn’t.
I sent you a couple PM’s, with the attempted android version of the project. For a cleaner version without android stuff you can get it from our website, www.eliassoftware.com.

For others reading this thread and looking for answers, the problem was that I assumed that “S(PluginDir)” was the Plugins directory, it’s NOT! It’s the directory where I have the Modules build.cs file and the APL.xml file! (Not sure which one of these it’s actually related to.)

It is the directory of the XML file registered in AdditionalPropertiesForReceipt.Add.