zz : http://blog.csdn.net/turui/article/details/6596093
zz : http://blog.csdn.net/turui/article/details/6620951
交叉工具链制作至尊宝典(一)
一些必须知道的基础知识
- Debian 操作系统 以及 aptitude 命令
- autoconf and automake
- 什么是交叉编译,configure 的几个参数 build host target
build:
编译代码的机器,的CPU指令集
host:
编译生成的东西,的CPU指令集(目标板上的CPU的指令集)
target:
编译生成的东西,他编译生成的的东西,的指令集(所以此选项一般不用,大多只有在做交叉工具链时使用)0、以Expert mode 安装Debian
不要升级,确保环境是一个纯净的环境
1、声明环境变量
- export IS_TARGET=arm-linux
- export DIR_SRC=/root/cross_toolchains/src
- export PREFIX=/opt/cross_toolchains/arm
- export CONFIGURE_BASE="../configure --prefix=$PREFIX --with-sysroot=$PREFIX"
2、下载制作交叉工具链所必须的的代码
- binutils
- ftp://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.gz
- gcc
- ftp://ftp.gnu.org/gnu/gmp/gmp-5.0.2.tar.gz
- ftp://ftp.gnu.org/gnu/mpfr/mpfr-3.0.1.tar.gz
- http://www.multiprecision.org/mpc/download/mpc-0.9.tar.gz
- ftp://ftp.gnu.org/gnu/gcc/gcc-4.6.1/gcc-4.6.1.tar.gz
- glibc
- ftp://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz
- ftp://ftp.gnu.org/gnu/glibc/glibc-ports-2.13.tar.gz
- linux kernel
- http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.2.tar.bz2
3、安装(卸载)必要的的软件包
- aptitude install build-essential automake bison flex texinfo gawk g\+\+
- aptitude remove mawk
4、解压、归档软件包
- cd $DIR_SRC
- tar -xf binutils-2.21.tar.gz
- tar -xf gmp-5.0.2.tar.gz
- tar -xf mpc-0.9.tar.gz
- tar -xf mpfr-3.0.1.tar.gz
- tar -xf gcc-4.6.1.tar.bz2
- tar -xf glibc-2.14.tar.gz
- tar -xf glibc-ports-2.13.tar.gz
- tar -xf linux-2.6.39.2.tar.bz2
- mv gmp-5.0.2 gcc-4.6.1/gmp
- mv mpc-0.9 gcc-4.6.1/mpc
- mv mpfr-3.0.1 gcc-4.6.1/mpfr
- mv glibc-ports-2.13 glibc-2.14/ports
5、编译 BINUTILS
- cd $DIR_SRC
- cd binutils-2.21
- mkdir build
- cd build
- $CONFIGURE_BASE --target=$IS_TARGET --disable-nls --enable-shared --disable-multilib
- make configure-host
- make
- make install
- export PATH=$PATH:$PREFIX/bin
问题:
编译binutils一般不会遇到什么问题,但是,如果前面步骤3中安装的软件不全会出现问题6、建立用于编译C库的GCC
- cd $DIR_SRC
- cd gcc-4.6.1
- mkdir build
- cd build
- $CONFIGURE_BASE \
- --target=$IS_TARGET \
- --disable-nls \
- --disable-shared \
- --without-headers \
- --with-newlib \
- --enable-languages=c \
- --disable-threads \
- --disable-multilib \
- --disable-decimal-float \
- --disable-libgomp \
- --disable-libmudflap \
- --disable-libssp
- make all-gcc all-target-libgcc
- make install-gcc install-target-libgcc
- 值得注意的几个configure选项
- --target
- --disable-shared
- --without-headers
- --with-newlib
- --enable-language-c
- --disable-thread
- cd $PREFIX/lib/gcc/$IS_TARGET/4.6.1
- ln -s libgcc.a libgcc_eh.a
- 有建议修改 gcc/config/t-linux 这个文件
- 增加 -D__gthr_posix_h -Dinhibit_libc 两个宏,但我这里没这样做,是因为:
- 在configure后,编译使用的命令并不是 make 或者是 make all 而是 make all-gcc 和 make all-target-libgcc,所以很多问题不会出现
- -with-newlib,这个选项不会迫使我们必须使用newlib
- libgcc.mvars: No such file or directory
- 不能在 GCC 的源代码目录进行configure,必须在另外的目录进行configure make 等工作
- 所以这里在代码所在目录下 mkdir build 并 cd build 再进行 ../configure 等工作
- configure: error: C compiler cannot create executables
- 如果使用 make 或 make all 会出现这样的问题,因为我们还未编译出目标指令集的 C 库
- 所以只能先使用 make all-gcc make all-target-libgcc
- ../../../../arm-linux/bin/ld: cannot find -lgcc
- ../../../../arm-linux/bin/ld: cannot find -lgcc_eh
- 很多资料都只写了 make all-gcc 而没有写 make all-target-libgcc 这样只建立了gcc,没有建立libgcc.a会出现以上第一个错误
- 如果没手工建立链接文件 libgcc_eh.a 则会出现第二个错误
7、配置内核生成必要的头文件
- cd $DIR_SRC
- cd linux-2.6.39.2
- make ARCH=arm CROSS_COMPILE=$IS_TARGET- menuconfig
- make ARCH=arm CROSS_COMPILE=$IS_TARGET-
- mkdir -p $PREFIX/include
- cd $PREFIX/include
- ln -s $DIR_SRC/linux-2.6.39.2/arch/arm/include/asm asm
- ln -s $DIR_SRC/linux-2.6.39.2/include/linux linux
- ln -s $DIR_SRC/linux-2.6.39.2/include/asm-generic asm-generic
- 这里并没有将内核的头文件复制到交叉工具链的安装目录
- 编译C库的时候,需要对应的CPU指令集的汇编代码所以做了链接处理
- 编译内核在执行 make ARCH=arm CROSS_COMPILE=$IS_TARGET- 时如果出错,是没有关系的,这里只要生成了对应的 version.h autoconf.h就可以了
8、编译C库
- cd $DIR_SRC
- cd glibc-2.9
- mkdir build
- cd build
- vi ../configure
- vi ../ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S
- vi ../sysdeps/unix/syscall-template.S
- vi ../nptl/allocatestack.c
- vi ../elf/dl-tls.c
- vi ../sysdeps/ieee754/dbl-64/s_fma.c
- vi ../sysdeps/ieee754/dbl-64/s_fmaf.c
- 具体的修改,我写在下面(觉得还是要说清楚为什么修改,所以就没用sed命令或是做一些patch文件了,请向下看)
- CC=$IS_TARGET-gcc \
- $CONFIGURE_BASE \
- --host=$IS_TARGET \
- -enable-add-ons \
- --with-binutils=$PREFIX/bin \
- --with-headers=$PREFIX/include \
- libc_cv_forced_unwind=yes \
- libc_cv_c_cleanup=yes
- 值得注意的几个configure选项
- --host
- --with-headers
- lib_cv_forced_unwind
- lib_cv_c_cleanup
- make
- make install
- 这里编译的时候并有选择TARGET为EABI,所以在制作交叉工具链时会有很多问题需要修改
- *** These critical programs are missing or too old: as ld
- *** Check the INSTALL file for required versions.
- vi ../configure
- 查找 "$AS --version" 将 2.1[3-9] 修改为 2.[1-2][0-9]
- 查询 "$LD --version" 将 2.1[3-9] 修改为 2.[1-2][0-9]
- Error: previous CFI entry not closed (missing .cfi_endproc)
- vi ../ports/sysdeps/unix/sysv/linux/arm/sigrestorer.S
- ENTRY(__default_sa_restorer) 下增加
- END(__default_sa_restorer)
- ENTRY(__default_rt_sa_restorer) 下增加
- END(__default_rt_sa_restorer)
- syscall-template.S:82: Error: CFI instruction used without previous .cfi_startproc
- vi ../sysdeps/unix/syscall-template.S
- 这个问题的修改我也不是十分确定,我是这样来思考的
- 看到 syscall-template.S 中 有 #include <sysdep.h>
- 去查看 ports/sysdeps/unix/sysv/linux/arm/sysdep.h
- 看到如下代码
- #ifdef __ASSEMBLER__
- #undef PSEUDO
- #define PSEUDO(name, syscall_name, args) \
- .text; \
- ENTRY (name); \
- DO_CALL (syscall_name, args); \
- cmn r0, $4096;
- 猜测是__ASSEMBLER__宏未打开,以至于未能找到PSEUD0函数的声明,则将
- #define PSEUDO(name, syscall_name, args) \
- .text; \
- ENTRY (name); \
- DO_CALL (syscall_name, args); \
- cmn r0, $4096;
- 这段代码 添加至 ../sysdeps/unix/syscall-template.S 中
- LS_DTV_UNALLOCATED undeclared (first use in this function)
- vi ../nptl/allocatestack.c
- vi ../elf/dl-tls.c
- 这个错误会出现在编译以上两个文件的时候,这个宏的定义我grep了整个glibc的所有代码,没找到ARM相关的声明及定义,按照其他指令集的定义猜测着修改如下
- 在以上两个C文件中增加相应的定义
- #define TLS_DTV_UNALLOCATED ((void *) -1l)
- E_TOWARDZERO undeclared (first use in this function)
- E_INEXACT undeclared (first use in this function)
- 以上两个错误会出现在以下两个文件的的编译过程中
- vi ../sysdeps/ieee754/dbl-64/s_fma.c
- vi ../sysdeps/ieee754/dbl-64/s_fmaf.c
- 参考 ports/sysdeps/arm/eabi/bits/fenv.h中的定义
- 在两个文件中添加
- #define FE_TOWARDZERO 0xc00000
- #define FE_INEXACT 16
- mawk: scripts/gen-sorted.awk: line 19: regular expression compile failed
- 所以要 aptitude install gawk 所以也顺带着 aptitude remove mawk
- configure: error: forced unwind support is required
- configure 中增加配置参数 libc_cv_forced_unwind=yes
- error: the compiler must support C cleanup handlin
- configure 中增加配置参数libc_cv_c_cleanup=yes
- --enable-add-ons 为 C 库 增加 thread 支持,目前默认使用的是 nptl 所以这里没有去下载 glibc-threads 相关的代码
- --with-headers 指定内核头文件所在的目录
9、编译完整的 gcc 工具链
- mkdir -p $PREFIX/usr
- cd $PREFIX/usr
- ln -s ../include include
- cd $PREFIX
- mkdir -p opt/cross_toolchains
- cd opt/cross_toolchains/
- ln -s ../../../arm arm
- cd $DIR_SRC
- cd gcc-4.6.1
- cd build
- make clean
- make distclean
- rm * -rf
- $CONFIGURE_BASE \
- --target=arm-linux \
- --enable-languages=c,c++ \
- --enable-shared \
- --disable-nls \
- --enable-c99 \
- --enable-long-long \
- --disable-multilib \
- --enable-__cxa_atexit
- 几个值得注意的configure 选项
- --target
- --enable-shared
- make
- make install
- The directory that should contain system headers does not exist:
- 这个问题我没具体的去跟踪了,从表面上看出来是一些路径上的问题,并且经过验证,这个问题是在configure时使用了--with-sysroot选项时产生的
- 为了尝试不通过建立链接的方式去解决这个问题
- 在指明了 --includedir --libdir --sysconfdir 等等一系列参数后编译,依然会出现此问题
- 所以不再跟踪,暂且是当做GCC编译环境上的一个 BUG好了
- /opt/cross_toolchains/arm/arm-linux/bin/ld: cannot find /opt/cross_toolchains/arm/lib/libc.so.6 inside /opt/cross_toolchains/arm
- 这个问题更是有点神经病了,所以这里也不跟踪了,也是由于使用了 --with-sysroot选项产生的问题,建立了第二个链接文件
- 目的是让 /opt/cross_toolchains/arm 这个被当做是根目录的目录里面能有一个跟 --prefix 指定的 /opt/cross_toolchains/arm 一样的目录结构(说起来真别扭)
https://www.ibm.com/developerworks/cn/linux/l-embcmpl/
http://cross-lfs.org/view/clfs-embedded/arm/cross-tools/introduction.html
http://www.linuxsir.org/bbs/showthread.php?t=267672(这个文章虽然有点老,也有点神,把一些能看懂的说的让人看不懂,那个图更是让人觉得,汗,但原理还是说的很清楚的,这里强调的--with-sysroot的3次出现的问题,还是值得仔细想想的,这也是我为什么将 --with-sysroot 选项 做到$CONFIGURE_BASE 这个环境变量中的原因)
本文在前章的基础上,继续深入研究,如何能正确的编译出交叉工具链
关于 --with-sysroot 这个参数,真是一个让人觉得可恨的参数,这个参数会引起一系列的问题,前章中,不得已的在 /opt/cross_toolchains/arm 中建立了两个连接文件
- mkdir usr
- cd usr
- ln -s ../include include
- mkdir -p opt/cross_toolchains
- cd opt/cross_toolchains
- ln -s ../../../arm arm
还记得这两段脚本吗?让我觉得极其不爽,不得已才用这种办法去解决遇到的问题,而这两个问题都是因为使用了 --with-sysroot 这个 configure 参数而导致的,关键是我不知道如何解决!!下面的脚本中我们将不再使用 --with-sysroot 这个configure 参数
下面的脚本将编译 arm eabi 的交叉工具链
值得注意的地方是,在编译完 glibc 后的一些处理
- cd $PREFIX/arm-none-linux-gnueabi
- rm lib include -rf
- ln -s ../lib lib
- ln -s ../include include
与这个bin 同一层的 lib 和 include 目录并不存在,所以会引起编译gcc 中 pthread.h 头文件找不到,链接需要的 c 库 开工代码 ctri.o ctxxx几个 o文件找不到等问题
通过这样处理,可以解决这个问题,并且避免了使用 --with-sysroot 这个恶心的参数(autoconf 做的不够好啊,要么就是 gcc 的 autoconf脚本没写好)
比如这种问题:
- arm-none-linux-gnueabi/bin/ld: cannot find crti.o: No such file or directory
自动化脚本如下,使用方法:将脚本保存为 makecross.sh,并且设置权限 chmod a+x makecross.sh,然后执行脚本./makecross.sh,可以看到帮助
后续我会补充上 targe的选择以及检测方法,cpu指令集的选择,uclibc 编译,等相关内容
- #!/bin/sh
- # the newer four-part form:
- # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
- unset CPU
- unset MFR
- unset KERNEL
- unset OS
- unset VER_GCC
- unset DIR_OPT
- unset DIR_SRC
- unset PREFIX
- unset TARGET
- export CPU=arm
- export MFR=none
- export KERNEL=linux
- #export OS=uclibceabi
- export OS=gnueabi
- export VER_GCC=4.6.1
- export DIR_OPT=/opt/cross_toolchains
- export DIR_SRC=/root/cross_toolchains/src
- export PREFIX=$DIR_OPT/$CPU/$VER_GCC
- export CONFIGURE_BASE="../configure --prefix=$PREFIX"
- export TARGET=$CPU-$MFR-$KERNEL-$OS
- export PATH=$PATH:$PREFIX/bin
- function do_unzip_single()
- {
- cd $DIR_SRC
- if [ "$1" = "binutils" ];then
- tar -xf binutils-2.21.tar.gz
- elif [ "$1" = "gcc" ];then
- tar -xf gcc-4.6.1.tar.gz
- tar -xf mpfr-3.0.1.tar.gz
- tar -xf mpc-0.9.tar.gz
- tar -xf gmp-5.0.2.tar.gz
- mv gmp-5.0.2 gcc-4.6.1/gmp
- mv mpc-0.9 gcc-4.6.1/mpc
- mv mpfr-3.0.1 gcc-4.6.1/mpfr
- elif [ "$1" = "glibc" ];then
- tar -xf glibc-2.13.tar.gz
- tar -xf glibc-ports-2.13.tar.gz
- mv glibc-ports-2.13 glibc-2.13/ports
- elif [ "$1" = "kernel" ];then
- tar -xf linux-2.6.39.2.tar.bz2
- fi
- }
- function do_download_single_do()
- {
- cd $DIR_SRC
- if [ ! -e $DIR_SRC/$1 ];then
- wget $2
- fi
- }
- function do_download_single()
- {
- FILE_NAME=""
- URL=""
- if [ "$1" = "binutils" ];then
- set FILE_NAME=binutils-2.21.tar.gz
- set URL=ftp://ftp.gnu.org/gnu/binutils/binutils-2.21.tar.gz
- do_download_single_do $FILE_NAME $URL
- elif [ "$1" = "gcc" ];then
- set FILE_NAME=gcc-4.6.1.tar.gz
- set URL=ftp://ftp.gnu.org/gnu/gcc/gcc-4.6.1/gcc-4.6.1.tar.gz
- do_download_single_do $FILE_NAME $URL
- set FILE_NAME=mpfr-3.0.1.tar.gz
- set URL=ftp://ftp.gnu.org/gnu/mpfr/mpfr-3.0.1.tar.gz
- do_download_single_do $FILE_NAME $URL
- set FILE_NAME=mpc-0.9.tar.gz
- set URL=http://www.multiprecision.org/mpc/download/mpc-0.9.tar.gz
- do_download_single_do $FILE_NAME $URL
- set FILE_NAME=gmp-5.0.2.tar.gz
- set URL=ftp://ftp.gnu.org/gnu/gmp/gmp-5.0.2.tar.gz
- do_download_single_do $FILE_NAME $URL
- elif [ "$1" = "glibc" ];then
- set FILE_NAME=glibc-2.13.tar.gz
- set URL=ftp://ftp.gnu.org/gnu/glibc/glibc-2.13.tar.gz
- do_download_single_do $FILE_NAME $URL
- set FILE_NAME=glibc-ports-2.13.tar.gz
- set URL=ftp://ftp.gnu.org/gnu/glibc/glibc-ports-2.13.tar.gz
- do_download_single_do $FILE_NAME $URL
- elif [ "$1" = "kernel" ];then
- set FILE_NAME=linux-2.6.39.2.tar.bz2
- set URL=http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.2.tar.bz2
- do_download_single_do $FILE_NAME $URL
- fi
- }
- function do_remove_single()
- {
- cd $DIR_SRC
- # only remove the directory,but not the zip file.
- if [ "$1" = "binutils" ];then
- rm -rf binutils-2.21
- elif [ "$1" = "gcc" ];then
- rm -rf gcc-4.6.1
- rm -rf mpfr-3.0.1
- rm -rf mpc-0.9
- rm -rf gmp-5.0.2
- elif [ "$1" = "glibc" ];then
- rm -rf glibc-2.13
- rm -rf glibc-ports-2.13
- elif [ "$1" = "kernel" ];then
- rm -rf linux-2.6.39.2
- fi
- }
- function do_reconstruction_single()
- {
- echo "reconstruction single package $1"
- cd $DIR_SRC
- do_remove_single $1;
- do_download_single $1
- do_unzip_single $1
- }
- function do_reconstruction()
- {
- cd $DIR_SRC
- if [ "$1" = "all" ]
- then
- do_reconstruction_single binutils
- do_reconstruction_single gcc
- do_reconstruction_single glibc
- else
- do_reconstruction_single $1
- fi
- }
- function do_build_single_pre()
- {
- if [ "$1" = "binutils" ];then
- cd binutils-2.21
- elif [ "$1" = "gcc_first" ];then
- # glibc need kernel's .h file
- mkdir -p $PREFIX/include
- cd $PREFIX/include
- rm -f asm
- rm -f linux
- rm -f asm-generic
- ln -s $DIR_SRC/linux-2.6.39.2/arch/arm/include/asm asm
- ln -s $DIR_SRC/linux-2.6.39.2/include/linux linux
- ln -s $DIR_SRC/linux-2.6.39.2/include/asm-generic asm-generic
- cd $DIR_SRC
- cd gcc-4.6.1
- elif [ "$1" = "glibc" ];then
- cd glibc-2.13
- echo "/* Value used for dtv entries for which the allocation is delayed. */" >> ports/sysdeps/arm/dl-tls.h
- echo "#define TLS_DTV_UNALLOCATED ((void *) -1l)" >> ports/sysdeps/arm/dl-tls.h
- elif [ "$1" = "gcc" ];then
- cd gcc-4.6.1
- elif [ "$1" = "kernel" ];then
- cd linux-2.6.39.2
- fi
- # create build directory
- rm -rf build
- mkdir -p build
- if [ "$1" = "kernel" ];then
- rm -rf build
- fi
- }
- function do_build_single_config
- {
- # configure
- if [ "$1" = "binutils" ];then
- $CONFIGURE_BASE \
- --target=$TARGET \
- --enable-shared
- elif [ "$1" = "gcc_first" ];then
- $CONFIGURE_BASE \
- --target=$TARGET \
- --disable-shared \
- --without-headers \
- --with-newlib \
- --enable-languages=c \
- --disable-threads
- elif [ "$1" = "glibc" ];then
- CC=$PREFIX/bin/$TARGET-gcc \
- $CONFIGURE_BASE \
- --host=$TARGET \
- -enable-add-ons \
- --with-headers=$PREFIX/include \
- --with-binutils=$PREFIX/bin \
- libc_cv_forced_unwind=yes \
- libc_cv_c_cleanup=yes
- elif [ "$1" = "gcc" ];then
- $CONFIGURE_BASE \
- --target=$TARGET \
- --enable-shared \
- --enable-languages=c,c++ \
- --enable-c99 \
- --enable-long-long \
- --enable-__cxa_atexit
- elif [ "$1" = "kernel" ];then
- make menuconfig
- fi
- }
- function do_build_single_make()
- {
- # make and make install
- if [ "$1" = "gcc_first" ];then
- make -j4 all-gcc all-target-libgcc
- make -j4 install-gcc install-target-libgcc
- cd $PREFIX/lib/gcc/$TARGET/$VER_GCC
- rm libgcc_eh.a
- ln -s libgcc.a libgcc_eh.a
- elif [ "$1" = "glibc" ];then
- make -j4
- make -j4 install
- cd $PREFIX/arm-none-linux-gnueabi
- rm lib include -rf
- ln -s ../lib lib
- ln -s ../include include
- else
- make -j4
- make -j4 install
- fi
- }
- function do_build_single()
- {
- cd $DIR_SRC
- echo "build single package $1"
- if [ "$1" = "kernel" ];then
- do_build_single_pre $1
- do_build_single_config $1
- else
- do_build_single_pre $1
- cd build
- do_build_single_config $1
- do_build_single_make $1
- fi
- }
- function do_build()
- {
- if [ "$1" = "all" ]
- then
- do_build_single binutils
- do_build_single gcc_first
- do_build_single glibc
- do_build_single gcc
- else
- do_build_single $1
- fi
- }
- function do_rebuild()
- {
- rm -rf $PREFIX/*
- do_reconstruction $1
- do_build $1
- }
- function do_help()
- {
- echo "usage:"
- echo " ./makecross reconstruction binutils"
- echo " ./makecross reconstruction gcc"
- echo " ./makecross reconstruction glibc"
- echo " ./makecross reconstruction all"
- echo " ./makecross build binutils"
- echo " ./makecross build gcc_first"
- echo " ./makecross build glibc"
- echo " ./makecross build gcc"
- echo " ./makecross build all"
- echo " ./makecross rebuild all"
- }
- # main entery
- # to install necessary package
- # aptitude install build-essential automake bison flex texinfo gawk g\+\+ zip
- # aptitude remove mawk
- SOME=`aptitude show build-essential automake bison flex texinfo gawk g\+\+ zip|grep "State: not install"`
- #echo $SOME
- if [ ! "$SOME" = "" ];then
- echo "aptitude install"
- aptitude install build-essential automake bison flex texinfo gawk g\+\+ zip
- fi
- SOME=`aptitude show mawk | grep "State: installed"`
- if [ ! "$SOME" = "" ];then
- echo "aptitude remove mawk"
- aptitude remove mawk
- fi
- # about kernel
- # if there is no kernel headers,then rebuild kernel
- # include/linux/version.h and include/generated/autoconf.h
- if [ ! -e $DIR_SRC/linux-2.6.39.2/include/linux/version.h ];then
- #echo "version"
- if [ ! -e $DIR_SRC/linux-2.6.39.2/include/generated/autoconf.h ];then
- echo "reconstruction kernel"
- do_reconstruction_single $1
- fi
- fi
- echo "check and rebuild env done."
- # do command
- if [ "$1" = "reconstruction" ];then
- do_reconstruction $2
- elif [ "$1" = "build" ];then
- echo "build"
- do_build $2
- elif [ "$1" = "rebuild" ];then
- do_rebuild $2
- else
- do_help
- fi