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 source.
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 agcc, 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.
Display X windows on X11.app from another linux box
15 years ago
Wow!
ReplyDeleteI just need it now =)
Thousands of thanks!
thanks very much, I've done now.
ReplyDeleteI followed those steps and run it on the emulator/cupcake branch. It did not work. I got file not found.
ReplyDeleteNeil
Awesome man, keep up the updates. I just got my dev phone and have used a few of your posts already.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThank you so much. It helped me a lot.
ReplyDeleteI created similar tool named 'droid-wrapper'. It can be used for generic software using 'configure' script.
ReplyDeleteI published it at http://github.com/tmurakam/droid-wrapper/
just like neiln, I get:
ReplyDelete# ./hw
./hw: not found
my compile options add a couple of -I because the compiler didn't find the headers. also, trying to compile the cupcake from sources (pulled via git) does not compile bionic. do you know anything about that?
For those with the "not found" problem:
ReplyDeleteThat's because you have to specify the path to the Android dynamic linker:
arm-eabi-gcc [...] -Wl,-rpath-link=...,-dynamic-linker=/system/bin/linker
I've had a hard time with this issue, too.
Hi,You helped me so much :)
ReplyDeleteBut I developed an application using threads,and made the make file as you stated ,but each time I try to run it on the target ,it arisen a linking error that tells me that it doesn't can to link "libpthread.s0.6",,I know that android uses different libc implementation bionic,,How can I resolve this matter ??
Any help will be appreciated :)
Using the NDK r3 in Android 2.1, I was able to compile with the following (from the ndk directory):
ReplyDelete./build/prebuilt/darwin-x86/arm-eabi-4.2.1/bin/arm-eabi-gcc -o hello hello.c -Wl,-rpath-link=./build/platforms/android-5/arch-arm/usr/lib/,-dynamic-linker=/system/bin/linker -L./build/platforms/android-5/arch-arm/usr/lib/ ./build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o -I./build/platforms/android-5/arch-arm/usr/include -nostdlib -lc
Don't know if it works -- I don't have an Android device, just the SDK emulator!
This comment has been removed by the author.
ReplyDeletehi, i am trying to compile Hello.c same as above
ReplyDeletearm-eabi-gcc -o hello hello.c -Wl,-rpath-link=/home/builds/android/out/target/product/generic/obj/lib -L/home/builds/android/out/target/product/generic/obj/lib -nostdlib /home/builds/android/out/target/product/generic/obj/lib/crtbegin_dynamic.o -lc
I am getting below error, can any one help me
/home/builds/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/../lib/gcc/arm-eabi/4.4.0/../../../../arm-eabi/bin/ld: cannot find -lc
collect2: ld returned 1 exit status
I just installed the new NDK (android-ndk-r3)...before which I was using CodeSourcery's toolchain.
ReplyDeleteWhen I try to compile from command line, I get the following:
main.c:14:24: error: sys/socket.h: No such file or directory
main.c: In function 'main':
main.c:31: error: 'pthread_t' undeclared (first use in this function)
main.c:31: error: (Each undeclared identifier is reported only once
main.c:31: error: for each function it appears in.)
main.c:31: error: expected ';' before 'listenerThread'
main.c:38: error: 'listenerThread' undeclared (first use in this function)
main.c: In function 'openSocket':
main.c:53: error: 'AF_INET' undeclared (first use in this function)
main.c:53: error: 'SOCK_STREAM' undeclared (first use in this function)
And so on. The NDK cannot find the #includes.
Any way around this? With CodeSourcery I was able to compile from command line very simply:
arm-none-linux-eabi-gcc -static -pthread main.c -o main
It is not working as I expected. Please advise!
Thank you.
The agcc wrapper doesn't work with android-ndk-r4b due to changed paths. I hacked it enough to get a simple printf("Hello, world!") to compile. Modified agcc here:
ReplyDeletehttps://docs.google.com/leaf?id=0B8R6VSvTZHZWYWI5OTY3NDgtNmFmMS00OTY2LWI1MmMtYTc0ZmZkZDBmZjk2&hl=en
Here is another copy of patched up agcc script. http://bit.ly/91wnsa
ReplyDelete@lunkwill You've beaten me by a few days, unfortunately your link is not valid. Could you fix it?
This article is old. You now can use the NDK to compile a native C code file, not only JNI libraries.
ReplyDeleteHere's how to do it:
http://www.pocketmagic.net/?p=1462
Hope this helps.
I can't stress this enough to my friends and people I talk to about Android apps in general- Most of the best Android apps are the free ones.
ReplyDeletebest android apps
best iphone apps
Great article. I like esp. your analysis of leaving out each options and showing the affect.
ReplyDeleteThanks a lot.
This is awesome post and good imformation
ReplyDeleteC interview questions
@Nirnimesh : This method is better than NDK ??
ReplyDeleteGreat post, you have pointed out some wonderful details, I as well conceive this s a very excellent website. Hong Kong Company
ReplyDeleteThe most pervasive influence on these languages has been syntactical, and they tend to combine the recognizable expression and statement syntax of C with underlying type systems and data models that can be radically different. C++ started as a preprocessor for C and is currently nearly a superset of C. Thanks.
ReplyDeleteRegards,
website design company
I managed to get a "Hello, World!" application running under Android 4.1 with the command line below:
ReplyDeletearm-eabi-gcc -o hello hello.c -I/home/sandy/android/google_repositories/arm-toolchain/prebuilt/ndk/android-ndk-r7/platforms/android-14/arch-arm/usr/include -Bdynamic -Wl,--gc-section -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,--dynamic-linker=/system/bin/linker -Wl,-rpath-link=/home/sandy/android/google_repositories/android-4.0.4_r1/prebuilt/ndk/android-ndk-r7/platforms/android-14/arch-arm/usr/lib -L/home/sandy/android/google_repositories/android-4.0.4_r1/prebuilt/ndk/android-ndk-r7/platforms/android-14/arch-arm/usr/lib -nostdlib /home/sandy/android/google_repositories/android-4.0.4_r1/prebuilt/ndk/android-ndk-r7/platforms/android-14/arch-arm/usr/lib/crtend_android.o /home/sandy/android/google_repositories/android-4.0.4_r1/prebuilt/ndk/android-ndk-r7/platforms/android-14/arch-arm/usr/lib/crtbegin_dynamic.o -lc
Application Source:
#include
#include
int main( int argc, char **argv )
{
printf( "Hello, World!\n" );
return 0;
}
I only tested this on the AVD emulator so your mileage may vary...
A simple house is a house with few exterior corners. Every house corner beyond a simple box will add roofing complications and increase the cost of building the house. The simplest house is a square or rectangle. Reducing the number of interior walls will also reduce the cost and complexity of a house. Thanks.
ReplyDeleteWeb design norwich
This article is old. You now can use the NDK to compile a native C code file, not only JNI libraries.
ReplyDeletecheap jerseys
wholesale cheap jerseys
Your photos are lovely. The time you have taken to invest in preserving memories is priceless.I hope more. Great job on the site, it looks wonderful. I am going to bookmark it and will make sure to visit often.
ReplyDeletejerseys cheap
Hello! I simply would really like to present large thumbs up for the nice information you’ve got here on this post. i’ll be coming to your journal for a lot of before long
ReplyDeletecheap jersey
cheap nike jerseys
cheap jerseys wholesale
cheap mlb jerseys
Here is the perfect app for you guys http://akshayeminem.blogspot.in/2013/01/c-and-c-programming-in-android.html
ReplyDelete