韦一之gcc和makefile(009课)

本文详细介绍了GCC编译器的工作流程,包括预处理、编译、汇编和链接四个阶段,并通过实例演示了不同选项下的编译过程。此外,还讲解了Makefile的基础语法和如何处理头文件依赖,以及GCC的编译参数如-Werror和-I。文章最后提到了在64位和32位系统下指针大小的差异,并探讨了动态链接与静态链接的区别。
摘要由CSDN通过智能技术生成

在这里插入图片描述

在这里插入图片描述
-v:两个功能:查看gcc编译器的版本(单独gcc -v);显示gcc执行时的详细过程,(和其它搭配,如gcc -v -o hello hello.o)。

(1)预处理 Preprocess only; do not compile, assemble or link
C/C++源文件中,以#开头的命令被称为预处理命令,如包含命令#include、宏定义命令#define、条件编译命令#if、#ifdef等。预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到一个.i文件中等待进一步处理。(把h内容插入,生成.i文件,一般很长)

(2)编译
编译就是把C/C++代码(比如上述的.i文件)翻译成汇编代码。

(3)汇编
汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现为ELF目标文件(OBJ文件,.o文件)。反汇编是指将机器代码转换为汇编代码,这在调试程序时常常用到。
(4)链接
链接就是将上步生成的OBJ文件和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。

方式1:
gcc hello.c(直接接要编译的文件) 注意前提是进入到了文件所在目录,ls命令要可以看到所在位置有本文件。
ls查看编译后文件发现多了一个a.out,是个可执行程序,然后./a.out来执行该应用程序。(要执行程序必须有./!!!有些指令呢就不需要./直接用文件名就行)
上面这个可以,不好。常使用这个:

gcc -o hello hello.c 输出hello,然后./hello来执行该应用程序。

方式2:
gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o

小结:

1)输入文件的后缀名和选项共同决定gcc到底执行那些操作。
编译器源文件的后缀名(!!!)表示源文件用的语言(支持多种语言,也包括上述c语言编译过程的中间语言),决定了编译器的默认动作(比如i文件只执行编译和汇编)
.o及.a文件呢会被传递给连接器,.o文件就只能执行链接操作了。
2)在编译过程中,除非使用了-E、-S、-c选项(或者编译出错阻止了完整的编译过程)
否则最后的步骤都是链接。

方式3:
gcc -c -o hello.o hello.c(上述方式复杂,通过这两句配合简化整个过程)
gcc -o hello hello.o

重:gcc会对.c文件默认进行预处理操作(后缀名决定了编译器进行哪些操作),
-c再来指明了编译、汇编,从而得到.o文件
。再通过gcc -o hello hello.o将.o文件进行链接,得到可执行应用程序。

链接就是将汇编生成的OBJ文件、系统库的OBJ文件、库文件链接起来,
最终生成可以在特定平台运行的可执行程序。

一个十几行小程序编译出来可能会有几千字节,为什么呢?
因为为了程序在linux平台运行,在链接时肯定会链接很多必要的函数
crt1.o、crti.o、crtbegin.o、crtend.o、crtn.o是gcc加入的系统标准启动文件,
对于一般应用程序,这些启动是必需的。

-lc:链接libc库文件,其中libc库文件中就实现了printf等函数。(-L大L是指明链接的路径的,-l指明链接哪个库文件,c是libc简写,所以是lc)

gcc -v -nostdlib -o hello hello.o会提示因为没有链接系统标准启动文件和标准库文件,而链接失败。(-nostdlib表示的不链接)
我们的程序这样编译的话会有很多错误,比如cannot find symbol_start; undefined reference to ‘puts’ 'prin

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值