gcc/g++、动静态链接(6)

  • Post author:
  • Post category:其他



目录


1、gcc


2、初识链接


3、如何理解c程序的翻译过程


4、初始动/静态链接


5、g++


1、gcc

Linux中C语言的编译器为gcc

gcc  -E  源文件            从现在开始翻译,完成预处理之后停下来

gcc  -S         执行程序的翻译,完成编译工作停下来

gcc  -c         执行程序的翻译,完成汇编工作停下来

-o     生成指定的文件(后面要跟要生成的文件名)

注意:(1)预处理:头文件展开、宏替换、条件编译、删注释。

(2)编译之后形成汇编语言

(3)汇编之后形成二进制文件

汇编之后形成的二进制文件并不能直接运行,该文件称为可重定向目标文件。

预处理之后,形成 .i文件

编译之后,形成 .s文件

汇编之后,形成 .o文件

注意:上面的gcc选项,只是了解编译器的工作过程,实际使用时,并不需要一步步的生成。正常使用gcc时就如下图所示即可。

2、初识链接

语言给我们提供了一套头文件和一套库文件,需要链接来将我们自己代码中的函数调用、外部数据和库中相关联。

例如:上述c程序中,我们使用的printf函数,我们只是调用了该函数,但是printf函数是如何将字符串打印到显示器上的,我们没关心。因此需要在汇编之后,再进行链接工作,将该函数与库里的相关联。

3、如何理解c程序的翻译过程

为什么c程序的翻译过程是预处理、编译、汇编、链接这个过程,说起这个问题,还要追溯到计算机的发展史。

由于计算机只认识二进制,且早期时并没有很好的编程语言。所以人们只能通过一系列的0、1序列来操纵计算机。例如:通过纸带打孔的方式,有孔无孔就是对应的0和1。但是二进制编程效率低,所以又引出了助记符,也就是汇编语言,因为计算机只认识二进制序列,所以便有了编译器。后来人们又推出c语言,以及后面的面向对象的高级语言。因为历史是这样发展的,所以c的翻译工作就是倒着来的。


问:通过上述的小故事,了解了编译与汇编,但是为什么要有预处理阶段呢?

答:因为c语言从语法层面提供了许多特性,例如:注释。所以需要预处理阶段,对源代码进行预处理工作,对于注释,那就是删注释。


问:那为什么还要有链接这个步骤?

上述已经阐述了,链接是将自己的代码与库里的相关联,能调用别人写的东西,也就是不需要自己写了,可以提高开发效率。

4、初始动/静态链接

问:链接是如何将自己的代码与库里的相关联呢?

首先先认识以下知识:

ldd  可执行程序                   查看可执行程序所依赖的第三方库

Linux中的库分为:静态库 .a

动态库 .so


如何理解动态链接、静态链接?

下面将通过小故事回答这个问题:

静态链接:将库中有关的代码拷贝到自己的程序中。


由于静态链接会将库中的代码拷贝到程序中,所以生成的可执行程序的内存体积可能比较大,相对的可移植性比较好。

由于动态链接会到对应的库中执行相应的代码,拿到结果后返回,接着刚刚的继续运行,所以生成的可执行程序所占内存体积小,但是比较依赖库。

具体的链接细节,会在后续的博客中写到。现在只需要知道,静态链接的时候,需要.a静态库,动态链接的时候,需要.so动态库。


Linux是默认采用动态链接,如果需要静态链接,需要在命令行后添加 -static选项

gcc  test.c  -o  test  -static

5、g++

Linux中C++的编译器为g++

用g++编译器,前提是Linux中安装了g++

g++  -v                查看g++编译器的版本号

g++的操作与上述gcc基本相同,这里不做赘述,下面将通过一个示例来演示相关使用:



版权声明:本文为qq_44463986原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。