gcc编译的过程

gcc编译大致分为4步:预处理编译汇编连接

1.预处理:gcc -E hello.c -o hello.i  

处理#开头的语句,头文件展开,宏替换,删除注释,预处理阶段通常不会有警告或者报错,生成预处理文件hello.i

        可以看到,hello.c文件的printf函数少了个分号结束,在预处理阶段并没有警告或者报错,查看hello.i预处理文件可以看到#include头文件被展开了,调用的宏定义(宏函数)也被替换了。

2.编译:gcc -S hello.i -o hello.s

编译预处理文件hello.i生成汇编文件hello.s编译阶段有语法错误通常会有警告或者报错。

hello.c: In function ‘main’:
hello.c:8:5: error: expected ‘;’ before ‘return’
     return 0;
     ^~~~~~

编译阶段报错,提示第八行return前少了个';',当我们加上';',再编译就不报错了并且生成了汇编文件hello.s

生成了汇编文件hello.s

3.汇编:gcc -c hello.s -o hello.o

汇编文件hello.s转换成机器能识别的二进制文件hello.o,但是二进制文件hello.o还不能运行,因为缺少库的信息,如果是第三方库,在第四步编译时就要加上-l参数指定第三方库的名称,标准库就不用加-l参数指定第三方库,比如C语言的标准库stdio.h

 生成的二进制文件hello.o

4.链接:gcc hello.o -o hello -lpthread

二进制文件hello.o链接库文件,生成可执行文件hello,比如项目中用了第三方线程库pthread,在第四步编译链接时就要加上-lpthread,编译时编译器就会自动去找libpthread.so。

#include <stdio.h>
#include <pthread.h>

#define PRODUCT(a,b) ((a)*(b)) 

void *myPrintf(void *arg)
{
    printf("hello world\n");
    pthread_exit(NULL); // 返回线程函数的值
}

int main()
{
    pthread_t tid;
    int a = PRODUCT(1+1, 2+2);
    printf("a = %d\n", a);
    pthread_create(&tid, NULL, myPrintf, NULL);
    pthread_join(tid, NULL); // 等待线程结束
    return 0;
}

执行./hello打印结果:

a = 8
hello world

 总结:

gcc编译主要分为4步:预处理编译汇编链接

1.预处理:处理#开头的语句,头文件展开,宏替换,删除注释,有语法错误通常不会有警告或者报错;

2.编译:把预处理文件编译成汇编文件,有语法错误通常会有警告或者报错;

3.汇编:把汇编文件转换成机器能识别的二进制机器文件,但是二进制机器文件还不能运行,因为缺少库的信息;

4.链接:把二进制文件链接到库文件生成可执文件,当项目中使用了第三方库时,需要加-l参数指定第三方库的名称。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值