一般情况下我们最好是在一个平台上编译本平台的二进制程序,比如在32位平台上编译32位程序而在64位平台上编译64位程序。
现在64位的系统(这里主要指x86_64系统,包括AMD64和Intel的EM64T)已经开始广泛的使用起来了,甚至于你现在要是想买32位的Xeon根本就没有。64位的系统在性能和处理能力上相对32位系统也都有很大的提高。所以现在很多用户已经选择使用64位的系统了。
但是,目前有一些软件还没有64位的版本,不过由于64位操作系统都兼容32位应用程序的运行(x86_64是硬件兼容,IA64主要靠软件实现,不过据说现在最新的Itunium2已经在硬件中加入了32位的处理,有机会要了解一下),所以,我们可以安装32位的软件。
有一些软件,在安装过程中需要对部分代码进行编译以便在不同的发布版本都可以很好的运行。那么当我们在64位系统上安装32位的软件时,它的编译就会出错,因为软件的二进制部分是32位的,但是编译出来的部分是64位的,所以我们就需要让我们的64位系统可以编译32位的程序,并且需要默认就是编译32位的程序。
上次帮同事解决tuxedo8.0 32位版本在x86_64系统上安装的问题时,就遇到了这样的问题。我现在就以这个事情位例,简单介绍一下如何在x86_64系统上编译32位程序。
tuxedo安装后需要编译一个服务器和客户端,然后用编译的东西启动服务。但是编译不成功,错误是ld无法找到需要的库,但是这个库在,提示跳过了不兼容的库,原因就是因为编译出来的是64位的程序,但是需要连接的是32位的库(tuxedo带的)。因为tuxedo就是向上面我们说的,带了一部分32位的二进制程序,另一部分需要根据当前的系统版本来编译,那么它带的二进制的东西我们肯定是不能改了,所以我们就必须让编译出的程序也是32位的,而不能是64位的。
通过查阅资料,发现可以使用-m32来使得gcc编译32位程序(在x86_64系统上),使用-m elf_i386参数可以使得64位的ld能够兼容32位的库,但是tuxedo编译时是使用自己的一个命令,所以没有办法给他加参数,但是这个命令也是要调用gcc和ld得,所以我们可以通过修改gcc和ld来解决,也就是将上述的两个支持32位编译连接的参数默认给加上去:
将/usr/bin/gcc和/usr/bin/ld都改名为*.bin,就是改为:
/usr/bin/gcc.bin和/usr/bin/ld.bin,然后写两个脚本:
/usr/bin/gcc:
#!/bin/sh
gcc.bin -m32 $@
/usr/bin/ld:
#!/bin/sh
ld.bin -m elf_i386 $@
这样就保证调用时将需要的参数加上,然后再调用真正的参数($@表示当前命令的所有参数,也就是把传给教本的所有参数再传给真正的命令),经测试可以解决问题。
在IA64系统上,目前据我所知还不能编译32位的程序,可能是因为IA64的体系结构根本和i386的完全不同吧,不过也许为了考虑兼容性,听说Intel已经在新的Itanium2中加入了兼容32位的设计,也许未来的IA64上也可以编译32位的程序吧。不过还是像前面说的,最好是在一个平台上编译和运行相应的二进制程序,除非万不得以,因为兼容必竟要牺牲一些性能和可靠性的。