64位Linux系统在gcc编译时默认是生成64位的程序或库。
首先编写一个简单的程序:
main.c:
-
#include "test.h"
-
-
int main()
-
{
-
int a, b;
-
-
add(a,b);
-
-
return 0;
-
}
Test.c:
-
#include "test.h"
-
-
int add(int a, int b)
-
{
-
return (a+b);
-
}
Test.h:
-
#ifndef _TEST_H_
-
#define _TEST_H_
-
-
int add(int, int);
-
-
#endif
Makefile:
-
main:libtest.so
-
gcc main.c -L./ -o main -ltest
-
libtest.so:test.c test.h
-
gcc -shared -fPIC test.c -o libtest.so
-
clean:
-
rm -f libtest.so main
在Linux终端直接 make,结果正确,生成了程序:
-
make
-
gcc -shared -fPIC test.c -o libtest.so
-
gcc main.c -L./ -o main -ltest
-
ls
-
libtest.so main main.c Makefile test.c test.h
现在,把Makefile中的内容改一改:
-
main:libtest.so
-
gcc main.c -L./ -o main -ltest
-
libtest.so:test.c test.h
-
gcc -m32 -shared -fPIC test.c -o libtest.so
-
clean:
-
rm -f libtest.so main
再 make,就会出现下面的错误:
-
make
-
gcc -m32 -shared -fPIC test.c -o libtest.so
-
gcc main.c -L./ -o main -ltest
-
/usr/bin/ld: skipping incompatible .//libtest.so when searching for -ltest
-
/usr/bin/ld: cannot find -ltest
-
collect2: ld returned 1 exit status
-
make: *** [main] Error 1
由于在编译生成 libtest.so 时增加了 -m32 这个参数,导致 libtest.so 是一个 32 位的动态库,而链拉步骤没有改,还是按照64位进行编译,结果就导致了上面的错误,看一下 libtest.so 的文件类型:
-
file libtest.so
-
libtest.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xc19c3e44615cd4951e4c65e76c8b838e3dcc2507, not stripped
现在再把 Makefile改动一下:
-
main:libtest.so
-
gcc -m32 main.c -L./ -o main -ltest
-
libtest.so:test.c test.h
-
gcc -m32 -shared -fPIC test.c -o libtest.so
-
clean:
-
rm -f libtest.so main
两个步骤都加入了 -m32 这个参数,再编译:
-
0@lhn:tmp]$ make
-
gcc -m32 -shared -fPIC test.c -o libtest.so
-
gcc -m32 main.c -L./ -o main -ltest
-
0@lhn:tmp]$ ls
-
libtest.so main main.c Makefile test.c test.h
-
0@lhn:tmp]$ file libtest.so main
-
libtest.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xc19c3e44615cd4951e4c65e76c8b838e3dcc2507, not stripped
-
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xf44ed317c9c75795b3ff90e008d93ea770aeb0a1, not stripped
编译成功,而且最终结果也是32位的程序.
由此可见,只要在gcc编译时加入 -m32(或者-m64)就可以影响生成的程序类型.这里看似很简单.但我这里前期已经做了一些必要的准备工作,因此看起来简单.
因为有时候用户系统是64位的,但只提供了32位的库,因此知道如何在64位机上编译32位程序就很必要.
在64位机上编译32位的程序首先需要
ia32-libs 这个动态的支持,看一下 /usr/lib32 这个目录下有没有东西,如果没有, Ubuntu上安装这个包:
sudo apt-get install ia32-libs ia32-libs-multiarch
如果在加入 -m32 这个参数时编译仍然有问题,比如
-
In file included from /usr/include/stdio.h:28:0,
-
from AVAPIs_Client.c:1:
-
/usr/include/features.h:324:26: fatal error:bits/predefs.h: No such file or directory compilation terminated.
-
make: *** [all] Error 1
这通常是由于没有32位的编译工具引起, 需要安装
gcc-multilib 这个软件包,在Ubuntu 上安装这个软件包:
sudo apt-get install gcc-multilib
g++ 也同样如此
sudo apt-get install g++-multilib
到这里,编译32位程序应该没有问题了,运行程序的时候记得修改
LD_LIBRARY_PATH 这个变量,否则程序会找不到指定的动态库.
export LD_LIBRARY_PATH=/home/user/lib/:$LD_LIBRARY_PATH
阅读(16605) | 评论(0) | 转发(0) |