Chinaunix首页 | 论坛 | 博客
  • 博客访问: 49042
  • 博文数量: 5
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-19 16:55
个人简介

哈哈

文章分类
文章存档

2014年(5)

我的朋友

分类: LINUX

2014-03-03 22:15:18

64位Linux系统在gcc编译时默认是生成64位的程序或库。
首先编写一个简单的程序:
main.c:

点击(此处)折叠或打开

  1. #include "test.h"

  2. int main()
  3. {
  4.     int a, b;

  5.     add(a,b);

  6.     return 0;
  7. }
Test.c:

点击(此处)折叠或打开

  1. #include "test.h"

  2. int add(int a, int b)
  3. {
  4.     return (a+b);
  5. }
Test.h:

点击(此处)折叠或打开

  1. #ifndef _TEST_H_
  2. #define _TEST_H_

  3. int add(int, int);

  4. #endif
Makefile:

点击(此处)折叠或打开

  1. main:libtest.so
  2.     gcc main.c -L./ -o main -ltest
  3. libtest.so:test.c test.h
  4.     gcc -shared -fPIC test.c -o libtest.so
  5. clean:
  6.     rm -f libtest.so main
在Linux终端直接 make,结果正确,生成了程序:

点击(此处)折叠或打开

  1. make
  2. gcc -shared -fPIC test.c -o libtest.so
  3. gcc main.c -L./ -o main -ltest

点击(此处)折叠或打开

  1. ls
  2. libtest.so main main.c Makefile test.c test.h

现在,把Makefile中的内容改一改:

点击(此处)折叠或打开

  1. main:libtest.so
  2.         gcc main.c -L./ -o main -ltest
  3. libtest.so:test.c test.h
  4.         gcc -m32 -shared -fPIC test.c -o libtest.so
  5. clean:
  6.         rm -f libtest.so main
再 make,就会出现下面的错误:

点击(此处)折叠或打开

  1. make
  2. gcc -m32 -shared -fPIC test.c -o libtest.so
  3. gcc main.c -L./ -o main -ltest
  4. /usr/bin/ld: skipping incompatible .//libtest.so when searching for -ltest
  5. /usr/bin/ld: cannot find -ltest
  6. collect2: ld returned 1 exit status
  7. make: *** [main] Error 1
由于在编译生成 libtest.so 时增加了 -m32 这个参数,导致 libtest.so 是一个 32 位的动态库,而链拉步骤没有改,还是按照64位进行编译,结果就导致了上面的错误,看一下 libtest.so 的文件类型:

点击(此处)折叠或打开

  1. file libtest.so
  2. libtest.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xc19c3e44615cd4951e4c65e76c8b838e3dcc2507, not stripped

现在再把 Makefile改动一下:

点击(此处)折叠或打开

  1. main:libtest.so
  2.         gcc -m32 main.c -L./ -o main -ltest
  3. libtest.so:test.c test.h
  4.         gcc -m32 -shared -fPIC test.c -o libtest.so
  5. clean:
  6.         rm -f libtest.so main
两个步骤都加入了 -m32 这个参数,再编译:

点击(此处)折叠或打开

  1. 0@lhn:tmp]$ make
  2. gcc -m32 -shared -fPIC test.c -o libtest.so
  3. gcc -m32 main.c -L./ -o main -ltest
  4. 0@lhn:tmp]$ ls
  5. libtest.so main main.c Makefile test.c test.h
  6. 0@lhn:tmp]$ file libtest.so main
  7. libtest.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0xc19c3e44615cd4951e4c65e76c8b838e3dcc2507, not stripped
  8. 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 这个参数时编译仍然有问题,比如

点击(此处)折叠或打开

  1. In file included from /usr/include/stdio.h:28:0,
  2. from AVAPIs_Client.c:1:
  3. /usr/include/features.h:324:26: fatal error:bits/predefs.h: No such file or directory compilation terminated.
  4. 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) |
给主人留下些什么吧!~~