LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: 聚焦深空

[原创]从源码构建本地编译GNU/Linux系统(gcc-4.3.1)

[复制链接]
 楼主| 发表于 2008-7-10 10:20:54 | 显示全部楼层
Post by 地球发动机;1871884
可能这仅能用于伪交叉编译也就是--build和--host相同的情况。

更正一点,NEW_OS_HOST、NEW_OS_TARGET事实上相同才是伪交叉编译。
如i686-cross-linux-gnu、i686-pc-linux-gnu。我们建立的交叉编译、伪交叉编译工具链运行于宿主,所以工具链gcc配置时--build和--host相同。
使用gcc-4.3之前版本时只是不需显式指明而已。

大多数人不会疯狂到建立交叉编译的交叉编译工具链,也就是--build、--host、--target都不同的情况。

建立交叉编译工具链时,添加--build是为gcc-4.3系列设置正确的编译系统类型,如MACHTYPE=i486-pc-linux-gnu,cpu为k8,即使使用xxx-i486的内核,gcc-4.3系列自动配置的--build仍为i686-pc-linux-gnu。
所以,建立交叉编译工具链时,需要强制指定--build。
回复 支持 反对

使用道具 举报

发表于 2008-7-12 08:20:42 | 显示全部楼层
Post by 聚焦深空;1872998
更正一点,NEW_OS_HOST、NEW_OS_TARGET事实上相同才是伪交叉编译。
如i686-cross-linux-gnu、i686-pc-linux-gnu。我们建立的交叉编译、伪交叉编译工具链运行于宿主,所以工具链gcc配置时--build和--host相同。
使用gcc-4.3之前版本时只是不需显式指明而已。

大多数人不会疯狂到建立交叉编译的交叉编译工具链,也就是--build、--host、--target都不同的情况。

建立交叉编译工具链时,添加--build是为gcc-4.3系列设置正确的编译系统类型,如MACHTYPE=i486-pc-linux-gnu,cpu为k8,即使使用xxx-i486的内核,gcc-4.3系列自动配置的--build仍为i686-pc-linux-gnu。
所以,建立交叉编译工具链时,需要强制指定--build。


根据你所做的hack(有些是我之前做的),我断定,你的系统上一定有把原本应该是just-compiled的东西检测为pre-installed的情况。

1、CC_FOR_TARGET 这个什么时候需要呢?GCC编译系统会进行检测,如果build=host,它会检测成just-compiled,也就是说,不用宿主的东西,以保证纯度。如果build不等于host,那么检测结果为pre-installed。这时GCC不得不依赖于宿主提供编译器去编译target上的东西因为编译出来的东西在宿主上(可能)无法运行。

2、由此可见,正常情况下如果CC_FOR_TARGET是just-compiled,那么就不需要在make all-target-libgcc之前先make all-gcc && make install-gcc。因为编译系统应该自动调用新编译出来的编译器进行编译。

3、回头看看关于specs的那个hack,这很明显也跟以上情况有关。原本GCC编译系统在完成gcc之后,需要调用GCC_FOR_TARGET获得一个SPECS。如上所述,如果GCC_FOR_TARGET被检测为just-compiled,那么编译系统将调用刚编译好的xgcc来获得SPECS,否则将依赖于预先安装的交叉编译器。

我刚刚完成一个x86_64 -> i686的build,在注意了确保build=host之后,configure后直接make all-target-libgcc是成功的。

关于build,host和target,我想可以总结如下:
1、build=host=target 是本机原生编译,默认的情况,LFS使用的情况。
2、build=host<>target是本机交叉编译,CLFS交叉编译工具链使用的情况。
3、build<>host=target是交叉原生编译,CLFS原生工具链就是这种情况:依赖于build上的交叉编译工具链,来编译target上的原生工具链
4、build<>host<>target是加拿大式编译,一般很少使用。
由上可见,至少情况3是必须依赖pre-installed cc的。更何况GCC必须支持情况4。所以才有需要设置CC_FOR_TARGET的情况。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-7-12 11:51:59 | 显示全部楼层
根据你所做的hack(有些是我之前做的),我断定,你的系统上一定有把原本应该是just-compiled的东西检测为pre-installed的情况。

哈,要为自己的断言负责。
交叉编译工具链,在创建过程中,其实是不需要考虑just-compiled、pre-installed的,因为宿主一清二白,所有交叉编译工具链需要的东西都是从〇建立起来的。
伪交叉编译工具链,在创建过程中,才需要考虑just-compiled、pre-installed的问题,因为工具链创建过程中可能会错误调用同名宿主程序,影响工具链纯度,所以必须注意安装步骤,要保证创建过程中总能找到合适的程序。
1、CC_FOR_TARGET 这个什么时候需要呢?GCC编译系统会进行检测,如果build=host,它会检测成just-compiled,也就是说,不用宿主的东西,以保证纯 度。如果build不等于host,那么检测结果为pre-installed。这时GCC不得不依赖于宿主提供编译器去编译target上的东西因为编 译出来的东西在宿主上(可能)无法运行。

我建立交叉编译工具链过程中,
不设置CC_FOR_TARGET 时,make all-target-libgcc开始部分的自动配置过程会出错,提示找不到${NEW_OS_TARGET}-cc,
设置CC_FOR_TARGET后,一切正常,但不会调用xgcc,也就是出现pre-installed的情况,按我的步骤,这个也是正常的,之前的make install-gcc已经安装过裸编译器,到这一步其实使用{NEW_OS_TARGET}-gcc与xgcc没有本质区别,他们事实上一样,只是名字、路径不同。
2、由此可见,正常情况下如果CC_FOR_TARGET是just-compiled,那么就不需要在make all-target-libgcc之前先make all-gcc && make install-gcc。因为编译系统应该自动调用新编译出来的编译器进行编译。

这里你懒惰了一下,依靠Makefile中依赖关系自动完成这个过程,对你的结果,不感到意外。

我使用的方法沿用gcc-4.2系列方法而来,条理清晰,与你之前hack结果一致。

我不怀疑有更简单方法,在你的贴子中,我曾提到自己用fakeroot方式验证过伪交叉编译方式gcc第一遍make && make install的结果与你的方法(也就是现在我沿用的方法)结果一致。

也许gcc第一遍,交叉编译方式与伪交叉编译方式,都只需make && make install,并且不需设置CC_FOR_TARGET,最初建立gcc-4.3.1的系统时,我怎么忘了验证一下。不过我还是喜欢现在条理清晰的方式。
3、回头看看关于specs的那个hack,这很明显也跟以上情况有关。原本GCC编译系统在完成gcc之后,需要调用GCC_FOR_TARGET获得 一个SPECS。如上所述,如果GCC_FOR_TARGET被检测为just-compiled,那么编译系统将调用刚编译好的xgcc来获得 SPECS,否则将依赖于预先安装的交叉编译器。

这个有点意思,我会验证一下。
我刚刚完成一个x86_64 -> i686的build,在注意了确保build=host之后,configure后直接make all-target-libgcc是成功的。

更有理由相信上面红色部分猜想是正确的。
关于build,host和target,我想可以总结如下:
1、build=host=target 是本机原生编译,默认的情况,LFS使用的情况。
2、build=host<>target是本机交叉编译,CLFS交叉编译工具链使用的情况。
3、build<>host=target是交叉原生编译,CLFS原生工具链就是这种情况:依赖于build上的交叉编译工具链,来编译target上的原生工具链
4、build<>host<>target是加拿大式编译,一般很少使用。
由上可见,至少情况3是必须依赖pre-installed cc的。更何况GCC必须支持情况4。所以才有需要设置CC_FOR_TARGET的情况。

既然讨论到这个,我们更进一步好了:
1、无异议
2、这是只有建立交叉编译工具链binutils、gcc部分才会出现的情况,严格的说不是交叉编译,他们还是宿主上的程序,但gcc中libgcc、libstdc++部分是交叉编译的,libgcc、libstdc++部分的自动配置过程事实是3所描述情况,这个你可以注意一下。我注意到libstdc++编译错误是--build不正确,才注意到gcc-4.3对--build的特殊处理,所以得出要添加--build的结论。
3、这是交叉编译方式,用于交叉编译工具链中glibc、以及上面提到的情况、交叉编译临时系统、或者交叉编译任何想象的到的软件包(只是困难程度不同罢了)。
4、这够疯狂的,这是特殊的交叉编译方式,可以看作是3的叠加,以自己手头的硬件,短期内看不到必要。
回复 支持 反对

使用道具 举报

发表于 2008-7-12 15:34:41 | 显示全部楼层
因为x86_64 to i686仍有可能调用宿主的东西(我是multilib),所以我刚才实验了一下真正的交叉编译:x86_64 to mips。

这个有些难度,原因是安装Glibc-ports headers for mips需要调用for mips的编译器。这是个死循环。解决方法是在没有Glibc头文件的情况下编译裸编译器。方法:同gcc-static的编译参数,然后make all-gcc && make install-gcc。(现在有点明白为什么新版本需要让make all-gcc不编译libgcc了,因为现在编译libgcc需要Glibc头文件,而之前的版本并不需要)

然后安装Glibc头文件,即可进行下一步安装。因为我全程采用FAKEROOT方式,因此在这个阶段我把TOOLS目录清空然后重新解压binutils+gmp+mpfr,保证之前的GCC裸编译器不会被意外调用。

第二次编译GCC相当于正常编译GCC的第一次static。经过验证,make all-target-libgcc可以一次成功,但是make install-target-libgcc只会安装libgcc,不安装编译器。所以编译安装方式是
make all-target-libgcc
make install-gcc
make install-target-libgcc

随后glibc可以正常安装(我懒得打那个includes补丁,直接下了一个snapshot;不过那个libeh_a的补丁跑不了)。
而这时进行gcc final编译,一次通过,没有任何问题。

顺便说一句,对于一般的交叉编译,我觉得可能在4.3系列可能真的需要三遍gcc才能完成:第一遍没有glibc的naked gcc,第二遍static with libgcc,第三遍final。换句话说,你的脚本还不够通用,还只能在x86上面跑。
回复 支持 反对

使用道具 举报

发表于 2008-7-12 17:09:56 | 显示全部楼层
也许gcc第一遍,交叉编译方式与伪交叉编译方式,都只需make && make install,并且不需设置CC_FOR_TARGET,最初建立gcc-4.3.1的系统时,我怎么忘了验证一下。不过我还是喜欢现在条理清晰的方式。

[/QUOTE]

要指出的是这并不正确。第一遍无论如何也不能直接make && make install。因为即使--enable-languages=c,但是除了libgcc之外还有一个libmud什么的需要编译,那个东西第一遍编译不出来。

经我验证configure之后最简单的编译安装方式是make all-target-libgcc && make install-gcc && make install-target-libgcc。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-7-16 11:12:59 | 显示全部楼层
以帖子中方法新建的系统移植到其他机器为宿主,重新用帖子中方法建立新系统—— i686-pc-linux-gnu -> x86_64-unknown-linux-gnu,在工具链部分binutils->libbfd.la过程中出现oom kill(Out of memory)。目前,我正在尝试解决这个问题,验证过程要延误一下。
因为x86_64 to i686仍有可能调用宿主的东西(我是multilib),所以我刚才实验了一下真正的交叉编译:x86_64 to mips。

这个有些难度,原因是安装Glibc-ports headers for mips需要调用for mips的编译器。这是个死循环。

查看CLFS、还有 youbest 关于mips的帖子,应当没有这样的问题的。是不是什么地方出错了?
make all-target-libgcc
make install-gcc
make install-target-libgcc

这样看起来是简单一点,真正的编译过程并没有减少。
实际上,我觉得挺丑陋的。
顺便说一句,对于一般的交叉编译,我觉得可能在4.3系列可能真的需要三遍gcc才能完成:第一遍没有glibc的naked gcc,第二遍static with libgcc,第三遍final。

你说的前两遍,是第一遍的两个步骤,没必要看作两遍吧。
换句话说,你的脚本还不够通用,还只能在x86上面跑。

这都被你看出来了。
我确实是想用一个脚本搞定尽可能多的目标架构,所以glibc部分把ports也整合进来,虽然x86、x86_64用不到。
官方手册CLFS、CLFS-Sysroot,arm、ppc、mips部分补丁、软件版本,我顺过一遍,我的脚本应该是适用的,只是没验证而已,即使真的不适用,需要修正的地方也不会很多。
早几年,想用相同版本的软件包编译x86、arm、ppc是不可能的,不同平台软件开发进度不同,现在的情况好多了。
但是除了libgcc之外还有一个libmud什么的需要编译

这个有些印象,验证时,我会关注一下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-7-16 18:53:45 | 显示全部楼层
参考 地球发动机 意见,经验证,创建交叉编译工具链gcc部分可作如下修正,不需要设置CC_FOR_TARGET、CXX_FOR_TARGET,不需要空spec。

回头看看,出现这种情况的过程是:
最初沿用gcc-4.2系列方法,第一遍gcc通过,glibc无法编译,缺少libgcc,
回头编译libgcc,make all-target-libgcc,出现错误,要调用不存在的${NEW_OS_TARGET}-cc,查看Makefile自然想到要添加CC_FOR_TARGET,再次编译通过,故添加CC_FOR_TARGET到gcc配置部分,
恢复到第一遍gcc之前状态,再次编译,make all-gcc过程中出现错误,要调用不存在的{NEW_OS_TARGET}-gcc生成spec,自然想到要用空spec修正,[color="Red"]忽略了最初是可以通过的,也没有注意到是pre installed的问题,更没考虑make all-gcc之后,先不安装直接make all-target-libgcc,
该方法被保留,
到了第二遍gcc时,注意力集中在解决libstdc++的循环依赖问题,发现要添加--build,配置部分想当然参考gcc第一遍添加了CC_FOR_TARGET、CXX_FOR_TARGET,编译通过,
为美观对称,工具链部分统统添加--build,清空工具链,重新验证一遍通过,定型。

第一遍
  1. HOMEPAGE="http://gcc.gnu.org/"
  2. SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
  3.             http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
  4. SOURCE_MD5=""

  5. SOURCE_DIR=${SOURCE}/gcc-${PACKAGE_VERSION}
  6. BUILD_DIR=${SOURCE}/gcc-build

  7. source_tree()
  8. {
  9.     cd ${SOURCE}
  10.     tar -xvf gcc-${PACKAGE_VERSION}.tar.bz2

  11.     cd ${SOURCE_DIR}

  12.     #posix
  13.     sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
  14.     sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
  15.     sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)

  16.     #--disable-multilib /lib64->/lib
  17.     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
  18.         sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
  19.         sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
  20.             -e "s@../lib64 ../lib@../lib ../lib@g" \
  21.             -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
  22.     fi

  23.     #cross hacking
  24.     sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c

  25.     mkdir -pv ${BUILD_DIR}
  26. }

  27. source_config()
  28. {
  29.     cd ${BUILD_DIR}
  30.     AR=ar \
  31.     ${SOURCE_DIR}/configure --prefix=${TOOLS} \
  32.         --build=${NEW_OS_HOST} \
  33.         --host=${NEW_OS_HOST} \
  34.         --target=${NEW_OS_TARGET} \
  35.         --with-sysroot=${ROOTFS} \
  36.         --disable-nls \
  37.         --disable-shared \
  38.         --enable-languages=c \
  39.         --disable-multilib
  40. }

  41. source_build()
  42. {
  43.     cd ${BUILD_DIR}
  44.     [color="Red"]make all-gcc
  45.     make all-target-libgcc
  46.     make install-gcc
  47.     make install-target-libgcc[/color]
  48. }
复制代码


第二遍
  1. HOMEPAGE="http://gcc.gnu.org/"
  2. SOURCE_URL="http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2
  3.             http://ftp.gnu.org/gnu/gcc/gcc-4.3.1/gcc-4.3.1.tar.bz2.sig"
  4. SOURCE_MD5=""

  5. SOURCE_DIR=${SOURCE}/${PACKAGE_NAME}-${PACKAGE_VERSION}
  6. BUILD_DIR=${SOURCE}/${PACKAGE_NAME}-build

  7. source_tree()
  8. {
  9.     cd ${SOURCE}
  10.     tar -xvf ${PACKAGE_NAME}-${PACKAGE_VERSION}.tar.bz2

  11.     cd ${SOURCE_DIR}

  12.     #posix
  13.     sed -i -e "s@tail -1@tail -n 1@g" $(grep -lr "tail -1" *)
  14.     sed -i -e "s@tail -3@tail -n 3@g" $(grep -lr "tail -3" *)
  15.     sed -i -e "s@head -1@head -n 1@g" $(grep -lr "head -1" *)

  16.     #--disable-multilib /lib64->/lib
  17.     if [ "${NEW_OS_NO_LIB64_DIR}" = "yes" ]; then
  18.         sed -i -e "s@/lib64/ld@/lib/ld@g" gcc/config/*/linux64.h
  19.         sed -i -e "s@../lib32 ../lib ../lib64@../lib32 ../lib ../lib@g" \
  20.             -e "s@../lib64 ../lib@../lib ../lib@g" \
  21.             -e "s@../lib64@../lib@g" gcc/config/*/t-linux64
  22.     fi

  23.     #cross hacking
  24.     sed -i -e "s@/usr/libexec/gcc/@@g" -e "s@/usr/lib/gcc/@@g" gcc/gcc.c

  25.     mkdir -pv ${BUILD_DIR}
  26. }

  27. source_config()
  28. {
  29.     cd ${BUILD_DIR}
  30.     AR=ar \
  31.     ${SOURCE_DIR}/configure --prefix=${TOOLS} \
  32.         --build=${NEW_OS_HOST} \
  33.         --host=${NEW_OS_HOST} \
  34.         --target=${NEW_OS_TARGET} \
  35.         --with-sysroot=${ROOTFS} \
  36.         --disable-nls \
  37.         --enable-shared \
  38.         --enable-languages=c,c++ \
  39.         --enable-__cxa_atexit \
  40.         --enable-c99 \
  41.         --enable-long-long \
  42.         --enable-threads=posix \
  43.         --disable-multilib
  44. }

  45. source_build()
  46. {
  47.     cd ${BUILD_DIR}
  48.     make
  49.     make install
  50. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-7-16 19:09:04 | 显示全部楼层
oom kill的问题最新进展如下:
1、怀疑作为宿主的移植过来的i686-pc-linux-gnu系统没有针对目标机优化编译、出现了不兼容的情况,把宿主工具链部分重新本地编译一遍,重新建立交叉编译工具链问题依旧。
2、启动移植过来的i686-pc-linux-gnu系统,chroot到一个已知可进行交叉编译的系统——debian etch i386,以此为宿主,用贴子中方法验证通过,顺便验证了一下建立交叉编译工具链的更好的方法,同时也排除了移植过来的i686-pc-linux-gnu系统内核问题。
回复 支持 反对

使用道具 举报

发表于 2008-7-16 21:02:06 | 显示全部楼层
Post by 聚焦深空;1875064

查看CLFS、还有 youbest 关于mips的帖子,应当没有这样的问题的。是不是什么地方出错了?
首先CLFS并没有SYSROOT版本的MIPS。非SYSROOT版本的CLFS是不需要Glibc头文件的,直接在static GCC上就可以编译Glibc。
其次youbest做的是64位龙芯。
而我build的是32位的MIPS,所以Glibc会使用一个-mabi32的参数调用宿主GCC。这个参数在x86机器上是不支持的,x86_64版本相应的参数是-m32。这就是为什么我会遇到这个问题,而别人没有。解决的方法只能是先build出一个支持该参数的GCC。

这样看起来是简单一点,真正的编译过程并没有减少。
实际上,我觉得挺丑陋的。
我同意。这个仅供参考了。

你说的前两遍,是第一遍的两个步骤,没必要看作两遍吧。
这是两遍。因为完整的顺序是
naked GCC
Glibc-headers
static GCC
Glibc
GCC final
如果把GCC final看作单独的步骤,那么naked也应该是单独的步骤。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-7-16 22:24:23 | 显示全部楼层
首先CLFS并没有SYSROOT版本的MIPS。非SYSROOT版本的CLFS是不需要Glibc头文件的,直接在static GCC上就可以编译Glibc。
其次youbest做的是64位龙芯。
而我build的是32位的MIPS,所以Glibc会使用一个-mabi32的参数调用宿主GCC。这个参数在x86机器上是不支持的,x86_64版本相应的参数是-m32。这就是为什么我会遇到这个问题,而别人没有。解决的方法只能是先build出一个支持该参数的GCC。
这是两遍。因为完整的顺序是
naked GCC
Glibc-headers
static GCC
Glibc
GCC final
如果把GCC final看作单独的步骤,那么naked也应该是单独的步骤。

严重怀疑与你宿主的mulitlib有关,youbest已做过64位龙芯Sysroot方式交叉编译,等会我做一下i486-pc-linux-gnu -> mips-unknown-linux-gnu 的验证。
如果是因为mulitlib引起的,你的第一遍,我会看作是对宿主的要求,不算在工具链部分。
我同意。这个仅供参考了。

已参考,前面验证贴中使用的是:
  1. make all-gcc     
  2. make all-target-libgcc
  3. make install-gcc
  4. make install-target-libgcc
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表