Chinaunix首页 | 论坛 | 博客
  • 博客访问: 237973
  • 博文数量: 68
  • 博客积分: 884
  • 博客等级: 准尉
  • 技术积分: 700
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-25 14:34
文章分类

全部博文(68)

文章存档

2016年(3)

2015年(4)

2014年(9)

2013年(8)

2012年(6)

2011年(19)

2010年(19)

我的朋友

分类: LINUX

2011-12-04 23:31:35

Forward this great article...
 
 
 
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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.
 Posted by Nirnimesh .  at 1:16 AM 
 21 comments:
sheiff said...
 Wow!
I just need it now =)
Thousands of thanks!
 Thursday, February 26, 2009 1:53:00 AM PST
jervis said...
 thanks very much, I've done now.
 Wednesday, March 11, 2009 10:10:00 AM PDT
neiln said...
 I followed those steps and run it on the emulator/cupcake branch. It did not work. I got file not found.
Neil
 Saturday, March 28, 2009 8:56:00 PM PDT
Jared said...
 Awesome man, keep up the updates. I just got my dev phone and have used a few of your posts already.
 Monday, April 6, 2009 3:12:00 PM PDT
Yarx said...
This post has been removed by the author.
 Wednesday, April 22, 2009 7:56:00 PM PDT
Jayden's Mobile World said...
 Thank you so much. It helped me a lot.
 Friday, May 15, 2009 8:49:00 AM PDT
むらかみ たくや said...
 I created similar tool named 'droid-wrapper'. It can be used for generic software using 'configure' script.
 I published it at
 Thursday, July 23, 2009 12:21:00 AM PDT
StyXman said...
 just like neiln, I get:
# ./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?
 Friday, November 27, 2009 11:54:00 AM PST
Pedro J. Estébanez said...
 For those with the "not found" problem:
That'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.
 Saturday, December 5, 2009 7:24:00 AM PST
tarek.attia said...
 Hi,You helped me so much :)
But 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 :)
 Monday, December 21, 2009 2:11:00 PM PST
Winston said...
 Using the NDK r3 in Android 2.1, I was able to compile with the following (from the ndk directory):
./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!
 Monday, March 22, 2010 3:13:00 PM PDT
Danny said...
This post has been removed by the author.
 Tuesday, April 13, 2010 5:44:00 AM PDT
Danny said...
 hi, i am trying to compile Hello.c same as above
arm-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
 Tuesday, April 13, 2010 5:47:00 AM PDT
Vince said...
 I just installed the new NDK (android-ndk-r3)...before which I was using CodeSourcery's toolchain.
When 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.
 Thursday, April 29, 2010 12:02:00 PM PDT
Lunkwill said...
 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:

 Sunday, August 15, 2010 5:43:00 PM PDT
Vlad said...
 Here is another copy of patched up agcc script.
@lunkwill You've beaten me by a few days, unfortunately your link is not valid. Could you fix it?
 Wednesday, August 18, 2010 5:07:00 PM PDT
Radu Motisan said...
 This article is old. You now can use the NDK to compile a native C code file, not only JNI libraries.
Here's how to do it:
Hope this helps.
 Thursday, November 18, 2010 1:57:00 AM PST
sasha said...
 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.
best android apps
best iphone apps
 Tuesday, May 31, 2011 10:35:00 AM PDT
Prasad H. L. said...
 Great article. I like esp. your analysis of leaving out each options and showing the affect.
Thanks a lot.
 Thursday, June 9, 2011 11:27:00 PM PDT
Muhammad Azeem said...
 This is a nice article..
Its very easy to understand ..
And this article is using to learn something about it..
asp.net, c#, javascript
Thanks a lot..!
 Saturday, June 11, 2011 12:42:00 AM PDT
jignesh said...
 This is awesome post and good imformation
C interview questions
 Wednesday, September 7, 2011 1:57:00 PM PDT
 
阅读(3192) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~