c语言的编译和链接

隐藏的细节:编译与链接

编译:将源代码翻译成机器代码

在编译过程中使用gcc -c main.c 先编译main.c文件

然后使用gcc -c math.c 编译math.c 文件

在编译后会生成2个扩展为.o 的文件 main.o 和 math.o

.o文件是目标文件,该类型的文件在Linux通用格式是ELF,在windows下是PE, 这2个格式虽不兼容,但是结构类似,都是对二进制代码的封装

//main.c
#include <stdio.h>
int add(int a,int b); //一句声明
int main(){
    printf("Hello");
    int result = add(1,4); //在编译main.c的过程中不知道add函数具体是什么,但是有定义了声明,编译不会错
    return result;
}

//math.c
int add(int a,int b){
    return a+b;
}

可以使用一些命令查看elf的内容

readelf -h main.o 查看文件头

readelf -S main.o 查看段信息

objdump -s -d main.o 查看汇编指令

objdump -r main.o 查看重定位表

在编译main.c文件,编译器将add函数和printf函数的跳转地址暂时设置0,在后面的链接过程中修改

main.o里面有2个需要被重定位的函数printf和add

使用gcc main.o math.o -o main 链接得到可执行文件main

链接就是将编译好的目标文件连同用到的静态库、运行时库组合拼装成一个独立可执行的文件,包括将函数的跳转地址修正成正确的

如果你使用gcc main.o -o mian, 链接器找不到add函数的实现,报错undefined reference

makefile

makefile其实是构建一颗依赖树,使用make main命令执行

all: main
main: main.o math.o
		gcc main.o math.o -o main
main.o: main.c
		gcc -c main.c
math.o: math.c
		gcc -c math.c
clean:
		rm main main.o math.o

image-20230102111916966

posted @ 2023-01-02 11:25  cyfly  阅读(80)  评论(0)    收藏  举报