I can build openssl-1.0.2j successfully for android (libcrypto.so and libssl.so) using GitHub stdchpie/android-openssl:
Environment: Linux OS, (my case I use Mac OS)
Android NDK: 12b
On Android 5.x if using:
System.loadLibrary("crypto");
System.loadLibrary("ssl");
It will get conflict with native OS libs which also have same names. And unluckily, manually change their names didn't work. So that I want to compile them into different names , like libcryptox.so and libsslx.so
I try to play with Makefile.org all day but not lucky. So please someone tell me how to do.
The system has those libs loaded in the run-time environment, you can't use the System.loadLibrary
You can make small ndk code that will use native dload for those libs.
And eventually, I think its best to use the ssl api's through the common android API as you never know what they will do next version.
Related
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.
I would like to use a shared library, that is compiled for arm64, on Android. I have my .so file inside a aarch64-linux-gnu folder, but for other libraries I have instead a aarch64-linux-android folder.
Please can these libraries compiled for aarch64-linux-gnu run on an arm64 Android device? What do these names stand for precisely? I know that aarch64 refers to the arm64 processor architecture but I don't know how the operating system is related here.
Thank you!
Android and ARM my have some libraries that are the same. Basically the SO file has to be able to find all the libraries it was linked against to run, and the versions need to match up so nothing breaks. This is risky, and it is generally safest to compile the entire program on your target machine. You can see if everything can be located/what is missing using:
ldd /path/to/file.so
this will give you a list of libraries and where the file thinks they are - or ??? if it can't find it. You need to double check and see if the results of this look OK.
Even if all dependencies are found, mismatch in versions or architecture will cause the program to break at run-time. You need to extensively test the use of the externally linked library and even then you may miss some cases that break your program. For this reason I would try and get the source code if possible, and re-compile everything on the target machine.
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
My project includes native libraries compiled only for ARMv7. When I try to install it on Samsung Galaxy Y (which has ARMv6), I get INSTALL_FAILED_CPU_ABI_INCOMPATIBLE error.
However, I want to make my application deployable for every devices, no matter they have ARMv7 or not. If target device is an ARMv7, using native library will be a plus. That's it. For the rest of devices, application will do its job without calling native methods. (Because of libary has a large .so file, I don't want to include compilations for other architectures).
Any ideas to overcome this error ? How can I tell Android to ignore native libraries compiled for different architectures and make my APK deployable ?
PS. I'm seeking soultions rather than "creating mutiple APKs"
Thanks
So, by looking trough the NDK documentation I found this interesting hint (look inside the NDK folder in docs/Programmers_Guide/html/md_3__key__topics__c_p_u__support__chapter_1-section_8__a_b_is.html):
put your library inside assets folder
at runtime detect the cpu architecture using this java call: String arch = System.getProperty("os.arch");
If the result is something like "armv71" copy the lib from your assets to your data directory in the lib subdir: /data/data/<package_name>/lib/
Now you can safely call System.loadLibrary(...)
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.