Building Open Source libraries with Android NDK

Having scrambled through a NDK documentation and a lot of hit and trials and experimentation, finally I could figure out how could one build (even though partially) Open Source libraries with Android NDK.

Some background on how Autotools work:

The way autootool and friends work is this:

You write a configure.ac file, which is read in by Autoreconf and generates a configure script. Configure script test the build system for headers, libraries etc. and generates a config.h which contains definitions like #define HAVE_XXX 1 and also generates Makefiles after reading in the Makefile.in files which in turn is generated using Automake by reading in Makefile.am.

configure.ac —> input to –> autoreconf –> generates -> configure script –> checks host system for headers, libraries etc. -> generates -> config.h

Also

Makefile.am –> input to automake –> generates –> Makefile.in –> input to –> configure script –> generates Makefile

The code uses the generated config.h in the following fashion:

#ifdef HAVE_XXXX
#include <some-header>
#endif
….
….
#ifdef HAVE_XXXX
Call some function which is declared in the header
#else
Provide some other mechanism or report error to user or do whatever you want
#endif

The problem?

Most Open Source libraries use GNU autotools and its friends for building.

The first problem is that the Autools generate some configuration headers based on build time probe of the system. By build time probe I mean checking for things like if a header, library or a tool is present or not. In cross compiling scenario some of these probe should be done on the target system and not on the build system.

Second, the build system for most cross compiler tools have their own quirks which need passing some extra flags.

Third, in case of Android, it provides its own build system which are essentially some Makefile definitions and rules. This is provided so that people can build their code easily without having to deal with usual cross compiling issues. Thus there is a gap that while your autotools would generate the Makefiles while Android build system requires its own styled Makefiles in the form of Android.mk. One cannot simply generate Android.mk files using autotools.

Fourth, even if one gets to write Android specific Makefiles, the build would most probably fail as during the build it would look for a file config.h included in the fashion shown below, while no such file would exist as it is generated by the configure script.

#ifdef HAVE_CONFIG_H
#include “config.h”
#endif

Simply copying a config.h file from a run of configure script on another build system wouldn’t really work as the header files and other libraries present on Android may not match with the header and libraries present on the build system. Thus config.h would probably differ if it is somehow generated for Android with the one generated on a build system.

So how does one build an open source library for Android?

Solution:

The way I have managed to work around this trouble is to run the configure script with right cross compilation variables so that a config.h matching my Android system gets built and then writing Android.mk files which would simply use the Android build system.

The way I figured out the right flags was by building the Android source tree which displayed what flags are being used for building and then taking the cues from there, I passed the right flags to the configure script.

It looks something like this for building Android-3 target API on a linux host:

export ANDROID_ROOT=/home/divkis01/mydroid

The command above is sets the path where the Android sources are checked out from git respository.

NOTE: It is not necessary to check out the ANDROID sources and you can replace the ANDROID_ROOT with NDK_ROOT in all the commands below, along with proper path to the NDK cross compiler.

export PATH=$PATH:$ANDROID_ROOT/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/

The command above is necessary so that configure can find out the path to the cross compiler which is needed to build some test programs during the configure run process. Please note that you can also set the path to the NDK compiler root

./configure –host=arm-eabi CC=arm-eabi-gcc CPPFLAGS=”-I$ANDROID_ROOT/build/platforms/android-3/arch-arm/usr/include/” CFLAGS=”-nostdlib” LDFLAGS=”-Wl,-rpath-link=$ANDROID_ROOT/build/platforms/android-3/arch-arm/usr/lib/ -L$ANDROID_ROOT/build/platforms/android-3/arch-arm/usr/lib/” LIBS=”-lc “

The command above has several points that should be well understood.

–host=arm-eabi –> This tells the configure script if the cross compilation is being done or not. It is also used as a prefix to some of the cross compiler tools like strip, nm etc.

CC=arm-eabi-gcc –> This tells the compiler that should be used for building

CPPFLAGS –> This tells the location where the header files should be searched which were specified in configure.ac with AC_CHECK_HEADER macro

CFLAGS=”-nostdlib” passes the option to build some test programs during configure process run. If you don’t pass this the compiler would link the standard C library of the host system which wouldn’t be compatible with the C library of the target system. You will end up getting error something like this, if you don’t pass this option:

/home/divkis01/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: crt0.o: No such file: No such file or directory

LIBS=”-lc” –> This option tells that it should explicitly link to a library called libc.so which is present in the location specified using the -L in the LDFLAGS option. If you are wondering that usually to build a C executable one doesn’t need to provide -lc as libc is automatically linked, then why do we need to specify this here? The answer lies in -nostdlib flag, which instructs not to link with the standard C library on the build system.

You will end up getting error something like this, if you don’t pass this option:

/home/divkis01/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: crt0.o: No such file: No such file or directory
collect2: ld returned 1 exit status

LDFLAGS = –> This option is also passed to build some test programs during configure process run.If you don’t pass the -Wl,-rpath-link option, then linker does not know where do the libraries dependent on the library specific using LIBS reside. If you don’t pass the -L option then the linker doesn’t know where do the libraries specified in LIBS reside.

You will end up getting error something like this, if you don’t pass the -Wl,-rpath-link option:

/home/divkis01/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: warning: libdl.so, needed by /home/divkis01/mydroid/development/ndk/build/platforms/android-3/arch-arm/usr/lib//libc.so, not found (try using -rpath or -rpath-link)
/home/divkis01/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 00008184
/home/divkis01/mydroid/development/ndk/build/platforms/android-3/arch-arm/usr/lib//libc.so: undefined reference to `dl_unwind_find_exidx’

You will end up getting error something like this, if you don’t pass the -L option:

/home/divkis01/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-
eabi/bin/ld: cannot find -lc
collect2: ld returned 1 exit status

Once you run the configure script with these flags and options, it will generate the appropriate config.h which is compatible / in sync with your target system. Now you can go ahead and start writing the Android.mk files to build your sources.

Other troubles:

This solves only part of the problem as Autotools not only help in building but also in installing. Given it doesn’t make sense to install the build for a target system on host except for the headers. This can be done by augmenting the Android.mk files or writing some shell scripts to do this manually.

Conclusion:

Autotool is good only on GNU systems and using it for cross compiling can be really tedious, confusing, error prone or even impossible. The method described here is a hack and should be used at your own risk.

Let me know if this post was helpful for you.

CC=arm-eabi-gcc

36 thoughts on “Building Open Source libraries with Android NDK

  1. Hi Kishore

    Thanks for your post, You explained well about Android makefile in detail.

    I trying cross compile a library with android toolchain right now, but facing same problem, Can you kindly advise me on this ??

    Here is my configure options.

    export ANDROID_ROOT=/home/arun/mydroid
    export PATH=$PATH:$ANDROID_ROOT/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/

    If i run the following command, i getting one common error, but not able resolve my slef, can you please assist on this

    ./configure –host=arm-eabi CC=arm-eabi-gcc CPPFLAGS=”-I$ANDROID_ROOT/build/platforms/android-3/arch-arm/usr/include/” CFLAGS=”-nostdlib” LDFLAGS=”-Wl,-rpath-link=$ANDROID_ROOT/build/platforms/android-3/arch-arm/usr/lib/ -L$ANDROID_ROOT/build/platforms/android-3/arch-arm/usr/lib/” LIBS=”-lc “

    configure: error: unrecognized option: -L/home/arun/mydroid/build/platforms/android-3/arch-arm/usr/lib/”
    Try `./configure –help’ for more information.

    • Hi kishore Thanks for ur document,
      I am also facing the same problem while compiling gstreamer components in froyo.while compiling i am getting the following error.
      target SharedLib: libgstcoreelements (out/target/product/generic/obj/PLUGIN_LIBRARIES/libgstcoreelements_intermediates/LINKED/libgstcoreelements.so)
      /home/venu/Gstreamer/froyo/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: cannot find -lgstbase-0.10
      collect2: ld returned 1 exit status
      make: *** [out/target/product/generic/obj/PLUGIN_LIBRARIES/libgstcoreelements_intermediates/LINKED/libgstcoreelements.so] Error 1
      make: Leaving directory `/home/venu/Gstreamer/froyo’

      Can u please give me some suggestions to solve this error

  2. Hi kishore,

    Here is my cross build environment setup.

    export PATH=$PATH:/home/arun/mydroid/prebuilt/linux-x86/toolchain/arm-
    eabi-4.2.1/bin

    LD=arm-eabi-ld
    AR=arm-eabi-ar
    STRIP=arm-eabi-strip
    RANLIB=arm-eabi-ranlib
    CC=arm-eabi-gcc
    CXX=arm-eabi-g++
    CPPFLAGS=”-I/home/arun/mydroid/bionic/libstdc++/include -I/home/arun/
    mydroid/bionic/libc/include -I/home/arun/mydroid/bionic/libc/arch-arm/
    include/ -I/home/arun/mydroid/external/jpeg -I/home/arun/mydroid/
    bionic/libc/kernel/common -I/home/arun/mydroid/bionic/libc/kernel/arch-
    arm -I/home/arun/mydroid/bionic/libm/include -I/home/arun/mydroid/
    bionic/libm/include/arch/arm -I/home/arun/mydroid/bionic/libm/arm -I/
    home/arun/mydroid/bionic/libm”

    CFLAGS=”-nostdlib”

    LDFLAGS=-Wl,–entry=main,–no-undefined,-rpath-link=”-L/home/arun/
    mydroid/out/target/product/imx51_BBG/obj/STATIC_LIBRARIES/
    libjpeg_intermediates/ -L/home/arun/mydroid/development/ndk/build/
    platforms/android-3/arch-arm/usr/lib/ -L/home/arun/mydroid/out/target/
    product/imx51_BBG/system/lib”

    LIBS=”-lc -lgcc -lm -ldl -lstdc++ -L/home/arun/mydroid/out/target/
    product/imx51_BBG/obj/STATIC_LIBRARIES/libjpeg_intermediates -ljpeg”
    ————————————————————————————————————————————-
    Then i execute “./configure”. It went well.

    But while doing “make” c and c++ souces are compiled properly.

    At the linking stage i got this error

    /home/arun/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../
    lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: crt0.o: No such
    file: No such file or directory
    collect2: ld returned 1 exit status

    I tried using different options.I have googled and tried some
    solution. But not proper ending.

    Kindly help/guide me on this.

    Thanks
    Thangamani Arun

    • Just looking at the error it seems the linker flags are either not being passed properly or the paths are not correct. Compilers do not complain about the non existent directories, thus make sure that directories you pass to linker do exist. It appears that somehow the libc of the host system is getting linked with your sources which is not compatible with the Android libc. I see that you are using the compiler present in the android sources itself rather then using the one shipped with the Android NDK. Unless you explain the complete / relevant scenario, no one can really help. Overall I would ask the following questions to be able to help.

      1. What are you trying to do? It is possible that there is a shorter and cleaner way to compile your sources.
      2. What is the final build command issued when doing make?
      3. Why are you using cross compiler present in the Android sources? Are you building Android image itself or your goal is only to build some library for Android?
      4. What is your target platform? Android or some other platform?

  3. Hi Kishore,

    I am trying to build a executable from normal Linux source package. I followed the these steps to cross compile my linux source

    step1:
    export PATH=$PATH:/home/arun/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin

    step2:

    ./configure LD=arm-eabi-ld AR=arm-eabi-ar STRIP=arm-eabi-strip RANLIB=arm-eabi-ranlib CC=arm-eabi-gcc CXX=arm-eabi-g++ CPPFLAGS=”-I/home/arun/mydroid/bionic/libstdc++/include -I/home/arun/mydroid/bionic/libc/include -I/home/arun/mydroid/bionic/libc/arch-arm/include/ -I/home/arun/mydroid/external/jpeg -I/home/arun/mydroid/bionic/libc/kernel/common -I/home/arun/mydroid/bionic/libc/kernel/arch-arm -I/home/arun/mydroid/bionic/libm/include -I/home/arun/mydroid/bionic/libm/include/arch/arm -I/home/arun/mydroid/bionic/libm/arm -I/home/arun/mydroid/bionic/libm” CFLAGS=”-nostdlib” LDFLAGS=-Wl,–entry=main,-rpath-link=”-L/home/arun/mydroid/out/target/product/imx51_BBG/obj/STATIC_LIBRARIES/libjpeg_intermediates/ -L/home/arun/mydroid/development/ndk/build/platforms/android-3/arch-arm/usr/lib/ -L/home/arun/mydroid/out/target/product/imx51_BBG/system/lib” LIBS=”-lc -lgcc -lm -ldl -lstdc++ -L/home/arun/mydroid/out/target/product/imx51_BBG/obj/STATIC_LIBRARIES/libjpeg_intermediates -ljpeg”

    step3:
    make

    /home/arun/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: crt0.o: No such file: No such file or directory
    collect2: ld returned 1 exit status

    At the end of the source compilation, while linking getting the above error.

    step4:
    To solve the above error, i did

    cp /home/arun/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1/crtn.o /home/arun/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1/crt0.o

    Step5:

    make
    /home/arun/mydroid/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: cannot find -lg
    collect2: ld returned 1 exit status

    I do not know what is wrong with my compiler/linker flags. Kindly correct me if anything wrong.

    Regards
    Arun

    • You have still not specified what is your target system and why are you using android’s toolchain for building it. Anyways try removing -lgcc and -lstdc++.

      Also please do not manually copy the object files that you are doing in your comment as that might screw up your compiler setup.

      Hope that helps, Divkis

      • I just tried for understanding. I will remove those -lgcc & -lstdc++. Then i will see if it goes well.

        Kindly note that the Linux source package used for cross compilation has both .C .CPP file. While linking these objects and libs throwing those errors. Let me know if you any concern on this statement

  4. Hello

    Really nice and informative article.
    I’m trying to port libsigc++ library to Android.
    First of all I don’t know exactly what more flags and paths to include to ./configure
    In my experience with porting libcurl library, you could just ‘make libcurl showcommands’ from mydroid folder and it would reveal the necessary flags.
    This time when I try make I get make: *** No rule to make target `libsigcpp’. Stop.

    Now I try to pass the following to ./configure by running this sh file:

    #!/bin/sh

    A=`realpath ../..` && \
    PATH=”$A/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/:$PATH” \
    ./configure –host=arm-eabi CC=arm-eabi-gcc CXX=arm-eabi-g++ \
    CPPFLAGS=”-I $A/system/core/include \
    -include $A/system/core/include/arch/linux-arm/AndroidConfig.h” \
    CFLAGS=”-nostdlib” \
    LDFLAGS=”-Wl,-rpath-link=$A/out/target/product/passion/obj/lib \
    -L$A/out/target/product/passion/obj/lib” \
    LIBS=”-lc”

    When I run it I get exactly the error you were talking about:

    /prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: crt0.o: No such file: No such file or directory
    collect2: ld returned 1 exit status

    What stuff do I miss to pass along to ./configure?
    How do I reveal all the necessary libraries, flags and paths to make libsigc++?
    Thanks in advance and best regards,
    Alexej

    • It appears you are trying to build the library using the non prescribed way i.e. you are not using NDK to build the library but you are using the android sources itself to build the library. Since I have not tried using that I can’t say much but probably you are better off using the NDK build system instead of using the android sources for rootfs, libs, headers etc. as not all of them are exposed to Native developers on Android. Hope that helps.

  5. Here is the command line that works for dpkg:

    ./configure –host=arm-eabi CC=arm-eabi-gcc CPPFLAGS=”-I/usr/local/android-ndk-r4b/build/platforms/android-3/arch-arm/usr/include/” CFLAGS=”-fpic -mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 -DANDROID -Wa,–noexecstack” LDFLAGS=”-nostdlib -Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,–gc-sections -Wl,-z,nocopyreloc /usr/local/android-ndk-r4b/build/platforms/android-3/arch-arm/usr/lib/crtbegin_dynamic.o” LIBS=”/usr/local/android-ndk-r4b/build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/libgcc.a /usr/local/android-ndk-r4b/build/platforms/android-3/arch-arm/usr/lib/libc.so /usr/local/android-ndk-r4b/build/platforms/android-3/arch-arm/usr/lib/libstdc++.so /usr/local/android-ndk-r4b/build/platforms/android-3/arch-arm/usr/lib/libm.so -Wl,–no-undefined -Wl,-z,noexecstack -Wl,-rpath-link=/usr/local/android-ndk-r4b/build/platforms/android-3/arch-arm/usr/lib /usr/local/android-ndk-r4b/build/platforms/android-3/arch-arm/usr/lib/crtend_android.o” –without-dselect –without-start-stop-daemon –disable-nls –disable-rpath –disable-largefile

    make will fail for various reasons, the fixes for which are probably outside the scope of my comment here (the default NDK tree doesn’t have all the include headers one might hope for).

  6. Dear sir,

    I’m trying to build sysfsutils-2.1.0. The thing actually goes pretty well, it makes fine. I have added the –prefix=/system to your ./configure line, and when I run make install on the build machine, it successfully copy everything to /system/bin and /system/lib (on the LInux build machine, /system is simply a directory I made to see if make install was working ;) ).

    If I check the file type (on the build machine):
    dlist_test: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
    get_device: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
    get_driver: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
    get_module: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
    systool: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

    so it seems the files correctly build as ARM binaries.

    I push all the bin/libs to my actual device (to /system/bin and /system/lib respectively).

    When I try to run systool, I get:

    # /system/bin/systool
    /system/bin/systool: not found

    The file is actually there:
    # ls -l /system/bin/systool
    -rwxr-xr-x system system 63622 2010-11-11 09:15 systool

    I believe the not found error is actually meaning here something else (maybe a missing lib?), but I don’t know where to look at… Any idea what is wrong here? (no ldd on Android afaik).

    Thanks in advance for your help (you can contact me by email would you need some more details).

    • The trouble is that you don’t have shared libraries which systool is dependent upon in the LD_LIBRARY_PATH. Try copying the required libraries in the same folder where you have systools installed or try setting the LD_LIBRARY_PATH. ldd is just a script which actually invoked ld. To get equivalent functionality you can do

      /lib/ld.lnux.so.2 –list /lib/systools

      Just match it to where your ld and systools are installed. Let me if it works.

      • If I understand correctly, you mean I have to copy the libs that compiled with systool to somewhere that is in the LD_LIBRARY_PATH?

        Actually that I have already done.

        On the device: LD_LIBRARY_PATH=/system/lib

        /system/lib is where I have copied the 2 lib files created during the compilation.

        There is no /lib/ld-linux.so.2 on my Android device :-/, what would be the equivalent on Android? (No “*ld*” in /system/lib/).

      • The equivalent of ld-linux.so on android is actually /system/bin/linker but somehow it behaves quite differently on android so I am afraid that it might not be able to list the dependencies. Sorry for the confusion. To list dependencies you can do

        /build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-readelf -d systools

        where systools is the binaries that you build. The outout of this would be something similar to as shown below. Note that at the top the second column shows the ‘NEEDED’ and third column lists the libraries that are needed. This one is the output from running readelf on libGLESv1_CM.so.

        Dynamic section at offset 0×5000 contains 19 entries:
        Tag Type Name/Value
        0×00000001 (NEEDED) Shared library: [liblog.so]
        0×00000001 (NEEDED) Shared library: [libcutils.so]
        0×00000001 (NEEDED) Shared library: [libEGL.so]
        0×00000001 (NEEDED) Shared library: [libdl.so]
        0×00000001 (NEEDED) Shared library: [libc.so]
        0×00000001 (NEEDED) Shared library: [libstdc++.so]
        0×00000001 (NEEDED) Shared library: [libm.so]
        0x0000000e (SONAME) Library soname: [libGLESv1_CM.so]
        0×00000010 (SYMBOLIC) 0×0
        0×00000004 (HASH) 0xb4
        0×00000005 (STRTAB) 0x17a8
        0×00000006 (SYMTAB) 0x7c8
        0x0000000a (STRSZ) 3995 (bytes)
        0x0000000b (SYMENT) 16 (bytes)
        0×00000003 (PLTGOT) 0x50c0
        0×00000002 (PLTRELSZ) 8 (bytes)
        0×00000014 (PLTREL) REL
        0×00000017 (JMPREL) 0×2744
        0×00000000 (NULL) 0×0

        Hope that helps

  7. Pingback: cji->setMode(GEEK); » Starting work on G3D…

  8. Pingback: Compiling open source libraries for Android: Part 1 | ampersand

  9. Hi! I could have sworn I’ve been to this website before but after browsing through some of the post I realized it’s new to me.

    Anyways, I’m definitely happy I found it and I’ll be book-marking and checking
    back often!

    Sue

  10. Pingback: How to build open source programs with a configure script for Android using NDK? - Tech Forum Network

  11. Pingback: Compiling open source libraries with Android NDK: Part 1 | cmumobileapps

  12. After looking at a handful of the blog articles
    on your website, I really like your way of blogging.

    I saved as a favorite it to my bookmark site list
    and will be checking back soon. Take a look at my website too and tell me what you think.

  13. hi , i got an issue almost similar to this.
    iam trying to run gstreamer on jellybean. my toolchain looks like :
    /arm/arm-linux-androideabi-4.6/bin/arm-linux-androideabi-

    >>> And my jellybean code works fine but this toolchain is not detected by my gstreamer code. it only works for the toolchain “toolchain/arm-eabi-4.4.3/bin/arm-eabi-” when i try my jellybean with 4.6 toolchain, i get warning like “checking whether C compiler works ….. : no ” and leads to error. please help me to fix this, where can we change the code so that my gstreamer can run with the toolchain 4.6…

  14. Hi Divick!

    Thanks for the wonderful post.
    I had to explore innumerable articles to figure all this out.
    Too bad I didn’t find this article earlier.

    I am trying to port Trickle (https://github.com/mariusaeriksen/trickle) on android.

    What I have figured out till now is that I need to cross-compile the individual libraries that this application depends on (libevent)

    I have managed to cross-compile libevent with the following script:
    ____________________________________________________________________
    export ANDROID_ROOT=/home/narayan/installations/android-ndk-r9d

    export PATH=$PATH:$ANDROID_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin
    export PATH=$PATH:$ANDROID_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/include

    rm *_so.o
    ln -s $ANDROID_ROOT/platforms/android-19/arch-arm/usr/lib/crtbegin_so.o
    ln -s $ANDROID_ROOT/platforms/android-19/arch-arm/usr/lib/crtend_so.o

    ./configure \
    –host=arm-linux-androideabi \
    CC=$ANDROID_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc \
    LD=$ANDROID_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld \
    AR=$ANDROID_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar \
    RANLIB=$ANDROID_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ranlib \
    CPPFLAGS=”-I$ANDROID_ROOT/platforms/android-19/arch-arm/usr/include/” \
    CFLAGS=”-nostdlib” \
    LDFLAGS=”-Wl,-rpath-link=$ANDROID_ROOT/platforms/android-19/arch-arm/usr/lib/ -L$ANDROID_ROOT/platforms/android-19/arch-arm/usr/lib/” \
    LIBS=”-lc -lgcc -L$ANDROID_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.8″
    __________________________________________________________________

    Now when i do the same for the trickle application, I get the following error on running the same script as above inside trickle project directory-

    ___________________________________________________________________
    checking if we can access libc without dlopen… no
    checking if we can access libc with libc.so… no
    checking if we can access libc with /usr/lib/libc.so*… no
    configure: error: Couldn’t figure out how to access libc
    ___________________________________________________________________

    So I have a couple of questions:-

    1. How to resolve the above error?
    2. How to tell the compiler to link the shared library (libevent) that i have cross-compiled for android earlier so as to generate the final executable command line app for android.

    3. Is it really feasible to port trickle on android? If not then what’s the major problem.

    I would be delighted if you could help me or at least guide me to some articles which would help me out with this problem.

    Thanks :)

    • Hi Anurag,

      1. From the output it seems that it is trying to look for libc but it is unable to find it. You might have to look at the configure.in/am script to see the location where it is checking for libc and why. Without actually trying to compile it at my end, it is hard to say why it is complaining and how to fix it.

      2. To tell the compiler where to look for shared libraries there are couple of options -L, -wl-rpath and -rpath. Check the gcc man page to see the difference. These options are what are passed to configure script which in turn generates the Makefiles with appropriate options.

      3. I don’t know anything about trickle so it is really hard to say if it is portable on android but if it builds on linux x86, and doesn’t have dependency on a specific architecture, it should be compilable for android too. Best would be to check with the author of the library.

      To really solve this problem you will need to understand a bit more on how gnu build tools (autotools) work. First look at the how configure script is generated based in configure.in/am using autotools and then look at the options/checks, present in configure.in/am, which do the check for dlopen, accessing of libc etc. That should give you an idea on why it is looking at libc at the wrong place. My guess is that it probably does not handle that properly.

      If the application is your own and is small, you can compile it manually too using directly Makefiles instead of using autotools as the libevent, and trickle libs are now already built for android/arm. If you have the library built then I think you are already in a good shape. You just need to compile an application which utilizes trickle. If it is your own, it should be super simple and if it is someone else’s then you need to understand autotools a bit more to see what are the sources that you need to compile.

      Sorry that without looking at the autotools scripts I can’t really say what’s going on though.
      Hope that helps,
      Cheers,
      Divick

      • Thanks a ton Divick for such a quick response :)
        I admit I should have formed the question more appropriately.

        If it is okay to put links to stackoverflow, then I have re-framed the question here -

        http://stackoverflow.com/questions/23909317/porting-opensource-application-to-android

        The application is in no way mine. A genius named
        Marius Eriksen (http://monkey.org/~marius/) wrote this.

        I am trying to make it work on android as it is an indispensable application to limit the rate at which individual processes consume network bandwidth and as of now there isn’t any application which does the same on android.

        I did get an overview of the autotools. But I guess you are very much correct in suggesting that the problem lies in configure.in.

        It would be very kind of you if you can take a look at that stackoverflow link and suggest the way I should proceed for resolving that issue.
        Some directions would also do :)
        Whenever you get time, ofcourse. :)

        Thanks & Regards,
        Anurag

  15. Hi,

    I am able to cross compile for android but not able to execute it on android
    platform.
    I if execute any of the binaries i am getting ” no such file or directory”
    I checked that the issue with dynamic linker :

    readelf –program

    Elf file type is EXEC (Executable file)
    Entry point 0x87e8
    There are 8 program headers, starting at offset 52

    Program Headers:
    Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
    EXIDX 0x000a7c 0x00008a7c 0x00008a7c 0×00048 0×00048 R 0×4
    PHDR 0×000034 0×00008034 0×00008034 0×00100 0×00100 R E 0×4
    INTERP 0×000134 0×00008134 0×00008134 0×00013 0×00013 R 0×1
    [Requesting program interpreter: /lib/ld-linux.so.3]
    LOAD 0×000000 0×00008000 0×00008000 0x00ac8 0x00ac8 R E 0×8000
    LOAD 0x000ac8 0x00010ac8 0x00010ac8 0×00148 0×00158 RW 0×8000
    DYNAMIC 0x000ad4 0x00010ad4 0x00010ad4 0x000f0 0x000f0 RW 0×4
    NOTE 0×000148 0×00008148 0×00008148 0×00020 0×00020 R 0×4
    GNU_STACK 0×000000 0×00000000 0×00000000 0×00000 0×00000 RW 0×10

    Its taking default linker file as /lib/ld-linux, it should be
    /system/bin/linker for android i guess.
    Can someone suggest me hoe to change this.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s