Compiling C files on Ubuntu and using them on Android - android

so today I've tried to use my C code in Android. I've made it work on intellij with regular generated dll files. From what I've understood, Android uses .so files instead of .dll files. So I've compiled with ubuntu and gcc, using the following commandline :
gcc -m32 -fPIC -o libilcore.so -shared -I/usr/lib/jvm/java-9-openjdk-amd64/include -I/usr/lib/jvm/java-9-openjdk-amd64/include/linux java.c -lc this went fine, no errors whatsoever and I got the .so file. I've put it in the jniLibs directory, and inside I made a armeabi directory, However when I try to load the library, it says
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/org.packagename.test-1/lib/arm/libilcore.so" has unexpected e_machine: 3
I have no clue on what this means, I've looked it up on google, its either the wrong way to compile on ubuntu or I've done something else wrong, can anyone please help?
Thank you in advance!

Related

Unable to get qmake to cross compile correctly

I am new to this build system, but I've spent dozens of hours trying to get qmake + clang to produce a working android binary. I would appreciate any help or advice. Here is as simple an example as I can come up with:
First, here is a working build command. It gives me a shared object that I can call from android (with Unity, using C# native interops):
C:\Users\deltav\AppData\Local\Android\Sdk2\ndk\21.3.6528147\toolchains\llvm\prebuilt\windows-x86_64\bin\clang.exe ^
-target aarch64-none-linux-android21 -shared -v ^
-DANDROID_ABI=arm64-v8a -DANDROID_ARM_MODE=arm -DANDROID ^
M:\simpleExample\simpleExample.c ^
-o M:\simpleExample\libsimpleExample.so
Here is the verbose output of running that command: https://pastebin.com/18HcnDYh
On the other hand, here is the simpleExample.pro file that is NOT giving me a good binary: https://pastebin.com/wxrx6Myc
Here is the qmake output for building in release mode: https://pastebin.com/KWavwrb7
As you will know, qmake uses a kit to execute the project. My kit: https://imgur.com/a/Ehtmgin
The specific issue that has pushed me down this debugging path is from C# trying to load my shared object like this:
[DllImport("simpleExample")]
public static extern float getSpeedY();
The error that I get is this:
"DllNotFoundException: Unable to load DLL 'simpleExample': The
specified module could not be found."
Again, this error is not an issue if I just build from the CLI without qmake. I do not beleive this is a unity or C# error, as I worked the problem from that side first.
What I have tried so far:
I have used multiple ELF & DWARF tools to compare the ABIs of the generated binaries, which all told me the binaries were identical.
I tweaked and shaved down the clang calls that qmake generated until I got a vaild build command. Unfortunately I can't just replace qmake with the complile command because there are other projects that I need to apply this fix to.
QMake version 3.1
Ironically, CMake basically works out of the box.
Answer: Looking at the clang linking call, you can see QMake 3.1 was adding "libc++shared" as a dependency. I'm not sure why, as this was a C project.
The equivalent CMake project did not do this.
Packaging libc++shared with my binary fixed the issue.

#include <exception> - No such file or directory

I am currently trying compiling GnuTLS (for wget) for Android with the Android cross-compile toolchain.
I already fixed many missing-library errors, but now I get the error
./includes/gnutls/gnutlsxx.h:26:21: fatal error: exception: No such file or directory
#include <exception>
I am using "arm-linux-androideabi-gcc (GCC) 4.9 20140827 (prerelease)" and am using this script https://gist.github.com/z3ntu/57b95b02ebe8e153d5a8 for settings up the env-variables.
You want to run the following command which will tell you where gcc's pre-processor is. Then ask that pre-processor here it's looking for C++ header files:
gcc -print-prog-name=cc1plus -v
then tweak your setup accordingly.
Actually I solved it myself... (still thanks for the help everybody!)
So for all who wonder how to compile GnuTLS for Android:
Create a standalone toolchain: Execute build/tools/make-standalone-toolchain.sh --platform=android-21 --install-dir=<your_directory> --toolchain=arm-linux-androideabi-4.9 --stl=gnustl from the NDK root dir (maybe ~/Android/Sdk/ndk-bundle/)
Compile it with extra -lgnustl_shared in your LDFLAGS.

Compiling FFMpeg for android

A lot of people have mentioned about compiling ffmpeg for android. But I recently tried many of them and did not find them working.
Here is what I tried.
https://github.com/guardianproject/android-ffmpeg-java
but in this I got the following errors.
/home/musil/Desktop/android-ndk-r10c-linux-x86_64/android-ndk-r10c/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=/home/musil/Desktop/android-ndk-r10c-linux-x86_64/android-ndk-r10c/platforms/android-3/arch-arm -I../x264 -mfloat-abi=softfp -mfpu=neon -mcpu=cortex-a8 -c -o /tmp/ffconf.6LOSva5W.o /tmp/ffconf.YWZ9ftQ8.c
arm-linux-androideabi-gcc: error trying to exec 'cc1': execvp: No such file or directory
C compiler test failed.
Than I have tried other way mentioned on
http://www.roman10.net/how-to-build-ffmpeg-with-ndk-r9/
but in that I got the following error.
But in that the prefix install is /usr/local/ instead of ./arm/ and arch is x86 instead of arm. And it compiles but no arm folder is created.
Does anyone know how to compile ffmpeg for ndk-r10c.
Will be very helpful if someone can point out what I am doing wrong or how can I build the ffmpeg 2.4.1 for latest ndk.
Thanks
I am not sure why you see that error. I was able to successfully compile FFMpeg and you should be able to get the .so files for all architecture from this link https://github.com/android-native-libraries

Android r8b c++ shared library problems

This is a weird setup here. I compiled a custom NDK with GCC 4.7 (for Debian armhf chroot host). In testing, it compiles and runs regular c and c++ binaries on Android perfectly. When trying to compile a test shared library with C++ using:
arm-linux-androideabi-g++ -fPIC -shared test.cpp -lstdc++ -o test.so
I get numerous linker errors to _staticinitialization_destruction and _dso_handle being unreferenced.
I have both libstdc++.a and libstdc++.so available in the lib folder under arm-linux-androideabi directory. What is going on? There's hardly any info on Android C++ standalone compiling out there.
Edit
It seems __dso_handle is undefined for the iostream portion of the GNU STL. I found the answer from a 2005 Linux post. Still an issue in 2012 it seems :O lol.

compile ffmpeg with android ndk r5b

compile ffmpeg with android ndk r5b.
ffmpeg 0.6.1
android ndk r5b
cygwin 1.7
build reference url : http://www.cnblogs.com/scottwong/archive/2010/12/17/1909455.html
but, ffmpeg ./configure result error! (below config.err file)
check_cc
BEGIN /tmp/ffconf.GlDiY1P8.c
1 int main(void){ return 0; }
END /tmp/ffconf.GlDiY1P8.c
/android-ndk-r5b/toolchains/arm-eabi-4.4.0/prebuilt/windows/bin/arm-eabi-gcc -fPIC -DANDROID -c -o /tmp/ffconf.1kQLpGaU.o /tmp/ffconf.GlDiY1P8.c
arm-eabi-gcc.exe: /tmp/ffconf.GlDiY1P8.c: No such file or directory
arm-eabi-gcc.exe: no input files
C compiler test failed.
so, i just try test code.
// test.c code
int main(){
return 0;
}
/android-ndk-r5b/toolchains/arm-eabi-4.4.0/prebuilt/windows/bin/arm-eabi-gcc -fPIC -DANDROID -c -o ./test.o ./test.c
ok!!!! no problem.
but,
cp ./test.c /tmp (copy to /tmp)
/android-ndk-r5b/toolchains/arm-eabi-4.4.0/prebuilt/windows/bin/arm-eabi-gcc -fPIC -DANDROID -c -o ./test.o /tmp/test.c
arm-eabi-gcc.exe: /tmp/test.c: No such file or directory
arm-eabi-gcc.exe: no input files
fail!!!
difference is only file path. /tmp directory exist, and permission is right. /home/test.c is same result.
what's wrong?
I have had a hard time to get it working in Windows, but finally I've managed to do it!
The previous posts were correct - there's a problem with Cygwin paths and Windows paths.
I have tried the solution described in the post above as the very first thing, but it was not working. Finally I've understand the reason: even if you put into your build_android.sh file the Windows path, the config for FFmpeg still contains the wrong path.
So in my case I have changed partially the config file in FFmpeg root directory from:
#set temporary file name
: ${TMPDIR:=$TEMPDIR}
: ${TMPDIR:=$TMP}
: ${TMPDIR:=/tmp}
to this:
# set temporary file name
#: ${TMPDIR:=$TEMPDIR}
#: ${TMPDIR:=$TMP}
: ${TMPDIR:=D:/InstallTools/Android/Cygwin_Root/tmp}
After this, I got it compiling.
You don't set the tmp directory. You can set it in /etc/profile or just in the terminal with export TMPDIR=/your/tmp/directory.
Notice:
1. If you compile with cygwin, the directory must be like D:/tmp. You can't use /cygdrive/d/tmp.
2. You must have the permission of the folder.
I could not get this to work either, I had the exact same problem. However I was able to compile using "android-ndk-r4". I am not sure at the moment what is causing the problem but if I ever get around to figuring it out I'll post that too.
So for now workaround is to use ndk r4.
I managed to build it, using NDK R6, cygwin. Indeed, it does not support /cydrive/ paths, simply use paths like windows; example below:
NDK=e:/AndroidSDK/NDK6
PLATFORM=$NDK/platforms/android-9/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows
If you have not solved this problem, check the last part of config.log in the ffmpeg directory; it is most likely a path or CC parameter problem.
I have been having the exact same problem with r6. I have tried Lambage's suggestion with r4 but still could not get this to work.
I have been looking into the problem quite a lot and I think I've discovered the reason.
1)configure is calling the android cross compiler which is a windows .exe file.
2)It is calling it through cygwin which uses unix file naming conventions. E.G /cygdrive/c/directory instead of C:\directory
3)It says in the android NDK toolchain documentation that the cross compilers do NOT accept cygwin style filepaths (source: NDK/docs/STANDALONE_TOOLCHAIN.html):
5.1/ Windows support:
The Windows binaries do not depend on Cygwin. The good news is that they
are thus faster, the bad news is that they do not understand the Cygwin
path specification like /cygdrive/c/foo/bar (instead of C:/foo/bar).
I'm still trying to find a way to do this. If i solve it then I'll come back and edit this post...tbc

Categories

Resources