在构建lfs系统之前我们需要构建脱离宿主系统的新的工具链,然后在使用新的工具链构建其他基础的工具。这样做的目的减少宿主系统的依赖和影响。
构建出来的新工具链会放在$LFS/tools 的文件夹中,让其与后面安装的文件和宿主系统生成的目录分开,防止污染后面要制作的lfs系统。
构建临时lfs系统
解压包命令:
tar -xjf ***
附:在没有特殊说明的情况下,编译安装完一个就删除掉解压后的目录
1. Binutils-2.26
进入到Binutils-2.26目录下,创建编译目录:
mkdir -v build
cd build
进行编译配置:
…/configure --prefix=/tools
–with-sysroot=$LFS
–with-lib-path=/tools/lib
–target=$LFS_TGT
–disable-nls
–disable-werror
开始编译:
make
由于我使用的是x86_64架构平台,所以需要创建符号链接:
case $(uname -m) in
x86_64) mkdir -v /tools/lib && ln -sv lib /tools/lib64 ;;
esac
安装编译结果:
make install
2. GCC-5.3.0
还记得第一张的准备工作中,检查宿主机的库时,有如下的输出:
: not found
: not found
: not found
说明当前宿主机没有这三个库,所以我们解压sources目录下的这三个包,并重命名,使得编译gcc的时候可以识别到这三个库。
tar -xf …/mpfr-3.1.
mv -v mpfr-3.1.3 mpfr
tar -xf …/gmp-6.1.
mv -v gmp-6.1.0 gmp
tar -xf …/mpc-1.0.
mv -v mpc-1.0.3 mpc
以上是将这三个包解压后,移动到gcc的编译目录下。
以下命令将更改GCC默认动态链接器的位置,以使用/ tools中安装的链接器。 它还从GCC的include搜索路径中删除/ usr / include:
for file in
$(find gcc/config -name -o -name linux.h -o -name )
do
cp -uv $file{,.orig}
sed -e ‘s@/lib(64)?(32)?/ld@/tools&@g’
-e ‘s@/usr@/tools@g’ $ > $file
echo ’
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_1 “/tools/lib/”
#define STANDARD_STARTFILE_PREFIX_2 “”’ >> $file
touch $
done
以上具体的含义详见lfs7.9文档。
同Binutils-2.26,创建build目录:
mkdir -v build
cd build
配置命令如下:
…/configure
–target=$LFS_TGT
–prefix=/tools
–with-glibc-version=2.11
–with-sysroot=$LFS
–with-newlib
–without-headers
–with-local-prefix=/tools
–with-native-system-header-dir=/tools/include
–disable-nls
–disable-shared
–disable-multilib
–disable-decimal-float
–disable-threads
–disable-libatomic
–disable-libgomp
–disable-libquadmath
–disable-libssp
–disable-libvtv
–disable-libstdcxx
–enable-languages=c,c++
然后进行make和make install,这里提醒一下,最好不要手打进行操作,复制粘贴的方式更能保证正确性。
3. Linux-4.13.16 API Headers
由于业务需求,我这里使用的是Linux-4.13.16的内核(没有特殊需求就使用lfs7.9提供的)。所以将该版本的内核的api头文件移动到tools文件夹中。
解压linux-4.13.文件:
tar zxvf linux-4.13.
清除旧文件并移动头文件到tools文件夹中:
make mrproper
make INSTALL_HDR_PATH=dest headers_install
cp -rv dest/include/* /tools/include
4. Glibc-2.23
与上述的Binutils-2.26类似,区别在于编译配置:
…/configure
–prefix=/tools
–host=$LFS_TGT
–build=$(…/scripts/)
–disable-profile
–enable-kernel=2.6.32
–enable-obsolete-rpc
–with-headers=/tools/include
libc_cv_forced_unwind=yes
libc_cv_ctors_header=yes
libc_cv_c_cleanup=yes
确认新工具链的功能像预期的一样,运行如下命令:
echo ‘int main(){}’ >
$LFS_TGT-gcc
readelf -l | grep ‘: /tools’
如果一切正常,则有如下输出格式:
[Requesting program interpreter: /tools/lib/.2]
我的输出格式如下:
[Requesting program interpreter: /tools/lib64/.2]
正常则清理测试文件:
rm -v
5. Libstdc++5.3.0
Libstdc++在gcc源码中,所以需要重新解压gcc并编译Libstdc++。Libstdc++编译配置如下:
…/libstdc+±v3/configure
–host=$LFS_TGT
–prefix=/tools
–disable-multilib
–disable-nls
–disable-libstdcxx-threads
–disable-libstdcxx-pch
–with-gxx-include-dir=/tools/$LFS_TGT/include/c++/5.3.0
6. 重新编译Binutils-2.26
至于为什么需要重新编译Binutils-2.26,我猜测是去掉宿主的依赖,之前编译Binutils-2.26,可能是为了用它编译后面的几个工具,然后再次编译Binutils-2.26,从而脱离宿主系统的依赖。
Binutils-2.26的编译配置:
CC=$LFS_TGT-gcc
AR=$LFS_TGT-ar
RANLIB=$LFS_TGT-ranlib
…/configure
–prefix=/tools
–disable-nls
–disable-werror
–with-lib-path=/tools/lib
–with-sysroot
为下面的阶段准备连接器:
make -C ld clean
make -C ld LIB_PATH=/usr/lib:/lib
cp -v ld/ld-new /tools/bin
7. 重新编译GCC-5.3.0
第一次编译GCC-5.3.0的时候不包括系统头文件:/tools/include/,本次编译需要/tools/include/头文件,所以创建完整版版的头文件:
cat gcc/ gcc/ gcc/ >
dirname $($LFS_TGT-gcc -print-libgcc-file-name)
/include-fixed/
更改默认动态连接器的位置:
for file in
$(find gcc/config -name -o -name -o -name )
do
cp -uv $file{,.orig}
sed -e ‘s@/lib(64)?(32)?/ld@/tools&@g’
-e ‘s@/usr@/tools@g’ $ > $file
echo ’
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_1 “/tools/lib/”
#define STANDARD_STARTFILE_PREFIX_2 “”’ >> $file
touch $
done
同样的设置三个库:
tar -xf …/mpfr-3.1.
mv -v mpfr-3.1.3 mpfr
tar -xf …/gmp-6.1.
mv -v gmp-6.1.0 gmp
tar -xf …/mpc-1.0.
mv -v mpc-1.0.3 mpc
编译配置:
CC=$LFS_TGT-gcc
CXX=$LFS_TGT-g++
AR=$LFS_TGT-ar
RANLIB=$LFS_TGT-ranlib
…/configure
–prefix=/tools
–with-local-prefix=/tools
–with-native-system-header-dir=/tools/include
–enable-languages=c,c++
–disable-libstdcxx-pch
–disable-multilib
–disable-bootstrap
–disable-libgomp
将gcc链接到cc
ln -sv gcc /tools/bin/cc
同样的确认新工具链的正确性:
echo ‘int main(){}’ >
cc
readelf -l | grep ‘: /tools’
我的输出结果如下:
[Requesting program interpreter: /tools/lib64/.2]
清理测试文件:
rm -v
8. Tcl-core-8.6.4
此软件包和后面三个软件包(Expect, DejaGNU, and Check),为gcc和Binutils等其他软件包提供测试套件的运行支持。
tcl编译配置
cd unix
./configure --prefix=/tools
编译和测试tcl
make
TZ=UTC make test
让安装的库文件可写:
chmod -v u+w /tools/lib/libtcl8.
安装tcl的头文件
make install-private-headers
创建必要的链接
ln -sv tclsh8.6 /tools/bin/tclsh
9. Expect-5.45
强制Expect的配置脚本使用 /bin/stty ,代替宿主机的/usr/local/bin/stty:
cp -v configure{,.orig}
sed ‘s:/usr/local/bin:/bin:’ > configure
配置Expect:
./configure --prefix=/tools
–with-tcl=/tools/lib
–with-tclinclude=/tools/include
编译和测试:
make
make test
安装软件包:
make SCRIPTS=“” install
10. DejaGNU-1.5.3
执行如下命令进行编译和安装:
./configure --prefix=/tools
make install
make check
11. Check-0.10.0
执行如下:
PKG_CONFIG= ./configure --prefix=/tools
make
make check
make install
12. Ncurses-6.0
首先,确保在配置期间首先找到gawk:
sed -i s/mawk// configure
编译配置:
./configure --prefix=/tools
–with-shared
–without-debug
–without-ada
–enable-widec
–enable-overwrite
编译和安装:make 和make install
12. Bash-4.3.30
执行如下:
./configure --prefix=/tools --without-bash-malloc
make
make tests
make install
ln -sv bash /tools/bin/sh
13. Bzip2-1.0.6
make
make PREFIX=/tools install
14. Coreutils-8.25
./configure --prefix=/tools --enable-install-program=hostname
make
make RUN_EXPENSIVE_TESTS=yes check
make install
15. Diffutils-3.3
./configure --prefix=/tools
make
make check
make install
16. File-5.25
./configure --prefix=/tools
make
make check
make install
17. Findutils-4.6.0
./configure --prefix=/tools
make
make check
make install
18. Gawk-4.1.3
./configure --prefix=/tools
make
make check
make install
19. Gettext-0.19.7
cd gettext-tools
EMACS=“no” ./configure --prefix=/tools --disable-shared
按照需求,只编译如下的软件包:
make -C gnulib-lib
make -C intl
make -C src msgfmt
make -C src msgmerge
make -C src xgettext
进行安装msgfmt, msgmerge and xgettext
cp -v src/{msgfmt,msgmerge,xgettext} /tools/bin
20. Grep-2.23、Gzip-1.6、M4-1.4.17、Patch-2.7.5、Sed-4.2.2、Tar-1.28、Texinfo-6.1、Xz-5.2.2
./configure --prefix=/tools
make
make check
make install
21. Make-4.1
./configure --prefix=/tools --without-guile
make
make check
make install
22. Perl-5.22.1
sh Configure -des -Dprefix=/tools -Dlibs=-lm
make
cp -v perl cpan/podlators/pod2man /tools/bin
mkdir -pv /tools/lib/perl5/5.22.1
cp -Rv lib/* /tools/lib/perl5/5.22.1
如上,只安装一小部分应用和库。
23. Util-linux-2.27.1
配置如下:
./configure --prefix=/tools
–without-python
–disable-makeinstall-chown
–without-systemdsystemunitdir
PKG_CONFIG=“”
编译并安装make && make install
24. Stripping
这一步为可选项,如果你的空间足够大,可以不用做这一步,它主要是清理一些无用的内容:删除一些调试符号等等,为了减少文件的大小。
strip --strip-debug /tools/lib/*
/usr/bin/strip --strip-unneeded /tools/{,s}bin/*
删除帮助文档:
rm -rf /tools/{,share}/{info,man,doc}
我的空间比较大,考虑到后续可能会去查看这些东西,所以不做这一步了。
24. 改变属主
后续的操作我们需要在root用户下进行,并且确保root下也有lfs用户,这里改变$LFS/tools的用户目录属组为root用户:
chown -R root:root $LFS/tools
同时我们可以备份 $LFS/tools文件夹,方便后续更新lfs版本的时候使用,在以后的lfs构建中可以减少对这一步的操作。