Linux 下编译链接动静态库
来源:互联网 发布:java项目遇到最大困难 编辑:程序博客网 时间:2024/05/10 19:19
输入 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));
}
$nm libtest.a //nm工具可以打印出库中的涉及到的所有符号,库既可以是静态的也可以是动态的。nm列出的符号有很多, 常见的有三种:
一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;
一种是库中定义的函数,用T表示,这是最常见的;
另外一种是所谓的"弱态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。
四、
$gcc -c -I/home/xxxxxxxx test.c //假设test.c要使用对应的静态库
$gcc -o test -L/home/xxxxxxxx test.o libadd.a
说明:这里的-I/home/xxxxxxxx和-L/home/xxxxxxxx 是通过-I(是大i还是小L)和-L指定对应的头文件和库文件的路径,libadd.a就是要用的静态库。在test.c中要包含静态库的头文件。
五、
然后执行程序就可以看到成功了。
------------------- 静态链接库end -------------------------
动态链接库
动态链接库的静态调用
一、
把add.c编译成动态链接库
1)$gcc -fPIC -o libadd.o -c add.c
2)$gcc -shared -o libadd.so libadd.o
也可以直接使用一条命令gcc -fPIC -shared -o libadd.so add.c
二、
编译test.c
gcc -o test test.c ./libadd.so
或者把libadd.so copy到目录/usr/lib中,然后执行
gcc –o test test.c libadd.so
三、
执行./test
动态链接库的动态调用
静态库和动态库同时存在,首先链接的是动态库,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 test.c -ldl ./libadd.so
0 0
- Linux 下编译链接动静态库
- linux编译动静态库
- 编译链接和动静态库
- 编译链接和动静态库
- linux下makefile多目录编译动、静态库
- 软硬链接-动静态编译
- 在linux下创建静态链接库和编译链接
- 动静态库及动静态链接
- LINUX编程下自定义库的生成与动静态链接
- linux下制作使用动静态库
- 动静态链接库解析
- Linux下静态链接库
- 老生常谈--关于Linux下编译和使用动态链接库静态链接库
- Linux下gcc编译过程,静态链接库和动态链接库
- 关于Linux下编译和使用动态链接库静态链接库
- Linux下编译boost动态链接库和静态链接库
- 动、静态库编译顺序
- 编译过程、动静态库
- VMware中CentOS设置静态IP
- 剑指offer-面试题10:二进制中1的个数
- 2010年山东省第一届ACM大学生程序设计竞赛:Balloons
- NSTimer 简述
- CodeForces 21 C Stripe 2
- Linux 下编译链接动静态库
- 阿里云上安装Git
- 你不知道的JavaScript--Item37 面向对象高级程序设计
- Swift UITextField/UITextView(placeholder的制作)
- Ubuntu下apache环境搭建
- 关于友盟推送收不到消息,有可能是用的不是友盟的V4包
- 嵌入式linux:LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
- map排序
- 修改HTML元素