Android NDK doesn't link static library - android

Some mystery is going on with my project :)
I have a shared library that uses libjpeg which is static library. It all worked fine but now when I need to add a few changes to the project it just stopped including libjpeg in my shared module.
So before when it worked, my shared module (.so file) was around 90Kb and now it 4Kb and application can't run saying that it can't find libjpeg.so
And folders structure is following:
/platform/libjpeg - include files for libjpeg
/platform/libraries - contain libjpeg.a and a few other libraries
UPDATE: After playing around with the projects I figured out that the problem appeared after I wanted to add android:installLocation into manifest. Following Google's recommendations for backward compatibility (http://developer.android.com/guide/appendix/install-location.html) I changed project's API level to 8 (so it parses manifest without errors) and left minSdkVersion="7" (so it runs on previous version). However, this particular change in the project affects the NDK build. Probably, libjpeg is included in android-8 and it doesn't want to build it in as a static library?
Anyway, the question is: Is it possible in eclipse to ignore error about installLocation in manifest using API level 7 or is it possible to force ndk-build to use API level 7 while keeping level 8 in the project settings?

In NDK you can find document docs/ANDROID-MK.html. In this document you will find option TARGET_PLATFORM. This should help.

Related

Android project with multiple so files in different ndk versions

I have an Android project with lots of so files which are built by third party. I wonder if it is OK when they build these so files by different ndk versions. And how does android device know which ndk version should be used to run these so files?
The NDK version only determines which header files are available at compile time (eg "asset_manager.h").
These header files in turn define some required functions ("AAssetManager_openDir"), which -- if you use them -- will result in dynamic symbol dependencies in your final library.
A device with a given Android version contains libraries with all the dynamic symbols for the versions up to that NDK version.
So to answer your first question: it does not matter, everything should just work.

System.loadLibrary() failed after adding apk into AOSP

I have developed android project using android studio.
It uses android native library which other developer built for speech recognization.
The APK works perfectly when i install on android devices.
I need to put this APK into AOSP because I am going to make android device only for our system. (I have already customized AOSP)
But after adding the APK into AOSP, the APK can not load library.
Error log:
java.lang.UnsatisfiedLinkError: dlopen failed: can't protect segments for "../libsengine.so": Permission denied
Please help me to fix this problem.
If you add your apk into AOSP system/app/ path as a prebuilt app, this might be of help:
Error adding prebuilt apk with shared libraries to AOSP
http://blog.csdn.net/a462533587/article/details/46380795
The problem is the shared library packaged in your apk has never been extracted to /data/app-lib directory, so it can't be linked.
It seems that the library you are using is utilizing some sort of dynamic code loading that is strictly prohibided on Android 26+ (Writable and Executable Segments Enforced for API level >= 26) .
You can read more about the security risk of TEXTREL on the following blog.
I assume that the reason the code works when compiling with Android Studio is because your build.gradle defines a minSdkVersion/targetSdkVersion that does not enforce the TEXTREL check. When compiling via the AOSP make, targetSdkVersion is most probably defined to be the 'current' version where the TEXTREL check is enforced.
These are only assumptions, so I guess you could check or alternatively provide more information such as the platform you are building and the Android.mk + build.gradle files.
I Think This is related to Marshmallow switching from OpenSSL to BoringSSL.
Your exception is occurring in the referenced library code. Contact the vendor for a fix or manually include the OpenSSL libraries to avoid the issue.
You can see this link: https://sourcedna.com/blog/20150806/predicting-app-crashes-on-android-m.html

UnsatisfiedLinkError in Android application with my JNI libraries

I am making an application that uses some JNI libraries built for an another app. I have, of course, imported all the necessary Java calsses to my application while keeping the package names the same. I have two libraries imported:
libopencv_java3.so
libopencv_xfeatures2d.so (I built this for an another project)
When I go into my old application, all the libraries load fine, but in this one I do not get any errors regardin loading the libaries themselves, but i only get errors regarding the acutal methods. This happens only with my library, as all opencv_java3 calls seem to work fine. I have placed all of the .so files in the jniLibs folder, and I checked the apk to see if they were packaged correctly, and everything seems fine there. Anybody else having my same issue?
BTW I am using Android Studio 1.5.1, libraries built with NDK r10 with target API 15 (which is also the minimum API for the application).

android nkd and sdk compatibility issue (run time linker error)

Should/does NDK9 work with android API19? (though it was released with API18).
Full story:
I was building an Android App using kivy, python-for-android and buildozer.
compiling with MDK9 (ie 9d) and api19 result in error:
E/AndroidRuntime( 1773): java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "wait4" referenced by "libpython2.7.so"...
compiling with NDK9 (ie 9d) and API18 works. :)
Just in case anyone stumbles across this. I had the same issue, but building python from scratch using the platform tools, and with NDK r10 and r10b.
It's because google removed an inline wait4() declaration in the NDK platform android-19. The original problem was that wait4() was exposed in the headers but not declared anywhere, so if you tried to use wait4 on older NDKs, you'd probably crash (like you do now).
So they went in and added it to libc.so in API 18 I believe, but libc.so is shipped with the O/S, so devices with O/S older than 18 would not have wait4, so they patched it by adding an inlined wait4() method in NDK platforms up through android-18, then took it out in android-19 I'm not fully sure why yet, seems like it could have made more sense to leave it alone at that point, especially since it's considered an obsolete function. I was told I should not build against android-19 if I wanted the app to run on devices older than API 18, but others say to always use the latest NDK to match your build target. Here is a link to the problem.
https://code.google.com/p/android/issues/detail?id=19854
In my case, I went into the cpython Modules/posixmodule.c file, and added:
#if defined(__ANDROID__)
#undef HAVE_WAIT4
#endif
And in my case that's fine, because none of my python modules use wait4. Indeed, Linux deems the wait4 command obsolete (http://linux.die.net/man/2/wait4). You should instead use the waitpid.
So, even if you download some 3rd party python module that does use wait4, you have 2 options. 1) change that module to use waitpid, or 2) update the Modules/posixmodule.c file inside the "ifdef HAVE_WAIT4" section, and replace the wait4 call with waitpid. The downside is you lose the returned resource usage information, which waitpid doesn't provide, so then if your module needs that, you'd have to add something to retrieve resource usage for that pid separately.
Alternatively, you could remove "wait4" from your configure script if you never plan to use it, and any modules you add that needed it would break, at which point the new engineer working on the problem would have to rediscover all of this over again.
Android SDK are released more often that NDK. It happened more than once that if you use a too recent SDK, the NDK will not have the .h for it. Now i'm not sure this would be related to your issue at all.

Android can't load local libcrypto unsatisfied link error

I need to run a newer version of openssl in my app than the one that comes in the OS. I was able to patch and android source to compile a newer version and then extract the shared library to use in my app.
I was then able to compile and link my native code that requires a function only in newer versions of openssl against my new shared library (the patch to a newer openssl worked).
I was also able to create a few jni functions that work as expected but as soon as I added in the function that is only in the newer openssl shared library local to the app I get an unsatisfied link error.
My assumption is that the system version of libcrypto and libssl are overriding my local versions in /libs/armeabi/libcrypto.so and /libs/armeabi/libssl.so .... how to I fix this?
The system already ships with a library known as libcrypto, and that will be picked before your library will. The easiest solution is to give your library a different name, and use that in your System.loadLibrary(...) call.
Update
As you pointed out, you will need to rebuild the library with the new name, in stead of just renaming the file.
Yes JNI is picking up the system versions. It didn't use your patched versions at all. On standalone JVM you would say -Djava.library.path=/libs/armeabi or modify environment variable LD_LIBRARY_PATH. On Android i guess you can either look up the system property java.library.path and put your libs in some known place (but before the folder where the system versions are) or actually modify the property - prepend the path to your local versions. I do have some experience with Android but not specifically with NDK.

Categories

Resources