x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Office Holiday

Epic Games' offices will be on holiday from June 22nd to July 7th. During this period support will be limited. Our offices will reopen on Monday, July 8th. 

What is correct and present method of packaging a prebuilt shared library (.so) for Android

While there are replies on this topic historically, they tend to be several years old and definitely not in keeping with the modern way (4.11 at the time of this post) UE deploys custom libraries on Android.

So I would like to know: what is the correct, modern (per our present version of UE) method of packaging prebuilt shared libraries for android such that we can call into them from our GameActivity.Java?

I know that the answer is not modifying private engine source and creating a custom build (that is what a lot of posts outline). I doubt that I need to modify the .MK files for unreal (the present architecture uses things like GameActiivityInsert.XML and such to create changes in the manifest and elsewhere). And I see all kinds of methods all over the place in terms of where to put one's .so binaries ranging from a plugin to a number of other places.

Here is a simple scenario to answer:

I have a library for android, compiled as arm7 called libsimplelibrary.so. It has a function called AddTwo that adds two floats.

Specific Question:

1) Where exactly should this binary sit in the file/directory structure a newly generated Unreal project? 2) what files, specifically, do I need to modify to inform UE4 that this file exists and needs to part of my APK? GameActivityInsert.XML I would think, and our build.cs. But would like to see and understand the bare minimum necessary here. 3) What UE files need to be modified to load this library. I see a section in gameActivityInsert.XML. Do I add it there? And if so, what is the syntax?

Bonus: 4) how do I call into the library and call the Add function. GameActicityInsert.XML again I would think, but can I simply declare the C function in the shared library as a"native" in the java and call into it? or do I need to craft a JNI call by hand?

(I know there are many posts on this, but they are several years old and either 1) involve modifying a custom build of the ue4 engine or 2) suggest "look at what ", but we are not developing a plugin. I am really hoping for the "hello world"/simplest demonstration of this.)

Product Version: UE 4.11
Tags:
more ▼

asked Apr 27 '16 at 10:16 PM in Packaging & Deployment

avatar image

gbrill
131 5 8 14

avatar image Rama Apr 28 '16 at 05:26 PM

I would really like to know the answer to this too :)

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

1 answer: sort voted first

Hi gbrill,

The proper way to do this since 4.10 is to use AndroidPluginLanguage. During packaging, all the APL XML files registered with the build system (in the module Build.cs files) are run to allow copying of resources, modify the AndroidManfest.xml and proguard files, and insert code into GameActivity.java. While APL was intended for plugins, any module may register a XML file to process, so you can just have a code based project and add to its Build.cs, for example.

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

The above is an example. The My_APL.xml is expected to be placed in the same directory as the Build.cs (PluginPath).

You can find an example in GearVR_APL.xml. It does some conditional staging of libraries and modifications to the manifest, proguard, and GameActivity.java. is the section you would want to copy your .so into place for packaging. is where your .so would be loaded. Since this is just native code, you can just call it from your C++ code. You only need to use JNI to call back and forth between native C++ and Java code.

more ▼

answered May 03 '16 at 05:47 PM

avatar image

Chris Babcock STAFF
1k 11 110 35

avatar image gbrill May 03 '16 at 06:05 PM

I have used the XML archutecture, and I do see my shared libraries packaged. I can also call these libraries on the android device BUT only through dlopen()/dlsym() dynamic calls. You can not, as one would expect, simply link and call the native code function within a shared library from ue4...i get "undefined reference" to any function I try to do this with. It seems as though clang c++ that ue4 is using to compile itself and the gcc that is uses from the NDK are either 1) not binary compatible or 2) are not linking in the correct order.

note that I am adding the prebuilt .so library in build.cs, and that normally allows me to call a C++ shared library from ue4 C++, but not in the case of android.

So yes, the XML plugin architecture will work mostly (with a lot of reading, studying and work) but I can not call native-to-native as I would expect.

avatar image kamrann Sep 13 '16 at 05:52 PM

I know this is old but just want to add that I've had no problems doing this. I add PublicAdditionalLibraries.Add("path/to/mylib.so"); to an Android-only section of my .build.cs and am able to call into the library without issue.

If you did not sort this out, I would guess there is something wrong with your compilation settings when building your .so.

avatar image gbrill Sep 19 '16 at 05:25 PM

wrt. linking error, I think I can close this off also and provide some troublehooting advice for others...This was some time ago, but I did ultimately succeed with linking, and I am trying to remember the issue....but it may have had to do with one of two related things:

1) an extern "C" declaration (important to stave off name mangling) 2) it was a C++ dll, not a straight C, so we have name mangling even for standalone, global functions. I think I rectified that with #1.

All in all, I do believe there was a distinction between a C++ and C .so, and my linking issues were do to this.

avatar image FilAl Oct 21 '17 at 09:01 AM

Doesn't work for me at v4.16.2 ! I got over all linking and include errors (thanks to this post also), but got dead stuck on error:

error: inline function 'ExternalFunctionName' is not defined [-Werror,-Wundefined-inline]

Where ExternalFunctionName is the name of the function from .so file. Please help!

What do i do: Include .h file with all function signatures in the code and perform PublicAdditionalLibraries.Add("path/to/mylib.so"); at the Build.cs file. Do i miss something?

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question