目录
一、关于gcc/g++
程序翻译的过程
①预处理:
②编译:
③汇编:
④链接:
二、gcc的使用
gcc的常见命令
①-E
②-S
③-c
三、动静态库
四、make、Makefile
首先,在我们自己的云服务器中,运行gcc -v、g++ -v如果能运行出来,就说明我们装了这两个工具,如果有的g++ -v 没有运行出来,只需要sudo yum install -y gcc-c++(sudo的前提是普通用户被添加到了信任列表中,即在root用户下输入vim /etc/sudoers后,110行左右那个%wheel ALL=ALL那行复制一下,并在复制那行的开头改为你的用户名,从而添加为信任列表)
完成gcc和g++的安装后,即可进行相关操作
gcc是一个专门用来编译链接C语言的编译器,g++是编译链接C++的编译器(g++也可以编译C语言)
程序翻译也就是将文本模式的C语言转化为计算机二进制语言
有四步:预处理、编译、汇编、链接
预处理主要有四步(不止四步)
去注释;宏替换;头文件展开;条件编译等等
编译是将C语言转化为汇编语言
汇编是将汇编语言转化为可重定向二进制目标文件
链接是将多个.o/.obj合并为一个可执行文件(.exe)
当然gcc/g++也会遵守上面的四个步骤
g++和gcc的使用一模一样,所以下面只演示了gcc,g++以此类推就行
一步到位的方式,直接将C文件变为可执行文件:
创建一个test.c文件,vim一个简易的C语言代码
直接输入gcc test.c -o test
就有了最终的可执行程序test
gcc test.c -o test中-o 后面跟的文件名称就是我们自己命名的可执行程序的名称
首先我们vim一个test.c
test.c里面包含了注释,宏,头文件,条件编译,主要是为了方便我们后续观察这几种经过预处理后的结果
从现在开始进行程序的翻译,如果预处理完成,就停下来
同样可以理解为-o后面跟的文件名称就是形成的文件的名称,即test.i就是test.c预处理之后的所形成的
然后vim test.i观察预处理后的结果:
在test.i文件的最后,我们可以观察到test.i和test.c的区别很大
首先注释消失了,头文件展开了,宏Max直接变为100在printf里了,条件编译也没有了
并且我们可以发现,行数非常多,有800多行,而我们的test.c只有18行,这时因为头文件stdio.h展开了,而头文件stdio.h中也包含了其他头文件,所以展开会非常多
从现在开始进行程序的翻译,如果编译完成,就停下来
即形成了汇编语言就停下来
vim test.s可以看到汇编语言:
从现在开始进行程序的翻译,如果汇编完成,就停下来
这里的test.o叫做可重定向二进制目标文件
这里的test.o还不能被执行,那么我们想执行,进行如下操作:
形成了可执行文件test
这一步就叫做链接过程
一般链接的过程是有两种方式的:
一是动态链接--》需要动态库
二是静态链接--》需要静态库
在Linux中,.so结尾(动态库);.a结尾(静态库)
在Windows中,.dll结尾(动态库);.lib结尾(静态库)
ldd + [文件名称]可以查看文件
框出来就是所需的库
file + [文件名称]可以查看文件具体信息
可以看到多少位的可执行程序,还有动态链接之类的信息
所以可以得知,gcc,g++所用的链接是动态链接的
动态链接:将库中我要的方法的地址,填入我的可执行程序中,建立关联(节省资源)
静态链接:将库中方法的实现,拷贝到我们的可执行程序中(占用资源)
gcc中正常编译出test的可执行程序
通过ldd和file可以观察得知是动态链接的
如果我们想静态链接,就在gcc test.c -o [文件名称]后面加-static
-static表示使用静态链接的方式形成可执行程序
有些机器在加-static时可能会报错,是因为没有安装静态库
安装C语言静态库的指令:sudo yum install -y glibc-static
安装C++静态库的指令:sudo yum install -y libstdc++-static
安装完成后,执行相应的操作:
可以发现,使用静态链接的文件大小相比于使用动态链接的文件大小,大了十倍左右,所以上面说到比较占用资源
项目自动化构建工具:make、Makefile
make是一个命令
Makefile是一个文件
所以我们可以编写Makefile,包含依赖关系和依赖方法
第一行test是目标文件名称,冒号后面是依赖文件test.c
第二行必须Tab开头,然后使依赖方法
这时我们保存退出后,如果想编译test.c,直接make
这时就形成了可执行的目标文件test
构建有了,也得有清理,所以继续vim Makefile
.PHONY相当于一个关键字,在PHONY后面的称为伪目标,下一行还是依赖方法
所以构建输入make,清理输入make clean 即可
在执行make时只会执行第一个遇到的目标文件,所以我们的下面的这个Makefile
第一个遇到的是gcc对应的目标文件,如果想执行下面的clean需要在make后面加上clean
所以如果我们不想执行第一个遇到的目标文件,就只需要在make后面带上名字即可
上面说到PHONY后面的称为伪目标,为伪目标是总是被执行的
当我们执行make时,第一次会执行,在输入make就不会执行了,提示已经是最新的了(这是根据文件的最新修改时间判断的)
而当我们执行伪文件时:
不管我们输入几次,都会执行,所以称之为总是被执行的
所以我们通常习惯给clean设置.PHONY