Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Static Linking vs Dynamic Linking against glibc

I have been cross-compiling some Linux tools (and some of my own C code) to Android and one of the challenges that I face is that Android's libc has some missing/stripped components and I end up patching my code to make it work with Android's libc (for e.g. a problem like this http://credentiality2.blogspot.com/2010/08/compile-ncurses-for-android.html)

Q1 : How do I go about statically linking against glibc (and other dependencies) while cross-compiling with the arm toolchain (or ndk-build)?

Q2 : Is it a good idea to statically link against glibc for binaries for Android? Should I expect anything to break if I start statically linking? Are there any performance/memory issues?

I understand most of the pros and cons of static vs dynamic linking from here - C++ application - should I use static or dynamic linking for the libraries? and Static linking vs dynamic linking

So I wish to know if I should be statically linking glibc for Android when cross-compiling binaries.

like image 419
angadsg Avatar asked Apr 30 '12 08:04

angadsg


People also ask

Should I use dynamic or static linking?

The main difference between static and dynamic linking is that static linking copies all library modules used in the program into the final executable file at the final step of the compilation while, in dynamic linking, the linking occurs at run time when both executable files and libraries are placed in the memory.

Is glibc dynamically linked?

Applications built with the glibc toolchain will by dynamically linked by default. Application that load shared libraries at runtime using dlopen() must link with the libdl library ( -ldl ).

Is dynamic linking faster than static linking?

Static linking produces a larger executable file than dynamic linking because it has to compile all of the library code directly into the executable. The benefit is a reduction in overhead from no longer having to call functions from a library, and anywhere from somewhat to noticeably faster load times.

What is advantage of static linking over dynamic linking?

Library references are more efficient because the library procedures are statically linked into the program. Static linking increases the file size of your program, and it may increase the code size in memory if other applications, or other copies of your application, are running on the system.


2 Answers

First a small note on the libc. The Android libc is the Bionic libc (https://github.com/android/platform_bionic/) rather than the GNU libc (glibc). Thus the libc contained in the NDK is Bionic, as is the libc available on android devices.

As far as glibc is concerned, it is possible to build it with the NDK. However, it's name will clash with the system libc when installed on android devices. Note that this is only if you go for building a dynamic library. If you build the GNU libc as a static library, then the whole issue above is sidestepped, as you never need to install a static library.

Now to answer your questions:

  1. Q1: If you're building the glibc using the NDK, then the Android.mk uses the variable BUILD_STATIC_LIBRARY to build static libraries. However, if you dont use the NDK, then you'll probably need to get into the a lot of headache(dont know how much). I can't tell you more on this as I haven't tried a build of glibc, either static or dynamic. Also, it seems that static linking with glibc is highly discouraged, at-least for non-mobile platforms.

  2. From a breakage viewpoint, there is no difference between static and dynamic linking. From a start-up viewpoint, a static executable start up faster as the dynamic libraries loading step is not needed. There is no memory or execution speed penalty in either static or dynamic linked executables. Disk storage requirement is larger for static executables.

As far as problems with the bionic libc missing functionality, you can use the method used by most GNU software, which is, provide your own implementation of a function in case it is missing from the system libraries. I've compiled file-5.11, GNU make 3.82, diffutils-2.8 for Android passing the NDK toolchains/includes/libs to autotools (./configure ...). It seems that these programs contain implementations of most of the non-core library function, in case the standard libraries dont provide them (in this case Bionic).

Note: I'll try and build a static glibc and update the answer as and when I succeed/fail.

like image 96
Samveen Avatar answered Oct 15 '22 23:10

Samveen


If you are going to use glibc instead of bionic, it may be worth looking into using the toolchain of a (compatible kernel generation) arm-linux distro rather than the ndk. This would especially be true if you were generating a command line executable. (People have experimentally shoved chroot debian environments on android devices all the way back to the G1)

For a jni sub (which remains the only officially endorsed vehicle for native application code) it could get a bit "interesting" with either toolchain, as you will be running in a process that has already mapped and is making ongoing use of the bionic libc to support the Dalvik VM. Presumably if you statically link the library's own dependencies you won't run into name conflicts, but I expect whatever path you choose this will be a learning experience about the inner workings - not that that's necessarily a bad thing.

Do you have to have ncurses? I successfully built curses for android with the ndk once. Also consider if the program is seriously leveraging that (ie, are you actually doing substantial text formatting?), or just using it for some little thing because it was assumed to be available on target systems?

like image 22
Chris Stratton Avatar answered Oct 15 '22 21:10

Chris Stratton