当前位置:文档之家› 编译器和连接器

编译器和连接器

1.编译器和连接器
1.1程序怎么运行
1.1执行文件格式
a.a.out格式:unix最早提出的格式,默认输出格式
b.elf格式(excute link format):独立执行main,依赖其他程序执行(现在)
工具介绍:readdelf -h 执行文件
注意:
elf类型:ELF32(32位)
字节序:little endian/big endian
#include
char a[2]={255,1};
short *p=(short *)a;
printf("%d\n",*p);
Unix :1,255:big endian -255
Linix:255,1:little endian 511
网络字节序:little endian
注意:window的执行格式PE
1.2.执行过程
strace main追踪执行过程
结论:
执行文件本身被加载到内存
加载调用so库
程序的加载都是由init负责:根进程:init(可以通过pstree查看)

ldd main 打印共享库依赖
linux-vdso.so.1 => (0x00007fff7c7fd000)(内核处理)
libc.so.6 => /lib64/libc.so.6 (0x0000003592200000)(标准C库)
/lib64/ld-linux-x86-64.so.2 (0x0000003591e00000) (初始化进程库)
程序执行可以直接/lib64/ld-linux-x86-64.so.2 ./main

1.3.so文件
so可以执行的文件,但没有main方法,不能独立执行
so:shared objective:动态链接库
2。编译程序的过程
预编译->编译->汇编->连接
|-------gcc------|--ld--|
-E 预编译 默认是标准输出,可以使用-o,输出建议i文件-omain.i
-c 编译,默认输出.o文件,-o
-S 汇编,默认输出.s文件,-o
每次一个文件
只有连接才能多个文件
3.通用选项
-o
-w
-Werror
-Wall 打开所有警告
-O0 -O1 -O2 -O3 优化编译 影响-c
-g0 -g1 -g2 -g3 调试编译 影响-c
要调试,必须加-g编译
4.库文件的编译和连接
c:函数与函数调用构成的代码
c++:类与类对象化及其调用的代码

某些函数可以单独编译成文件
nm可以查看独立elf文件,目标文件中的函数

独立的文件有两种类型:
独立目标文件:静态库(需要连接) (.a(archive)结束的文件)
静:与执行文件连接到一起,成为执行程序的一部分
独立执行文件:共享库--动态库(不需要连接就可以使用)
动:与执行程序不在一起,需要查找加载,执行时需要加载 (.so(shell objective)结束的文件)
库的作用:复用
库的命名规则:
*.a静态库
*.so共享库
lib库名.a
lib库名.so.主版本号.次版本号.批号 -建立
5.静态库的编译与使用
5.1编译成目标文件
gcc -c [-static] *.c
(生成*.o文件,可以加上-static选项)
5.2压缩归档成*.a文件
ar命令处理
d 删除归档文件中某个文件
m 移动归档文件中某个文件
p 打印归档文件
q 快速追加一个文档
r(最常用) 插入文件到归档文件
t(常用) 显示归档内容列表
x(常用) 从归档文件提取文件
5.3使用静态库
案例:
编写代码
2个函数分别在不

同文件中input.c,diamond.c
编写调用程序
第三个文件中main,调用前两个函数,不用声明,c是弱语言,main.c
按照普通方式使用
gcc input.c diamond.c main.c -omain
直接编译,连接成可执行文件,运行main
按照静态库方式使用
gcc -c input.c
gcc -c diamond.c
首先生成input.o和diamond.o文件
(此处可以nm查看两个文件中的有哪些函数)
ar -r libku.a input.o diamond.o
压缩成libku.a的静态库,此时也可以使用nm查看库中有那些函数

方式一:当成目标文件使用
gcc *.c *.a -o输出文件
方式二:当成库使用
-l 库名 或者 -l库名
-L 库所在目录 -L库所在目录
如果直接
gcc main.c -l libku是不会找到libku.a的
必须
gcc main.c -l libku -L .
这样才会去当前路径下寻找

注意:连接库时的搜索按如下规则
/lib
/usr/lib/
不按照Path指定单位路径,而是专用环境变量LD_LIBRARY_PATH
绝对不搜索当前路径
6。共享库的编译和使用
6.1 编译
-c -fpic
6.2 连接
-shared
6.3 调用动态库
当成目标文件
gcc *.c *.so -o输出文件
当成库文件
gcc *.c -l库名 -L库所在路径 -o输出文件
6.4 程序执行怎么加载动态库?
1.找到动态库(拷贝到/lib,/usr/lib必须要root权限)
a./lib(windows)
b./usr/lib(system32)
c.LD_LIBRARY_PATH(PATH)
(declare -x LD_LIBRARY_PATH=.)
非绿色安装--有文件写入/lib或者/usr/lib:/usr/local
绿色安装: /opt/
6.5 查看执行文件需要哪些库
ldd 执行文件

#!/bin/bash
#compile the objective file
echo "compile the objective file ..."
gcc -c -fpic input.c
gcc -c -fpic diamond.c
echo "linking the shared file."
gcc input.o diamond.o -shared -olibku.so

echo "called the shared file ..."
gcc main.c -lku -L. -omain

问题:
1)动态库没有连接成执行文件的一部分,那么动态库在连接时作什么
作用:确定函数在动态库的偏移地址
(nm libku.so可以查看用到函数的偏移地址,T代表自己实现的函数,U代表外部函数)
(如果是c++的话--g++ 函数名会改变--为了函数重载)
window中:dll(运行时使用) lib(编译时使用--偏移地址)
2)函数调用的声明与头文件的作用

结论与总结:
1.gcc与g++连接时,函数名转换规则不同
(如果想防止函数名改变,可以在函数前面加上extern "C")
2.c语言弱类型语言(编译阶段)
c++强类型语言
每个变量,函数使用前,必须声明
尤其是函数
识别:编译错误还是连接错误
函数的声明比较麻烦,建议开发函数的人员在开发时,使用头文件进行声明
3.动态库的编译连接
gcc *.c -shared -fpic -o输出文件
4.调用:
gcc 调用代码.c -o输出 -l库 -L.
5.库的查找
/lib
/usr/lib

么把库所在路径设置到LD_LIBRARY_PATH环境变量
6.在c++建议使用头文件声明函数
-I 头文件搜索目录
系统默认所以头文件在/usr/include目录下
7.gcc指定编译语言
-x c++|c|assembler|nono
nono 自动根据扩展名确定语言
-x c++=cpp
-x c=.c
-x assembler=.s
8.指定语言的版本
-std=c99
-std=c89(默认)
restrict关键字是c99标准中提出
语法:修饰函数指针(register)
作用:使用restrict关键字,优化连接,使得函数参数直接使用寄存器的值
9.预处理指令(gcc *.c -E预处理之后,指令会被替换成需要的代码)
#include 头文件查找机制
/usr/inlcude目录
-I在指定目录中查找,多个目录使用多个-I
#pragma指令的作用
编译器由不同厂商实现
c标准中允许每个厂商通过#pragma扩展编译选项
#pragma GCC dependency "文件" "文件2"
#pragma GCC poison 标识字 标示字2
##使用在宏参数中
#
10.宏的定义:
#define
c编译器内置宏
命令行宏 -D
#ifdef DEBUG
printf("%d\n",NUM);
#endif
gcc main.c -DDEBUG

三。使用动态库调用动态库
共享库通过连接器定位函数
通过dlxxx系列函数定位函数
使用/lib/libdl.so的动态库
dlopen
dlsym(symbol)
dlclose
dlerror
上面函数实际是共享库操作函数
dlopen 打开共享库文件
dlclose 关闭共享库
dlsym 打开共享库中查找调用函数地址
使用dlopen打开加载共享库,返回库在内存中的地址
1)在库中根据函数名查找函数,返回函数地址
void *h=dlopen("libku.so",RTLD_NOW);
if(h==(void*)0)printf("加载失败!\n"),exit(-1);
2)在库中根据函数名查找函数,返回函数地址
int (*inp)(const char*)=dlsym(h,"input");
void (*dia)(int)=dlsym(h,"diamond");
3)调用查找到的函数
r=inp("输入半径");
dia(r);
4)关闭共享库
dlclose(h);

相关主题
文本预览
相关文档 最新文档