编译链接和动静态库

Author-------Dansen-----xzd2734@163.com

Linux 版本是 Red Hat 9 ,内核版本是 2.4.18
输入 which gcc 查看 gcc 的位置在 /usr/bin/gcc
gcc -v 查看 gcc 编译前的配置信息
--prefix=/usr 说明了安装目录
没有 --with-headers 说明默认的 include 就在安装目录下
所以 gcc 默认的 include 目录是 /usr/include ,要包含另一个目录,
可以用 -I dir 选项包含该目录,想要更方便的可以
在 /etc/profile 中添加一个环境变量 C_INCLUDE_PATH
C_INCLUDE_PATH="your include path"
export C_INCLUDE_PATH
gcc 默认的 lib 目录很多,一般是 /lib 和 /usr/lib
可以输入 gcc -print-search-dirs 查看
同样可以在编译时通过 -L dir 来添加,也可以在 /etc/profile 中添加
LD_LIBRARY_PATH="your ldlib path"
export LD_LIBRARY_PATH
还有就是可以/etc/ld.so.conf中添加目录,这对于安装别的库很方便
当然修改了库文件后需要运行一下ldconfig

自己制作交叉编译工具太复杂了,直接下一个arm-linux-gcc-3.4.1.tar.bz2
tar jxvf arm-linux-gcc-3.4.1.tar.bz2  -C /          解压缩到根目录下
其实由于压缩包带的目录是 usr/local/arm/3.4.1
所以实际还是在 /usr/local/arm/3.4.1 目录下
在bin中可以看到各个工具 arm-linux-gcc  ...
输入 ./arm-linux-gcc -v 可以看到配置信息
有 --with-headers=/usr/local/arm/3.4.1/arm-linux/include 说明了默认的include目录
输入 ./arm-linux-gcc -print-search-dirs 查看搜索的 lib 目录,主要的库文件还是在
/usr/local/arm/3.4.1/arm-linux/lib目录下.
arm-linux-gcc 3.4.1 可以用来编译2.6的内核
而编译bootloader还是用原来的2.95.2版的 arm-linux-gcc

程序的预处理、编译、链接都可以由gcc完成,gcc会自动调用cpp来做预处理,ld来进行链接。其中对库的链接是很重要的一部分,有静态库和动态库两种,静态库以 .a 为后缀,ld会把静态库中的代码拷到待链接的程序中,形成完整的可执行的程序。而链接动态库生成可执行程序又分为静态调用和动态调用,静态调用是在程序中包含头文件直接调用库函数,也叫显式调用,程序被加载的同时也加载了库,在加载时完成真正的地址链接。而动态调用则不需要包含头文件,在程序中使用库加载函数dlopen来加载库,使用dlsym来获取所需函数的地址,所以是在需要时才加载动态库,也是隐式调用。这样编译时和库就没有关系,不需要链接了。

对各种方式都给个实例就比较好理解了
使用库主要是为了实现代码的共享,所以一些能共用的函数放在一起写成库就最好了。
先vi add.c  代码为

int add(int x,int y)
  {
     return x+y;
  }
int sub(int x,int y)
  {
     return x-y;
  }

然后 vi add.h 代码为

int add(int x,int y);
int sub(int x,int y);

需要把 add.c 编译成.o文件,然后再用 ar 命令生成静态库
gcc -c add.c
ar -rc libadd.a add.o  遵循静态库命名的规则 lib + 名字 + .a

下来可以编写测试文件test.c
#include <stdio.h>
#include "add.h"
void main()
 {
    printf("add(5,4) is %d/n",add(5,4));
    printf("sub(5,4) is %d/n",sub(5,4));
 }

编译 gcc -o test test.c -ladd -L.
没有把libadd.a放到库搜索路径中,所以要加-L.表示当前目录。


把add.c编译成动态链接库
gcc -shared -o libadd.so add.c
同样的编译test.c
gcc -o test test.c -ladd -L.
运行提示找不到 libadd.so ,把它copy到 /lib 中,运行成功了
显然我们只给出了链接是的路径是当前目录,不过运行时找不到,说明运行时加载库是有
另外的路径的,不过在 /lib 和 /usr/lib 中肯定没问题,当然也可以添加环境变量来添加
LIBRARY_PATH="your lib path"
export LD_LIBRARY_PATH  (ms这个好像还不好用,不管了吧)

静态库和动态库同时存在,首先链接的是动态库,gcc有指定链接动静态库的选项。

使用ldd可以查看程序依赖的动态库
ldd test

下面来看看真正的动态调用动态链接库的test.c

#include <stdio.h>
#include <dlfcn.h>
void main()
 {
    int (*add)(int x,int y);
    int (*sub)(int x,int y);
    void *libptr;
    libptr=dlopen("./libadd.so",RTLD_LAZY); //加载动态库
    add=dlsym(libptr,"add");  //获取函数地址
    sub=dlsym(libptr,"sub");
    printf("add(5,4) is %d/n",add(5,4));
    printf("sub(5,4) is %d/n",sub(5,4));
    dlclose(libptr);
 }

编译: gcc -o test -ldl test.c 嘿嘿,要链接libdl.so库才可以用这些函数哦

这样就动态按需加载了,不需要包含该库的头文件了
这些都和windows中是一样的嘛

该睡觉了.... 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值