0. 首先解释下build, host和target
build:编译过程运行在build上
host:编译出来的东西运行在host上
target:运行在host上的编译器编译出来的东西运行于target。
例如,编译gcc时,build=x86,host=arm,target=mips,表示:
a) 在x86上编译gcc源代码;
b) a步骤得到的gcc在arm上运行(姑且把这个编译器叫做xxx-linux-gcc)
c) 你写了个小东西main.c在arm上用xxx-linux-gcc编译,得到的东西在mips上运行。
As you see, only if $build != $host a cross-compilation is performed.
1. We start from VMWare
2. Add a new disk in VMWare for our guest OS (Maybe you need restart)
3. fdisk this new disk, one partition for root, one partition for swap
4. format our new partitions:
# mkfs -t ext4 /dev/sdb1
# mkswap /dev/sdb2
5. # mkdir /mnt/lfs
6. # mount /dev/sdb1 /mnt/lfs
6.1 # chmod a+w lfs
7. # mkdir -p /mnt/lfs/sources
8. # chmod a+wt /mnt/lfs/sources
9. # mkdir /mnt/lfs/tools
我们首先制作一个development suite,在这个suite里包含构建LFS所需要的全部packages。这个suite本身也是一个不依赖于host就能独立工作的小系统。在LFS构造完成后,这个目录里的东西就可以吃干抹净了(误,见下文)。
9.1 我们构造LFS所用的各组件版本及它们的编译选项和host上跑着的不可能一致,为了避免依赖问题,我们不直接用host上的东西来构造LFS;
9.2 作为一个合格的development suite,你可以把它拿(拷)出来到处用。
10. # ln -s /mnt/lfs/tools /
在host的根目录上创建一个指向lfs/tools的symbolic link,这样在host侧和lfs侧能够用相同路径(/tools)访问development suites。这样chroot前后suites路径保持不变。
11. 新建一个用户专用于我们的工作
# groupadd lfs
# useradd -s /bin/bash -g lfs -m -k /dev/null lfs -s: bash; -g: group; -m: create home directory;
-k: useradd默认会从/etc/skel复制东西来初始化用户目录,-k /dev/null让useradd从/dev/null复制。
12. passwd lfs
13. su - lfs
切换到lfs
14. exec env -i HOME=$HOME TERM=$TERM PS1='u:w$ ' /bin/bash
exec命令替换当前shell,因此该命令会清除系统默认环境变量(/etc/profile),得到一个干净的环境。
注意u和w小写。
15. cat > ~/.bashrc << "EOF"
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
LFS_TGT=$(uname -m)-lfs-linux-gnu
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL LFS_TGT PATH
EOF
# 关于set +h:比如你在/bin下有个gcc执行了一下,后来在/tools/bin下有了个gcc,尽管PATH规定先搜索/tools/bin,但bash会记住/bin下已经有个gcc而执行/bin下的。我们需要禁止该功能。
16. 我们希望使用自己的编译器来构造自己的系统。
16.1 但这里有个问题,在一无所有的情况下,我们不得不先使用host上的这些东西。
16.2 所以我们先要制作一个“半成品”的binutils和gcc,制作它们时仍然要使用host上的glibc和gcc;
16.3 然后用这个“半成品”来编译出自己的glibc;
16.4 最后用自己的glibc重新制作binutils和gcc。
17. 在sources目录下解压Binutils。Binutils的Doc说建一个build目录用于编译:
cd binutils-2.26 && mkdir build && cd build
../configure --prefix=/tools # 安装目录
--with-sysroot=$LFS # build system在需要时到$LFS下找target system的libraries(误,见下文)
--with-lib-path=/tools/lib # 编译出来的linker在运行(链接目标程序)时将搜索该目录
--target=$LFS_TGT # 编译出来的东西要使用该前缀,前缀使用约定架构名+自定义名的形式,必须以约定架构名开始。
--disable-nls # 不要国际化
--disable-werror # 忽略编译过程中的警告
make
mkdir -v /tools/lib && ln -s lib /tools/lib64 # 64位系统用
make install # 因为我们安装目录是/tools,不需要su就可安装
[在binutils的configure文件中完全找不到--with-sysroot和--with-lib-path选项:也许这两者其实是不必要的?(误)]
[此处我们将去除以上选项编译binutils,以验证之。如果发生问题,我们会再回来。(误)]
[-with-sysroot指定编译出来的binutils在工作时使用的sysroot。对编译出来的ld使用--print-sysroot选项可打印出该项。]
[因为这还是一个半成品binutils,所以此处指定的sysroot仍然从主机路径开始(/mnt/lfs)。]
[省略-with-sysroot的情况下,--print-sysroot无打印输出,据说此情况下编译出来的binutils不支持--with-sysroot选项。]
[如果要指定编译binutils时使用的sysroot,使用--with-build-sysroot选项。]
[--with-lib-path在默认的库搜索路径的基础上增加我们自己的库搜索路径。其效果可用ld --verbose | grep "SEARCH"验证。]
18.