LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2487|回复: 5

【毁灭小貼士】软连结的妙用

[复制链接]
发表于 2008-5-14 22:27:14 | 显示全部楼层 |阅读模式
这是一个在同一系统下让软件多版同存的技巧,灵感来自 Debian 及 BLFS 手册而纵合出来,具体如下:

很多时候,基於各种原因或某些特定需要,我们都有机会安装不同版本的软件在同一系统下,最普遍的不同版本的 gcc、QT、KDE、apache 等等,而为免各版软件互相干扰,一般比较盛行的做法是把不同版本的软件安装到不同的路径下来执行,再建立适当的连结,如此就可以方便於各版软件之间切换了,正如 BLFS 手册里介绍的 QT 及 KDE 的方式。Debian 也是采用连结来切换,但它的软件却是装在相同的路径下,并更改执行文件名字的方式来达成,比较麻烦一点。

也许各位对 BLFS 手册里的技俩早已熟态详了,所以我不打算重覆其内容,准备以 gcc 来说明。

众所周知,每一个 gcc 的 major release 在效能上都有明显突破,可是也带来一些相容性问题,因为新版 gcc 对语法的检查更加严格,从而引起编译不能通过的问题,所以多版 gcc 共存是非常普遍的做法,LFS 系统的默认设置是将 gcc 装在 /usr/bin 之下,额外版本就按 BLFS 手册方式装到 /opt/gcc-xxxxx 之下,当初 BLFS 手册加装 gcc 版本原意是取其旧版 gcc 所提供而跟新版 gcc 不兼容的库,不过这技巧是可以进一步发扬光大,为自己带来不少方便的。

言归正传,系统默认的 gcc 并非一定要装在 /usr/bin 之下的,俺的机器是从 LFS-6.2 期间开始创建的,当时系统默认的 gcc 是 4.0.3,期後系统不断升级,现在系统里的 gcc 有 4.2.3,4.3-RC2 与及刚刚最新出炉的 4.3-20080508 (即是 4.3.1 的 pre-release snapshot)。

/usr/bin 下的 gcc-4.0.3 早已被干掉,我把所有的 gcc 都设定安装在 /opt/gcc-xxxx 之下,也就是说: gcc-4.2.3(或者 g++-4.2.3)其实是 /opt/gcc-4.2.3/bin/gcc 或者 /opt/gcc-4.2.3/bin/g++ 了,如此类推,系统里还有 /opt/gcc-4.3.0-RC-20080222/bin/gcc,/opt/gcc-4.3-20080508 /bin/gcc 等等

这样好了,我只要在 /lib/cpp 及 /usr/bin 下利用 symlink,将 gcc、g++、cpp、gccbug。。。及其他等连结到 /opt/gcc/bin/gcc、g++、cpp、gccbug 及其他之下,再於 /opt 下建一个对应当前希望使用版本 gcc 的 symlink,於是每次想变换版本,都只需要修改一个连结就行了。

也许我的中文表达不大好,请看下面例子:

系统当前的 gcc 是 4.3-RC2(gcc-4.3.0-RC-20080222),因为 /usr/bin/gcc 是连结到
/opt/gcc/bin/gcc,也就是 /opt/gcc-4.3.0-RC-20080222/bin/gcc 里的
  1. root@BlackMesa:/opt#
  2. root@BlackMesa:/opt# ll /usr/bin/gcc
  3. lrwxrwxrwx 1 root root 16 Jan 28 16:42 /usr/bin/gcc -> /opt/gcc/bin/gcc
  4. root@BlackMesa:/opt# ll /usr/bin/g++
  5. lrwxrwxrwx 1 root root 16 Jan 28 16:42 /usr/bin/g++ -> /opt/gcc/bin/g++
  6. root@BlackMesa:/opt# ll
  7. total 40
  8. lrwxrwxrwx  1 root root   16 May 14 18:27 gcc -> gcc-4.3.0-RC-20080222
  9. drwxrwxr-x  8 root root 4096 Feb 25 18:48 gcc-4.2.3
  10. drwxrwxr-x  8 root root 4096 May 14 18:26 gcc-4.3-20080508
  11. drwxrwxr-x  8 root root 4096 Feb 23 15:30 gcc-4.3.0-RC-20080222
  12. drwxr-xr-x  7 root root 4096 Jun 28  2006 jre1.5.0_08
  13. lrwxrwxrwx  1 root root    9 Mar 24 14:07 kde -> kde-3.5.9
  14. drwxrwxr-x  6 root root 4096 Mar 24 15:23 kde-3.5.9
  15. lrwxrwxrwx  1 root root   11 Oct 16  2007 lampp -> lampp-1.6.4
  16. drwxr-xr-x 20 root root 4096 Oct  7  2007 lampp-1.6.4
  17. drwxr-xr-x 20 root root 4096 Aug 18  2006 lampp-154b3
  18. drwxr-xr-x  6 root root 4096 May  5 14:28 ooo-dev3
  19. lrwxrwxrwx  1 root root    8 May  5 14:31 openoffice -> ooo-dev3
  20. drwxr-xr-x  4 root root 4096 May  5 14:28 openoffice.org
  21. lrwxrwxrwx  1 root root    8 May 23  2007 qt -> qt-3.3.8
  22. drwxrwxr-x 11 root root 4096 May 23  2007 qt-3.3.8
  23. root@BlackMesa:/opt#
  24. root@BlackMesa:/opt# gcc --version
  25. gcc (GCC) 4.3.0 20080222 (prerelease)
  26. Copyright (C) 2007 Free Software Foundation, Inc.
  27. This is free software; see the source for copying conditions.  There is NO
  28. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
复制代码

假如现在我想将默认 gcc 由 4.3-RC2 改为 gcc-4.2.3,很简单,只要把 /opt 下的 gcc 连结更改
  1. root@BlackMesa:/opt# rm gcc
  2. rm: remove symbolic link `gcc'? y
  3. root@BlackMesa:/opt# ln -s gcc-4.2.3 gcc
  4. root@BlackMesa:/opt# g++ -v
  5. Using built-in specs.
  6. Target: i686-pc-linux-gnu
  7. Configured with: ../gcc-4.2.3/configure --prefix=/opt/gcc-4.2.3 --libexecdir=/usr/lib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++
  8. Thread model: posix
  9. gcc version 4.2.3
  10. root@BlackMesa:/opt#
复制代码

当前版本马上就改变了,无需其他任何变更,多麽方便!

所谓一里通,百里明,善用 symlink 就能推广到其他软件,我在 /opt 下装的软件都以此为监,方便切换或日後升级,希望此小贴士对各位有启发作用。在下才疏学流,如有错漏,敬请指正。
发表于 2008-5-15 00:24:19 | 显示全部楼层
lz 方法适合尝鲜,长驻系统时要看个人习惯。

比如,在我自己的系统中/opt用来放置不可信任软件(预编译二进制软件包如ooo、非开源软件如电信adsl拨号程序),而且是放置在chroot jail的/opt中,我一向忌讳使用主系统/opt。

要尝鲜的话,我习惯使用/usr/local。

debian下软件多版本共存的方式个人感觉更好,也就是软件包配置过程中指定版本号为可执行程序后缀。(个人习惯安装系统软件包到/usr,lz指定不同安装路径的方法不适用)

在我的系统中有/usr/bin/gcc-4.2.3 /usr/bin/gcc-3.3.6 /usr/bin/gcc-4.3.0。
其中主gcc版本为/usr/bin/gcc-4.2.3,并连接为/usr/bin/gcc、/usr/bin/cc。
gcc-3.3.6到现在仅用来编译qemu、kvm,配置编译时自动调用。
gcc-4.3.0实验性使用,软件包配置编译时通过CC=gcc-4.3.0调用。
唯一的缺点是man、info被最后一个安装版本覆盖。
我使用fakeroot方式通过自己编写的脚本管理软件包,删除特定软件包不是问题。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-5-15 01:41:43 | 显示全部楼层
嘿嘿,这个真的要看个人习惯了,我跟超新星兄刚好相反,一向对使用主系统 /usr/local 感冒,偏向使用 /opt。

Debian下软件多版本共存的方式不是不好,只是比较麻烦,而且要干掉某版本就不及独立路径来得方便及彻底。

从前我也使用 CC=/path/to/version/gcc CXX=/path/to/version/g++ 去定义,但每次都要键入长长的感觉实在太烦人,於是才会想出此懒招

man 及 info 一般可以 configure 的时候配置安装路径就可避免覆写,好像 Debian 也是用此策略的

./configure --mandir=/usr/local/share/man --infodir=/usr/local/share/info

最後兄台可否分享一下您的 fakeroot 脚本管理软件包技巧 :)
回复 支持 反对

使用道具 举报

发表于 2008-5-15 09:08:44 | 显示全部楼层
Post by d00m3d;1849775
嘿嘿,这个真的要看个人习惯了,我跟超新星兄刚好相反,一向对使用主系统 /usr/local 感冒,偏向使用 /opt。

自己习惯就好。只是好奇兄台为什么对/usr/local 感冒?莫非有什么惨痛的经历?
Post by d00m3d;1849775
  Debian下软件多版本共存的方式不是不好,只是比较麻烦,而且要干掉某版本就不及独立路径来得方便及彻底。

如果类似 debian dpkg 系统记录了安装文件列表,删除很轻松的。
Post by d00m3d;1849775
  从前我也使用 CC=/path/to/version/gcc CXX=/path/to/version/g++ 去定义,但每次都要键入长长的感觉实在太烦人,於是才会想出此懒招

debian方式,如果gcc-version放在shell搜索路径,通过CC=gcc-version即可调用特定版本gcc,无需指明路径。
Post by d00m3d;1849775
  man 及 info 一般可以 configure 的时候配置安装路径就可避免覆写,好像 Debian 也是用此策略的

./configure --mandir=/usr/local/share/man --infodir=/usr/local/share/info

这个不算大问题,man info我这里现在保留的是相应软件主版本的,你那样配置好像还是会覆盖的。等无聊时回头研究研究debian具体是怎么解决的。
Post by d00m3d;1849775
   最後兄台可否分享一下您的 fakeroot 脚本管理软件包技巧 :)

这个涉及软件包管理,是见仁见智的事情,有时间我贴一下。

下面这篇hint有fakeroot方法介绍
http://www.linuxfromscratch.org/ ... /files/fakeroot.txt
这里有hint作者使用的脚本
http://linuxfromscratch.org/~tushar/

我个人使用的脚本要简单的多:
自己搭了一个fakeroot方式配置编译环境脚本架子,
每个软件包对应一个模块化fakeroot方式配置编译命令集文件,
用目录分组软件包配置编译命令集文件,
每个目录下放置一个软件包列表文件,
软件包列表文件用来控制软件包编译顺序,同时用来维持最简单的包依赖关系,
真正安装软件前,先用fakeroot方式安装,之后打包备份为tarball,最后解包到/完成安装。

备份tarball可以用来安装全新的系统,
同时可以提供软件包安装文件列表(tar -tf *.tar.bz2),
将软件包安装文件列表反序(sort -r),结合rm -f(用来删除文件)、rmdir(用来删除空目录),即可彻底删除特定软件包。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-5-17 17:50:24 | 显示全部楼层
Post by 1987a;1849811
自己习惯就好。只是好奇兄台为什么对/usr/local 感冒?莫非有什么惨痛的经历?
沒什麼,只是 /usr/local/bin 跟 /usr/bin 比較相似,昔日犯過低級錯誤,原先想干掉 /usr/local/bin 下的東東,卻打成 /usr/bin,結果。。。:Broken-heart:
Post by 1987a
如果类似 debian dpkg 系统记录了安装文件列表,删除很轻松的。
這當然了,但也得先做 deb 包來裝,還不如用 paco 算了(我太懶了 :p)
Post by 1987a
debian方式,如果gcc-version放在shell搜索路径,通过CC=gcc-version即可调用特定版本gcc,无需指明路径。
這個沒注意,未出懶招前,我在 Debian 系統下也是把完整的路徑給出來的,thanks for the hint!
Post by 1987a
这个涉及软件包管理,是见仁见智的事情,有时间我贴一下。
期待中。。。:)
回复 支持 反对

使用道具 举报

发表于 2008-6-24 03:14:39 | 显示全部楼层
debian etch 下 gcc -v 结果

Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
回复 支持 反对

使用道具 举报

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

本版积分规则

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