dack 发表于 2008-10-17 15:56:58

原创:编译arm-linux工具链【恢复】

搞了一个“中基学生电脑”(详细的见这里http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1420850&bbs_page_no=1&search_mode=4&search_text=dack&bbs_id=9999),当作arm开发板用。但本人对linux不熟,arm更是没有搞过,所以从头开始学,先编译一套工具链才能进行下一步。

了解到有crosstools可以方便的编译工具链,甚至还有编译好的下载,但是鉴于本人初学,什么都不懂,决定还是自己一步一步编译,权当熟悉linux,熟悉一下编译流程了。花了一个多星期终于搞好了,其实第一次编译成功用了不到一个星期,为了写这篇文章和搞清楚其中的一些不明所以的地方,又重新编译了两次,现在基本搞清楚了,发上来与大家共享。其实还有一些不明所以的地方,以后再说吧,实在不想再编译了。

中基是基于sa1110芯片的,主要部分和assabet开发板一样。以下linux头文件是基于这样的系统产生的,不过我想也能用于其他型号的芯片。

先说说我的编译环境,一台384M内存的p4电脑,win2000系统,开vmware虚拟机,装了一个puppy linux 3.01,这个linux以小巧见称。可想而知有多慢了。

个人感觉,编译这个很考人品,人品不好总会碰到一些稀奇古怪的问题。呵呵,我估计是那个人品最差的。

虽然我已经很小心,最后一遍命令都是粘贴上去执行的,后面又进行了一些修改,主要是安装目录,但文中难免有错漏,发现了请指出。

初学者可以尝试自己编译工具链,能够学到一下东西。

所有用到的软件都是最新版的。

好了,闲话少说,开干。



1.下载

ftp://mirrors.kernel.org/gnu/binutils/binutils-2.18.tar.gz

ftp://mirrors.kernel.org/gnu/gcc/gcc-4.3.2/gcc-4.3.2.tar.gz

ftp://mirrors.kernel.org/gnu/gdb/gdb-6.8.tar.gz

ftp://mirrors.kernel.org/gnu/glibc/glibc-2.7.tar.gz

ftp://mirrors.kernel.org/gnu/glibc/glibc-ports-2.7.tar.gz

http://ftp.osuosl.org/pub/clfs/conglomeration/glibc/glibc-2.7-libgcc_eh-1.patch

ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.tar.gz

http://www.mpfr.org/mpfr-current/mpfr-2.3.2.tar.gz

ftp://ftp.gmplib.org/pub/gmp-4.2.4.tar.gz



2.建立工作目录

    我的工作目录放在一个单独的盘上,/mnt/hdc1。你可以任选一个目录做工作目录,例如~/work。将下载的文件全部放到工作目录下。

    工作目录中建立目录build,用来放解压后的源码和build时产生的文件,最终产生的工具放到/usr/armtools下。

3.设置环境变量

    在etc/ld.so.conf中加上一行/usr/local/lib,用来设置动态库的搜索目录,已经有的话就不用加了,因为gmp和mpfr会装到这里,不加以后的编译通不过。

    开一个终端窗口

    export TARGET=arm-linux

    export PREFIX=/usr/armtools

    export PATH=$PATH:/usr/armtools/bin

    export BUILD_DIR=/mnt/hdc1/build

4.安装gmp和mpfr库,这两个库是gcc需要的,老版本如果不用fortan77的话不需要,但新版本只编译c也需要。有的话就不用装了。

    cd /mnt/hdc1        进入工作目录

    cd build

    tar -zxvf ../gmp-4.2.4.tar.gz    这里有个技巧,打完gm后直接按tab键文件名会自动补全。后面需要输入目录的地方都可以这么用。

    cd gmp-4.2.4

    ./configure

    make

    make check        文档里说这个非常重要。

    make install

    cd ..

    rm -rf gmp-4.2.4    装完源目录没用了,删掉,节省空间。



    ldconfig /usr/local/bin

    tar -zxvf ../mpfr-2.3.2.tar.gz    这里有个技巧,打完gm后直接按tab键文件名会自动补全。后面需要输入目录的地方都可以这么用。

    cd mpfr-2.3.2

    ./configure

    make

    make check        文档里说这个非常重要。

    make install

    cd ..

    rm -rf mpfr-2.3.2    装完源目录没用了,删掉,节省空间。



    ldconfig /usr/local/bin    更新一下缓存

    完成,这一步一般不会出问题。

5.编译binutils

    tar -zxvf ../binutils-2.18.tar.gz

    mkdir binutils-2.18-build

    cd binutils-2.18-build

    ../binutils-2.18/configure --target=$TARGET --prefix=$PREFIX

    make

    make install

    cd ..

    rm -rf binutils-2.18

    rm -rf binutils-2.18-build

    ok,这一步也很简单,完成后armtools里会有很多文件。

6.编译bootstrap gcc

    tar -zxvf ../gcc-4.3.2.tar.gz

    mkdir gcc-4.3.2-build

    cd gcc-4.3.2-build   

    ../gcc-4.3.2/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c --with-local-prefix=$PREFIX/arm-linux --without-headers --with-newlib --disable-shared --disable-threads --disable-libmudflap --disable-libssp

    这一步参数比较多,大概说一下

    --target=$TARGET    目标,arm-linux,就是要产生linux下编译arm程序的编译器

    --prefix=$PREFIX    安装目录

    --enable-languages=c     只产生c编译器

    --with-local-prefix=$PREFIX/arm-linux     不知道有啥用,实在不想再编译一遍试验了,谁有空可以试试不加行不行。

    --without-headers     不使用头文件,因为还没有glibc

    --with-newlib     这个不太明白,似乎是编译一个自带的库

    --disable-shared     不编译共享库

    --disable-threads     不编译线程支持

    --disable-libmudflap     禁止mudflap库,这个库需要glibc支持

    --disable-libssp     禁止ssp库,这个库需要glibc支持



    make all-gcc        编译安装gcc

    make install-gcc

    make all-target-libgcc        编译安装库,不做的话编译glibc时找不到库

    make install-target-libgcc

    cd ..

    rm -rf gcc-4.3.2-build

7.建立linux头文件

    tar -zxvf ../linux-2.6.27.tar.gz

    cd linux-2.6.27

    make ARCH=arm menuconfig

    菜单最下面选择load一个arm板子的config文件,我load的arch/arm/configs/assabet_defconfig,然后保存为.config。退出

    make ARCH=arm CROSS_COMPILE=$PREFIX/bin/arm-linux-        出现CC什么的时候就可以停止了。

    cd ..

    2.6.27版和2.6.26.5版比目录结构发生了变化,所以编译glibc时要改路径,否则找不到头文件。编译glibc时候用到了特定arm芯片(例如我用的sa1100)的头文件,难道编译出来的glibc只能用在特定的芯片上吗,有知道的说一下。

8.编译glibc

    tar -zxvf ../glibc-2.7.tar.gz

    cd glibc-2.7

    tar -zxvf ../../glibc-ports-2.7.tar.gz    glibc本身是不支持arm等的,需要加这个port。

    mv glibc-ports-2.7 ports

    打补丁,sed -i 's/aaa/bbb/' file 就是把file里的aaa替换成bbb,bbb里面的&代表aaa,\t代表tab,\n代表换行。你也可以用文本编辑器来做,用sed做要注意不要打错任何一个字符,空格啦,大小写啦都要注意。

    sed -i 's/-nostdinc -isystem $ccheaders /-nostdinc -isystem $ccheaders -isystem $ccheaders-fixed /' configure.in   

    sed -i 's/-isystem $cxxheaders /-isystem $cxxheaders -isystem $cxxheaders-fixed /' configure.in   

    sed -i 's/# define UNDOCARGS_5\tUNDOCARGS_4/&\n\n# define DOCARGS_6\tUNDOCARGS_5\n# define UNDOCARGS_6\tUNDOCARGS_5/' ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h

    sed -i 's/#include <kernel-features.h>/&\n#include <tls.h>/' ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h

    sed -i 's/__deprecated/__attribute__((deprecated))/' ../linux-2.6.27/arch/arm/include/asm/memory.h

    patch -p1 < ../../glibc-2.7-libgcc_eh-1.patch

    

    cd ..

    mkdir glibc-2.7-build

    cd glibc-2.7-build

    CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib ../glibc-2.7/configure --host=$TARGET --prefix=$PREFIX/$TARGET --enable-add-ons --with-headers=$BUILD_DIR/linux-2.6.27/include:$BUILD_DIR/linux-2.6.27/arch/arm/include:$BUILD_DIR/linux-2.6.27/arch/arm/mach-sa1100/include libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes cross_compiling=yes build_alias=i386-linux-gnu

    上面这句里的cross_compiling=yes build_alias=i386-linux-gnu不是必需的,我第一遍编译时没加也通过了,但后来不知道为什么就不行了,如果出错或者make出错可以加上试试,主要是因为configure自动判定交叉编译判断错误,把交叉编译出来的文件在本地执行,当然执行不了啦。

    make

    make install

    cd ..

    rm -rf glibc-2.7-build

    rm -rf glibc-2.7

9.拷贝linux头文件

    cp -r linux-2.6.27/include/linux $PREFIX/$TARGET/include

    cp -r linux-2.6.27/arch/arm/include/asm $PREFIX/$TARGET/include

    mv $PREFIX/$TARGET/include/asm $PREFIX/$TARGET/include/asm-arm

    cp -r -f linux-2.6.27/include/asm-arm $PREFIX/$TARGET/include

    cp -r linux-2.6.27/include/asm $PREFIX/$TARGET/include

    cp -r linux-2.6.27/include/asm-generic $PREFIX/$TARGET/include

    cp -r linux-2.6.27/arch/arm/mach-sa1100 $PREFIX/$TARGET/include

    mv $PREFIX/$TARGET/include/mach-sa1100 $PREFIX/$TARGET/include/mach

    这些文件不但编译glibc gcc时有用,而且似乎在以后编译应用程序的时候也可能有用,因为glibc库的头文件里有包含他们,所以我把他们拷贝到安装目录里。

10.编译gcc

    mkdir gcc-4.3.2-build

    cd gcc-4.3.2-build   

    ../gcc-4.3.2/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ --with-local-prefix=$PREFIX/$TARGET

    make

    make install

    cd ../..

    rm -rf build



    到此,工具链就算装好了,可以写个hello world程序来试验一下了。



然后把我前面的艰辛历程贴出来,如果大家编译的时候发生什么问题,可以在里面找一下有没有我碰到过的。格式嘛,我就不排版了,大家凑活看吧。



   1. 安装linux 的头文件,可以在编译glibc之前再做



    * 个人认为这一步得到的头文件应该只和arm有关,和arm什么板子,什么型号没多大关系

    * 解压缩,打补丁



cd ~/tars/SourceDir

tar -zxf ../linux-2.4.5.tar.gz

cd linux

zcat ../../patch-2.4.5-rmk7.gz | patch -p1



 打补丁不知道为什么出错,先不打了。原来是patch-2.6.26.5.bz2是给linux-2.6.26打补丁的,不是给2.6.26.5打补丁的





    * 修改 Makefile 建议先删除 .config 文件, 否这以后会遇到麻烦。没用

    * 将Makefile中ARCH := ......改为:ARCH=arm #。似乎没用

    * 执行一下 make clean。一开始不需要



    * 我的做法:make ARCH=arm menuconfig

    * 选择load一个arm板子的config文件,我load的ARCH/arm/configs/assabet_defconfig,然后保存为.config。退出

    * make ARCH=arm dep

    * 加上ARCH=arm是因为不加的话会有好多提问,像是否支持多cpu等,后面的dep不知道什么意思,待查。

    * 产生了include/linux/autoconf.h,但是没有version.h。不知道是不是现在的版本不需要。

    * 网上查的make dep的意思,不过还是不太明白

    * dependence 依赖。

      make dep的意思就是说:如果你使用程序A(比如支持特殊设备),而A需用到B(比如B是A的一 个模块/子程序)。

      而你在做make config的时候将一个设备的驱动 由内核支持改为module,或取消支持,这将可能影响到B的一个参数 

      的设置,需重新编译B,重新编译或连接A....如果程序数量非常多, 你是很难手工完全做好此工作的。

      所以,你要make dep。如果你make menu或make config或make xconfig后,直接reboot,会更快。 

      只是你的内核根本没有任何改变。^=^ 

      make xconfig;

      make dep;

      make clean;

      make bzImage;

      make modules; 

      make modules_install 

    * 又作了一次,发现make dep现在不起作用,要用make ARCH=arm来建立头文件。



    * 要用make ARCH=arm CROSS_COMPILE=/mnt/home/arm/armtools/bin/arm-linux-来编译,必须先编译好bootstrap gcc后才能这样用



    * 拷贝头文件,感觉不需要拷贝,编译glibc的时候加上路径就好了。



cp -dR include/linux ~/armtools/arm-linux/include

cp -dR include/asm-arm ~/armtools/arm-linux/include/asm



   1. 编译安装binutils 



          *



            解压缩



            cd ~/tars/SourceDir

            tar -zxf ../binutils-2.11.gz



          *



            编译



            cd ~/tars/BuildDir

            mkdir binutils

            cd binutils

            ../../SourceDir/binutils-2.11/configure --target=arm-linux --prefix=~/armtools

            make all install



          * 这一步没什么问题,很顺利

   2.



      编译安装gcc 的c 编译器



       

          *



            解压缩



            cd ~/tars/SourceDir

            tar -zxf ../gcc-2.95.3.tar.gz



          *



            修改gcc 的t-linux 文件在t-linux文件中的TARGET_LIBGCC2_CFLAGS上加上__gthr_posix_h inhibit_libc



            cd gcc-2.95.3/ gcc/config/arm

            mv t-linux t-linux-orig

            sed 's/TARGET_LIBGCC2_CFLAGS =/TARGET_LIBGCC2_CFLAGS = -D__gthr_posix_h -Dinhibit_libc/' < t-linux-orig> t-linux-core

            cp ./t-linux-core ./t-linux



          *



            编译



            cd ~/tars/BuildDir

            mkdir gcc-core

            cd gcc-core

            ../../SourceDir/gcc-2.95.3/configure \

                                    --target=arm-linux \

                                    --prefix=~/armtools \

                                    --enable-languages=c \

                                    --with-local-prefix=~/armtools/arm-linux \

                                    --without-headers \

                                    --with-newlib \

                                    --disable-shared

            make all install



          * ./configure 时需要gmp和mpfr库支持,下载,安装,顺利,已做成pet包。换了一台机重新编译的时候,发现编译mpfr的时候会出错,找不到库,还是要加上下面那个路径。

          * ./configure 通过

          * make 出错,查看arm-linux/libgcc/config.log,说找不到libmpfr.so.1,估计是做的pet包没有将ld搜索路径加上,先加上环境变量试下,回头再修改pet包。export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

          * 加上后上个问题没有了,又有新问题。

          * config.log says:

          * configure:2747: checking for /mnt/hdc1/build/gcc-core/./gcc/xgcc -B/mnt/hdc1/build/gcc-core/./gcc/ -B/mnt/hdc1/armtools/arm-linux/bin/ -B/mnt/hdc1/armtools/arm-linux/lib/ -isystem /mnt/hdc1/armtools/arm-linux/include -isystem /mnt/hdc1/armtools/arm-linux/sys-include option to accept ANSI C

            configure:2817: /mnt/hdc1/build/gcc-core/./gcc/xgcc -B/mnt/hdc1/build/gcc-core/./gcc/ -B/mnt/hdc1/armtools/arm-linux/bin/ -B/mnt/hdc1/armtools/arm-linux/lib/ -isystem /mnt/hdc1/armtools/arm-linux/include -isystem /mnt/hdc1/armtools/arm-linux/sys-include  -c -O2 -g -g -O2    conftest.c>&5

            conftest.c:10:19: error: stdio.h: No such file or directory

            conftest.c:11:23: error: sys/types.h: No such file or directory

            conftest.c:12:22: error: sys/stat.h: No such file or directory

            conftest.c:15: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token

            conftest.c:44: error: expected declaration specifiers or '...' before 'FILE'

            configure:2823: $? = 1

          * try to add --disable-libiberty and make it

          * 上面的没用,改--disable-shared为--disable-threads,似乎这个错误过去了

          * 发现修改t-linux里的-D__gthr_posix_h这个现在已经没用了。-Dinhibit_libc这个参数似乎可以用--with-newlib代替。

          * 然后又出找不到crti.o的错误。重新加上--disable-shared,搞定

          * 然后又出问题,c编译器不能建立可执行文件。找不到crt1.o。查看发现gcc编译完后进行了编译测试,但这时候还没有这些启动文件,据说这些是编译glibc产生的。

          * configure时加上--disable-libmudflap,不加似乎也行,不要理会错误,直接make install就可以把gcc装上了。似乎有问题,make glibc的时候找不到头文件。

          * 加上--disable-libssp --disable-libgomp终于编译通过了,make install没有问题。

          * 重新make一次,不知道怎么又出错了,奇怪。而且make clean有的时候只显示几行,而有的时候显示一大堆,不知道为什么。

          * 改成make all-gcc和make install-gcc通过,不知道行不行。

   3. 编译glibc

         1. 因为现在glibc包不支持arm,所以要加上port包,解压port包到glibc原目录,改名为ports。

         2.



            CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib ../../SourceDir/glibc-2.2.3/configure --host=arm-linux \

                            --prefix=~/armtools/arm-linux --enable-add-ons --with-headers=~armtools/arm-linux/include



         3. 报错configure: error: forced unwind support is required

         4. 回到gcc,try make all-target-libgcc  make install-target-libgcc 通过,但上述问题还在。第二次编译产生cannot compute sizeof(long double) 的错误。这个错误又好像不是这个引起。结果是下面两句写错了。还是不对,加上--build=i686-pc-linux-gnu后通过

         5. 加上两句echo "libc_cv_forced_unwind=yes"> config.cache

            echo "libc_cv_c_cleanup=yes">> config.cache,然后configure加上 --cache-file=config.cache,通过。这两句可以直接把双引号里的内容写到configure后面做参数,而不用--cache- file参数。

         6. make又出问题,找不到../include/limits.h,打补丁http://sources.redhat.com/bugzilla/show_bug.cgi?id=5442后通过。



glibc/libc/configure.in

if test -n "$sysheaders"; then

   ccheaders=~$CC -print-file-name=include~

-  SYSINCLUDES="-nostdinc -isystem $ccheaders \

+  SYSINCLUDES="-nostdinc -isystem $ccheaders -isystem $ccheaders-fixed \



         1. 再出问题,找不到errno.h,copy linux源目录下include/asm-generic到armtools/arm-linux/include下,通过

         2. /usr/local/arm-linux/include/asm/memory.h:191: error: expected '=', ',', ';', 'asm' or '__attribute' before 'unsigned'

            /usr/local/arm-linux/include/asm/memory.h:196: error: expected '=', ',', ';', 'asm' or '__attribute' before 'void'

         3. 找不到解决方法,尝试修改autoconf.h里的#define CONFIG_ENABLE_WARN_DEPRECATED 1为0,无效

         4. 找了好久,分析源码,终于找到问题所在,但在网上查不到解决办法,只能自己改了,应该不会有其它问题。这个问题的原因是ioperm.c(port里arm 中带的)包含了linux头文件asm/page.h,page.h又包含了linux/memory.h,memory.h包含了linux /compiler.h,这里面有个条件编译,如果定义了__KERNEL__就会包含compiler_gcc4.h等等,反正会定义一个 __deprecated属性,而如果没有定义__KERNEL__就不会定义这个属性,但是memory.h里两次用到这个属性,结果就出问题。我的改法是把memory.h里的 __deprecated改成__attribute__((deprecated))。第二次编译又没发现这个问题,奇怪。可能是升级了linux版本的原因。

         5. 然后不出所料,还是有问题,<stdin>: Assembler messages:

            <stdin>:2: Error: bad instruction ~docargs_6'

            <stdin>:2: Error: bad instruction ~undocargs_6',这个网上有解决办法。

         6.



            改ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h里增加蓝色的两行

            # define DOCARGS_5 DOCARGS_4 

            # define UNDOCARGS_5 UNDOCARGS_4 



            # define DOCARGS_6 DOCARGS_5 

            # define UNDOCARGS_6 UNDOCARGS_5 



            # ifdef IS_IN_libpthread 

            #  define CENABLE bl PLTJMP(__pthread_enable_asynccancel) 

            #  define CDISABLE bl PLTJMP(__pthread_disable_asynccancel) 



         7. lowlevelloch.c:34出问题



            在ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h里加一行

             #include <sysdep.h>

             #include <kernel-features.h>

            +#include <tls.h>



         8. 终于make通过了,make install

         9. 通过,开始编译gcc

        10.



            ../../SourceDir/gcc-2.95.3/configure --target=arm-linux --prefix=~/armtools \

                                    --enable-languages=c,c++ --with-local-prefix=~armtools/arm-linux



        11. make

        12. make install

        13. 成功

        14. 编译一个例子,然后准备开始第二次编译工具链

        15. 看到有新的linux,换用新的linux,结果好多问题,include/asm下的东西都移走了,移到arch/arm/include/asm下了,编译glibc又出好多新问题

        16. 第二次编译glibc产生cannot compute sizeof(long double) 的错误。这个是configure自动识别build类型错误,并且认为不是交叉编译造成的,加上--build=i686-pc-linux-gnu后通过configure,但make产生redefinition of '__copysign' 的错误,改成--build=i386-linux-gnu后通过

        17. 又出config-name.h找不到的问题,这个文件应该是configure产生的。

        18. 看样子是和我用虚拟机有关,编译工具链个人感觉极考人品,顺不顺利看人品了。

        19. 上面发现的问题看来是和configure检查系统环境出现偏差有关

        20. 改成CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib ../glibc-2.7/configure --host=arm-linux --prefix=/mnt/hdc1/armtools1 --enable-add-ons --with-headers=/mnt/hdc1/build/linux-2.6.27/include:/mnt/hdc1/build/linux-2.6.27/arch/arm/include cross_compiling=yes build_alias=i386-linux-gnu后配置通过,make出现问题。还是因为linux改了目录结构引起的,拷贝需要的文件后ok

        21. 在编译gcc的时候不小心输错目录,在原文件目录下进行了编译,结果出错。一定不能在源文件目录下编译。

        22. 第三次编译glibc出ld找不到-lgcc的问题,是没有make all-target-libgcc和make install-target-libgcc

        23. 找不到-lgcc_eh,原因是没打补丁,又要退回去重做。

本贴被 dack 编辑过,最后修改时间:2008-10-17,20:18:52.

willowdon 发表于 2008-12-26 23:25:10

同意7楼的观点。搭建编译环境,用交叉编译工具(crosstools)比较简练。如果自己一步一步搭建,步骤太多且容易出错。这种方法对于ARM和一些成熟应用的处理器用还可以,如果对于一些用的人少的器件(如:powerpc  mips TIDSP... 等等)会累把人累坏的,当然学习学习也是好的,仅个人观点。

METAL_MAX 发表于 2008-12-3 21:15:33

学习的过程就是排错的过程,一下子就弄好了感觉心是虚的。

banyan_city 发表于 2008-12-3 15:28:55

mark 

hassim 发表于 2008-11-16 21:35:41

终于找到组织了,呵,,

我近来也在搞这个事情,我先也是想自己全编译一下,结果失败.N多错误.E文不好,不想去搞了.后来用Crosstool成功编译了.

呵呵,,Linux 起步有点难,是考验一个人的耐心.

huanxian 发表于 2008-11-14 00:34:39

mark 

wcm_e 发表于 2008-11-13 22:38:42

mark

dack 发表于 2008-11-13 16:25:05

windows下也有这种问题,少动态库啦,动态库版本不对啦,内存泄漏啦,使用非标准api,出现问题的也很多。

只是windows大家比较熟而已。

hexenzhou 发表于 2008-11-13 16:18:38

呵呵,编译出错还好办,最麻烦的是编译通过可是不能运行,gcc的版本问题不是三言两语可以说清的,Windows下的编程就没有这个问题了。

dack 发表于 2008-11-13 16:02:08

看得出你是个高手,你说得很对。但是对我这样对arm甚至linux一无所知的人来说,通过这次编译,还是学到了很多东西。确实,编译的时候出现的问题稀奇古怪,甚至换一台电脑都可能出不同的问题,但这其中我学到了碰到问题如何去解决,这也是一个积累经验的过程。你在18楼举的那个买单反的例子我非常之同意,但是人就是这么成长起来的,如果当时那个人听从了建议,恐怕现在还在玩卡片机呢,很多事情不自己去尝试,是学不到东西的。

例如很多人都说新版本编译redboot,uboot等会出错,某某版本gcc编译某某版本redboot正常,可是我就是不信邪,偏要用最新版gcc编译最新版redboot,中间也确实出现编译错误,但经过分析,我发现redboot源码中使用了非标准用法,从rom call ram子程序超过了arm 32M的限制,而这个非标准的用法在新版的gcc上失效了,结果就出现错误,我经过搜索尝试,加了一个属性在函数上,解决了这个问题,我想以后无论gcc怎么升级,这段代码都不会出错了。如果我一开始就听从大家的建议,使用某某版本的编译器,我就不能学到如何对付这样的长call。

好多话想说,可又不知道怎么说,唉,还是不说了。

本贴被 dack 编辑过,最后修改时间:2008-11-13,16:13:33.

watercat 发表于 2008-11-13 09:38:47

另外补充说明一点:



我个人反对的,只是【花时间在自己琢磨交叉编译工具链上】,而不是【建立一个基于ARM的LFS Linux系统】,其实从时间和精力的消耗上看,两者的开销几乎等同,但前者百无一用(每一个版本的GCC、Glibc、binutils和Linux Headers都有截然不同的问题,各自的不同搭配又会引发更多千奇百怪的麻烦,每一个麻烦都足以让你的所有工作不得不一切从头来过,而且,更重要的是,你没办法保证你自以为正确的交叉编译链最终的输出程序拿到目标系统上不会出非法指令或段错,而且你也不可能一成不变的用一套工具链打天下,并且无论如何,这些抓虫的过程在下一次构建工具链的时候又会全然无用,最后你会发现这些时间其实都是白白浪费掉的);而后者却是切实掌握嵌入式研发技术的基础,两者不可一概而论



最后不得不说,任何时候,都别指望【交叉编译器】能够百分之百的按照你的臆测去干活,那个东西最大的(甚至可能是唯一的)功能,就只是编译bootloader和内核这类绝对不需要也不可能用到libc的东西,最多再加上个静态联编的busybox……对于其它所有与运行时库有关的上层应用程序,本机编译工具都是真正最好用的……



本贴被 watercat 编辑过,最后修改时间:2008-11-13,09:42:58.

watercat 发表于 2008-11-13 09:31:19

我只是作为过来人谈一下我自己的切身体验,楼主愿不愿意认同与我无关



不过,我可以肯定,楼主这样一意孤行下去,最终只会发现自己把太多的时间用在了看似很漂亮但其实丝毫无用的内容上,然后迟早有一天也会像我一样奉劝别人不要在这些无聊的小事上耽误时间……



这就好像买单反,几乎所有买单反的人在买前,都会有已经买过的朋友同事不停的建议你说【如果没有充足的时间金钱,就不要玩单反,那是个花钱无底洞】、【如果一定要买,切记一次购买到位,不要从低端机器开始买】,可大家依然故我,一意孤行,然后等到一两年后,突然发现原来当初朋友们的建议才是真正的至理名言,于是后悔莫及,再然后就到其他朋友打算买单反的时候,把当初别人对自己说过的话原封不动的再说一遍……



这世上,不撞南墙不回头的人实在太多了……

dack 发表于 2008-11-13 08:13:51

楼上说的不敢苟同,学习是个渐进的过程,不可能只吃最后一张饼就会饱。虽说想吃馒头不用从种麦子开始,但是从种麦子开始也不能说就没用,只要能学到东西,任何过程都是有用的,哪怕是失败的过程。你说呢。我注重的是学习过程中的乐趣,而不是结果。当然如果是时间紧迫,项目压在身上,我也会选择一些捷径,但那样对学习没什么好处。

watercat 发表于 2008-11-13 07:37:02

emerge 是 portage 软件管理程序的核心程序,而 portage 是比 rpm 和 deb 之类更安全简便有效的程序,目前集成了 portage 的 Linux 发行版中,最著名的就是 Gentoo Linux



另外,对于 Gentoo Linux 来说,其实发行团队已经做好了完整的基于多种处理器平台(包括ARM平台)的操作系统环境,所有这些环境都包括了从 bootloader 到字符界面开发环境所需的全部软件,并且也很容易安装X于其上



因此其实类似楼主所做的事情,在我看来就是纯粹的重复劳动和无用功,因为无论如何,与其花大把的时间搞明白“为什么构建GCC工具链会出错”,不如把这些时间拿去休闲娱乐——就算是读Linux内核源码,也会比玩工具链有意义……

chhaich 发表于 2008-11-13 01:11:42

标记了,正想学LINUX

mtheory 发表于 2008-10-20 23:06:14

很详细,不错!!!!

thriller 发表于 2008-10-20 23:00:36

标记一下,肯定有用

155107149 发表于 2008-10-20 22:40:01

楼主辛苦了,另外水猫说的那个# emerge crossdev 

是什么?

dack 发表于 2008-10-18 19:42:10

puppy linux 3.01,4.0版的不太稳定,新出的4.1版没试过。个人感觉常用的功能都有了。512包括了256的存储空间,整个系统应该不会超过256M

ghosthd 发表于 2008-10-18 14:10:34

to 9

512就能搞定?基于那个linux?

dack 发表于 2008-10-18 13:31:02

呵呵,酷了,等阵我会再写一篇“装在u盘上的随身开发环境”包括linux系统,IDE,编译器(i386系统),编译器(arm系统),大小不超过526M,装在一个512M以上可启动u盘上就可以移动开发了。

new.ease 发表于 2008-10-18 12:10:25

谢谢楼主



呵呵水猫发话了.我也试试,这省心方法.谢谢

watercat 发表于 2008-10-18 11:40:14

个人认为



1、建立交叉编译环境,请在任何内建 emerge 软件管理功能的 Linux 发行版(最典型的是 Gentoo Linux,不过甚至 Cygwin 也能做到)中,执行如下操作

 # emerge crossdev

 # crossdev -S --binutils 2.18.50.0.8 --gcc 4.3.1-r1 -s4 --ex-gdb --target arm-unknown-linux-gnu

然后就会一切自动搞定,不需要做任何多余的事情



2、建立 arm 的本机编译环境,请参照 LFS,非常容易

dack 发表于 2008-10-18 10:53:53

谢谢lofeng,但我还是不太明白,如果只是删除,那参数后面的的路径是干什么用的。



我是个新手,这里面有没有问题我说不准,现在我作出来的工具链armtools下有个bin目录,里面是以arm-linux-开头的工具(ar,gcc等),而armtools/arm-linux下也有个bin目录,里面是没有前缀的工具(ar,gcc等),但又不完全一样,不知道有什么区别。

thriller 发表于 2008-10-17 23:12:02

这个要顶!

lofeng 发表于 2008-10-17 22:49:44

--with-local-prefix=/tools

这个参数的目的是把 /usr/local/include 目录从 gcc 的 include 搜索路径里删除。这并不是绝对必要,但我们想尽量减小宿主系统的影响,所以才这样做。

这个是LFS中编译GCC时对参数的一个简单说明

hexenzhou 发表于 2008-10-17 19:28:15

支持,一般都是直接用人家编译好的arm-linux-gcc工具链,网上常见的arm gcc 工具链有2.95.3和3.3.2和3.4.1的版本。gcc工具链的版本众多,编译开源软件包的时候得经常有gcc版本不同造成编译通不过的情况,非常的令人头疼。

rkfch 发表于 2008-10-17 17:18:49

虽然不懂,但是看楼主这么辛苦还是不得不支持一下!

YourARM 发表于 2008-10-17 17:07:35

这个要支持一下。

Doraemon 发表于 2011-10-21 16:02:59

mark

okwhz 发表于 2013-6-8 17:12:55

{:victory:}{:victory:}{:victory:}
页: [1]
查看完整版本: 原创:编译arm-linux工具链【恢复】