Linux编译器-gcc/g++使用

目录

 GCC

gcc简介:

gcc/g++的区别:

gcc的完成:

预处理(进行宏替换):

编译(生成汇编):

汇编(生成机器可识别代码):

连接(生成可执行文件或库文件):

 技巧:gcc命令选项与生成文件后缀:

动态库,静态库 :

动态库,静态库简介:

动态库,静态库的格式:

 查询c的动态库静态库:

【ldd】指令:

 感性理解动态库,静态库:

验证:

 静态库的安装:

c静态库:

 c++静态库:

动态库,静态库的优缺点:


 GCC

gcc简介:

      gcc(GNU Compiler Collection,GNU编译器套件)是由 gnu 开发的编程语言 译器。gnu 编译器套件包括C、C++、Objective-C、Java、Ada 和 Go 语言前端,也包括了这些语言的库(如 libstdc++,libgcj等)。
      gcc 不仅支持 C 的许多“方言”,也可以区别不同的 C 语言标准;可以使用命令行 选项来控制编译器在翻译源代码时应该遵循哪个 C.

gcc/g++的区别:

:gcc编译器只能用来编译c语言,g++可以编译c语言也可以编译c++。在一些具体的语法规则上,C++在编译过程中的语法检查会更加严格。C++语言本身在编译 过程中也会引入C++的标准库,如果使用gcc编译器直接编译C++语言会在编译过程中添加额外的参数,这样会显得编译过程较为繁琐。为了更方便使用编译器,我们选择g++来编译C++代码。

gcc的完成:

  对于gcc而言,具体的过程:【预处理】--->【编译】--->【汇编】--->【连接】

预处理(进行宏替换):
预处理功能主要包括 头文件展开,宏替换,去注释,条件编译   等。
  
gcc –E file.c –o file.i

-E” 的作用是让 gcc 在预处理结束后停止编译过程。

-o 是指目标文件,“-o”后面紧跟的是后面你所形成的文件的名称
" .c "文件是源文件,“ .i ”文件是 已经过预处理的 C 原始程序
编译(生成汇编):
在这个阶段中 ,gcc 首先要检查代码的规范性、是否有语法错误等 , 以确定代码的实际要做的工作 , 在检查无误后,gcc 把代码翻译成汇编语言。
gcc –S file.i –o file.s

-S” 只进行编译而不进行汇编,从而生成汇编代码。

.i结尾的文件表示源程序;“.s结尾的文件表示经过编译生成的汇编代码

汇编(生成机器可识别代码):
汇编阶段是把编译阶段生成的 “.s” 文件转成目标文件
gcc –c file.s –o file.o
-c 就可看到汇编代码已转化为 “.o” 的二进制目标代码

.s结尾的文件表示经过编译生成的汇编代码;“.o结尾的文件表示经过编译生成的汇编代码

连接(生成可执行文件或库文件):
在成功编译之后 , 就进入了链接阶段。
gcc file.o –o file

 将可重定位目标二进制文件,和库进行链接形成可执行程序

 

在这里涉及到一个重要的概念:函数库
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

最后的答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函 数“printf”了,而这也就是链接的作用。

 技巧:gcc命令选项与生成文件后缀:

命令选项-E -S -c 【键盘左上角的Esc,只有c是小写】
文件后缀.i .s .o 【.iso为镜像文件的后缀,ISO也为国际标准化组织

动态库,静态库 :

动态库,静态库简介:

   静态库是指编译链接时 , 把库文件的代码全部加入到可执行文件中 , 因此生成的文件比较大 , 但在运行时也就不再需要库文件了。其后缀名一般为“.a”
动态库与之相反 , 在编译链接时并没有把库文件的代码加入到可执行文件中 , 而是在程序执行时由运行时 链接文件加载库, 这样可以节省系统的开销。动态库一般后缀名为 “.so”, 如前面所述的 libc.so.6 就是动态 库。gcc 在编译时默认使用动态库。完成了链接之后 ,gcc 就可以生成可执行文件。

动态库,静态库的格式:

库的本质:就是一个文件

动态库:

liunx下以lib为前缀,.so为后缀

格式:【  libfilename.soXXXX】

 window:以dll结尾

 

静态库:

liunx下:.a为后缀 

 

 window:.lib后缀

注:在我们的机器上,默认只会安装 动态库,静态库是没有安装的。

 查询c的动态库静态库:

cd /lib64/
ls
ls /lib64/libc*
ls /lib64/libc.so*
ls /lib64/libc.a*

【ldd】指令:

ldd filename —— 检测可执行程序形成的时候都依赖了哪些库

  • l -> list 【列出】
  •  d -> dynamic 【动态的】
  •  d -> dependencies【依赖关系】
  • 然后我们就可以去看看每次gcc最终链接后形成的text这个可执行程序都依赖了哪些库。然后可以看到起来的这个就是标准的C语言库

 感性理解动态库,静态库:

  高中星期学校就放半天假,张三想出去玩,从李四(混混)那里得知校外有个网吧,就去校外的网吧打游戏。张三在网吧玩了半天玩爽了就回宿舍,舍友们知道张三去了网吧玩,不带他们气愤了,舍友几个就打算也去网吧玩。他们刚去,碰到警察查身份证,结果是黑店,查封了,舍友们就只能回宿舍呆着了。

上图里(人物对应):

李四:编译器

 网吧:动态库         (只有一个)

张三和舍友们:可执行的程序

这里的动态库不能缺失,一旦缺失,影响的不止一个程序,可能很多程序都无法正常运行


张三看舍友回来,得知网吧查封,李四也知道了,李四就去二手手机店淘手机,开个手机店,按小时收费借给张三和舍友们玩。但李四这是非法经营,结果查封了,张三和舍友并不知情。

 

 手机:静态库

张三和舍友们:可执行的程序

李四:编译器

在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序,该程序以后就不需要再依赖静态库!

验证:

使用上述的ldd指令

 

 要想使用静态库需要输入:

gcc a.c -o test-static -static

相当于再结尾加了一个 -static

 静态库的安装:

c静态库:

 root用户:yum -y glibc-static

普通用户:sudo yum -y glibc-static

 c++静态库:

 root用户: yum -y install libstdc++-static

普通用户:sudo yum -y install libstdc++-static

   对于动态链接和静态链接所产生的可执行文件大小不太一样 ,差了可是100多倍!

  所以这就是为什么云服务器默认就是以动态链接进行编译了,因为静态链接虽然是无需调用库函数,但是形成的程序体积会非常庞大;而且其中有一部分库的代码,然后系统中本身又带有库,这就造成了磁盘空间的浪费。

动态库,静态库的优缺点:

【动态链接】 —— 仅仅是把库中的你所用的方法的地址拷贝到程序里 。

动态库优点:因为可以做到被大家共享方法,所以真正的实现永远都是在库中,程序内部只有地址,比较节省空间。
动态库缺点:我们的程序还是依赖任何库,一旦动态库缺失,我们的程序便无法运行。

【静态链接】 —— 自己代码当中用到的库中的方法直接拷贝到程序里 。

静态库优点:我们的程序不依赖任何库,自己就可以独立运行。
静态库缺点:因为自身的拷贝问题比较浪费空间。

以上是对gcc/g++,动态库,静态库的简单理解。 以后有更深的理解,会再续更新。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J 2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值