900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Linux编译器gcc/g++

Linux编译器gcc/g++

时间:2023-10-28 04:46:16

相关推荐

Linux编译器gcc/g++

文章目录

Liinux编译器gcc/g++1.背景知识(程序的翻译)2.动态库、静态库

Liinux编译器gcc/g++

1.背景知识(程序的翻译)

以gcc编译

以g++编译,但是此时会发现没有g++这个指令,所有需要安装它,安装指令

yum install gcc gcc-c++

gcc和g++都会形成可执行文件a.out

gcc只能编译c语言代码,g++能编译c/c++

以c程序为例,来看看它从一个文本类的c程序编译成计算机可以认识的二进制程序它需要经过四个阶段

预处理

编译

汇编

连接

每个阶段要做什么?

预处理

预处理阶段会做

1.去注释

2.头文件展开

3.条件编译

4.宏的替换

编写一个c程序,其中有宏、头文件、注释

而gcc它预处理阶段所需的选项是-E

-E后面跟的是编写的文件,然后-o是生成目标文件,可以自己指定生成文件名

然后再打开文件将这两个文件一对比

预处理之后mycode这个文件里面的内容较于mycode.c文件多了太多内容了

从开始行一直往下翻,直到int main,它多了这些内容都是从头文件中拷贝过来的,而这个行为是头文件的展开

它多出了这么多内容是从头文件中拷贝过来的,那么这个头文件又是从哪来,其实在你安装编写c/c++或者其它语言的环境时,不仅仅是安装了软件,还将其所需的头文件库文件等内容也一并安装了,头文件头文件他也是文件对吧!来看看头文件存在系统哪里

一般开发所需的头文件它是在/usr/include/这个路径下

这个路径是Linux下gcc/g++它的头文件的搜索路径

如打开stdio.h这个头文件

它里面有很多内容

所有我们在安装如vs之类的开发环境之外,还安装了对应的开发包!同步也在下载了c/c++的头文件

而其中宏定义的M,经过预处理之后进行了值替换

注释也去掉了

条件编译

它是以宏的方式定义DEBUG,它是如果存在这个,那么就输出 printf(“hello\n”);

没有保留printf(“xiao\n”);,他这是选择!

在预处理之后编译器继续运行形成汇编!这个阶段叫做编译

编译

编译会将代码形成汇编

gcc -S mycode.c -o mycode.s

汇编,是-S选项,后面跟源文件,-o 汇编成目标文件,一般以.s为后缀

vim打开mycode.s文件,会发现里面都是汇编代码

形成汇编代码之后再经过汇编阶段形成机器可以识别的二进制码

汇编

它汇编阶段的选项是-c

演示汇编阶段gcc -c mycode.s -o mycode.o

当以vim打开这个文件,全是乱码,这是因为它是一个文本编辑器,要以专门看二进制文件的。

以od这个工具查看

汇编之后再经过连接形成可执行文件。

连接

直接gcc编译不用再跟选项,gcc mycode.i -o mytest它会形成可执行文件

-o后面紧跟着你要形成的文件名,自定义的!如果不加,那么它会形成a,out

-E:预处理!对程序进行翻译,将预处理工作做完就停下来,再执行就是编译了

-S:编译!将c语言代码翻译成汇编代码,编译工作做完之后就停下来,再执行就是汇编

-c:汇编!将汇编代码翻译成机器可识别的二进制码,它生成可重定向的二进制文件

2.动态库、静态库

连接:将二进制文件与库进行链接形成可执行程序

链接它的库是啥作用?这个库给我们提供方法,他其实就是c语言的标准库,那么它在哪存在?

存在:/usr/lib64之下,

此时只看见有动态库,等会安装静态库

静态库安装

安装C语言静态库

yum -y install glibc-static

安装c++静态库

yum -y install libstdc++-static

c语言的标准库本质上是一个文件,库分两种,Linux下:动态库(.so),静态库(.a)

windows:动态库(.dll),静态库(.lib)

而库一般有自己的命名规则的:libname.so.xxx

有了头文件有了库文件,它方法的实现也是再库中实现,它是把源文件经过一定的翻译,然后打包,只提供一个文件,这样也可以达到隐藏文件的目的

头文件提供方法的声明,库文件提供方法的实现,加上写的代码就成为一个软件了

gcc自动去找c语言库中找与.o文件链接形成可执行文件!那它们是如何链接的?

两种链接方案:动态链接;静态链接!

动态链接:就相当于高中,学校旁边哪哪哪有一个网吧,然后学生周天去上网,学生在执行着各种活动,然后忽然想去上网,它他在学校是上不了的,因为他没有电脑,所有他跑去网吧上网,打游戏!这个网吧就相当于动态库,每次想上网都要去网吧登机才行,这种链接方式就叫做动态链接!而网吧上网不可能只有你一个人吧,有很多人去,他是共享的,动态库是共享的,这所学校的所有学生要上网都去这个网吧去!

而当这个网吧倒闭之后,这所学校的学生就不能去上网了,真惨啊!

所有动态库不能缺失,一旦一个动态库缺失,可能很多程序都无法运行,不然会让很多程序都无法跑起来!

查看一个可执行程序依赖的动态库

ldd指令

如果删掉了这个动态库文件他就跑不起来了!不要删,不然可能不止他一个程序跑不起来,可能会很多都跑不起来,因为Linux很多指令都是用c语言实现的,如果你删了,可能很多指令也不能执行噢!

静态链接:将库中的方法拷贝到自己程序中,他每次要用的时候不用再去库中,自己就能实现,这样的方式就叫做静态链接!如果有一天他的方法所在库不在了他还是可以照样运行!它不再依赖于这个库了,它将所有方法都拷贝到这个程序中!

动态链接是将方法实现在哪里拷贝到程序中,每次要连接时都要去动态库中,静态连接是将方法实现拷贝到程序中,每次要时不必去静态库中连接!但是静态连接会使程序变大,因为它拷贝了更多的东西!

在Linux中默认采用的就是动态链接!使用动态库!

而如果当想要使用静态链接要在编译时要加-static选项。静态链接是需要手动添加选项的。此时也就要求系统提供静态库。

而静态链接可以发现它的体积远大于动态链接方式!

如果没有静态库是不能使用静态链接方式的,但是如果没有动态库,只有静态库,并且能够找到,这是可以的,就算没有使用static也可以因为gcc默认链接是动态如果没有会用静态链接!其实使用static是改变链接优先级了,所以啊,一个可执行程序,为其提供的库可能不止一个偶,可能动态静态都有!

来动静态库比一比

动态vs静态

动态库是共享库,可以有效的节省资源(磁盘、网络、内存空间)缺点:动态库不可缺失,一旦缺失导致很多程序无法运行

静态库不依赖库,程序可以独立运行。缺点:占用体积大,比较消耗资源!

debug和release

在vs下程序有两种开发方式debug和release方式,平时用的就是debug方式,当代码需要提测测试时要将其以release的方式发布!测试发布的版本和用户拿到的时一样的,默认发布为release,而以debug形成的可执行程序可以被追踪,为何?因为它添加了可调试信息

而由于它添加了调试信息,它形成的可执行程序的体积又要比一般程序的大

还说一个选项 -g选项,它会将软件以debug方式发布,

那么如何去看是否是debug方式发布呢,可以使用readelf -S来查看

它会以二进制方式查看,然后可以grep debug过滤

这些也就是添加的debug信息!

g++也是一样的,就不再演示了!

🆗就到这了!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。