I have upgraded my react-native project to 0.59.x so that it may provide a 64 bit version.
I now need to check whether each library I use provides a 64 bit version, such as react-native-firebase or various other popular libraries.
I've already decompressed the APK and observed that x86_64 contains files with the same names as in the x86 directory. My concern is that because my upgrade path was so complex and fraught with issues/hacks, and I'm using very old libraries which seem less likely to have 64bit versions, that perhaps some of those libraries within x86_64 directory might actually be 32 bit.
I feel like there must be some way, such as inspecting the .so files within the directory some way.
NOTE:
I understand that only libraries which provide native code will need to provide 64 bit version.
I assume React Native 0.59.x does not somehow guarantee my libraries are compiled to 64 bit also. I assume it's up to me to find a version of each library which also provides 64 bit version. If this is not true, and simply upgrading to 0.59.x does somehow guarantee my libraries are compiled to 64 bit, then tell me that and my entire question itself is solved. This seems extremely unlikely though.
My paranoia stems from using OLD react native libraries and then using this hack to bypass version mismatch issues during build.
Check out this issue, read the discussions, according to this if your any library is not 64 bit compatible it won't be compiled into 64 bit. And build won't be happening! If you have that kind of problem. Then you can detect which library is compatible or not!
In another way, you can do the split by ABI setting true def enableSeparateBuildPerCPUArchitecture = true
Produce the 64-bit version apks and check it out on 64 -bit version phone or emulator.
Related
I have an app that relies on some ARM 32-bit native libraries along with my own native library. Due to the new 64-bit requirement I need to have both 32- and 64-bit libraries in my APK, but I do not have access to the source code of those libraries so cannnot compile them to satisfy this demand.
I looked for 64-bit versions of the libraries I rely on and am sure they don't exist. Is it possible to somehow translate binaries from 32-bit to 64-bit or create fake libraries that won't be loaded at all?
No this is not possible. Your problem is similar to:
Linking 32-bit library to 64-bit program
Sadly the already bad solution for this type of problem, which is interprocess communication between an 32bit and a 64bit application will not work since the application which runs the native code needs to be 64bit.
This solution won't work anymore too see the statement at the bottom.
So you have only the following options:
Contact the publisher / owner of the library and request 64bit binaries.
Look for another library which might replace the current one.
Recode the needed functionality yourself. You might wanna disassemble the original library for that.
Run the 32bit library on a Server and make the app communicate with the Server. May be super slow and it requires an permanet internet connection.
I am pretty sure that providing "Fake" 64bit binaries will violate the ToS of the PlayStore so even if it get's accepted in first place it your app might get removed at any time.
But if you are willing to take the risk you can create you own 64bit version of the library you just need to make sure the linker is satisfied.
I want to release my SDK. but I have no idea Do I have some unknown problems if I compile the .so from different platforms (Mac or Window using same ndk version).
I think it is same between different platforms but I didn't have windows platform to confirm.
So Are the libraries different build from different platforms?
Bluntly, you should not believe that compilers produce the same code on the same input deterministically. Many do, but many do not. This is especially true when using optimization. (This situation is improving now the problem is recognized). The consequence of this is no matter what you build on you must only release the exact binary you have tested.
That said, you can totally build with the NDK on multiple platforms. Many of the large games studios use Windows and Macs for development, and production builds are done on Linux continuous integration systems, so this is done in practice all the time. You are far more likely to run into trouble with any extra tooling you have than the ndk itself.
You can safely mix Android binaries built on Mac and Windows, but please make sure you use the same NDK release and same parameters (most notably, same APP_STL).
You can send your native libraries built on Mac to Java developers who work on Windows. They don't even need NDK and don't care which release you were using (as long as it works).
I have an Android app that uses some JNI code. Long story short (pun intended), it is nearly impossible to convert the JNI libraries to 64-bit as it would require a lot of changes. The code (both Java and JNI) works nicely on armeabi-v7a architecture.
The libraries are being loaded using loadLibrary. When I attempt to run my app on a Nexus 6, the app loads fine. As soon as loadLibrary is executed, the app crashes with the error described here.
The problem, as I understand it, is that when executing on Nexus 6, the app builds as arm64-8a. But the libraries are not built for arm64-8a (as the 64-bit version has issues I mentioned at start of the question).
My question is, can I force arm64-8a devices to also run armeabi-v7a code? How do I force my app apk to be armeabi-v7a so it is only 32-bit regardless of device?
Yes, arm64-v8a devices can also run armeabi-v7a code.
When the APK is installed, the installer checks if the package contains libraries in the official directories, and marks the activity as 32 or 64 bit depending on the outcome.
If it finds libraries in lib/arm64-v8a within the APK (normally taken from the directory libs/arm64-v8a in the build directory), it will be marked as 64 bit, and will ignore all other directories. If it finds libraries in lib/armeabi-v7a or lib/armeabi in the APK, the process is marked as 32 bit. If there's no native libraries in any of these, the installer assumes that the application doesn't use native code at all and is free to run it in either mode, in practice in 64 bit mode.
Now if you do ship some, but not all, libraries in 64 bit mode, the process will be launched in 64 bit mode and will be unable to load the 32 bit libraries (which won't even be installed). In this case, you must avoid bundling any 64 bit libraries unless all of them are available.
Or you don't use the official libs directory but install your libraries some other way (e.g. by downloading them at runtime or keeping them in e.g. assets), the system has no idea that your process wants to run libraries in 32 bit mode (at which point it is too late to switch to the other mode). In these cases, make sure to include at least some dummy library in the normal/official way, in order to flag the application as 32 bit.
See https://stackoverflow.com/a/33919454/3115956, https://stackoverflow.com/a/27713998/3115956 and https://stackoverflow.com/a/35450911/3115956 for answers to similar issues.
I have some libraries that use native components, the libraries are built with NDK for 32 bit Arm architectures.
now we have 64-bit processors on modern devices, so I'm wondering if the libraries will work. In my situation, I don't have the source code files of the native library, just the SO files, I can't build them for 64-bits.
So will the 32-bits libraries run on 64-bits processors? or I have to re-build them?
**
EDIT
**
In my scenario I have the following:
1- I distribute the APK manually, didn't publish to Google Play yet.
2- The project has two native libraries, one with 64 & 32-bits support and the other with 32-bits only.
Is there a way to make the application work on 64-bits devices without having to publish to Google Play for now? can I remove the 64-bits libs to enforce the package manger to load the 32-bits ones?
The 32 bits libraries will work just fine on 64 bits processors.
As long as the libraries get installed the right/official way (i.e., not manually downloaded or extracted from some nonstandard part in the APK, but packaged properly in the APK), the package manager will detect that the process uses 32 bit libraries, and the process should be started in 32 bit mode. If not, the process will be started in 64 bit mode, and later will be unable to load 32 bit libraries. (If your APK would contain some .so files, but not all, in 64 bit mode, it would only install them, and the process would be launched in 64 bit mode. So unless all .so files are available for a specific ABI, don't include any of them).
So if you have a 64 bit version of one of the native libraries, just remove that and only ship the 32 bit version, until you have 64 bit versions of all of them.
I am currently in the process of updating our project OpenSSL to 1.0.1i using http://wiki.openssl.org/index.php/Android.
Looking in the config file I found that OpenSSL has 2 Android build options: android-armv7 and android-x86.
I have been able to build the armv7 configuration and it appears to be working correctly on a Nexus 5 and a Kindle Fire 1st Gen.
What I am wondering is would my current library work if it were in the armeabi directory instead of the armeabi-v7a directory? I was not able to find sufficient information as to whether it matters if the OpenSSL is built with armv7 but my project libraries are built with older arm in mind.
Note: My minimum API level is 8.
What I am wondering is would my current library work if it were in the armeabi directory instead of the armeabi-v7a directory?
I think there are a couple questions here. First, can you put libssl and libcrypto in armeabi/. That's an Android question (not an OpenSSL question). I seem to recall Brian talking about this on the NDK mailing list (but I can't find it at the moment). I believe the idea is armeabi/ is a fallback if a more specific library is not found in, for example, armeabi-v7a/.
Second is, can you run ARMv7a version of libssl and libcrypto on other platforms. I believe ARMv7a added a few hypervisor extensions over ARMv7, so you should be OK since OpenSSL does not use them. However, you might find yourself in trouble if running on an older device with ARMv6 or ARMv5.
In this case, you might want to download an older version of the Android NDK that builds for ARMv5, and then place ARMv5 version of libssl and libcrypto in armeabi/. You can find older versions of the NDK at Android NDK about a third of the way down the page.
To be more specific, Android 2.2 is API 8, and it was released around May 2010. So you might want to fetch and build with Android NDK Revision 3 from March 2010. NDK R3 only supported armeabi and targeted ARMv5TE (from the CPU-ARCH-ABIS.TXT file). The download is http://dl.google.com/android/ndk/android-ndk-r3-linux-x86.zip.
OpenSSL does not follow the instructions at Standalone Toolchain for ARMv7a. Its missing the -mfloat-abi=softfp flag. You might have trouble calling a function that passes a float to the library from Java. There are not many of them, but one is RAND_add. The entropy estimate is passed as a float and after the incompatibility, your estimate will likely be 0.0f. See Hard-float and JNI on the NDK mailing list and [Bug #3080]: Android NEON and CFLAGS options.
Here's a note from the README's that you should also be aware of:
III.3. Automatic extraction of native code at install time:
-----------------------------------------------------------
When installing an application, the package manager service will scan
the .apk and look for any shared library of the form:
lib/<abi>/lib<name>.so
If one is found, then it is copied under $APPDIR/lib/lib<name>.so,
where $APPDIR corresponds to the application's specific data directory.
If you update the APK and nothing changes, then be sure to delete anything under lib\ or delte the APK first (they have a tendency to become "sticky").
Another issue you will likely encounter is building and compiling against 1.0.1. Be sure you provide a wrapper shared object with a different name. Otherwise, you will likely link against 0.9.8 at runtime, and not the 1.0.1 gear in your APK. That's because Zygote loads Android's version of OpenSSL, and that version is 0.9.8. Later, when Zygote forks to create your process, the link-loader will not map-in your version of OpenSSL because its already present from Zygote.
OpenSSL has 2 Android build options: android-armv7 and android-x86
I added android-x86 to the script in June 2014. I was able to get through the build with one patch: [Bug #3398] PATCH: fix broken compile on android-x86 with no-comp configure option. I don't have an x86 Android device, so I was not able to run the self tests on a device. Feedback is welcomed.