Android Static Linking vs Dynamic Linking against glibc
Asked Answered
B

2

10

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.

Bridgettebridgewater answered 30/4, 2012 at 8:11 Comment(0)
T
5

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.

Treblinka answered 1/5, 2012 at 9:32 Comment(3)
It's not just usage on disk - also usage in memory that is increased. When you link and Android app's jni libraries against Bionic libc, you inherit shared read-only access to a copy already in memory.Soliloquize
Could you point me to your source of information on this? I want to know more, but cannot find anything on this. I do know that if the libraries contain any data, the data seems not shared between processes, however that may just be a case of copy-on-write replication of the memory pages if the library code changes it's internal data variables.Treblinka
I believe ChrisStratton mentions - the case for statically linked libc. Each process would end up with its own entire-copy of ALL the sections of the same library. With dynamic linking, you're correct @TreblinkaWamble
S
2

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?

Soliloquize answered 1/5, 2012 at 12:37 Comment(1)
You may want to come over and answer this question: #10798857Sophronia

© 2022 - 2024 — McMap. All rights reserved.