I had reported earlier how I had gotten a C Hello World
statically-linked
program running on my Android phone using CodeSourcery's toolchain (on
linux). Today I got a dynamically-linked Hello World program running on the
phone, compiled using Android's prebuilt toolchain from the .
It's well known
that Android uses a stripped down version of libc, called bionic. When you
compile your program with static linking, you don't use bionic because well, you
linked statically. This is non-ideal. You want to use the bionic library on the
phone, and besides you want to compile using Android's prebuilt cross-compiler
arm-eabi-gcc
If
you are anxious to get things working, use , a perl wrapper over arm-eabi-gcc that sets up
everything for you so that you can just:
$ agcc hello.c -o
hello
and the resulting binary (hello) just works. Of
course you should have the directory containing arm-eabi-gcc in your PATH
for agcc to
work.
Let's explore a bit deeper. But let me first simplify my hello
program to contain just a main
$ cat hello.c int main(int argc, char* argv[])
{
return
0;
}
The minimal set
of flags to pass to arm-eabi-gcc to get this working is:
$ arm-eabi-gcc -o hello hello.c
-Wl,-rpath-link=/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib
-L/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib
-nostdlib /Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/crtbegin_dynamic.o
-lc
Here /Users/nirnimesh/NIR/android/mydroid/cupcake
is the root of my Android source.
$ file hello
hello: ELF 32-bit LSB executable,
ARM, version 1 (SYSV), dynamically linked (uses shared libs), not
stripped
Note that the executable binary is dynamically
linked.
If you leave out -Wl,-rpath-link=/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib
you get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld:
warning: libdl.so, needed by
/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/libc.so,
not found (try using -rpath or -rpath-link) /Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/libc.so:
undefined reference to `dl_unwind_find_exidx' collect2: ld returned 1 exit
status
If you leave out -L/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib
you get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-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
If you leave out -nostdlib you
get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-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
If you leave out /Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/crtbegin_dynamic.o
you get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-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
And finally, f you leave out -lc your compilation
fails with:
/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/crtbegin_dynamic.o:
In function `_start': bionic/libc/arch-arm/bionic/crtbegin_dynamic.S:(.text+0x10):
undefined reference to `__libc_init' collect2: ld returned 1 exit
status
So far we've been able to compile C programs using Androids
toolchain and run on the phone.
To summarize, it's the most convenient to use
agcc as the
compiler so you don't have to bother.