android linux 系统总结4

来源:互联网 发布:ipad如何看淘宝直播 编辑:程序博客网 时间:2024/06/05 21:05
====================================================================3. 制作交叉工具链3.1 什么是工具链3.2 获取交叉工具链的几种途径3.3 android工具链与gnu工具链的比较       每一个软件,在编译的过程中,都要经过一系列的处理,才能从源代码变成可执行的目标代码。这一系列处理包括:预编译,高级语言编译,汇编,连接及重定位。这一套流程里面用到的每个工具和相关的库组成的集合,就称为工具链(tool chain)。以GNU的开发工具GCC为例,它就包括了预编译器cpp,c编译器gcc,汇编器as,和连接器ld等。在GNU自己对工具链定义中,还加进了一套额外的用于处理二进制包的工具包binutils,整个工具链应该是GCC+binutils+Glibc, binutils其实与Glibc关系不是很大,它可以被独立安装的,所以GNU工具链也可以狭义地被理解为GCC+Glibc。要构建出一个交叉工具链,需要解决三个问题。一是这个工具链必须是可以运行在原工作站平台上的。二是我们需要更换一个与目标平台对应的汇编器,使得工具链能产生对应的目标代码,三是要更换一套与目标平台对应的二进制库,使得工具链在连接时能找到正确的二进制库。3.2 获取交叉工具链的几种途径3.2.1 利用源代码制作交叉工具链网上直接下载工具链或者从方案商处获取(如:marvell)下载地址:http://www.angstrom-distribution.org/unstable/3.2.2 用脚本制作工具链3.2.2.1 croostool-0.43http://www.kegel.com/crosstool/crosstool-0.43.tar.gz制作工具链的源码包搭配情况: http://www.kegel.com/crosstool/crosstool-0.43/buildlogs/3.2.2.2 buildroothttp://buildroot.uclibc.org/downloads/snapshots/buildroot-snapshot.tar.bz2若想详细地了解buildroot可参考该文档http://buildroot.uclibc.org/buildroot.html3.2.3 利用OE制作工具链http://www.scratchbox.org/wiki/OpenEmbedded3.3 android工具链与gnu工具链的比较Android所用的Toolchain(即交叉编译工具链)可从下面的网址下载:http://android.kernel.org/pub/android-toolchain-20081019.tar.bz2。如果下载了完整的Android项目的源代码,则可以在“<your_android>/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin”目录下找到交叉编译工具,比如Android所用的arm-eabi-gcc-4.2.1。Android并没有采用glibc作为C库,而是采用了Google自己开发的Bionic Libc,它的官方Toolchain也是基于Bionic Libc而并非glibc的。这使得使用或移植其他Toolchain来用于Android要比较麻烦:在Google公布用于Android的官方Toolchain之前,多数的Android爱好者使用的Toolchain是在http://www.codesourcery.com/gnu_toolchains/arm/download.html 下载的一个通用的Toolchain,它用来编译和移植Android 的Linux内核是可行的,因为内核并不需要C库,但是开发Android的应用程序时,直接采用或者移植其他的Toolchain都比较麻烦,其他Toolchain编译的应用程序只能采用静态编译的方式才能运行于Android模拟器中,这显然是实际开发中所不能接受的方式。目前尚没有看到说明成功移植其他交叉编译器来编译Android应用程序的资料。与glibc相比,Bionic Libc有如下一些特点:-          采用BSD License,而不是glibc的GPL License;-          大小只有大约200k,比glibc差不多小一半,且比glibc更快;-          实现了一个更小、更快的pthread;-          提供了一些Android所需要的重要函数,如”getprop”, “LOGI”等;-          不完全支持POSIX标准,比如C++ exceptions,wide chars等;-          不提供libthread_db 和 libm的实现另外,Android中所用的其他一些二进制工具也比较特殊:-          加载动态库时使用的是/system/bin/linker而不是常用的/lib/ld.so;-          prelink工具不是常用的prelink而是apriori,其源代码位于” <your_android>/build/tools/apriori”-          strip工具也没有采用常用的strip,即“<your_android>/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin”目录下的arm-eabi-strip,而是位于<your_android>/out/host/linux-x86/bin/的soslim工具。参考文档:CLFS2.0原理分析 http://www.linuxsir.org/bbs/showthread.php?t=267672Cross-Compiled Linux From Scratchhttp://cross-lfs.org/view/clfs-sysroot/arm/全手工制作arm-linux交叉编译工具链《一》http://blog.chinaunix.net/u2/62168/showart_1898748.html自己制作arm-linux交叉编译环境(一)-scratch篇http://blog.csdn.net/chenzhixin/archive/2007/01/12/1481442.aspx如何建立交叉编译工具链http://www.decell.org/article.asp?id=53Android Toolchain与Bionic Libchttp://www.top-e.org/jiaoshi/html/?151.htmlndroid编译环境(2) - 手工编译C模块==================================================================================================4. 软件编译常识4.1 链接器和加载器4.2 android 的标准链接器和加载器4.3 Makefile基本语法何为链接器和加载器? 链接器为ld,加载为ld-linux.so.2,两个的区别很大,一个编译时用,一个运行时用,ld负责在编译的搜索路径里找到要求的库,并查看是否有提供了需要的 符号(如函数等),如果有,记录相关信息到程序中,由ld-linux.so.2在执行时查找到该库,并根据相关信息进行需要符号的重定位等工作.注意 这两者的搜索库的方式是不同的。动态连接器通常是指的动态加载器(不要与 Binutils 里的标准连接器 ld 混淆了)。动态连接器由 Glibc 提供,用来找到并加载一个程序运行时所需的共享库,在做好程序运行的准备之后,运行这个程序。动态连接器的名称通常是 ld-linux.so.2,标准连接器 ld 由 Binutils 这个包提供。标准连接器查看gcc使用的标准连接器mhf@mhf-desktop:/usr/local/marvell-arm-linux-4.1.1/bin$ arm-linux-gcc -print-prog-name=ld编译时库的搜索路径,以下几种方式让连接器去找需要的库1. 编译的时候明确指定,如: gcc test.c  ./say.so -o test中的   ./say.so2. 编译 Binutils 的时候通过LIB_PATH 变量指定,如:make -C ld LIB_PATH=/tools/lib -C ld LIB_PATH=/tools/lib这个选项重新编译 ld 子目录中的所有文件。在命令行中指定 Makefile 的 LIB_PATH 变量值,使它明确指向/tools/lib工具目录,以覆盖默认值。这个变量的值指定了连接器的默认库搜索路径。来源:Linux From Scratch - 版本 6.4第 5 章 构建临时系统  5.4. Binutils-2.18 - 第一遍http://www.bitctp.org/lfsbook-6.4/chapter05/binutils-pass1.html3. 在源码包configure的时候通过  --with-lib-path 指定,或者 --lib- path例如:binutils-2.18/configure --prefix=/tools --disable-nls --with-lib-path=/tools/lib配置选项的含义:--with-lib-path=/tools/lib    告诉配置脚本在为编译 Binutils 的过程中使用正确的库搜索路径,也就是将 /tools/lib 传递给连接器。这防止连接器搜索宿主系统中的库文件目录。来源: Linux From Scratch - 版本 6.4 第 5 章 构建临时系统  lfs 5.13. Binutils-2.18 - 第二遍 http://www.bitctp.org/lfsbook-6.4/chapter05/binutils-pass2.html4. 到 ld –verbose | grep SEARCH 列出的默认目录下去找5. -L/usr/gpephone/lib 指定的目录找经常以 LDFLAGS=" -L/usr/gpephone/lib  -L/lib -L/usr/lib -L/usr/X11R7/lib" 的方式传入参数 -rpath 与  -rpath-link 如果使用了'-rpath'选项, 那运行时搜索路径就只从'-rpath'选项中得到'nodefaultlib'标志一个对象,使在搜索本对象所依赖的库时,忽略所有缺省库搜索路径.LDFLAGS="-Wl,-rpath-link=/usr/gpephone/lib/:/usr/gphone/lib:/usr/local/lib  -L/usr/gpephone/lib  -L/usr/gphone/lib"-rpath 与  -rpath-link 的特性:1. 在编译的时候我们都可以使用这两个路径,2. '-rpath'跟'-rpath_link'的不同之处在于,由'-rpath'指定的路径会被包含到可执行程序中,并在运行时使用,而'-rpath-link'选项仅仅在链接时起作用。-dumpspecs               Display all of the built in spec strings  -dumpversion             Display the version of the compiler  -dumpmachine             Display the compiler's target processor  -print-search-dirs       Display the directories in the compiler's search path  -print-prog-name=<prog>  Display the full path to compiler component <prog>  -specs=<file>            Override built-in specs with the contents of <file>  -Wa,<options>            Pass comma-separated <options> on to the assembler  -Wp,<options>            Pass comma-separated <options> on to the preprocessor  -Wl,<options>            Pass comma-separated <options> on to the linker从工具链内建的规范中查看动态加载器gcc -dumpspecs | grep  dynamic-linker  //本机查看编译起所指定的动态加载器1. s3c2440 (arm9tdmi) 平台的工具链/scratchbox/compilers/arm-9tdmi-softfloat-linux-gcc-3.4.4-glibc-2.3.5/bin/arm-softfloat-linux-gnu-gcc -dumpspecs | grep  dynamic-linker/scratchbox/compilers/arm-softfloat-linux-gcc-3.4.4-glibc-2.3.5/bin/arm-softfloat-linux-gnu-gcc -dumpspecs | grep  dynamic-linker2. marvell 的工具链/scratchbox/compilers/marvell-arm-linux-4.1.1/bin/arm-linux-gcc  -dumpspecs | grep  dynamic-linker3. scrathbox 中工具链 host-gcc /scratchbox/compilers/host-gcc/bin/host-gcc  -dumpspecs | grep  dynamic-linker如果我们在编译的时候给编译起 gcc 指定 -specs=/scratchbox/compilers/host-gcc/host-gcc.spec ,那么-specs指定的规范将会覆盖工具链内建的规范。cat /scratchbox/compilers/host-gcc/host-gcc.specs  | grep ld 有如下内容:-dynamic-linker /scratchbox/host_shared/lib/ld.so/scratchbox/compilers/host-gcc/bin/gcc -specs=/scratchbox/compilers/host-gcc/host-gcc.specsmhf@mhf-desktop:/usr/local/marvell-arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/bin$ ./gcc -dumpspecs|grep dynamic-linkergcc -dumpspecs | sed 's@/lib/ld-linux.so.2@/tools&@g'  | sudo tee  `dirname $(gcc -print-libgcc-file-name)`/specscat `dirname $(gcc -print-libgcc-file-name)`/specs | grep tools查看本机应用程序使用的动态加载器readelf -l /usr/bin/make | grep interpreter [Requesting program interpreter: /lib/ld-linux.so.2]查看 scratchbox 中应用程序使用的动态加载器readelf -l /scratchbox/tools/bin/make | grep interpreter[Requesting program interpreter: /scratchbox/host_shared/lib/ld.so]cd ~/svn/mohuifu.svn/trunk/mysource/compiler_test/scratchbox/compilers/host-gcc/bin/gcc -specs=/scratchbox/compilers/host-gcc/host-gcc.specs -o ld.so.test1 ld.so.test.c/scratchbox/compilers/host-gcc/bin/gcc -o ld.so.test2 ld.so.test.creadelf -l ./ld.so.test1 | grep interpreter readelf -l ./ld.so.test2 | grep interpreter 其他示例:readelf -l /scratchbox/tools/bin/make | grep interpreterreadelf -l /usr/bin/make | grep interpreter分别显示:[Requesting program interpreter: /scratchbox/host_shared/lib/ld.so][Requesting program interpreter: /lib/ld-linux.so.2]下面的方式也可以查看应用程序所使用的加载器strings  /scratchbox/tools/bin/make  |grep libstrings  /usr/bin/make  |grep lib分别为:/scratchbox/host_shared/lib/ld.so/lib/ld-linux.so.2查看应程序加载器库的搜索路径显示 scratchbox 中加载器的库搜索路径strings /scratchbox/host_shared/lib/ld.so |grep libdisplay library search paths/scratchbox/host_shared/lib//scratchbox/tools/lib/显示本机中加载器的库搜索路径strings  /lib/ld-linux.so.2 |grep libdisplay library search paths/lib//usr/lib//lib/i486-linux-gnu//usr/lib/i486-linux-gnu/ldd 验证应用程序所使用动态库ldd /scratchbox/tools/bin/makelibc.so.6 => /scratchbox/host_shared/lib/libc.so.6 (0xb7ef9000)/scratchbox/host_shared/lib/ld.so => /scratchbox/host_shared/lib/ld.so (0xb802f000)ldd /usr/bin/makelibrt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7fb9000)libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e5b000)libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7e42000)/lib/ld-linux.so.2 (0xb7fd5000)参考文档:交叉编译中libtool相关的问题http://hi.baidu.com/lieyu063/blog/item/9c99a2dd23e41f365882dd39.html静态库和共享库库的定位搜索路径http://blog.csdn.net/lwhsyit/archive/2008/08/26/2830783.aspxLinux动态连接原理http://blog.chinaunix.net/u2/67984/showart_1359874.html程序编译链接运行时对库关系的探讨(原创)http://www.360doc.com/content/061107/09/13188_251964.htmlhttp://lamp.linux.gov.cn/Linux/LFS-6.2/chapter05/toolchaintechnotes.html[Linux命令] ld 中文使用手册完全版(译) http://blog.csdn.net/rstevens/archive/2008/01/28/2070568.aspxscratchbox 是mameo (nokia) 提供的一个集成开发环境,可以去官方网站:http://www.scratchbox.org/http://www.scratchbox.org/download/4.2 android 的标准链接器和加载器android的标准链接器 ./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-ldandroid 中标准连接器搜索库的路径./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-ld -verbose | grep SEARCHSEARCH_DIR("/android/mathias/armdev/toolchain-eabi-4.2.1/arm-eabi/lib");Android编译环境所用的交叉编译工具链是./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc,-I和-L参数指定了所用的C库头文件和动态库文件路径分别是bionic/libc /include 和out/target/product/generic/obj/lib,其他还包括很多编译选项以及-D所定义的预编译宏。这里值得留意的是参数“-Wl,-dynamic-linker,/system/bin/linker”,它指定了Android专用的动态链接器/system/bin/linker,而不是通常所用的ld.so。上面的“make clean-$(LOCAL_MODULE)”是Android编译环境提供的make clean的方式。android中应用程序使用的加载器strings  out/target/product/littleton/obj/EXECUTABLES/rild_intermediates/rild  | grep link/system/bin/linker./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc -dumpspecs|grep dynamic-linker%{mbig-endian:-EB} %{mlittle-endian:-EL} %{static:-Bstatic} %{shared:-shared} %{symbolic:-Bsymbolic} %{!static:%{shared: -Bsymbolic} %{!shared:%{rdynamic:-export-dynamic} %{!dynamic-linker:-dynamic-linker /system/bin/linker}}} -Xandroid中加载器搜索库的路径strings /nfsroot/rootfs/system/bin/linker | grep lib/system/lib/lib生成的可执行程序可用file和readelf命令来查看一下:file out/target/product/littleton/obj/EXECUTABLES/rild_intermediates/rild out/target/product/littleton/obj/EXECUTABLES/rild_intermediates/rild: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), strippedreadelf -d out/target/product/littleton/obj/EXECUTABLES/rild_intermediates/rild  |grep NEEDED 0x00000001 (NEEDED)                     Shared library: [liblog.so] 0x00000001 (NEEDED)                     Shared library: [libcutils.so] 0x00000001 (NEEDED)                     Shared library: [libril.so] 0x00000001 (NEEDED)                     Shared library: [libc.so] 0x00000001 (NEEDED)                     Shared library: [libstdc++.so] 0x00000001 (NEEDED)                     Shared library: [libm.so] 0x00000001 (NEEDED)                     Shared library: [libdl.so]这是ARM格式的动态链接可执行文件,运行时需要libc.so和libm.so。“not stripped”表示它还没被STRIP。嵌入式系统中为节省空间通常将编译完成的可执行文件或动态库进行STRIP,即去掉其中多余的符号表信息。在前面“make helloworld showcommands”命令的最后我们也可以看到,Android编译环境中使用了out/host/linux-x86/bin/soslim工具进行STRIP。4.3 Makefile基本语法Makefile详解(超级好)linux/Unix环境下的make和makefile详解http://www.unlinux.com/doc/program/20051026/2365.html跟我一起写 Makefilehttp://dev.csdn.net/develop/article/20/20025.shtm=================================================
原创粉丝点击