编译最终系统

优质
小牛编辑
120浏览
2023-12-01

配置选项

要做到最大限度的定制每一个软件包,获取完整的配置选项是必须的。当然,要想更加详细、全面的了解如何自定义安装,还需要查看 README INSTALL FAQ 之类的文档,甚至是软件包的官方手册。需要注意的是,有不少软件包的配置选项分布在多个 configure 脚本中,还有少数并不是通过 configure 脚本进行配置的,查看完整的配置信息就变成一件很吃力的事情了。因此唯一的建议就是:读文档、读文档、再读文档。当然,鸟语是免不了的...

关机与状态回复

由于编译过程漫长,下面的编译步骤被设计为"易于恢复状态的"(仅对"分支㈠"有效),意思是,你可以在编译完任意一个软件包之后关机,并且重新开机后就已经自动的恢复了工作状态。要达到这个目的,你可以使用任何你喜欢的方式关机(比如直接拔掉电源),但是你必须确保在关机前运行了"sync"命令。

对于分支㈡,恢复步骤如下:
①使用 LiveCD 开机,直接按回车键启动,所有设置均采用默认。
②如果希望使用ssh进行远程安装,步骤同前。
③挂载文件系统后进入虚根环境,即可完成状态恢复:

export LFS=/mnt/lfs && mkdir -p $LFS  &&
mount -t xfs   /dev/sda2  $LFS       &&
mount -t ext2  /dev/sda1  $LFS/boot  &&
mount -t xfs   /dev/sda5  $LFS/usr   &&
mount -t xfs   /dev/sda6  $LFS/root  &&
mount -t xfs   /dev/sda7  $LFS/var   &&
mount -t xfs   /dev/sda8  $LFS/www   &&
mount -t xfs   /dev/sda9  $LFS/data  &&
mount -t devpts  devpts  $LFS/dev/pts &&
mount -t tmpfs   shm     $LFS/dev/shm &&
mount -t proc    proc    $LFS/proc    &&
chroot $LFS /usr/bin/env -i TERM=$TERM /bin/bash --login +h

[提示]如果你和我一样使用虚拟机的暂停功能,那么重新连接ssh后只要使用最后一句chroot命令即可。甚至可以在chroot前用下面的命令偷懒到底:

echo "chroot $LFS /usr/bin/env -i TERM=\$TERM /bin/bash --login +h" > /etc/profile

内核头文件

根据 Glibc 的 FAQ ,编译 Glibc 时使用的内核头文件版本可以比实际运行 Glibc 的内核版本高。比如用于编译 Glibc 的内核头文件版本为 2.6.24 ,但是实际运行 Glibc 的可以是 2.6.16 版本的内核(编译 Glibc 时必须使用 --enable-kernel=2.6.16 而不能使用 --enable-kernel=2.6.24 )。允许这样做的好处是即使将来把内核升级到 2.6.24 也不需要重新编译 Glibc 了。另一方面,如果实际运行的内核版本比头文件版本高,那么新内核的新特性(主要是系统调用)将无法被Glibc使用。[注意]不要直接 INSTALL_HDR_PATH=/usr ,这样可能使得Glibc变得不稳定。[小提示]如果将来把内核升级为更高版本,头文件是不是也需要跟着一起升级?答案是:NO!!

( test ! -f $SRC/build.log ) && [ "`pwd`" = "$SRC" ] &&
R=/root/linux-headers-2.6.24.2/ &&
tar -xf linux-2.6.24.2.tar.bz2 && cd linux-2.6.24.2 &&
make distclean && make headers_check ARCH=x86 &&
make headers_install ARCH=x86 INSTALL_HDR_PATH=$R/usr &&
cp -r $R/usr/include /usr/ &&
cd $SRC && rm */ &&
echo '1-kernel-headers' >> $SRC/build.log && sync &&

Glibc

Glibc 的安装指南中说测试套件中的某些测试项目是假定以非 root 身份运行的,因此建议使用普通用户身份进行编译与安装。不过经过实践,以 root 用户进行编译和安装也没问题。这里仅安装了 zh_CN.UTF-8 的 locale 支持,如果你想支持更多的 locale 请自己添加适当的 localedef 命令。出于安全最大化的考虑还禁用了 DNS 。将时区设为UTC(相当于取消时区的概念,如果你有使用时区的需求可以设为"PRC")。更多关于安装 Glibc 的信息,请查看源码树下的 configure INSTALL FAQ 三个文件。[提示]由于没有安装C++编译器的缘故,bug-atexit3-lib.os tst-cancel24.o c++-types-check 测试将会失败,你可以安全的忽略它。touch用于阻止可能发生的Autoconf调用(当Makefile检测到一个configure文件的时间戳比它对应的configure.in文件旧的时候),这种调用有时候会导致编译失败。将"/dev/log"修改为"/dev/shm/log"是因为将来的根文件系统是只读挂载的,而syslogd会在启动的时候删除并重建此socket。

R=/root/glibc-2.6.1/ && mkdir {,$R}/usr/lib/locale &&
tar -xf glibc-2.6.1.tar.bz2 && cd glibc-2.6.1 &&
sed -i 's|libs -o|libs -L/usr/lib -Wl,-dynamic-linker=/lib/ld-linux.so.2 -o|' scripts/test-installation.pl &&
sed -r -i 's:/bin/(pwd|cat):\1:g' configure{.in,} io/ftwtest-sh stdio-common/{test-popen,xbug,tstscanf}.c &&
sed -i -e's|^rootsbindir =.*|rootsbindir=/usr/bin|' -e's|^sbindir =.*|sbindir=/usr/bin|' Makeconfig &&
sed -i 's|^sbindir=.*|sbindir=/usr/bin|' {,posix/glob/}configure &&
sed -i 's|libc_cv_rootsbindir=.*|libc_cv_rootsbindir=/usr/bin|' sysdeps/unix/sysv/linux/configure &&
sed -i 's|/dev/log|/dev/shm/log|' bits/syslog-path.h &&
find . -name configure | xargs touch &&
mkdir ../glibc-build && cd ../glibc-build &&
../glibc-2.6.1/configure --prefix=/usr --sbindir=/usr/bin --enable-add-ons=nptl --enable-shared --enable-kernel=2.6.22 --disable-oldest-abi --enable-omitfp --disable-profile --with-headers=/usr/include --with-binutils=/www/bin --without-cvs --with-elf --without-gd --without-gmp --without-selinux --with-tls &&
echo 'MAKEINFO = :' >> configparms &&
make && ( make -k check 2> $SRC/build_glibc.log ; make install ) &&
make install install_root=$R &&
localedef -i zh_CN -f UTF-8 zh_CN.UTF-8 && cp /usr/lib/locale/* $R/usr/lib/locale/ &&
rm {,$R}/etc/rpc {,$R}/{,usr}/lib/*_g.* {,$R}/usr/libexec/pt_chown {,$R}/usr/share/locale &&
echo 'passwd: files
group: files
shadow: files
hosts: files
networks: files
protocols: files
services: files
ethers: files
rpc: files' | tee {,$R}/etc/nsswitch.conf &&
cp --remove-destination /usr/share/zoneinfo/UTC   /etc/localtime &&
cp --remove-destination /usr/share/zoneinfo/UTC $R/etc/localtime &&
cp /etc/{passwd,group,hosts}  $R/etc/ &&
cd $SRC && rm */ &&
echo '2-glibc' >> $SRC/build.log && sync &&

再次调整工具链

mv /www/bin/{ld-new,ld} &&
gcc -dumpspecs | sed -e'/^\*link:$/{n;s@$@ -L/usr/lib@}' -e's@/www/lib/ld-linux.so.2@/lib/ld-linux.so.2@g' -e'/^\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' -e'/^\*cpp:$/{n;s@$@ -isystem /usr/include@}' > `dirname $(gcc -print-libgcc-file-name)`/specs &&
echo 'main(){}' > dummy.c && cc dummy.c -v -Wl,--verbose &> dummy.log &&
readelf -l a.out | fgrep '[Requesting program interpreter: /lib/ld-linux.so.2]' &&
fgrep 'attempt to open /usr/lib/crt1.o succeeded' dummy.log &&
fgrep 'attempt to open /usr/lib/crti.o succeeded' dummy.log &&
fgrep 'attempt to open /usr/lib/crtn.o succeeded' dummy.log &&
fgrep '#include <...> search starts here:
 /usr/include
 /www/include' dummy.log &&
# fgrep 'SEARCH_DIR("/www/i686-pc-linux-gnu/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");' dummy.log &&
fgrep 'attempt to open /lib/libc.so.6 succeeded' dummy.log &&
fgrep 'found ld-linux.so.2 at /lib/ld-linux.so.2' dummy.log &&
rm dummy.c a.out dummy.log &&
echo '3-adjusting' >> $SRC/build.log && sync &&

Tcl + Expect + DejaGNU

[提示]使用 --with(out)-tk 将导致 expect 配置失败,使用了 --with-tcl 之后就不需要再详细指定 --with-tclconfig --with-tcllib --with-tcllibdir 了。使用 --with(out)-docbook 或 --with(out)-oskith 将导致 dejagnu 配置失败。sed 一定要先修改 configure.in 再修改 configure ,否则会导致 Autoconf 的调用。dejagnu 的安装指南说测试套件需要以非 root 身份运行,可是经过实践,无论 root 与否,都不能在第一次安装后立即通过测试,一般需要安装两次甚至三次才能测试成功(无论是否root都是这样),不知何故。再加上dejagnu的测试程序依赖于这里并不存在的C++编译器,因此这里跳过dejagnu测试。

R=/root/tcl8.4.18/ &&
tar -xf tcl8.4.18-src.tar.gz && cd tcl8.4.18/unix &&
sed -i 's:/bin/rm:rm:g' ../library/ldAout.tcl &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-threads --enable-shared --enable-load --enable-gcc --disable-symbols --disable-64bit --disable-64bit-vis --disable-langinfo --disable-corefoundation --disable-dtrace --disable-framework --disable-man-symlinks --disable-man-compression --disable-man-suffix &&
make && TZ=UTC make test &&
make install install-private-headers                 && ln -sf tclsh8.4   /usr/bin/tclsh &&
make install install-private-headers INSTALL_ROOT=$R && ln -sf tclsh8.4 $R/usr/bin/tclsh &&
cd $SRC && rm */ && sync &&
tar -xf expect-5.43.0.tar.bz2 && cd expect-5.43 &&
patch $SRC/expect-5.43.0-spawn-2.patch &&
sed -i 's/STTY_BIN=.*/STTY_BIN=stty/g' configure{.in,} &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-threads --enable-shared --enable-load --enable-gcc --with-tcl=/usr/lib --with-tclinclude=/usr/include --with-x=no --disable-symbols &&
make expect && make test &&
make install SCRIPTS="" && make install SCRIPTS="" INSTALL_ROOT=/root/expect-5.43.0/ &&
cd $SRC && rm */ && sync &&
tar -xf dejagnu-1.4.4.tar.gz && cd dejagnu-1.4.4 &&
./configure --prefix=/usr --sbindir=/usr/bin &&
make install && make install DESTDIR=/root/dejagnu-1.4.4/ &&
cd $SRC && rm */ &&
echo '4-tcl-expect-dejagnu' >> $SRC/build.log && sync &&

Binutils

由于"-finline-functions"会导致ld测试出现多处错误,因此这里需要专门禁用它。对Makefile.in的修改用于移除对makeinfo的依赖,否则编译将会失败(因为工具链中并未安装Texinfo)。[提示]由于 binutils-2.17 的测试套件将路径 /bin/stty 进行了硬编码,且本文作者尚未找到简便的迂回方法,因此如果你使用的是 2.17 ,那么要先建立一个符号链接来满足测试套件的需求,安装完毕后再删除它。

R=/root/binutils-2.18/ &&
tar -xf binutils-2.18.tar.bz2 && mkdir binutils-build && cd binutils-build &&
echo 'MAKEINFO = :' >> ../binutils-2.18/Makefile.in &&
CFLAGS="$CFLAGS -fno-inline-functions" \
../binutils-2.18/configure --prefix=/usr --sbindir=/usr/bin --with-lib-path=/lib:/usr/lib --disable-nls --disable-rpath --disable-multilib --enable-shared --disable-static --disable-werror --without-gmp --without-mpfr --without-included-gettext --without-libiconv-prefix --without-libintl-prefix --with-pic &&
make all check install tooldir=/usr/  && cp ../binutils-2.18/include/libiberty.h   /usr/include/ &&
make install tooldir=/usr/ DESTDIR=$R && cp ../binutils-2.18/include/libiberty.h $R/usr/include/ &&
cd $SRC && rm */ &&
echo '5-binutils' >> $SRC/build.log && sync &&

GCC

因为GCC的Makefile.in并不传递LDFLAGS,所以需要sed一下。为了得到更加高效的编译器,这里使用"make profiledbootstrap"代替"make"。对"LINK_SPEC"的修改是为了将"--hash-style=gnu"选项添加到默认的连接器选项中去,如果你希望这样的话,就去掉相应的注释。[提示]如果Glibc的CFLAGS中使用了-freg-struct-return的话,gcc.dg/struct-ret-libc.c测试将会失败,不过这是二进制兼容性所致,可以安全的忽略它。

R=/root/gcc-4.2.3/ &&
tar -xf gcc-core-4.2.3.tar.bz2 && tar -xf gcc-testsuite-4.2.3.tar.bz2 && cd gcc-4.2.3 &&
sed -r -i 's|^LDFLAGS(_FOR_TARGET)? =|& @LDFLAGS@|' Makefile.in &&
sed -i -e's@\./fixinc\.sh@-c true@' -e'/^LIBGCC2_DEBUG_CFLAGS/d' gcc/Makefile.in &&
sed -i '/MULTILIB_OSDIRNAMES/d' gcc/config/i386/t-linux64 &&
sed -i 's/install_to_$(INSTALL_DEST) //' libiberty/Makefile.in &&
# sed -i '/LINK_SPEC/s/ "/&--hash-style=gnu /' gcc/config/i386/linux{,64}.h &&
mkdir ../gcc-build && cd ../gcc-build &&
../gcc-4.2.3/configure --prefix=/usr --sbindir=/usr/bin --with-local-prefix=/usr/local --enable-languages=c --enable-bootstrap --disable-nls --disable-rpath --disable-multilib --enable-shared=libgcc --disable-static --disable-libgomp --disable-libmudflap --disable-libssp --enable-linux-futex --enable-threads=posix --enable-tls --disable-symvers --with-as=/usr/bin/as --with-ld=/usr/bin/ld --without-included-gettext --without-libiconv-prefix --without-libintl-prefix --without-gmp --without-mpfr --without-system-libunwind --without-system-zlib --with-pic --without-x &&
make profiledbootstrap LIBCFLAGS="$CFLAGS" BOOT_CFLAGS="$CFLAGS" BOOT_LDFLAGS="$LDFLAGS" &&
( make -k check | tee $SRC/build_gcc.log ; make install ) &&
make install DESTDIR=$R &&
ln -sf gcc   /usr/bin/cc &&
ln -sf gcc $R/usr/bin/cc &&
INC=`gcc -print-file-name=include` &&
TOL=`gcc -print-file-name=install-tools` &&
rm  {,$R}/$INC/* &&
cp  $TOL/include/*     $INC &&
cp  $TOL/include/*  $R/$INC &&
cp  $TOL/gsyslimits.h     $INC/syslimits.h &&
cp  $TOL/gsyslimits.h  $R/$INC/syslimits.h &&
unset INC TOL &&
cd $SRC && rm */ && sync &&
echo 'main(){}' > dummy.c && cc dummy.c -v -Wl,--verbose &> dummy.log &&
readelf -l a.out | fgrep '[Requesting program interpreter: /lib/ld-linux.so.2]' &&
fgrep 'attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.2.3/../../../crt1.o succeeded' dummy.log &&
fgrep 'attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.2.3/../../../crti.o succeeded' dummy.log &&
fgrep 'attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.2.3/../../../crtn.o succeeded' dummy.log &&
fgrep '#include <...> search starts here:
 /usr/lib/gcc/i686-pc-linux-gnu/4.2.3/include
 /usr/include
End of search list.' dummy.log &&
fgrep 'SEARCH_DIR("/usr/i686-pc-linux-gnu/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");' dummy.log &&
fgrep 'attempt to open /lib/libc.so.6 succeeded' dummy.log &&
fgrep 'found ld-linux.so.2 at /lib/ld-linux.so.2' dummy.log &&
rm dummy.c a.out dummy.log &&
echo '6-gcc' >> $SRC/build.log && sync &&

到此,最终系统的工具链核心安装完毕。

Sed

[ "`tail -1 $SRC/build.log`" = '6-gcc' ] &&
R=/root/sed-4.1.5/ &&
tar -xf sed-4.1.5.tar.gz && cd sed-4.1.5 &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-largefile --enable-i18n --enable-regex-tests --disable-html --disable-nls --without-included-regex --without-libiconv-prefix --without-included-gettext --without-libintl-prefix &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '7-sed' >> $SRC/build.log && sync &&

E2fsprogs

[提示]"--disable-htree"和"--disable-debugfs"选项都会导致许多测试错误,"--disable-swapfs"会导致lib/ext2fs测试由于找不到"tst_types"而失败,此外由于lib/ext2fs测试总是由于"Failed to allocate scratch memory!"失败,原因不明,所以这里使用sed跳过这个测试。CFLAGS和LDFLAGS必须在configure选项上设置。[依赖提示]UUID被XFS依赖,blkid,uuid 被mount/umount依赖。

R=/root/e2fsprogs-1.40.6/ && mkdir $R/{lib,etc} &&
tar -xf e2fsprogs-1.40.6.tar.gz && cd e2fsprogs-1.40.6 &&
sed -i 's:/bin/rm:rm:g' lib/blkid/test_probe.in &&
sed -i 's/^check::/cancelled-check::/' lib/ext2fs/Makefile.in &&
sed -i 's|root_sbindir=.*|root_sbindir=/usr/bin|' configure{.in,} &&
mkdir build && cd build &&
../configure --prefix=/usr --enable-elf-shlibs --disable-profile --disable-swapfs --enable-uuidd --disable-nls --disable-rpath --with-ccopts="$CFLAGS" --with-ldopts="$LDFLAGS" --with-root-prefix=/usr --without-libiconv-prefix --without-included-gettext --without-libintl-prefix &&
make && make check &&
make install install-libs && make install install-libs DESTDIR=$R &&
cp /etc/blkid.tab $R/etc/ && rm {,$R}/etc/{init.d,*.old} {,$R}/usr/etc &&
cp   /usr/lib/lib{blkid,uuid}.so.1   /lib &&
cp $R/usr/lib/lib{blkid,uuid}.so.1 $R/lib &&
cd $SRC && rm */ &&
echo '8-e2fsprogs' >> $SRC/build.log && sync &&

Coreutils

运行 make check 的非特权用户要求至少位于两个不同的组中,因此这里将 pgsql 用户临时添加到 dummy 组内。"RUN_VERY_EXPENSIVE_TESTS=yes"用于运行更多的测试项目。[说明]因为test-getaddrinfo测试总是由于缺乏DNS支持而失败,需要跳过它。更多此版本的怪脾气,请看这里。[说明]由于Findutils包内的 xargs 程序将 echo 程序硬编码为"/bin/echo",且不能在源代码中将其修改为"echo"(会导致测试失败,原因不明),另一方面echo也是bash的内置命令,所以就将它也安装在 /bin 目录下。

R=/root/coreutils-6.10/ && mkdir $R/bin/ &&
tar -xf coreutils-6.10.tar.gz && cd coreutils-6.10 &&
patch $SRC/coreutils-6.10-i18n-1.patch &&
chmod +x tests/sort/sort-mb-tests &&
sed -i '/(setuid_root_mode)/s/(installed_su)/&;/' src/Makefile.in &&
echo 'int main (void) { return 0; }' > gnulib-tests/test-getaddrinfo.c &&
sed -i 's|HOME|& /dev/shm|' tests/other-fs-tmpdir &&
sed -i 's:/bin/rmdir:rmdir:g' lib/rmdir.c &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-option-checking --disable-acl --disable-assert --disable-rpath --enable-largefile --disable-nls --enable-install-program="arch,hostname,su" --without-libiconv-prefix --without-included-regex --without-libintl-prefix &&
make && make check-root NON_ROOT_USERNAME=pgsql &&
echo "dummy::1689:pgsql" >> /etc/group && chown pgsql gnulib-tests/.deps &&
su -c'make check RUN_EXPENSIVE_TESTS=yes RUN_VERY_EXPENSIVE_TESTS=yes' -s/bin/bash pgsql &&
sed -i '/dummy/d' /etc/group &&
make install install-root            && cp   /usr/bin/{echo,false,mktemp,sync}   /bin/ &&
make install install-root DESTDIR=$R && cp $R/usr/bin/{echo,false,mktemp,sync} $R/bin/ &&
cd $SRC && rm */ &&
echo '9-coreutils' >> $SRC/build.log && sync &&

M4

[依赖提示]至少被Bison/Autoconf/Automake/Flex依赖

R=/root/m4-1.4.10/ &&
tar -xf m4-1.4.10.tar.bz2 && cd m4-1.4.10 &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-changeword --without-included-regex &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '10-m4' >> $SRC/build.log && sync &&

Bison

[依赖提示]至少被Bash依赖

R=/root/bison-2.3/ &&
tar -xf bison-2.3.tar.bz2 && cd bison-2.3 &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-gcc-warnings --enable-yacc --disable-nls --disable-rpath --without-libiconv-prefix --without-libintl-prefix &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '11-bison' >> $SRC/build.log && sync &&

Libtool

[依赖提示]至少XFS的安装依赖于它。

R=/root/libtool-1.5.26/ &&
tar -xf libtool-1.5.26.tar.gz && cd libtool-1.5.26 &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-ltdl-install --enable-shared --with-pic &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '12-libtool' >> $SRC/build.log && sync &&

Ncurses

这个包的配置选项简直多如牛毛,这里没有(也没必要)涵盖全部选项。更多安装信息请查看源码树目录下的 INSTALL 文件(所有选项皆有描述,不需要查看 configure 的内容)。Ncurses 的测试套件与大多数包不同,不能用简单的非交互式"make check"来测试,因为 Ncurses 牵涉到视觉效果,所以必须是交互式的测试,更多有关如何测试的细节,请查看源码树下的 test/README 文件。更多官方补丁请查看:http://127.0.0.5/ftp://invisible-island.net/ncurses/5.6/。[提示]--enable/disable-database都将导致编译失败,不能使用。--disable-ext-funcs --disable-tparm-varargs 将导致 Procps 无法编译。如果你不想安装terminfo数据库可以使用"--disable-database --without-terminfo-dirs",如果你不想安装实用程序可以使用"--without-progs"。可以使用"make install.libs"仅安装共享库。

R=/root/ncurses-5.6/ && mkdir $R/lib/ &&
tar -xf ncurses-5.6.tar.gz && cd ncurses-5.6 &&
bunzip2 -kf ../ncurses-5.6-20071201-patch.sh.bz2 &&
chmod +x ../ncurses-5.6-20071201-patch.sh &&
../ncurses-5.6-20071201-patch.sh    &&
./configure --prefix=/usr --sbindir=/usr/bin --without-cxx --without-cxx-binding --with-progs --without-curses-h --disable-mixed-case --without-libtool --with-shared --without-normal --without-debug --without-profile --without-termlib --without-ticlib --without-gpm --without-dlsym --without-sysmouse --disable-rpath --enable-overwrite --with-database=misc/terminfo.src --without-hashed-db --without-fallbacks --with-terminfo-dirs=/usr/share/terminfo --with-default-terminfo-dir=/usr/share/terminfo --enable-big-core --enable-big-strings --disable-termcap --without-termpath --disable-getcap --disable-getcap-cache --disable-home-terminfo --disable-root-environ --enable-symlinks --disable-broken_linker --disable-bsdpad --enable-widec --enable-lp64 --enable-largefile --enable-tparm-varargs --without-caps --with-ospeed=int --without-rcs-ids --enable-ext-funcs --enable-const --enable-no-padding --enable-signed-char --enable-sigwinch --enable-tcap-names --without-develop --disable-hard-tabs --disable-xmc-glitch --enable-assumed-color --enable-hashmap --disable-colorfgbg --disable-ext-colors --disable-ext-mouse --disable-reentrant --disable-safe-sprintf --disable-wgetch-events --enable-echo --enable-warnings --disable-assertions --without-dmalloc --without-dbmalloc --without-valgrind --enable-leaks --disable-expanded --enable-macros --without-trace &&
make install            && cp   /usr/lib/libncursesw.so.5   /lib/ &&
make install DESTDIR=$R && cp $R/usr/lib/libncursesw.so.5 $R/lib/ &&
cd $SRC && rm */ &&
echo '13-ncurses' >> $SRC/build.log && sync &&

Procps

Procps 的测试套件与 Ncurses 类似,由于牵涉到视觉效果,因此也是交互式测试,具体细节请查看 README 文件。

R=/root/procps-3.2.7/ &&
tar -xf procps-3.2.7.tar.gz && cd procps-3.2.7 &&
sed -i 's:<curses.h>:<ncurses.h>:' {dummy,top}.c &&
sed -r -i -e'/CURSES/s/-lncurses/-lncursesw/' -e's|DESTDIR\)/s?bin/|DESTDIR)/usr/bin/|' -e's|DESTDIR\)(/usr)?/\$\(lib64\)/|DESTDIR)/usr/lib/|' Makefile &&
make install CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" &&
make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '14-procps' >> $SRC/build.log && sync &&

Perl

Perl的测试很奇怪,有时候第一次运行失败,再运行一次却能成功。

R=/root/perl-5.8.8/ &&
tar -xf perl-5.8.8.tar.bz2 && cd perl-5.8.8 &&
sed -i 's/command /command[ -]/' makedepend.SH &&
./configure.gnu --prefix=/usr -Dpager="/usr/bin/less -isR" &&
make && ( make test || make test ) &&
make install && make install DESTDIR=$R &&
rm /etc/{protocols,services} &&
cd $SRC && rm */ &&
echo '15-perl' >> $SRC/build.log && sync &&

Readline

由于只需要共享库,因此只编译和安装共享库(包括头文件)。"bash_cv_func_ctype_nonascii=yes"用于修正当en_US.ISO8859-1这个locale不存在时会出现的问题,具体细节参见这里

R=/root/readline-5.2/ && mkdir $R/{etc,lib} &&
tar -xf readline-5.2.tar.gz && cd readline-5.2 &&
patch $SRC/readline-5.2-fixes-5.patch &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-multibyte --enable-shared --disable-static --with-curses --without-purify bash_cv_func_ctype_nonascii=yes &&
make shared SHLIB_LIBS=-lncursesw SHOBJ_CFLAGS="$CFLAGS -fpic" SHOBJ_LDFLAGS="$LDFLAGS -shared" &&
make install-shared            && cp   /usr/lib/lib{history,readline}.so.5   /lib/ &&
make install-shared DESTDIR=$R && cp $R/usr/lib/lib{history,readline}.so.5 $R/lib/ &&
echo 'set horizontal-scroll-mode Off
set meta-flag On
set input-meta On
set convert-meta Off
set output-meta On
set bell-style none
"\eOd": backward-word
"\eOc": forward-word
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert' | tee {,$R}/etc/inputrc &&
cd $SRC && rm */ &&
echo '16-readline' >> $SRC/build.log && sync &&

Zlib

由于只需要共享库,因此只编译和安装共享库(包括头文件)。[提示]configure脚本只传递了CFLAGS而未传递LDFLAGS,因此需要在配置完毕后(不能提前修改Makefile.in,configure会覆盖掉你的修改)再修改Makefile中的LDSHARED(作用于共享库)和LDFLAGS(作用于二进制文件)。

R=/root/zlib-1.2.3/ && mkdir $R/lib/ &&
tar -xf zlib-1.2.3.tar.bz2 && cd zlib-1.2.3 &&
sed -i 's/${CFLAGS-"-fPIC -O3"}/"${CFLAGS-"-O3"} -fPIC"/' configure &&
./configure --prefix=/usr --shared &&
sed -i -e"s|^LDSHARED=.*|& $LDFLAGS|" -e"s|^LDFLAGS=.*|& $LDFLAGS|" Makefile &&
make && make check &&
make install                && cp   /usr/lib/libz.so.1   /lib/ &&
make install prefix=$R/usr/ && cp $R/usr/lib/libz.so.1 $R/lib/ &&
cd $SRC && rm */ &&
echo '17-zlib' >> $SRC/build.log && sync &&

Flex

由于没有安装C++编译器的原因,将会有6个与C++相关的测试项目失败,不必紧张。[依赖提示]仅在安装IPRoute2的tc工具和安装Bc时需要它。

R=/root/flex-2.5.35/ &&
tar -xf flex-2.5.35.tar.bz2 && cd flex-2.5.35 &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-nls --disable-rpath --without-libiconv-prefix --without-libintl-prefix &&
make && ( make -k check | fgrep FAILED > $SRC/build_flex.log ; make install ) &&
make install prefix=$R/usr/ sbindir=$R/usr/bin &&
cd $SRC && rm */ &&
echo '18-flex' >> $SRC/build.log && sync &&

AutoconfAutomake

以root身份运行automake-1.10.1的instsh2.test测试总是会失败,所以需要使用一个sed跳过它。[提示]如果你忍受不了测试的漫长可以去掉注释。[依赖提示]至少被PHP依赖。

tar -xf autoconf-2.61.tar.bz2 && tar -xf automake-1.10.1.tar.bz2 &&
sed -i 's|#! /bin/cat|#!/usr/bin/cat|' autoconf-2.61/lib/autoconf/specific.m4 &&
# sed -i 's|$(TESTSUITE_GENERATED_AT)|$(srcdir)/acprograms.at|g' autoconf-2.61/tests/Makefile.in &&
# sed -i 's|$(TESTS)|instsh2.test|g' automake-1.10.1/tests/Makefile.in &&
sed -i '/instsh2.test/d' automake-1.10.1/tests/Makefile.in &&
cd $SRC/autoconf-2.61 && ./configure --prefix=/usr --sbindir=/usr/bin  && make && make install &&
cd $SRC/automake-1.10.1 && ./configure --prefix=/usr --sbindir=/usr/bin && make && make check && make install &&
cd $SRC/autoconf-2.61 && make check && make install DESTDIR=/root/autoconf-2.61/ &&
cd $SRC/automake-1.10.1 && make install DESTDIR=/root/automake-1.10.1/ &&
cd $SRC && rm */ &&
echo '19-autoconf-automake' >> $SRC/build.log && sync
# [ "`tail -1 $SRC/build.log`" != '19-autoconf-automake' ] && ( test -d $SRC/automake-1.10.1 ) &&
# ( cd $SRC/autoconf-2.61 ; make uninstall ; cd $SRC/automake-1.10.1 ; make uninstall ; cd $SRC ; rm */ ; cd $SRC ; sync )

Bash

Bash 的测试套件不像其他软件包那样遇到错误就停下来并返回非零的错误代码,而是始终返回表示成功的零,因此不能在脚本中根据 make tests 命令的返回状态判断测试的成败,你必须用眼睛亲自检查 make tests 的输出结果。另一方面由于 Bash 的测试套件如同 GCC 一样,错误总是不可避免的,因此如果错误不是特别多就无需太在意(可以在 http://www.linuxfromscratch.org/lfs/build-logs/ 找到参照)。更多有关安装的详细信息请查看源码树下的 INSTALL config-top.h 以及 configure --help 本身。

[ "`tail -1 $SRC/build.log`" = '19-autoconf-automake' ] &&
R=/root/bash-3.2/ && mkdir $R/{bin,etc,root,usr/bin} &&
tar -xf bash-3.2.tar.gz && cd bash-3.2 &&
patch $SRC/bash-3.2-fixes-7.patch &&
echo '#define SYS_BASHRC "/etc/bashrc"
#define SYS_BASH_LOGOUT "/etc/bash_logout"
#define NON_INTERACTIVE_LOGIN_SHELLS
#define SSH_SOURCE_BASHRC' >> config-top.h &&
sed -i 's/LANG/LC_ALL/' tests/intl.tests &&
sed -i 's|test.tests|& </dev/tty|' tests/run-test &&
sed -i -e's/-lncurses/-lncursesw/g' -e's/-lcurses/-lncursesw/g' aclocal.m4 configure support/shobj-conf &&
sed -i 's|#! /bin/cat|#!/usr/bin/cat|' configure &&
sed -r -i 's:/bin/(true|date|cat|echo):\1:g' tests/{{array,redir,rsh}.tests,varenv.sh} &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-multibyte --disable-profiling --disable-static-link --enable-largefile --disable-nls --disable-rpath --without-bash-malloc --without-gnu-malloc --with-curses --without-termcap --disable-install-termcap --with-installed-readline --without-libiconv-prefix --without-included-gettext --without-libintl-prefix &&
make && chown -R pgsql . && su -c'make tests HOME=/data' -s/bin/bash pgsql 2>&1 | tee $SRC/build_bash.log &&
cp bash   /bin/ && cp bash   /usr/bin/ &&
cp bash $R/bin/ && cp bash $R/usr/bin/ &&
touch $R/etc/profile $R/root/.bash_history &&
cd $SRC && rm */ &&
echo '20-bash' >> $SRC/build.log && sync &&
# exec /bin/bash --login +h

Bzip2

Bzip2 的两个 Makefile 文件写的相当简洁易懂,建议直接阅读以获取安装信息。

[ "`tail -1 $SRC/build.log`" = '20-bash' ] &&
R=/root/bzip2-1.0.4/ && mkdir $R/usr/bin &&
tar -xf bzip2-1.0.4.tar.gz && cd bzip2-1.0.4 &&
sed -i 's:/bin/rm:rm:g' bzdiff &&
make test CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64" LDFLAGS="$LDFLAGS" &&
cp bzip2   /usr/bin/ && ln -sf bzip2   /usr/bin/bunzip2 &&
cp bzip2 $R/usr/bin/ && ln -sf bzip2 $R/usr/bin/bunzip2 &&
cd $SRC && rm */ &&
echo '21-bzip2' >> $SRC/build.log && sync &&

Diffutils

R=/root/diffutils-2.8.1/ &&
tar -xf diffutils-2.8.1.tar.gz && cd diffutils-2.8.1 &&
patch $SRC/diffutils-2.8.1-i18n-1.patch &&
touch man/diff.1 &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-largefile --disable-rpath --disable-nls --without-included-regex --without-libiconv-prefix --without-libintl-prefix &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '22-diffutils' >> $SRC/build.log && sync &&

Findutils

[提醒] xargs 程序将 echo 程序硬编码为"/bin/echo",且不能在源代码中将其修改为"echo"(会导致测试失败,原因不明)。

R=/root/findutils-4.2.33/ &&
tar -xf findutils-4.2.33.tar.gz && cd findutils-4.2.33 &&
# sed -i 's:/bin/echo:echo:g' xargs/testsuite/xargs.sysv/{s30-t,empty_def-t}.xe xargs/xargs.c &&
./configure --prefix=/usr --sbindir=/usr/bin --localstatedir=/var/locate --disable-id-cache --disable-debug --disable-leaf-optimisation --disable-d_type-optimization --enable-largefile --disable-nls --disable-rpath --without-included-regex --without-libiconv-prefix --without-libintl-prefix &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '23-findutils' >> $SRC/build.log && sync &&

Gawk

R=/root/gawk-3.1.6/ &&
tar -xf gawk-3.1.6.tar.bz2 && cd gawk-3.1.6 &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-portals --enable-lint --enable-switch --enable-directories-fatal --enable-largefile --disable-nls --disable-rpath --without-whiny-user-strftime --without-libiconv-prefix --without-libintl-prefix &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '24-gawk' >> $SRC/build.log && sync &&

PCRE

详细的安装信息位于源码树下的 README 文件中(不需要查看 INSTALL 了),需要仔细阅读。此外,pcrebuild手册页还有更详细的说明。

R=/root/pcre-7.6/ && mkdir $R/lib/ &&
tar -xf pcre-7.6.tar.bz2 && cd pcre-7.6 &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-shared=yes --enable-static=no --disable-cpp --disable-rebuild-chartables --enable-utf8 --enable-unicode-properties --enable-newline-is-anycrlf --enable-bsr-anycrlf --disable-ebcdic --enable-stack-for-recursion --disable-pcregrep-libz --disable-pcregrep-libbz2 --disable-pcretest-libreadline --with-pic --with-posix-malloc-threshold=15 --with-link-size=2 --with-match-limit=100000 --with-match-limit-recursion=100000 &&
make && make check &&
make install            && cp   /usr/lib/libpcre.so.0   /lib/ &&
make install DESTDIR=$R && cp $R/usr/lib/libpcre.so.0 $R/lib/ &&
cd $SRC && rm */ &&
echo '25-pcre' >> $SRC/build.log && sync &&

Grep

由于grep-2.5.3的文档依赖于Texinfo,所以为了编译成功,需要用一个sed去掉doc子目录。foad1.sh 和 fmbtest.sh 测试是意料中的失败(不过我这里却能通过)。

R=/root/grep-2.5.3/ &&
tar -xf grep-2.5.3.tar.bz2 && cd grep-2.5.3 &&
patch $SRC/grep-2.5.3-debian_fixes-1.patch &&
patch $SRC/grep-2.5.3-upstream_fixes-1.patch &&
sed -i '/^SUBDIRS/s/doc//' Makefile.in &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-perl-regexp --enable-largefile --disable-nls --without-libiconv-prefix --without-included-gettext --without-included-regex --without-included-getopt &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '26-grep' >> $SRC/build.log && sync &&

Gzip

R=/root/gzip-1.3.12/ &&
tar -xf gzip-1.3.12.tar.gz && cd gzip-1.3.12 &&
sed -i 's/futimens/gl_&/' gzip.c lib/utimens.{c,h} &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-largefile &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '27-gzip' >> $SRC/build.log && sync &&

IPRoute2

这个软件包不是通过 configure 脚本而是通过直接修改 Makefile 文件进行配置的,具体细节请阅读 README 文件。[提示]由于 arpd 对这个系统没有价值而且还依赖于 Berkeley DB ,所以这里用一个 sed 去掉它。如果你不需要依赖于Flex的tc可以去掉注释。

R=/root/iproute2-2.6.24-rc7/ && mkdir $R/bin &&
tar -xf iproute2-2.6.24-rc7.tar.bz2 && cd iproute2-2.6.24-rc7 &&
sed -i -e's|^SBINDIR=.*|SBINDIR=/usr/bin|' -e's|$(KERNEL_INCLUDE)|/usr/include|' Makefile &&
# sed -i '/^SUBDIRS/s| tc | |g' Makefile &&
sed -i '/^TARGETS/s| arpd | |g' misc/Makefile &&
make CCOPTS="-D_GNU_SOURCE $CFLAGS" LDFLAGS="$LDFLAGS" &&
make install            &&
make install DESTDIR=$R &&
cd $SRC && rm */ &&
sed -i 's|/www/bin/ip|/usr/bin/ip|' /bin/tmpinit &&
echo '28-iproute2' >> $SRC/build.log && sync &&

Make

[提示]不能明确指定 --enable/disable-case-insensitive-file-system ,否则无法编译成功。

R=/root/make-3.81/ &&
tar -xf make-3.81.tar.bz2 && cd make-3.81 &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-nls --disable-rpath --enable-largefile --enable-job-server --without-libiconv-prefix --without-libintl-prefix &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '29-make' >> $SRC/build.log && sync &&

Patch

R=/root/patch-2.5.4/ &&
tar -xf patch-2.5.4.tar.gz && cd patch-2.5.4 &&
sed -r -i 's:/bin/(mkdir|rmdir):\1:g' {mkdir,rmdir}.c &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-largefile &&
make && make install &&
make install prefix=$R/usr/ sbindir=$R/usr/bin/ &&
cd $SRC && rm */ &&
echo '30-patch' >> $SRC/build.log && sync &&

Psmisc

因为 Psmisc 默认的 configure 依赖于C++编译器,而实际上编译过程并不需要C++编译器,所以这里要重新生成一个不依赖于C++编译器的 configure 。

R=/root/psmisc-22.6/ &&
tar -xf psmisc-22.6.tar.gz && cd psmisc-22.6 &&
sed -i 's:<curses.h>:<ncurses.h>:' src/pstree.c &&
sed -i -e's/ncurses/ncursesw/g' -e'/AC_PROG_CXX/d' configure.ac &&
autoconf --force &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-selinux --disable-ipv6 --disable-nls --disable-rpath --enable-largefile --without-libiconv-prefix --without-libintl-prefix &&
make &&
make install            && ln -sf killall   /usr/bin/pidof &&
make install DESTDIR=$R && ln -sf killall $R/usr/bin/pidof &&
cd $SRC && rm */ &&
echo '31-psmisc' >> $SRC/build.log && sync &&

Tar

R=/root/tar-1.19/ &&
tar -xf tar-1.19.tar.bz2 && cd tar-1.19 &&
sed -i 's:/bin/rmdir:rmdir:g' lib/rmdir.c &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-largefile --disable-rpath --disable-nls --disable-backup-scripts --without-included-regex --without-libiconv-prefix --without-libintl-prefix &&
make && make check &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '32-tar' >> $SRC/build.log && sync &&

Util-linux-ng

SUID_CFLAGS 和 SUID_LDFLAGS 用于定义几个带有 suid 位的程序(chfn, chsh, newgrp, write, mount, umount)的编译选项,出于安全考虑,这里使用了"-fpie"和"-pie"编译选项。这个包硬编码了"/bin/{login,umount}"路径,由于这个硬编码还算合理,因此未作改动,如果你要改动的话,请查看源码树下的 include/pathnames.h 文件。由于本文将使用此包中的 simpleinit 而不是 Sysvinit 中的 init ,因此 /etc/inittab 的语法有所不同。simpleinit 不但比 init 的配置简洁,而且没有所谓"运行级"的概念。更多细节可以查看simpleinit的手册页。这个包的测试程序不是通过"make check"执行的,而是通过tests子目录中的run.sh脚本执行的,不过这里的测试程序仅供开发者使用,切勿用于生产系统!具体细节请看 tests/README 文件。

R=/root/util-linux-ng-2.13.1/ && mkdir {,$R}/{bin,etc/init.d} &&
tar -xf util-linux-ng-2.13.1.tar.bz2 && cd util-linux-ng-2.13.1 &&
sed -i 's:/sbin:/bin:g' include/pathnames.h disk-utils/mkfs.c mount/{,u}mount.c login-utils/shutdown.c tests/{,expected}/ts-mount-special &&
sed -i 's:-lncurses:-lncursesw:g' {fdisk,misc-utils,text-utils}/Makefile.{in,am} &&
SUID_CFLAGS="$CFLAGS -fpie" SUID_LDFLAGS="$LDFLAGS -pie"  \
./configure --prefix=/usr --bindir=/usr/bin --sbindir=/usr/bin --enable-largefile --disable-nls --disable-rpath --disable-arch --enable-agetty --disable-cramfs --disable-elvtune --enable-init --disable-kill --enable-last --enable-mesg --disable-partx --disable-raw --enable-rdev --enable-rename --disable-reset --enable-login-utils --enable-schedutils --enable-wall --enable-write --enable-chsh-only-listed --disable-login-chown-vcs --disable-login-stat-mail --enable-pg-bell --enable-require-password --disable-use-tty-group --disable-makeinstall-chown --with-fsprobe=blkid --without-libiconv-prefix --without-libintl-prefix --without-slang --without-pam --without-selinux --without-audit &&
make install usrsbinexecdir=/usr/bin && make install DESTDIR=$R usrsbinexecdir=/usr/bin &&
mv   /usr/bin/{simpleinit,agetty,login,mount,umount,initctl,shutdown}   /bin/ &&
mv $R/usr/bin/{simpleinit,agetty,login,mount,umount,initctl,shutdown} $R/bin/ &&
echo 'bootprog=/etc/init.d/rc
INIT_PATH=/etc/init.d/
tty1:linux:/bin/agetty -iL -l/bin/login tty1 9600
tty2:linux:/bin/agetty -iL -l/bin/login tty2 9600
tty3:linux:/bin/agetty -iL -l/bin/login tty3 9600' | tee {,$R}/etc/inittab &&
echo '#!/bin/bash
/bin/shutdown -r -q now' | tee {,$R}/bin/reboot &&
touch {,$R}/etc/{nologin,securesingle,init.d/rc} &&
chmod +x {,$R}/bin/reboot {,$R}/etc/init.d/rc &&
cd $SRC && rm */ &&
sed -i 's|:/www/bin||' /etc/profile &&
export PATH=/bin:/usr/bin &&
echo '33-util-linux' >> $SRC/build.log && sync &&

Linux-Kernel

为了尽可能简单,这个内核不支持initrd也不带任何动态加载模块,甚至禁用了模块加载功能。内核的编译优化参数是直接通过 CC 和 LD 传递的(而不是通常的 CFLAGS 和 LDFLAGS)。建议在修改默认值之前先用 make -qp | egrep '^(CC|LD|CFLAGS|LDFLAGS)' 查看一下默认值[在本文情况下的默认值是:CC='gcc -m32' LD='ld -m elf_i386']。[提示]在 LD 中使用"-s"会导致编译失败;"V=1"将显示详细的命令。此外,由于本文作者觉得默认的"-mtune"不过瘾,所以还修改了 Makefile*.cpu 文件的内容。更多有关内核编译的信息可以参考内核源码树下 Documentation/kbuild 目录中的内容;此外,《Linux Kernel in a Nutshell》也是一本不可多得的好书。[补充说明]patch-o-matic-ng是用于扩展内核Netfilter功能的模块,可以创建更强大的防火墙规则。最新的patch-o-matic-ng可以在这里下载,如果你需要可以打上这个补丁,详细说明请阅读源码树下的 README 文件。

R=/root/linux-2.6.24.2/ && mkdir $R/boot &&
tar -xf linux-2.6.24.2.tar.bz2 && cd linux-2.6.24.2 &&
make distclean &&
cp $SRC/linux-2.6.24-config.txt .config &&
make silentoldconfig ARCH=x86 &&
echo 'cflags-y += -march=athlon-xp' | tee arch/x86/Makefile*.cpu &&
make ARCH=x86 V=0 CC="gcc -m32 $CFLAGS" LD="ld -m elf_i386 $kLDFLAGS" &&
cp arch/x86/boot/bzImage   /boot/ &&
cp arch/x86/boot/bzImage $R/boot/ &&
cd $SRC && rm */ &&
echo '34-linux' >> $SRC/build.log && sync &&

Sysklogd

如果你需要使用 klogd 的延时启动功能,可以去掉注释。由于本文不将内核消息转发到 syslogd ,而是由 klogd 直接记录到日志,因此无需延时启动。将"/dev/log"修改为"/dev/shm/log"是因为将来的根文件系统是只读挂载的,而syslogd会在启动的时候删除并重建此socket。

R=/root/sysklogd-1.5/ && mkdir $R/{etc,bin,/var/log} &&
tar -xf sysklogd-1.5.tar.gz && cd sysklogd-1.5 &&
# sed -i '/DKLOGD_DELAY/s/^#//' Makefile &&
sed -i 's|/dev/log|/dev/shm/log|' syslog*.c &&
make RPM_OPT_FLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" LDFLAGS="$LDFLAGS" &&
make install_exec BINDIR=/bin &&
make install_exec BINDIR=$R/bin &&
echo 'syslog.info   -/var/log/syslog.log
auth,authpriv.info  -/var/log/auth.log
*.info;auth,authpriv,syslog.none    -/var/log/local.log
*.alert root' | tee {,$R}/etc/syslog.conf &&
touch {,$R}/var/log/{syslog,auth,local,kernel}.log &&
cd $SRC && rm */ &&
echo '35-sysklogd' >> $SRC/build.log && sync &&

Dcron

Dillon's Cron 是一种简单、严谨、安全的 cron 实现。此软件包非常简单,可以直接修改 Makefile 和 defs.h 对其进行定制。[注意]Dcron并不使用Sysklogd记录日志,一般的方法是直接将命令的结果重定向到日志文件。

R=/root/dcron32/ && mkdir $R/bin/ {,$R}/etc/crontabs $R/var/log &&
tar -xf dcron32.tgz && cd dcron &&
sed -i -e's|/var/spool/cron/crontabs|/etc/crontabs|' -e's|/etc/cron.d|/share/empty|' defs.h &&
make CFLAGS="$CFLAGS $LDFLAGS" &&
install -o 0 -g 0 -m 0500 crond   /bin/crond   &&
install -o 0 -g 0 -m 0500 crond $R/bin/crond   &&
touch {,$R}/etc/crontabs/root {,$R}/var/log/crond-std{out,err}.log &&
cd $SRC && rm */ &&
echo '36-dcron' >> $SRC/build.log && sync &&

XFS

这个包并不是典型的"configure && make && make install"风格的软件包,但是这里用一个 sed 来达到模仿的目的,但是仍然要注意的是 configure 的目的不是为了生成 Makefile 文件,而是为了生成 include/{builddefs,platform_defs.h} 文件。要了解更多安装信息,请仔细阅读源码树下的 Makefile include/builddefs.in doc/INSTALL 文件。内核源码树下的 Documentation/filesystems/xfs.txt 文件包含了 XFS 可以使用的挂载选项。[提示]"--enable-shared=yes"会导致 libxfs.so,libxlog.so 库丢失,不知何故。

R=/root/xfsprogs_2.9.6-1/ && mkdir $R/bin/ &&
tar -xf xfsprogs_2.9.6-1.tar.gz && cd xfsprogs-2.9.6 &&
sed -i '/autoconf$/,/LOCAL_CONFIGURE_OPTIONS$/d' Makefile &&
sed -i 's:/bin/true:true:g' configure aclocal.m4 m4/package_utilies.m4 &&
sed -i -e's|^DEBUG =.*|DEBUG=-DNDEBUG|' -e's|^OPTIMIZER =.*|OPTIMIZER=@CFLAGS@|' include/builddefs.in &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-shared=no --enable-gettext=no --enable-readline=yes --enable-editline=no --enable-termcap=no --enable-lib64=no &&
make install && make install prefix=$R/usr PKG_SBIN_DIR=$R/usr/bin &&
mv   /usr/bin/xfs_repair   /bin/ &&
mv $R/usr/bin/xfs_repair $R/bin/ &&
cd $SRC && rm */ &&
echo '37-xfsprogs' >> $SRC/build.log && sync &&

Iptables

建议编译前好好读一读 Makefile 文件,然后按你的需求进行修改[这里编译的是静态版本]。当然,还有 INSTALL 也不要忘记了。此外,如果你升级了内核,那么最好把这个包重新编译一次。由于配置Iptables是一个见仁见智的工作,需要根据实际情况灵活变通,因此本文只示范其安装,而没有涉及其配置。

R=/root/iptables-1.4.0/ && mkdir $R/bin &&
tar -xf iptables-1.4.0.tar.bz2 && tar -xf linux-2.6.24.2.tar.bz2 && cd iptables-1.4.0 &&
sed -i -e'/NO_SHARED_LIBS/s/^#//' -e'/DO_IPV6/s/^#//' -e's|^KERNEL_DIR=.*|KERNEL_DIR=/usr|' -e's|^PREFIX:=.*|PREFIX=/usr|' -e's|^LIBDIR:=.*|LIBDIR=/usr/lib|' -e's|^BINDIR:=.*|BINDIR=/usr/bin|' -e's|^DO_IPV6:=.*|DO_IPV6=0|' Makefile &&
make COPT_FLAGS="$CFLAGS" LDFLAGS="$LDFLAGS -static" KERNEL_DIR=$SRC/linux-2.6.24.2 &&
make install            &&
make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '38-iptables' >> $SRC/build.log && sync &&

Bc

如果你不打算运行 OpenSSL 的测试套件就可以不安装它(不建议这么做)。BC的测试程序在遇见错误的时候也不会返回非零的结果,因此这里将测试输出记录在一个文件中。大约有10个左右的测试项目会在最末尾一位出现舍入误差,这是正常的,无需在意。

R=/root/bc-1.06/ &&
tar -xf bc-1.06.tar.gz && cd bc-1.06 &&
sed -i 's/flex -I8/flex -I/' configure &&
sed -i '/_PROTOTYPE.*readline/d' bc/scan.l &&
sed -i 's/program_counter save_adr;/static &/' bc/load.c &&
sed -i '/<stdlib.h>/a #include <string.h>' lib/number.c &&
./configure --prefix=/usr --sbindir=/usr/bin --with-readline --without-editline --without-libedit --without-pkg &&
make && echo quit | ./bc/bc -l Test/checklib.b | tee $SRC/build_bc.log &&
make install && make install DESTDIR=$R &&
cd $SRC && rm */ &&
echo '39-bc' >> $SRC/build.log && sync &&

OpenSSL

config 脚本检查系统环境并调用 Configure 完成配置,因此配置选项是通过 config 脚本向 Configure 传递的。事实上 config 脚本的作用相当于 config.guess ,所以如果你想直接调用 Configure 的话就一定要正确指定"操作系统-目标平台"(本文就是这么干的),所有可用的目标机器列表可以使用"./Configure LIST"命令获取。Configure 脚本除了根据 Makefile.org 生成 Makefile 之外,还在 crypto/opensslconf.h 中定义了许多宏(基于 crypto/opensslconf.h.in)。详细的安装信息位于源码树下的 INSTALL Configure(特别是"PROCESS_ARGS"段) Makefile.shared Makefile.org 文件中。安装后的使用与配置信息位于 doc 目录中, FAQ 文件也可以提供一些参考。

Configure第一行是全局性选项,比如:如果你的CPU是P4/K8以上,那么就可以使用"enable-sse2"。所有可用的"[no-]***"全局选项如下:zlib,zlib-dynamic,threads,shared,asm,sse2,hw,gmp,rfc3779,krb5,ssl(ssl2,ssl3),tls,dso。no-dso仅在no-shared的前提下可用。[提示]为了安装Apache的mod_ssl成功,SSLv2/SSLv3/TLS都必须开启。[TODO]测试"asm,no-asm"的速度差异。

Configure第二行的"no-***"用于禁用crypto目录下相应的子目录,为了保证能够最小安装libcrypto,libssl,openssl,其中的大部分目录都必须保留,实际可选的目录仅有如下这些:md2,md4,mdc2,ripemd,des,rc2,rc4,rc5,idea,bf,cast,camellia,ec,dsa,ecdsa,dh,ecdh,comp,store。如果你禁用了其中的某些子目录,那么在编译前必须执行make depend步骤。[提示]为了安装OpenSSH成功,ripemd,des,rc4,bf,cast,dsa,dh目录不能被禁止。

Configure第三行相当于CPPFLAGS+CFLAGS的内容(DEVRANDOM指定随机设备,SSL_FORBID_ENULL则禁止使用NULL加密算法)。由于无法通过Configure设置LDFLAGS,并且Configure会强制清空Makefile中的LDFLAGS,所以在运行完Configure之后,使用一个sed修改所有Makefile中的LDFLAGS(用于连接openssl)和SHARED_LDFLAGS(用于连接libcrypto,libssl库)。[提示]不能省略find命令内"Makefile*"两边的引号。

OpenSSH 只依赖于该软件包的加密库(libcrypto),而带有 HTTPS 支持的 Apache 则依赖于该软件包的加密库和 SSL/TLS 库(libssl)。因此,如果你不打算使用 HTTPS 的话,可以只安装加密库(no-ssl no-tls);更多介绍可以查看 README 文件的"OVERVIEW"部分。由于本文将安装一个支持 HTTPS 的 Apache 服务器,所以这两部分库都安装了。

依赖于OpenSSL的包都对OpenSSL的版本很敏感,所以即使将来只把OpenSSL进行了很小的版本升级,也建议你将所有依赖于OpenSSL的包重新编译一遍。

R=/root/openssl-0.9.8g/ && mkdir $R/{lib,root} &&
tar -xf openssl-0.9.8g.tar.gz && cd openssl-0.9.8g &&
sed -r -i 's:/bin/(cat|cp|mkdir|mv|rm):\1:g' crypto/threads/*.sh demos/ssltest-ecc/*.sh test/* util/*.sh util/pl/*.pl &&
./Configure  linux-elf  --prefix=/usr --openssldir=/etc no-zlib no-zlib-dynamic no-threads shared no-asm no-sse2 no-hw no-gmp no-rfc3779 no-krb5  \
no-md2 no-md4 no-mdc2  no-rc2 no-rc5 no-idea no-camellia  no-ec no-ecdsa no-ecdh  no-store  \
-DSSL_FORBID_ENULL -DDEVRANDOM='"/dev/urandom"' `echo $CFLAGS` &&
find . -name "Makefile*" -exec sed -r -i -e"s|^(SHARED_)?LDFLAGS=|& $LDFLAGS |" {} \; &&
make depend && make && make test &&
make install_sw && make install_sw INSTALL_PREFIX=$R &&
rm ~/.rnd {,$R}/etc/misc/ &&
cp $SRC/openssl.cnf   /etc/ && cp   /usr/lib/lib{crypto,ssl}.so.0.9.8   /lib/ &&
cp $SRC/openssl.cnf $R/etc/ && cp $R/usr/lib/lib{crypto,ssl}.so.0.9.8 $R/lib/ &&
cd $SRC && rm */ &&
echo '40-openssl' >> $SRC/build.log && sync &&

OpenSSH

详细的安装信息可以从 configure INSTALL README.privsep 文件中获取,测试相关的信息可以从 regress/README.regress 文件中获取。TEST_SSH_QUIET=yes表示抑制测试成功的输出信息(仅输出失败信息),将TEST_SSH_TRACE设为"yes"可以输出详细且罗嗦的测试信息。TEST_SSH_PORT将用于测试的TCP监听端口改为非22以避免可能的端口冲突。如果 $PATH 中不包含"scp",那么 multiplex scp 测试将会失败,因此这里在测试前先建立一个符号链接。[提示]测试套件要求 /bin 目录下至少有两个"l"打头的文件,否则 sftp-badcmds 等测试会失败,诡异的要求!

R=/root/openssh-4.7p1/ && mkdir {,$R}/share/empty $R/bin $R/var/log &&
tar -xf openssh-4.7p1.tar.gz && cd openssh-4.7p1 &&
sed -i 's:/bin/ls:/usr/bin/ls:g' regress/*.sh &&
sed -i 's:/bin/passwd:passwd:g' openbsd-compat/bsd-cray.c &&
sed -i 's:/bin/false:false:g' configure{.ac,} &&
chown 0:0 /share/empty && chmod 1000 /share/empty &&
./configure --prefix=/usr --sysconfdir=/etc/ssh --sbindir=/usr/bin --enable-largefile --disable-etc-default-login --disable-lastlog --disable-utmp --disable-utmpx --disable-wtmp --disable-wtmpx --enable-libutil --disable-pututline --disable-pututxline --without-rpath --without-Werror --without-solaris-contracts --without-osfsia --with-zlib=/lib --with-zlib-version-check --without-skey --without-tcp-wrappers --without-libedit --without-audit --with-ssl-dir=/lib --with-openssl-header-check --without-ssl-engine --without-pam --with-random=/dev/urandom --without-rand-helper --without-prngd-port --without-prngd-socket --with-entropy-timeout=5000 --with-privsep-user=sshd --with-privsep-path=/share/empty --without-sectok --without-opensc --without-selinux --without-kerberos5 --without-xauth --with-mantype=man --with-md5-passwords --without-shadow --with-ipaddr-display --with-default-path=/bin:/usr/bin --with-superuser-path=/bin:/usr/bin:/sbin:/usr/sbin --without-4in6 --without-bsd-auth --with-pid-dir=/var/run --without-lastlog &&
make && ln -sf `pwd`/scp /usr/bin/ && touch /bin/ldummy{tjhftgs,zdeufsd} &&
make tests TEST_SSH_QUIET=yes TEST_SSH_PORT=967 &&
rm /usr/bin/scp /bin/ldummy{tjhftgs,zdeufsd} &&
make install && make install DESTDIR=$R &&
rm ~/.ssh {,$R}/etc/ssh/ssh* &&
ssh-keygen -b 4096 -t rsa -N "" -f /etc/ssh/ssh_host_rsa_key &&
chmod 000 /etc/ssh/ssh_host_rsa_key && cp /etc/ssh/ssh_host_rsa_key* $R/etc/ssh/ &&
cp $SRC/sshd_config   /etc/ssh/ && mv   /usr/{libexec/sftp-server,bin/sshd}   /bin/ &&
cp $SRC/sshd_config $R/etc/ssh/ && mv $R/usr/{libexec/sftp-server,bin/sshd} $R/bin/ &&
touch {,$R}/var/log/sshd.log &&
cd $SRC && rm */ &&
echo '41-openssh' >> $SRC/build.log && sync &&

PostgreSQL

configure脚本的主要任务是生成 src/Makefile.global 文件,阅读它可以得到不少信息。更多安装信息可以查看《PostgreSQL 8.2.3 中文手册》,这里就不多罗嗦了。此外,本文还安装了非常有用的加密模块。要了解如何添加模块,可以阅读 contrib/README 来选择你想要的模块,然后进入相应的子目录阅读 README 文件。此外,contrib/start-scripts 目录下有非常棒的启动脚本示范。由于对咱中国人来说,只需要utf8与gbk的编码转换即可,为了"减负",这里删除了许多在initdb时默认创建的转换规则,仅保留了utf8与gbk之间的转换规则。此外,加载库的搜索路径也被调整了。[TODO]测试-fprefetch-loop-arrays的效果。

R=/root/postgresql-8.3.0/ && mkdir $R/dev/shm/pg_socket {,$R}/{bin,{etc,lib,var/log}/postgresql} {,$R}/share/postgresql/{timezone,timezonesets} &&
tar -xf postgresql-8.3.0.tar.bz2 && cd postgresql-8.3.0 &&
sed -i 's:/bin/pwd:pwd:g' configure{.in,} &&
LDFLAGS_SL="$LDFLAGS" \
./configure --prefix=/usr --sbindir=/usr/bin --enable-integer-datetimes --disable-nls --enable-shared --disable-rpath --enable-spinlocks --disable-debug --disable-profiling --disable-dtrace --disable-cassert --disable-thread-safety --disable-thread-safety-force --enable-largefile --without-docdir --with-pgport=5432 --without-tcl --without-perl --without-python --without-gssapi --without-krb5 --without-pam --without-ldap --without-bonjour --without-openssl --with-readline --without-ossp-uuid --without-libxml --without-libxslt --with-zlib &&
make && chown -R pgsql . && su -c'make check' -s/bin/bash pgsql &&
make install && make install DESTDIR=$R &&
sed -i -e'/gbk/!d' -e's|$libdir/utf8_and_gbk|utf8_and_gbk.so|' {,$R}/usr/share/postgresql/conversion_create.sql &&
make distclean &&
LDFLAGS_SL="$LDFLAGS" \
./configure --prefix=/usr --sbindir=/usr/bin --enable-integer-datetimes --disable-nls --enable-shared --disable-rpath --enable-spinlocks --disable-debug --disable-profiling --disable-dtrace --disable-cassert --disable-thread-safety --disable-thread-safety-force --enable-largefile --without-docdir --with-pgport=5432 --without-tcl --without-perl --without-python --without-gssapi --without-krb5 --without-pam --without-ldap --without-bonjour --with-openssl --without-readline --without-ossp-uuid --without-libxml --without-libxslt --without-zlib &&
cd contrib/pgcrypto && make && make install && make install DESTDIR=$R && cd ../../ &&
sed -i 's|$libdir/pgcrypto|pgcrypto.so|' {,$R}/usr/share/postgresql/contrib/pgcrypto.sql &&
cp   /usr/bin/postgres   /bin/ && cp   /usr/lib/libpq.so.5   /lib/ && cp   /usr/lib/postgresql/{utf8_and_gbk,pgcrypto}.so   /lib/postgresql/ &&
cp $R/usr/bin/postgres $R/bin/ && cp $R/usr/lib/libpq.so.5 $R/lib/ && cp $R/usr/lib/postgresql/{utf8_and_gbk,pgcrypto}.so $R/lib/postgresql/ &&
cp   /usr/share/postgresql/timezone/UTC   /share/postgresql/timezone/ && echo 'UTC 0' >   /share/postgresql/timezonesets/Default &&
cp $R/usr/share/postgresql/timezone/UTC $R/share/postgresql/timezone/ && echo 'UTC 0' > $R/share/postgresql/timezonesets/Default &&
mkdir -m 700 /data/tmp && chown pgsql /data/tmp && sync &&
su -c'initdb -Atrust -D/data/tmp -EUTF-8 --locale=C -Upgsql &&
pg_ctl start -p/bin/postgres -w -D/data/tmp &&
make -C contrib/pgcrypto installcheck &&
pg_ctl stop -D/data/tmp -msmart' -s/bin/bash pgsql &&
cp $SRC/postgresql.conf   /etc/postgresql/ &&
cp $SRC/postgresql.conf $R/etc/postgresql/ &&
echo '' | tee {,$R}/etc/postgresql/pg_ident.conf &&
echo 'local all all md5
hostnossl all all 127.0.0.1/32 md5' | tee {,$R}/etc/postgresql/pg_hba.conf &&
cd $SRC && rm */ &&
echo '42-postgresql' >> $SRC/build.log && sync &&

Apache

详细的安装信息可以查看《Apache 2.2 中文手册》,这里就不详细解说了。[提示]--without-libtool 会导致apr编译失败;--disable-ipv6 会导致httpd和其他二进制程序编译失败。--without-ldap --without-dbm 会导致apr-util配置失败。

APR的configure脚本在--disable/enable-profile的时候都在CFLAGS中添加"-pg"(这应当是一个bug),而如果不明确指定则添加"-g",由于"-fomit-frame-pointer"与"-pg"是冲突的,所以在CFLAGS中含有-fomit-frame-pointer的情况下使用--disable-profile会导致apr配置和编译失败。为了可以使用"-fomit-frame-pointer",这里用一个sed来确保不向CFLAGS中(实际上是不向EXTRA_CFLAGS中)添加"-pg",另外,由于看"-g"也不顺眼,顺手也去掉它。

R=/root/httpd-2.2.8/ && mkdir {,$R}/{bin,lib,var/log/apache} &&
tar -xf httpd-2.2.8.tar.bz2 && cd httpd-2.2.8 &&
patch $SRC/httpd-2.2.8-layout.patch &&
sed -i 's|temp_create_method=.*|temp_create_method=mktemp|' support/check_forensic &&
sed -i -e's|"-pg"||g' -e's|"-g"||g' srclib/apr/configure &&
cd srclib/apr &&
./configure --enable-layout=apr --enable-shared --disable-static --enable-nonportable-atomics --disable-threads --with-pic --with-sendfile --with-devrandom=/dev/urandom  &&
make && make install && make install DESTDIR=$R &&
cd ../apr-util &&
./configure --enable-layout=apr-util --with-apr=/usr --enable-shared --disable-static --with-pic --without-pgsql --without-mysql --with-expat=builtin &&
make && make install && make install DESTDIR=$R &&
cd $SRC/httpd-2.2.8 &&
./configure --enable-layout=LAPP --with-apr=/usr --with-apr-util=/usr --with-mpm=prefork \
--enable-modules="auth-digest authn-default authn-file authz-default authz-user authz-host deflate dir env setenvif expires log-config mime status rewrite so" --enable-mods-shared="info ssl" --disable-actions --disable-alias --disable-asis --disable-auth-basic --disable-authz-groupfile --disable-autoindex --disable-cgi --disable-cgid --disable-filter --disable-imagemap --disable-include --disable-isapi --disable-negotiation --disable-userdir  \
--disable-v4-mapped --with-ssl=/lib --with-z=/lib --with-perl=/usr --with-pcre=/usr --disable-static-support --disable-suexec  &&
make && make install && make install DESTDIR=$R &&
rm {,$R}/etc/apache/* {,$R}/usr/lib/{,apache}/*.exp {,$R}/www/{build*,cgi*,error,htdocs,icons,manual} &&
cp $SRC/{authn.md5,httpd.conf,mime.types}   /etc/apache/ && mv   /usr/lib/apache/   /lib/ &&
cp $SRC/{authn.md5,httpd.conf,mime.types} $R/etc/apache/ && mv $R/usr/lib/apache/ $R/lib/ &&
cp   /usr/bin/{httpd,rotatelogs}   /bin/ && cp   /usr/lib/lib{apr-1,aprutil-1,expat}.so.0   /lib/ &&
cp $R/usr/bin/{httpd,rotatelogs} $R/bin/ && cp $R/usr/lib/lib{apr-1,aprutil-1,expat}.so.0 $R/lib/ &&
cd $SRC && rm */ &&
echo '43-httpd' >> $SRC/build.log && sync &&

JPEG + PNG

R=/root/jpeg-png/ && mkdir $R/{lib,usr/{lib,include}} &&
tar -xf jpegsrc.v6b.tar.gz && tar -xf libpng-1.2.25.tar.bz2 &&
cd $SRC/jpeg-6b &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-static --enable-shared --enable-maxmem=4 &&
make && make test &&
make install-lib && make install-lib prefix=$R/usr sbindir=$R/usr/bin &&
cp   /usr/lib/libjpeg.so.62   /lib/ &&
cp $R/usr/lib/libjpeg.so.62 $R/lib/ &&
cd $SRC/libpng-1.2.25 && sync &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-static --enable-shared --with-pic --without-binconfigs --without-libpng-compat &&
make && make check &&
make install            && cp   /usr/lib/libpng12.so.0   /lib/ &&
make install DESTDIR=$R && cp $R/usr/lib/libpng12.so.0 $R/lib/ &&
rm {,$R}/usr/bin/libpng-config &&
cd $SRC && rm */ &&
echo '44-jpeg-png' >> $SRC/build.log && sync &&

PHP[含APC模块]

PHP的安装比较复杂,好在官方文档提供了详尽的安装指导,请到http://www.php.net/manual/zh/查看。这里安装的PHP除了核心模块(date,standard)之外,还包括下列PECL扩展:PCRE Session APC GD mbstring PostgresSQL 。PHP的测试程序不像其他软件包那样遇到错误就停下来并返回非零的错误代码,而是始终返回表示成功的零,因此不能在脚本中根据 make test 命令的返回状态判断测试的成败,你必须用眼睛亲自检查输出结果。[提示]只有使用了--enable-cli选项后才能运行测试程序。[TODO]测试"-minline-all-stringops"的效果。

R=/root/php-5.2.5/ && mkdir $R/{etc,lib/apache,var/log} {,$R}/dev/shm/php_session {,$R}/www/upload  &&
tar -xf php-5.2.5.tar.bz2 && tar -xf APC-3.0.16.tgz &&
cd php-5.2.5 && mv ../APC-3.0.16 ext/apc &&
rm configure && ./buildconf --force &&
sed -i 's:/bin/ls:ls:g' build/shtool &&
sed -i 's:/bin/cat:/usr/bin/cat:g' ext/mbstring/tests/mb_send_mail*.phpt ext/standard/tests/general_functions/{bug34794,proc_open}.phpt &&
sed -i -e's:/bin/sleep:/usr/bin/sleep:g' -e's:string(28):string(32):' -e's:string(14):string(18):' ext/standard/tests/general_functions/{bug39322,proc_open02}.phpt &&
./configure --prefix=/usr --sbindir=/usr/bin --with-layout=GNU --with-apxs2=/usr/bin/apxs --enable-cli --disable-cgi --disable-mod-charset --without-pear  \
--disable-debug --disable-rpath --disable-libgcc --disable-ipv6 --enable-fd-setsize=4096 --disable-versioning --with-config-file-path=/etc  \
--enable-shared --disable-static --with-pic --with-tsrm-pthreads --enable-memory-limit --enable-zend-multibyte --disable-all --disable-reflection  \
--with-gd --with-jpeg-dir=/usr --with-png-dir=/usr --with-zlib-dir=/usr --enable-gd-native-ttf --disable-gd-jis-conv  \
--enable-mbstring --enable-mbregex --enable-mbregex-backtrack  --with-pcre-regex=/usr  --with-pgsql=/usr  --enable-session  \
--enable-apc --enable-apc-filehits --disable-apc-mmap --enable-apc-futex   &&
make && echo n | make test | tee $SRC/build_php.log &&
cp libs/libphp5.so   /lib/apache/ && cp $SRC/php.ini   /etc/ &&
cp libs/libphp5.so $R/lib/apache/ && cp $SRC/php.ini $R/etc/ &&
touch {,$R}/var/log/php_error.log &&
cd $SRC && rm */ &&
echo '45-php' >> $SRC/build.log && sync &&

现在所有软件包都已经安装完毕,距离完成最终系统只剩一步之遥了。可以通过查看 $SRC/build*.log 来了解前面的编译过程是否顺利。如果没有严重错误,那么就可以继续下面的操作。

Kbd[暂时不需要进行键盘设置,通过SSH一样可以在命令行上使用UTF-8中文]

由于官方的包好久都没有人维护了,因此这里使用非官方的 legion 版本。

R=/root/kbd-1.13/ && mkdir $R/bin &&
tar -xf kbd-1.13.tar.bz2 && cd kbd-1.13 &&
sed -i '/LOADKEYS_BINDIR/s|$(DESTDIR)/bin|$(DESTDIR)$(PREFIX)/bin|' src/Makefile.in &&
./configure --prefix=/usr --datadir=/usr/share/kbd --mandir=/usr/share/man --disable-nls &&
make RPM_OPT_FLAGS="$CFLAGS" LDFLAGS="$LDFLAGS" &&
make install            && mv   /usr/bin/unicode_start   /bin/ &&
make install DESTDIR=$R && mv $R/usr/bin/unicode_start $R/bin/ &&
cd $SRC && rm */ &&
echo '??-kbd' >> $SRC/build.log && sync &&

(尚未调试好)Memcached[含libevent]

Memcached是一个基于内存的高性能对象缓存系统。常用于加速动态web应用(本文的PHP将配置为使用它来存储会话数据)。libevent是一个执行事件通知的库,Memcache依赖于它。[提示]内核必须支持事件轮循的系统调用(CONFIG_EPOLL=y),否则该库的运行效率将大大降低。[说明]无论测试成功与否,libevent的测试程序总是返回表示成功的"0",所以这里记录下测试输出(regress: FAILED 是正常的)。memcached的测试程序总是无法启动,原因不明,所以这里跳过测试步骤。

R=/root/libevent-1.4.2-rc/ && mkdir $R/lib &&
tar -xf libevent-1.4.2-rc.tar.gz && cd libevent-1.4.2-rc &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-shared --disable-static --with-pic &&
make && make verify > $SRC/build_libevent.log &&
make install            && cp   /usr/lib/libevent-1.4.so.2   /lib/ &&
make install DESTDIR=$R && cp $R/usr/lib/libevent-1.4.so.2 $R/lib/ &&
cd $SRC && rm */ &&
R=/root/memcached-1.2.4/ && mkdir $R/bin $R/dev/shm &&
tar -xf memcached-1.2.4.tar.gz && cd memcached-1.2.4 &&
./configure --prefix=/usr --sbindir=/usr/bin --disable-threads --with-libevent=/usr &&
make && # make test &&
cp memcached   /bin/ &&
cp memcached $R/bin/ &&
touch {,$R}/dev/shm/memcached.sock &&
cd $SRC && rm */ &&
echo '??-memcached[libevent]' >> $SRC/build.log && sync &&

FreeType2 + 中文字库[尚未调试好,且与本文主题关系不大,故而暂时取消它]

除了查看 builds/unix/configure 之外,对包的定制还需要通过修改 modules.cfg 和 include/freetype/config/ftoption.h 文件来完成的,详细的信息可以阅读 doc/CUSTOMIZE 文件。[说明]考虑到效率问题,这里的字体都是来自文泉驿的点阵字体。

R=/root/freetype-2.3.5/ && mkdir /share/fonts $R/{lib,share} &&
tar -xf freetype-2.3.5.tar.bz2 && cd freetype-2.3.5 &&
rm objs/* include/freetype/config/ftmodule.h &&
echo 'FONT_MODULES = pcf
HINTING_MODULES =
RASTER_MODULES =
AUX_MODULES = cache
BASE_EXTENSIONS =' > modules.cfg &&
echo '#define __FTOPTION_H__
#include <ft2build.h>
FT_BEGIN_HEADER
#undef  FT_CONFIG_OPTION_FORCE_INT64
#define FT_RENDER_POOL_SIZE  0
#define FT_MAX_MODULES  4
#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
FT_END_HEADER' > include/freetype/config/ftoption.h &&
./configure --prefix=/usr --sbindir=/usr/bin --enable-shared --disable-static --without-zlib --without-old-mac-fonts --without-fsspec --without-fsref --without-quickdraw-toolbox --without-quickdraw-carbon --without-ats --with-pic &&
make && make install && make install prefix=$R/usr sbindir=$R/usr/bin &&
cp /usr/lib/libfreetype.so.* /lib/ && cp $R/usr/lib/libfreetype.so.* $R/lib/ &&
cd $SRC && tar -xf wqy-bitmapfont-pcf-0.8.1-7.tar.gz &&
cp wqy-bitmapfont/wenquanyi_{10,12}pt.pcf /share/fonts/ &&
cp -R /share/fonts $R/share/ &&
cd $SRC && rm */ &&
echo '??-freetype+fonts' >> $SRC/build.log && sync &&