源码编译安装,关键是恢复、比对。备份系统文件,用Live系统恢复原系统状态;比对发行版包管理器软件包的安装路径,移除冲突,比对发行版编译软件包时的编译选项,如果函数库没编译某些特性,可能会导致系统崩溃或已有的应用程序不可用。
pwd /root/linux-3.7 # make INSTALL_HDR_PATH=/root/headers headers_install # pwd /root/glibc-2.17/build $ ../configure --prefix=/usr --enable-add-ons=nptl,libidn --with-headers=/root/headers/include --enable-kernel=3.7.0 $ make $ make install_root=pwd
/dest install
pwd
/root/linux-3.7
make INSTALL_HDR_PATH=/root/headers headers_install
pwd
/root/glibc-2.17/build
$ ../configure --prefix=/usr --enable-add-ons=nptl,libidn --with-headers=/root/headers/include --enable-kernel=3.7.0
$ make
$ make install_root=pwd
/dest install
warning: 这里如果使用make DESTDIR=...将失效,因为glibc的Makefile是手写的,不是用autotools生成的,DESTDIR是GNU标准,autotools兼容GNU标准
nptl,libidn是为了跟Debian原有的程序兼容
ls dest/usr/lib/librt.so dest/usr/lib/librt.so # ldd /bin/ls | grep librt.so librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7730000)
ls dest/usr/lib/librt.so
dest/usr/lib/librt.so
ldd /bin/ls | grep librt.so
librt.so.1 => /lib/i686/cmov/librt.so.1 (0xb7730000)
发现不对劲,make install后的glibc,跟系统原来的glibc安装路径不同,这样会导致应用程序使用不同版本的glibc文件而崩溃
调试方法:
make install_root=pwd
/dest -p > /tmp/make $ dpkg -S librt.so libc6-dev: /usr/lib/librt.so libc6: /lib/librt.so.1 libc6-i686: /lib/i686/cmov/librt.so.1 # apt-get remove libc6-i686
make install_root=pwd
/dest -p > /tmp/make
$ dpkg -S librt.so
libc6-dev: /usr/lib/librt.so
libc6: /lib/librt.so.1
libc6-i686: /lib/i686/cmov/librt.so.1
apt-get remove libc6-i686
启发: 源码编译后,安装前,要查看比对发行版软件包管理器已安装的相关软件包的路径
接着,通过比对dest/和系统软件包的安装路径,备分系统重要的文件夹,以便系统崩溃后,用U盘里的GNU/Linux恢复系统
比对:
cat /tmp/diff.sh #! /bin/bash destdir=$1 pkg=$2 list=/tmp/list.diff pkglist=/tmp/list.pkg backupdir="/backup/pkg" answer=n if [ x"$destdir" == x -o x"$pkg" == x ] ; then echo "Usage: diff.sh destdir debian-pkg" exit 1 fi dpkg -L $pkg 2>&1 1>/dev/null if [ $? -ne 0 ] ; then echo "error: $pkg doesn't exists." exit 1 fi echo -n "backup $pkg to $backupdir/$pkg.tar?(y/[n])" read -N 1 -t 5 answer echo rm -f $list $pkglist for name in dpkg -L $pkg
do if [ ! -e $destdir/$name -a -f $name ] ; then echo $name | tee -a $list fi if [ x$answer == x"y" -a -f $name ] ; then echo $name >> $pkglist fi done mkdir -p $backupdir tar cf $backupdir/$pkg.diff.tar -T $list 2>/dev/null if [ x$answer == x"y" ] ; then tar cf $backupdir/$pkg.pkg.tar -T $pkglist 2>/dev/null fi # /tmp/diff.sh dest/ libc6 # /tmp/diff.sh dest/ libc6-dev
cat /tmp/diff.sh
! /bin/bash
destdir=$1
pkg=$2
list=/tmp/list.diff
pkglist=/tmp/list.pkg
backupdir="/backup/pkg"
answer=n
if [ x"$destdir" == x -o x"$pkg" == x ] ; then
echo "Usage: diff.sh destdir debian-pkg"
exit 1
fi
dpkg -L $pkg 2>&1 1>/dev/null
if [ $? -ne 0 ] ; then
echo "error: $pkg doesn't exists."
exit 1
fi
echo -n "backup $pkg to $backupdir/$pkg.tar?(y/[n])"
read -N 1 -t 5 answer
echo
rm -f $list $pkglist
for name in dpkg -L $pkg
do
if [ ! -e $destdir/$name -a -f $name ] ; then
echo $name | tee -a $list
fi
if [ x$answer == x"y" -a -f $name ] ; then
echo $name >> $pkglist
fi
done
mkdir -p $backupdir
tar cf $backupdir/$pkg.diff.tar -T $list 2>/dev/null
if [ x$answer == x"y" ] ; then
tar cf $backupdir/$pkg.pkg.tar -T $pkglist 2>/dev/null
fi
/tmp/diff.sh dest/ libc6
/tmp/diff.sh dest/ libc6-dev
备份:
ls dest/ etc lib sbin usr var # du -sh /etc/ /lib/ /sbin/ /usr/ /var/ # mkdir /backup # cp -R /etc/ /lib/ /sbin/ /usr/ /var/ /backup/
ls dest/
etc lib sbin usr var
du -sh /etc/ /lib/ /sbin/ /usr/ /var/
mkdir /backup
cp -R /etc/ /lib/ /sbin/ /usr/ /var/ /backup/
假想要进行的安装:
make install # while read name > do > rm -f $name > done < /tmp/list.diff
make install
while read name
do
rm -f $name
done < /tmp/list.diff
出现错误:
test ! -x /root/glibc-2.17/build/elf/ldconfig || LC_ALL=C LANGUAGE=C \ /root/glibc-2.17/build/elf/ldconfig \ /lib /usr/lib LD_SO=ld-linux.so.2 CC="gcc" /usr/bin/perl scripts/test-installation.pl /root/glibc-2.17/build/ Segmentation fault make[1]: *** [install] Error 139 make[1]: Leaving directory `/root/glibc-2.17' make: *** [install] 错误 2 #
test ! -x /root/glibc-2.17/build/elf/ldconfig || LC_ALL=C LANGUAGE=C
/root/glibc-2.17/build/elf/ldconfig
/lib /usr/lib
LD_SO=ld-linux.so.2 CC="gcc" /usr/bin/perl scripts/test-installation.pl /root/glibc-2.17/build/
Segmentation fault
make[1]: *** [install] Error 139
make[1]: Leaving directory `/root/glibc-2.17'
make: *** [install] 错误 2
试验正常的安装方法:
如果是编译安装比系统低版本的glibc,要用tar方式安装,然后删除/tmp/list.diff里的文件,再ldconfig。
这里我估计/lib/libc.so.6这些链接文件链接的是原来系统的库文件,所以要用tar方式覆盖以指向新的库文件,否则删除顺序出错,可能导致找不到函数库而导致系统崩溃,还没去做实验证实(懒)。ldconfig会链接高版本的函数库到系统。遇到问题用tar安装是非常好用的方法。这个方法也可以用来安装高版本glibc。
init 1 # cd dest # tar cf - . | (cd / && tar xf -) # while read name > do > rm -f $name > done < /tmp/list.diff # ldconfig -v
init 1
cd dest
tar cf - . | (cd / && tar xf -)
while read name
do
rm -f $name
done < /tmp/list.diff
ldconfig -v
如果是编译安装比系统高版本的glibc
init 1 # make install segment fault # ldconfig -v # make install
init 1
make install
segment fault
ldconfig -v
make install
warning: 不要用那个rm -f $name的/tmp/list.diff方法,目前不知道为什么会失败,难道是glibc的idn add on没装?
这里还有个问题glibc依赖特定版本的gcc和kernel吗?
如果make install的安装方法不成功,就用tar的方法安装吧,make install后面有个check,要测试不少东西,跟binutils, gcc, linux的版本都有关系。
上面那篇IBM文章的作者说,编译安装glibc建议在runlevel 1中进行,直接安装会出错,需要重启系统纠正关系链,如果重启系统仍出错,用U盘的Live系统手动纠正关系链或恢复系统
如果能正常重启系统,进入glibc再make install一次,这次安装通过的话就算安装成功了
验证:
ldd /bin/ls libc.so.6 => /lib/libc.so.6 (0xb76fb000) # ls -l /lib/libc.so.6 lrwxrwxrwx 1 root root 12 1月 5 11:55 /lib/libc.so.6 -> libc-2.17.so # /lib/libc.so.6 GNU C Library (GNU libc) stable release version 2.17, by Roland McGrath et al. Compiled by GNU CC version 4.4.5. Compiled on a Linux 2.6.39 system on 2013-01-05. # man ls
ldd /bin/ls
libc.so.6 => /lib/libc.so.6 (0xb76fb000)
ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root 12 1月 5 11:55 /lib/libc.so.6 -> libc-2.17.so
/lib/libc.so.6
GNU C Library (GNU libc) stable release version 2.17, by Roland McGrath et al.
Compiled by GNU CC version 4.4.5.
Compiled on a Linux 2.6.39 system on 2013-01-05.
man ls
昨晚在irc.freenode.net上的glibc channel,询问一位IBM glibc开发者,关于glibc开发和编译的事,记录如下:
您正在 #glibc 频道里聊天 * #glibc 的主题是:glibc wiki is at http://sources.redhat.com/glibc/wiki/HomePage | Feedback and FAQ are at http://sources.redhat.com/glibc/wiki/Feedback * #glibc 的主题由 ryanarn 于 Wed Oct 15 03:49:37 2008 设置 * Ajaeger 已退出(Quit: Ajaeger) <c-aries> What tools are you use for reading glibc source code? I use etags, but it usually lead me to wrong place * mjw 已退出(Quit: Leaving) <ryanarn> c-aries: I use grep and a knowledge of the sysdeps directory hierarchy <ryanarn> c-aries: sometimes you have to look at the glibc make output build log to see exactly which files are being picked up and how/when/from-where <ryanarn> c-aries: also, recompiling components with -dD -E will give you macro expanded source if the layers of macros are confusing. <c-aries> Thanks ryanarn. I have another question. What's your develop enviroment? I mean whether you build the newest glibc from git repo or just use the distribution build script? <ryanarn> c-aries: it depends on what your end goal is. I work for IBM enabling new features in GLIBC for new hardware, so I build from master. <ryanarn> if you're a user you should probably be using a distribution source rpm. <c-aries> I read sys_exeve () from kernel, and then reach at /lib/ld-linux.so. I wanna find a way to debug the ld.so actually. <ryanarn> ahh, I wrote a bit of a tutorial on the wiki about debugging the loader.. well I started to. <ryanarn> you need to set up the debugger to debug the loader and then break in the loader very very early. <c-aries> I also curious about how to build the newest glibc repo.. Do you have any good articles or resource instruct me to build the newest repo? <ryanarn> c-aries: the glibc git page on the wiki instructs you how to pull. As far as building... I would grab your distro's source RPM. Do the rpmbuild there, save the log file and then pull the configure invocation out of that and use it for configuring your own build of the git repo. <ryanarn> otherwise you're likely to spend days in configure hell. <c-aries> go hell and you'll find how to build the newest glibc XD. Many thanks ryanarn, you inspired me how to hack glibc, thanks for you clues. * kosaki8 已退出(Ping timeout: 260 seconds) * kosaki2 (kosaki2@nat/redhat/x-nnlnvliklfurxywh) 进入了 #glibc <ryanarn> c-aries: you're welcome
您正在 #glibc 频道里聊天
-
glibc 的主题是:glibc wiki is at http://sources.redhat.com/glibc/wiki/HomePage | Feedback and FAQ are at http://sources.redhat.com/glibc/wiki/Feedback
-
glibc 的主题由 ryanarn 于 Wed Oct 15 03:49:37 2008 设置
Ajaeger 已退出(Quit: Ajaeger)
<c-aries> What tools are you use for reading glibc source code? I use etags, but it usually lead me to wrong placemjw 已退出(Quit: Leaving)
<ryanarn> c-aries: I use grep and a knowledge of the sysdeps directory hierarchy
<ryanarn> c-aries: sometimes you have to look at the glibc make output build log to see exactly which files are being picked up and how/when/from-where
<ryanarn> c-aries: also, recompiling components with -dD -E will give you macro expanded source if the layers of macros are confusing.
<c-aries> Thanks ryanarn. I have another question. What's your develop enviroment? I mean whether you build the newest glibc from git repo or just use the distribution build script?
<ryanarn> c-aries: it depends on what your end goal is. I work for IBM enabling new features in GLIBC for new hardware, so I build from master.
<ryanarn> if you're a user you should probably be using a distribution source rpm.
<c-aries> I read sys_exeve () from kernel, and then reach at /lib/ld-linux.so. I wanna find a way to debug the ld.so actually.
<ryanarn> ahh, I wrote a bit of a tutorial on the wiki about debugging the loader.. well I started to.
<ryanarn> you need to set up the debugger to debug the loader and then break in the loader very very early.
<c-aries> I also curious about how to build the newest glibc repo.. Do you have any good articles or resource instruct me to build the newest repo?
<ryanarn> c-aries: the glibc git page on the wiki instructs you how to pull. As far as building... I would grab your distro's source RPM. Do the rpmbuild there, save the log file and then pull the configure invocation out of that and use it for configuring your own build of the git repo.
<ryanarn> otherwise you're likely to spend days in configure hell.
<c-aries> go hell and you'll find how to build the newest glibc XD. Many thanks ryanarn, you inspired me how to hack glibc, thanks for you clues.kosaki8 已退出(Ping timeout: 260 seconds)
kosaki2 (kosaki2@nat/redhat/x-nnlnvliklfurxywh) 进入了 #glibc
<ryanarn> c-aries: you're welcome
后记
Unix有好多小技巧,一个tar命令,居然会成为slackware的生命线,有tar,就能实现软件包管理的基本功能,还能保存权限复制特殊设备文件,归档供压缩程序使用,太强大了。昨天还了解到源码编译恢复系统的方法,就简简单单地在live系统上cp,什么都恢复了。还有init 1的作用第一次体会到。太兴奋太好玩了。学越久,发现越多小技巧,感觉魅力无穷啊,一个小小的命令能那么有用,太厉害了。