Building against GLIBC for an NDK library - android

I am interested in building an open source project and it requires the GNU libraries GLIBC and GLIBM. If I were to cross-compile this under Linux (I am using Ubuntu 11.10 as the host) for a shared (.so), or even a static (.a) object, with the ARMv7-a neon architecture, using API-9, as a library to call with Java's JNI, to ultimately compile as an APK for distribution, what steps would one undertake to achieve this outcome?
Given I have tried the Google NDK toolchain (setting $PATH and $CC the hard and easy way according to the documentation), a variety of custom toolchains, the Code Sourcery toolchain and a toolchain suggested on the XDA forum using crosstool-ng, is it possible to achieve a shared object file that can be called from JNI and has access to the full GLIBC library on a non-rooted Android device?
I have searched for an answer to this and the closest I have come is to build GLIBC and GLIBM locally and copy the relevant object (.o) files and link manually using the NDK's arm-linux-androideabi-ld. The libc.so.6 file from Crosstool-ng and CodeSourcery will not work as the relocations fail (giving error unknown reloc type 19) when calling the library using Java's System.LoadLibarary(). My knowledge of relocations is not the best but from what I have read this would require changes to the /linux/elf.h header file, but I am not sure exactly where to go from there.
I believe from what I have read that it may be possible to make a static executable that has all dependencies resolved when linked but then it would not be possible to package this as an APK file as far as I'm aware.
Surely I can't be the first to want to compile C code against something other than Bionic for the Android platform? There are so many C projects that could be ported to Android and apparently GLIBC has been available on iPhone for quite a while.

Any low level C library has very tight ties with the OS itself. While Linux and Android may mostly be the same thing, they are not. Building against another C library will require said C library to be ported first.

Related

How to create a prebuilt library that runs on the Android NDK?

I'm primarily a C developer who has been tasked with building some C libraries into shared object files that can be built into an Android app. I came across this link which discusses how to add a prebuilt library to an Android Studio project, but very little information on how to actually build a prebuilt library. I did find information saying I can't just use Linux cross-compilers to do so due to slight differences in ABI. How would I go about doing this? Do I need to use Android Studio? Do my sources need to include some special header? Or can I just use the cross compilers found in the NDK and compile using gcc -shared -fPIC?
It's enough to build your library with an NDK toolchain. Usually it's OK to use the lowest platform API level supported by NDK. You should produce the binaries for different CPUs. You may skip the 32-bit variants if you wish, but the rules of Android Play Store require that you have a 64-bit version. You don't need Android Studio for this task, and no changes to your sources are necessary.
If your library exports C++ API, use c++_shared runtime.

why do we need to use android tool-chain(or NDK) for compiling c/c++ code running in the context of an android app?

I built a library(.so) that is being called from JNI code in some android app. The JNI code is built using NDK.
If I build the library using android tool-chain, the library works well when called from JNI code.
If I build the library using another tool-chain (used on the same ARM device for none android applications), the library crashes when called from JNI code.
why do we need to use android tool-chain (or NDK) for compiling c/c++ code running in the context of an android app? why not use other tool-chains?
You can use other toolchains, but it requires special care.
Maybe a good starter would be to learn the UBERTC and Linaro Wiki.
The main difference is that NDK compilers are tuned for bionic (Android variant of C runtime libraries). Originally, bionic was a modest subset of Linux runtime. On latest platforms, most of the gap is closed, but now there are many extensions that you probably need.
Also, Android dynamic linker may require (depending on target platform) a set of ELF flags that are automatically delivered by NDK binutils, like PIC, id, and others.
It is quite possible to use arm-linux toolchain to build a statically linked executable that will run on Android, but for a library that must play well on the JNI environment the effort is probably not worth it.
Note that NDK provides tools to create a standalone toolchain, which behaves very similar to other toolchains you may be familiar with. This approach makes it easy to adopt 3rd-party libraries with sophisticated build scripts.

Can a shared library (.so) file built for linux be included/linked and used in an Android application?

I am working on a project in which I need to include NGSpice simulation library in an Android application and of course be able to use it.
I tried including the NGSpice windows DLL in my android application using SWIG and Android NDK, but it turned out that it is not even possible, so now I started to think about building NGSpice as a shared library for linux.
And now my question is, can I use the linux shared library for NGSpice as it is in my Android application, or does it need to built differently somehow to work on my Android application.
Thanks.
No. Android typically has two key differences from a traditional linux:
1) It uses the Bionic C library and dynamic linker, instead of a more traditional set such as glibc.
2) Android is typically run on an ARM or 32-bit x86 processor (or in rare cases MIPS), while your desktop Linux library might be either 64-bit or 32-bit x86 code.
If you build a .so compatible with the architecture of the machine and with bionic's system library functions and dynamic linker, then it should be workable.
Alternatively, if you have something for a compatible architecture but the wrong libc, it may be possible to write your own loader to get it into memory in working form on a secured device, or on a rooted device it is possible to run a more traditional linux userspace (typically Debian derived) in a chroot. But neither of these would be easy to integrate into an Android application - for the latter you'd almost definitely have to pass work over via interprocess communication, and that might prove easier in the former case as well.
Your only really endorsed solution is to rebuild the library from source, using either the ndk build system, or an ndk-generated "stand alone toolchain" and the library's current build system.

cmake vs waf: mainly for c++ windows/linux and android

After searching a lot and reading a lot of information, I cannot decide which tool I should use for compiling my code. My codebase is mainly c++. I use primarily linux as my development machine.
Based on opinions I read before, my final candidates are waf and cmake, but I cannot decide myself which one should be more appropiate.
My primary requirements are:
Must be able to compile software in windows/linux and android.
Must be ready to run tests.
Must be able to play nicely with other libraries that must be compiled with another build system but most likely will have to be compiled from source.
Must be able to add custom steps, like for example, generating some data from some files (mainly graphics) before compiling, all integrated in the build system.
Some strong preferences are:
Being ready to support MAC compilation.
Being able to cross-compile from linux as many platforms as I can (maybe windows/linux/android but cannot MAC?)
Being able to add support for iOS compilation if the need arises.
Would be nice if the invocation interface was similar to that of autotools, since it is the one many people know and it is well documented.
Some questions:
If I have some rare requirement, which build system would be more ready to be extended?
Are both currently well maintained? (I wonder about waf mainly).
Community: if I find a problem, both communities are big enough to support me, in your experience?
For now my feeling is that I favour waf a bit as a tool, but cmake seems to have been quite successful for whatever reason.
Don't know much about waf, but CMake fits your requirements pretty well. I do know waf is written in Python, my personal favourite programming language ATM.
My primary requirements are:
Must be able to compile software in windows/linux and android.
CMake does Windows and Linux very well but so does any other build system worth its salt.
Someone wrote some Android scripts for CMake. Can't find anything similar for waf (my Google-fu turns up nothing.)
Must be ready to run tests.
CMake has a sibling testing framework.
Must be able to play nicely with other libraries that must be compiled with another build system but most likely will have to be compiled from source.
CMake has good integration with pkg-config, and can link against arbitrary shared libraries.
Must be able to add custom steps, like for example, generating some data from some files (mainly graphics) before compiling, all integrated in the build system.
CMake can generate custom rules.
Some strong preferences are:
Being ready to support MAC compilation.
CMake supports Mac quite well. It will even make you an Xcode project if you want, but it can also do command line builds.
Being able to cross-compile from linux as many platforms as I can (maybe windows/linux/android but cannot MAC?)
Cross-compiling is supported in CMake. CMake will not be the primary source of pain with cross-compiling - literally everything else will.
Especially with regards to cross-compiling for Mac. It's possible, but not worth it to cross-compile for that platform, considering you need access to a Mac anyways to get the libraries and header files, you need to patch GCC and clang and LLVM, etc. The only sound reason I've heard for going through this much pain is running an automated build server. Anyways, if you get a working Linux -> Mac toolchain, you should be able to cross-compile with CMake as if it were any other Unix platform.
Being able to add support for iOS compilation if the need arises.
iOS cross-compilation can be done, but you need a Mac.
Would be nice if the invocation interface was similar to that of autotools, since it is the one many people know and it is well documented.
Write a configure script that just calls CMake (cmake .). Then your users can do a ./configure && make && make install on platforms where that makes sense. There's also CPack which lets you generate DEB, RPM, NSIS (Windows) and DMG (Mac) installers/packages.
Some questions:
If I have some rare requirement, which build system would be more ready to be extended?
CMake is very extensible. It can be extended to support new languages and target platforms. (Given that waf is written in Python, it's going to be pretty hackable too.)
Are both currently well maintained? (I wonder about waf mainly).
CMake is mature and well-maintained.
Community: if I find a problem, both communities are big enough to support me, in your experience?
The community and extensions available are what keeps me coming back to CMake, from things like bakefile, honestly.
WAF
is pure Python
becomes part of your project, i.e. no external dependency
supports many build tools
can be used to do all kind of automations, not just building
It works perfectly for Linux, Mac or Windows.
On Android, gradle is the chosen build tool of Google. To use that is
wise, because it is set up to work by Google. You can call waf from
gradle and vice-versa, though.
If you want to learn all the low level Android
SDK tools, you could also use
WAF directly.
The SDK has
javac for Android Runtime (formerly Dalvik), Android\'s JVM, and produces a .class file
jar can also be used for Android
d8 (formerly dx) produces .dex files, with Dalvik executable code
aapt2 can then produce the .apk
javac and jar are known to WAF. For dx and aapt2 you would need
to create your own tasks, which is very
easy.
You would best make a WAF tool and
share it. Tools are either part of WAF or there is
waftools.
There are also these Steinwurf
tools.
If you make Android native code using
NDK:
you use CLANG, which is known to WAF
Further on you mentioned requirements:
WAF has waf_unit_test
WAF can do gnu_cross compilation. The Gnu toolchain knowns many
targets. But for Android you would need to set things up yourself
using the SDK or NDK. For NDK you could use the Gnu toolchain.
You would do waf configure, waf build instead of configure,
make, but you could wrap a Configure or Makefile around waf to
have the same commands.
WAF is very easily extendible with Python
WAF is now on gitlab and
constantly worked on.
The community is surely smaller than for CMake. But it is Python.
You can look into it and find out for yourself. You can also
contribute and become part of the community.

Android-Ndk vs Cross-Compile? Both work, but what was the need of Android NDK then?

I can cross-compile any C/C++ application, statically link it Linux libraries and run it on Android. What was the need of an Android-ndk then? Android-ndk limits us to bionic which has a small subset of gnu libc. Isn't it a better idea to straightaway cross-compile applications and run them through Android shell? Is there any limitation to cross-compiling that I can't see? This URL : Can Linux apps be run in Android? answers my question to some extent but eventually leaves me confused and without clarity.
I think this is enough for Android-NDK
The Android NDK is a companion tool to the Android SDK that lets you build performance-critical portions of your apps in native code. It provides headers and libraries that allow you to build activities, handle user input, use hardware sensors, access application resources, and more, when programming in C or C++. If you write native code, your applications are still packaged into an .apk file and they still run inside of a virtual machine on the device. The fundamental Android application model does not change.
The NDK provides:
A set of tools and build files used to generate native code libraries
from C and C++ sources
A way to embed the corresponding native libraries into an application
package file (.apk) that can be deployed on Android devices
A set of native system headers and libraries that will be supported
in all future versions of the Android platform, starting from Android
1.5. Applications that use native activities must be run on Android 2.3 or later.
This thing you can not find in other cross-compilation with arm toolchain..
As mentioned in the link http://developer.android.com/sdk/ndk/index.html NDK is a companion for App development folk to create performance sensitive native code. NDK exposes some of the native implementation of Android which could not be found in the general Linux environments. Some of them include the Android/Bitmap, Android/nativeWindow etc. Using these Android natives applcation can speed up CPU intensive processes like some compression or decompression of images.
Even though the externally cross-compiled executables may run in the Android there no guarantee that versions of the standard library implementaions are the same. NDK provides a easier and Android compatible toolchain and other resources, using which is much easier to application developers than having to find a compatible cross-compiler for their usecase.

Categories

Resources