|
|
大多数程序都需要用到共享库,这会导致较长的读取时间,比如运行时每一个库都需要被读取来解析符号。对多数小程序来说这没什么,但是对于用C++写的程序来说链接库太多了,时间加起来也就很长。
一个解决办法是prelining,这种办法预先进行链接,静态绑定可执行程序。这样会稍微增加一点可执行程序的的大小,但是程序启动时会获得一些戏剧性的加速。预链接的缺点是每当库改变时就需要重新链接,而且不能动态的读取库文件。所以对那些需要动态读取库文件的程序来说prelinking没有效果,比如OpenOffice。
下一种开发中的办法产生于对binutils和glibc的改进中,这种办法被称作直接链接,Bdirect。Bdirect不像prelinking那么有效,但是它可以很好的动态读取库文件,并且不需要任何用户进行的预链接步骤。
关于hashstyle
hashstyle很快成为了下一种选择,上流开发中的版本已经整合了这个补丁,这个改进就是新的 DT_GNU_HASH 或 .gnu.hash,现在被亲切的称为Hashstyle。新的.gnu.hash大约比老的sysv .hash快50%。
hashstyle还可以与prelinking共存(假设你有最新的elfutils 和 prelink),并且支持ELF标准,不像 -Bdirect,这也是 -Bdirect没被整合到upstream(不晓得怎么翻译=_=)的原因。
这个wiki详细叙述了如何迁移到新的hashstyles环境。在你开始动手尝试之前,请先仔细阅读并重复阅读每一部分。
协议
Gentoo Linux组织并不支持使用hashstyles补丁。如果要执行本文以下的步骤,你要同意对自己的行为负责。本文作者和投稿人对本文并不负任何责任,也不保证能提供任何帮助,但是会提供基本的可供你执行的步骤,不过没有更进一步的帮助。 (In the case your system is no longer usable - system is equal to the gentoo installation, not your computer.)
第一次安装hashstyle
现在需要把“hashstyle”添加 到/etc/make.con中的USE变量里。这里我假设你知道如何去做,你正在用一个实验补丁,所以你一定知道怎么做。
现在需要unmask实验中的binutils。对 gcc 4.x来说需要至少为2.17.50.0.3的版本,gcc 3.4.的话则需要 2.17.50.0.4
- /etc/portage/package.keywords
- sys-devel/binutils -*
复制代码
如果你需要用prelink,那还要unmask最新版本。如果你用的是不稳定版那这步可以跳过。
- /etc/portage/package.keywords
- sys-devel/prelink
复制代码
现在开始有趣的部分了。确定你已经做好了备份,一旦某环节出现问题的话没人担保有办法能恢复你的系统,除非重新安装Gentoo。
- # emerge binutils glibc
- # binutils-config -l
- # binutils-config # (Replace # with the corresponding number to binutils-2.17.50.0.3)
复制代码
现在添加"-Wl,--hash-style=both" 到/etc/make.conf文件中的LDFLAGS。如果你的文件中还没这行,请加入这样完整的一行。
- LDFLAGS="-Wl,--hash-style=both"
复制代码
现在我们用新的LDFLAGS来重新构筑系统,以确保每一部分都获得了新的.gnu.hash段。Portage会自动运行prelink,但是我不敢肯定它会百分百工作,所以我们需要继续手动进行prelink。
- # emerge -e world
- # emerge prelink
- # prelink -amR
复制代码
当这些完成以后你可以用readelf -a和grep GNU_HASH检查任意一个二进制程序,看是否工作。输出应该看起来象这样。
- # readelf -a /usr/bin/nano | grep GNU_HASH
- [ 4] .gnu.hash GNU_HASH 00000000004009a0 000009a0
- 0x000000006ffffef5 (GNU_HASH) 0x4009a0
复制代码
关于prelinking的更多信息可以看这里: http://www.gentoo.org/doc/en/prelink-howto.xm
从旧补丁升级到较新版本
对那些已经使用了旧补丁的人来说(20060705之前的),新补丁有不一致的hash,所以如果你不按照下面的步骤做的话你的系统有可能受损害。这个过程会使你的系统不可用。在此过程没完成之前请千万别关掉计算机的电源。
首先确认你已经有最新的 overlay,把 -Wl,--hash-style参数从 LDFLAGS中删掉,然后运行:
- # LD_X=1 emerge -1 coreutils binutils glibc
复制代码
再添加 -Wl,--hash-style=both到LDFLAGS中。
现在安装prelink.
- # emerge prelink
- # prelink -amR
复制代码
这已经经过实验了。
从旧的bdirect/hashvals 升级到新的 hashstyle
首先需要从 /etc/make.conf的 LDFLAGS中移除 "-Wl,-Bdirect -Wl,-hashvals -Wl,-zdynsort"
然后emerge portage中的glibc(没有补丁过的glibc)
- # PORTDIR_OVERLAY="" emerge -a1 glibc
复制代码
然后我们 用新的hashstyle use参数emerge binutils (从 portage) 和 glibc (从 overlay)。
1请确保你正在emerge的binutils版本 >= 2.17.50.0.3,如果不是,请修改你的package.keywords
2请为你的glibc添加hashstyle use参数(package.use)
- # LD_X=1 emerge -1 binutils glibc
复制代码
这已经测试成功了。(roderick 19:50, 31 July 2006 (UTC))
现在我们emerge/setup prelink(需要elfutils >= 0.122 、 prelink >= 20060712)
- # emerge prelink
- # prelink -amR
复制代码
记住rebuild结束后从环境变量中移除 LD_BIND_DIRECT="1",这是否会导致问题还不确定,但是最好还是这样做。很多人可能在把它加入了"/etc/env.d/99local"(或者可能在 /etc/env.d).
Post Messages
好了现在你应该用--hash-style=both来预链接系统了。如果一切正常的话你就没什么好做的了。如果你的系统挂掉了,很抱歉,不过我之前警告过你。
已知的问题
[edit]
Known Issues
>=binutils-2.17.50.0.10的话(老版本则不会).,<=madwifi-ng-0.9.2.1 (latest current version, Feb 11 2007 -- the cvs version too) 拒绝链接 (ld 不识别 hal.o 文件各式)
要用的madwifi-ng 话你需要暂时降低你的 binutils 版本来编译它,然后它会正常工作的
=x11-drm-20070314 (最新版本有 unknown LDFLAGS的错误) (用 VIDEOCARDS="radeon"编译的,其他的没有测试) 简单的用 LDFLAGS=" " emerge 它。
[edit]
Troubleshooting
如果你的系统变糟了 当运行应用程序时得到一大堆符号错误,请使用 LD_X=1 命令.这会让你在解决问题之前暂时可以用这个程序。
I will post more in the Troubleshooting section regarding fixing a broken system soon.
The Gentoo Forums thread for hashstyle is: http://forums.gentoo.org/viewtopic-t-475538.html
+++++++++++++++++++++++++++++++++++++++++++++++++++++
大致翻译了一遍,因为专业不是这个,所以很多地方不知道翻译的对不对,大家凑合看,希望高手多指点。
=====================================================
据说效果挺明显的,我现在正emerge -e world中。。。
官方论坛有说fc6是用-Wl,--hash-style=gnu的,ubuntu的feisty据说也用的这个参数,就我的体验来说,feisty确实比edgy要快。 |
|