I'm having a set or Gradle modules that uses the core module based on c++ code:
Core (C++ with JNI glue, aar with libxyz-jni.so)
Tests (Android instrumentation tests)
App (regular Android app)
Core module includes native 32 bit libxyz-jni.so compiled for armeabi-v7a and x86 and is compiled to aar. It does not have arm64 libraries.
App module depends on Core and is working on arm64 hardware device without any issues (is able to load libxyz-jni.so)
Tests depends on Core and fails to load libxyz-jni.so (with System.loadLibrary(..)) with following error:
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/package.tests.test-2/lib/arm/libxyz-jni.so" is 32-bit instead of 64-bit.
I've checked tests apk not to contain any arch except armeabi-v7a and x86. The tests can run in android emulator but can't on 64 bit hardware device with Android Nougat. The App can run on arm64 device.
That's the difference between tests and app in terms of loading library?
You should check to see what libraries your app is using at runtime. You can do this with these commands:
# get your running pid
adb shell ps | grep <your package name> | tr -s ' ' | cut -d ' ' -f 2
32333
adb shell lsof | grep 32333 | grep so
.xxx 32333 u0_a222 mem REG 259,30 133152 2629 /system/lib64/libcompiler_rt.so
.xxx 32333 u0_a222 mem REG 259,30 30824 2759 /system/lib64/libmemalloc.so
As you can see in this case Android has loaded lib64 libraries. If you want it to default to loading 32-bit libraries, you need to have lib/armeabi-v7a/lib.so in your APK.
If you have your libraries somewhere else in the APK, and you extract, and load dynamically, Android won't know they are 32bit.
Related
I have a small application that uses a native ARM shared library (.so). When using Genymotion, I can successfuly install the ARM translation package (just by dropping the ZIP file) and the app runs fine on a x86-based emulator.
Now I have the need to run the same app in a headless linux server, which is not supported by Genymotion. I downloaded the official google emulator and corresponding system image. After extracting the files from zip archive and uploading to /system partition, I can run houdini --version, however the application won't install (INSTALL_FAILED_NO_MATCHING_ABIS).
Can you please guide me how to run the app which contains ARM library on the official google x86 emulator?
What is the output of houdini --version ?
When you install applications PackageManager checks ABI of the app(which libraries are contained in the apk .so files) and the ABI of the system (which type of libraries system supports)
if you run getprop | grep -i abi
getprop | grep -i abi
[ro.product.cpu.abi]: [x86]
[ro.product.cpu.abilist]: [x86,armeabi-v7a,armeabi]
[ro.product.cpu.abilist32]: [x86,armeabi-v7a,armeabi]
[ro.product.cpu.abilist64]: []
In this output, the system supports 32 bit .so files of x86, armeabi-v7a and armeabi type.
Please check this output on your device. Most probably there will be no mention of armeabi in this output.
So when PackageManager tries to install ARM app and checks that this ABI is not supported, it throws INSTALL_FAILED_NO_MATCHING_ABIS error.
So you will have to fix the system ABIs.
Edit the file /system/build.prop to add ARM support, in ro.product.cpu.abilist and ro.product.cpu.abilist32.
If you are running 64 bit Android, you will have to change these lines.
ro.product.cpu.abilist=x86_64,x86,arm64-v8a,armeabi-v7a,armeabi
ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
ro.product.cpu.abilist64=x86_64,arm64-v8a
I try to debug a very basic example Qt 5.3 Android native C++ project, and I would like to debug it on the target without using QtCreator or any other IDE like Eclipse but only NDK tools.
This project is compiled through QtCreator tools using Android platform target, in debug mode (-O0, -g), using NDK toolchain, BUT NOT ndk-build.
Therefore I got my .apk, the application itself has been installed on the target and works, everything is fine up to that point. Now I want to execute it in debug mode using NDK tools.
I would like to use ndk-gdb as this seems to be one of the most obvious ways, therefore:
- I created manually required files under my main project directory:
bin
src
res
...
jni
|-- Android.mk
`-- Application.mk
libs
|-- armeabi-v7a
| |-- gdbserver
| |-- gdb.setup
The tree above only underline the files I added by hand, given that they are normally created by ndk-gdb.
Under the 'libs' directory is also stored the native library of the project, called by a simple java wrapper.
jni/Android.mk and jni/Application.mk contains the same single line:
APP_ABI := armeabi-v7a
gdb.setup:
set solib-search-path ./libs/armeabi-v7a
directory <myrootdir>/NDKToolchain/sysroot/usr/include <myrootdir>/NDKToolchain/include/c++/4.6 <myrootdir>/NDKToolchain/include/c++/4.6/arm-linux-androideabi/armv7-a [...]
I checked that the target was connected and accessible by installing the application using adb:
% adb install -r bin/QtApp-debug.apk
It worked ('success'), which I could check directly on the target.
Then when I try to run ndk-gdb, it failed:
% ndk-gdb --start --nowait --verbose
WARNING: The shell running this script isn't bash. Although we try to avoid bashism in scripts, things can happen.
ndk-gdb: 84: Bad substitution
Android NDK installation path: [...]
Using default adb command: [...]/sdk/platform-tools//adb
ADB version found: Android Debug Bridge version 1.0.31
Using ADB flags:
Using JDB command:
Using auto-detected project path: .
Found package name: org.qtproject.example.fridgemagnets
ABIs targetted by application: armeabi-v7a
Device API Level: 18
Device CPU ABIs: armeabi-v7a armeabi
[: 564: 1: unexpected operator
Compatible device ABI: armeabi-v7a
Using gdb setup init: ./libs/armeabi-v7a/gdb.setup
Using toolchain prefix: [...]/ndk/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
Using app out directory: ./libs/armeabi-v7a
Found debuggable flag: false
Found gdb.setup under libs/armeabi-v7a, assuming app was built with NDK_DEBUG=1
ERROR: Could not extract package's data directory. Are you sure that
your installed application is debuggable?
A previous run of ndk-gdb showed me that for some reason it wanted to use ./obj/local/armeabi-v7a as "app out directory", while I set it in gdb.set to ./libs/armeabi-v7a, therefore I had to hack the ndk-gdb script to force it to use the path I chosed. I don't believe this is related to my real issue (?)
Given that I didn't use ndk-build, I believe that my attempt to use ndk-gdb is hopeless, or at least that it will ask me too much work and hacking of NDK scripts which I don't want to do.
Thus 2 questions:
Did I miss something during my build or deployment for getting a
debuggable app ? I know that debuggable flag in Manifest being
'false' is not necessarily an issue, as I built my app with debug
flags. BTW this seems to be confirmed by the fact that the error
message I get is not related to that flag but to the fact that the
script seems to exepect a DATA_DIR folder somewhere...
Is there a
way to debug my application, without using ndk-gdb (and any IDE),
but for example just 'gdb' ?
Thanks in advance
Question 1:
I know that as of SDK r8 you can invoke ant with release or debug. Building with the debug flag might package or run your application differently. Thus allowing or disallowing debugging? This seems like it might be the issue.
Question 2:
From what I understand ndk-gdb does a lot of setup and communication with adb to allow debugging your application, as you may have seen from the script. I wouldn't suggest going down the rabbit hole of not using it.
I'm trying to build ffmpeg4android on current AOSP tree (from /external), which is lunch-configured to aosp_arm-eng and set to PLATFORM_VERSION=4.2.
Resulting files are generated for AMD64 (host native) architecture, even though the major rest of tree is built (as expected) ARM:
readelf -a android/aosp_arm-eng/ffplay|egrep "Class:|Machine:"
Class: ELF64 Machine:
Advanced Micro Devices X86-64
versus
readelf -a
aosp/out/target/product/generic/symbols/system/lib/libril.so | egrep "Class:|Machine:"
Class: ELF32
Machine: ARM
I will probably switch to other ways of getting ffmpeg-arm (presumably the one described here); the reason of asking this question is to understand, at which build stage does cross-compilation environment breaks.
I have two processes in the Android application- main application process and a remote service process.
The native libraries are loaded from the remote service process.
I want to debug the native library code.
The application is debuggable. The native library was built from Windows command-line using ndk-build. In Android.mk, -g -ggdb flag was used for this library.
I am running ndk-gdb from cygwin.
Test device: Galaxy Nexus running Android 4.2.2
Error line: error while loading shared libraries: ?: cannot open shared object file: No such file or directory
In the verbose information, I see that gdbserver is trying to attach to process id of the main application process. Should it matter that the library is loaded from a remote process within this application.
Detailed ndk-gdb run information-
$ ndk-gdb --verbose --force
Android NDK installation path: /cygdrive/c/work/android/ndk/android-ndk-r9-windows-x86/android-ndk-r9
Using default adb command: /cygdrive/c/work/android/sdk/android-sdk_r10-windows/android-sdk-windows/platform-tools/adb
ADB version found: Android Debug Bridge version 1.0.31
Using ADB flags:
Using JDB command: /cygdrive/c/program files (x86)/java/jdk1.6.0_25/bin/jdb
Using auto-detected project path: .
Found package name: [application-pkg-name]
ABIs targetted by application: armeabi
Device API Level: 17
Device CPU ABIs: armeabi-v7a armeabi
Compatible device ABI: armeabi
Using gdb setup init: ./libs/armeabi/gdb.setup
Using toolchain prefix: /cygdrive/c/work/android/ndk/android-ndk-r9-windows-x86/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-
Using app out directory: ./obj/local/armeabi
Found debuggable flag: true
Found device gdbserver: /data/data/[applcation-pkg-name]/lib/gdbserver
Found data directory: '/data/data/[applcation-pkg-name]'
Found running PID: 17890
Launched gdbserver succesfully.
Setup network redirection
## COMMAND: adb_cmd shell run-as [applcation-pkg-name] lib/gdbserver +debug-socket --attach 17890
## COMMAND: adb_cmd forward tcp:5039 localfilesystem:/data/data/[applcation-pkg-name]/debug-socket
Attached; pid = 17890 [Comment: This pid is for the main application process]
Listening on Unix socket debug-socket
## COMMAND: adb_cmd pull /system/bin/app_process obj/local/armeabi/app_process
493 KB/s (9592 bytes in 0.019s)
Pulled app_process from device/emulator.
## COMMAND: adb_cmd pull /system/bin/linker obj/local/armeabi/linker
1165 KB/s (63244 bytes in 0.053s)
Pulled linker from device/emulator.
## COMMAND: adb_cmd pull /system/lib/libc.so obj/local/armeabi/libc.so
2442 KB/s (297608 bytes in 0.119s)
Pulled libc.so from device/emulator.
/cygdrive/c/work/android/ndk/android-ndk-r9-windows-x86/android-ndk-r9/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-gdb.exe: error while loading shared libraries: ?: cannot open shared object file: No such file or directory
Couple of side notes that could be helpful-
1) If I run the ndk-gdb command without --force, it gives me error that Another debug session is running. Although the gdb prompt came out during the last run.
2) On Android 4.3, with the same application and setup, I get error that "Could not extract package's data directory"
I'm trying to install an Android developement environment (JDK+SDK+Eclipse+Plugins) on my Toshiba AC100 (ARM architecture), but
http://developer.android.com/sdk/index.html
says the SDK is only available for x86 architecture. Does anyone have an idea how to get it running on my device? I'm using Ubuntu 11.10.
based on TerminalIDE chrooted arm env for compilling APK on android devices,
there is maybe a way to isolate compiller binaries to run under linux-arm
I'll try, if I'm able, I will let you known ....
But you will have notepad/eclipse // cmd line compillation (you could make an ant env or some not ugly .sh)
ok, a bit more ....
(based on terminal ide env & w32 env)
You'll need jdk (arm) then
aapt (is a binary so needs to find its sources ;( but it's just required to create R.java (resource id manager) -- if you project to make a cli program : it is not mandatory...) | ;( |
dx is a JVM script : that calls a pure java jar (w32 uses dx.jar from sdk) | ;) |
apkbuilder is a JVM script : that calls a pure java jar (w32 uses sdklib.jar from sdk) | ;) |
javac is the classical javac but add android.jar to its classpath (I recommend the API-8 froyo version to be most compatible) | ;) |