1️⃣什么是gcc
❄️GCC(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器。它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。
❄️GCC原本作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,GCC同样适用于微软的Windows。
❄️gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。
❄️Gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。
❄️在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。而gcc则通过后缀来区别输入文件的类别。
2️⃣gcc如何生成可执行文件
在我们初学编程时,我们所用的都是IDE,不需要我们去分别执行编译的步骤,我们只管写自己的代码,点击运行就可以了,系统会自动生成可执行文件去执行。但是你还是必须要知道整个编译的过程。不管是gcc还是ide,都缺省不了这四个过程😏。
🌼预处理:在此阶段,编译器会展开头文件,删除注释,进行宏替换和条件编译。生成**.i为后缀的文件。 **
🌼编译:检查语法,生成以汇编代码形成的**.s文件**。
🌼汇编:生成以二进制代码形成的**.o文件**。
🌼链接:将库函数和目标代码连接起来,生成可执行程序。
🌊gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段将预处理得到的源代码文件,进行“翻译转换”,产生出机器语言的目标程序,得到机器语言的汇编文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是链接。在链接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的库中链到合适的地方。
3️⃣简单使用gcc
💫使用格式:gcc [选项] [要编译的文件] [选项] [目标文件]
-E只预编译,不做任何处理-c只编译不链接,生成目标文件”.o”-S
只编译不会汇编,生成汇编代码”.s”
-o 指定将file文件作为输出文件
预处理:
编译:
**汇编: **
**链接: **
** 省略前面的步骤,如何直接生成可执行文件?**
直接用【gcc filename -o 目标文件】就可以啦😘!!
日常一问😳:如何查看生成的文件是否已经被链接?即是否已经是可独立执行的文件呢?
我们用到了ldd!
什么是ldd?
ldd用来打印或者查看程序运行所需的共享库(访问共享对象依赖关系)。
表示我们makefile这个可执行文件依赖于c语言库,这就表示makefile文件已经是被链接过了,**.so**表示这个库是动态库,.6是版本👍。
如果一个文件没有被链接,那么我们ldd file 会出现什么情况呢?
😇你看,这就表示我们没有权限去执行这个.c文件,并且它不是一个动态可执行的文件,也就是说明没有被链接。
4️⃣linux的库
linux的库分为两种,分别为静态库和动态库,并且库的本质也是文件,毕竟linux下一切皆文件。
- 静态库:libXXXX.a
- 动态库:libXXXX.so
我们安装的vs2022也好,vs2019也好,其中最重要的就是下载并安装语言的头文件和库文件!我们用的指令,有相当一部分是用C写的,那么我们应该如何看待指令呢❓其实吧,指令就是程序,是工具。
🌑静态库链接:找到静态库,拷贝静态库中我所需要的代码到我自己的可执行程序中;
🌒动态库链接:找到动态库,拷贝动态库中我所需要的代码的地址到我自己的可执行程序中的相关位置;
🌓静态链接成功:我们的程序,不依赖任何库,自己就可以独立运行;
🌘动态链接成功:我们的程序,依然依赖动态库,一旦动态库缺失,我们的程序便无法运行;
🌜动静态库链接的优劣:
静态库是拷贝过去的,不依赖链接成功之后的任何库,但是浪费空间,增加了没必要的开销;
动态库是拷贝过去的地址,空间开销较小,但是一旦静态库缺省,程序就无法正常运行;
🔥****注:linux默认使用的是动态链接和动态库!
如何查看一个文件是动态链接还是静态链接?------------file !
什么是file?:
file 命令用来识别文件类型。对文件的检查分为文件系统、魔数检查和语言检查三个过程,也可用来辨别一些文件的编码格式。它是通过查看文件的头部信息来获取文件类型,而不是像 Windows 通过扩展名来辨识文件类型。
如图所示,file + 文件名,观察出makefile这个可执行文件是dynamically linked,即动态链接的。
如何强制linux静态链接一个可执行文件呢?
如图所示, 我们用【gcc 源文件名 -o 可执行文件名 -static】强制linxu系统静态链接生成了一个可执行文件,并且我们用file也查看到了它的静态链接属性。
linux系统:你最好有事!😈
版权归原作者 rookieﻬ° 所有, 如有侵权,请联系我们删除。