kikitte / GDAL4Android

Builds GDAL into an Android Archive(AAR) file
10 stars 2 forks source link

Issue with compiled *.aar file #10

Open RGregat opened 3 weeks ago

RGregat commented 3 weeks ago

Cheers, thx for your work. I was able to create a .aar file with the Docker-Setup. If I add the .aar file to a brand new Android-Project I get the following error

nativeloader: Load libgdalalljni.so using ns clns-4 from class loader (caller=/data/app/~~xmfU620NYYwhDeNEAdvLtw==/com.example.gdaltest-m8Nv6D9x1evg6oVXSWWpGA==/base.apk!classes4.dex): dlopen failed: library "libgdalalljni.so" not found
System.err: Native library load failed.
System.err: java.lang.UnsatisfiedLinkError: dlopen failed: library "libgdalalljni.so" not found
xample.gdaltest: No implementation found for void org.gdal.gdal.gdalJNI.AllRegister() (tried Java_org_gdal_gdal_gdalJNI_AllRegister and Java_org_gdal_gdal_gdalJNI_AllRegister__) - is the library loaded, e.g. System.loadLibrary?
TestRunner: failed: testGDAL(com.example.gdaltest.ExampleInstrumentedTest)
TestRunner: ----- begin exception -----
TestRunner: java.lang.UnsatisfiedLinkError: No implementation found for void org.gdal.gdal.gdalJNI.AllRegister() (tried Java_org_gdal_gdal_gdalJNI_AllRegister and Java_org_gdal_gdal_gdalJNI_AllRegister__) - is the library loaded, e.g. System.loadLibrary?
TestRunner:     at org.gdal.gdal.gdalJNI.AllRegister(Native Method)
TestRunner:     at org.gdal.gdal.gdal.AllRegister(gdal.java:712)
TestRunner:     at com.example.gdaltest.ExampleInstrumentedTest.testGDAL(ExampleInstrumentedTest.kt:28)
TestRunner:     at java.lang.reflect.Method.invoke(Native Method)
TestRunner:     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
TestRunner:     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
TestRunner:     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
TestRunner:     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
TestRunner:     at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
TestRunner:     at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
TestRunner:     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
TestRunner:     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
TestRunner:     at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
TestRunner:     at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
TestRunner:     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
TestRunner:     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
TestRunner:     at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
TestRunner:     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
TestRunner:     at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
TestRunner:     at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
TestRunner:     at androidx.test.ext.junit.runners.AndroidJUnit4.run(AndroidJUnit4.java:162)
...
10-08 09:51:48.733 26484 26584 E TestRunner: ----- end exception -----

libgdalalljni.so is missing.

Adding cp $INSTALL_DIR/lib/jni/*.so $ABI_JNI_DIR to the build_cpp.sh and re exporting to .aar lead to the next error. This time is libgeos_c.so.1 missing. Which is of course out of the scope of this repository, because you have not included geos. I tried to add them in the build_cpp.sh but for some reason this file is not added to the resulting .aar.

RGregat commented 3 weeks ago

Here is an interesting SO about the issue (https://stackoverflow.com/questions/11491065/linking-with-versioned-shared-library-in-android-ndk).

In a nutshell, Android has problems to pack versioned *.so files.

kikitte commented 3 weeks ago

Prebuilt native libraries need to be placed on src/main/jniLibs/ABI directory, currently they are installed on $INSTALL_DIR/lib/, e.g GDAL4Android/gdal/cpp/.install/aarch64-linux-android/lib/ , and this is already done with https://github.com/kikitte/GDAL4Android/blob/110f22c03ef9cce14135979c83a75a49044b2041/gdal/build_cpp.sh#L218-L222

kikitte commented 3 weeks ago

Here is an interesting SO about the issue (https://stackoverflow.com/questions/11491065/linking-with-versioned-shared-library-in-android-ndk).

In a nutshell, Android has problems to pack versioned *.so files.

Sad. May be we need to move libgeos_c.so.1 to libgeos_c.so manually in $INSTALL_DIR/lib/ after geos is installed, so gdal will use libgeos_c.so. Or any methods to produce non-versioned so file may solve this problem too, e.g modify geos build script?

RGregat commented 3 weeks ago

This might be one solution. Another one, I stumbled upon my research, is patchelf (https://github.com/NixOS/patchelf). Both options are feeling hacky :)