【Linux系统编程】第十二弹---编辑器gcc/g++使用

✨个人主页:熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】

目录

1、什么是gcc/g++

2、gcc/g++编辑器的安装

3、gcc/g++编译的四个步骤

2.1、预处理

2.2、编译

2.3、汇编

2.4、链接

4、函数库

4.1、静态库

4.2、动态库

4.3、静态库和动态库的优缺点

5、gcc常见选项

总结


1、什么是gcc/g++

gcc是GCC中的GUN C编译器

g++是GCC中的GUN C++编译器

对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)。

对于 *.c和*.cpp文件,g++则统一当做cpp文件编译。

使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL。

gcc在编译C文件时,可使用的预定义宏是比较少的。

2、gcc/g++编辑器的安装

注意:没有安装过gcc/g++的都需要先进行安装才可以使用。

在使用gcc/g++编辑器之前我们需要先安装好此编辑器,才能进行后面的操作。步骤如下:

  1. 查看系统是否有gcc/g++编辑器

    [lin@VMCentos7 ~]$ gcc --version # 查看gcc版本
    -bash: /usr/bin/gcc: No such file or directory # 表示没有安装gcc

    [lin@VMCentos7 ~]$ g++ --version # 查看g++版本
    -bash: /usr/bin/g++: No such file or directory # 表示没有安装g++

安装过编辑器的可以直接跳过这个步骤喔~~~

  1. 安装gcc/g++编辑器

    [lin@VMCentos7 ~]$ sudo yum install -y gcc # 输入该命令,安装gcc
    #普通用户则需要使用sudo提权,root用户可以直接进行安装
    [sudo] password for lin:
    ......
    Running transaction
    Preparing : 1/1
    Installing : gcc-10.2.1-3.8.al8.x86_64 1/1
    Running scriptlet: gcc-10.2.1-3.8.al8.x86_64 1/1
    Verifying : gcc-10.2.1-3.8.al8.x86_64 1/1

    Installed:
    gcc-10.2.1-3.8.al8.x86_64

    Complete! # 表示安装成功

出现以下界面则表示安装成功!!!

复制代码
[lin@VMCentos7 ~]$ sudo yum install -y g++   # 安装g++
......
Running transaction
  Preparing        :                                                                                                1/1 
  Installing       : gcc-c++-10.2.1-3.8.al8.x86_64                                                                  1/1 
  Running scriptlet: gcc-c++-10.2.1-3.8.al8.x86_64                                                                  1/1 
  Verifying        : gcc-c++-10.2.1-3.8.al8.x86_64                                                                  1/1 

Installed:
  gcc-c++-10.2.1-3.8.al8.x86_64                                                                                         

Complete!  # 安装成功
  1. gcc/g++语法

格式 gcc [选项] 要编译的文件 [选项] [目标文件]

3、gcc/g++编译的四个步骤

⒈预处理(进行宏替换),生成 .i 的文件。

⒉编译,将预处理后的文件转换成汇编语言,生成 .s 文件。

⒊汇编,由汇编变为(目标代码)机器代码,生成.o的文件。

⒋链接,链接目标代码,生成可执行程序。

2.1、预处理

注意:g++编辑器和gcc编辑器的用法基本一致,由于我们C++的博客没有写完,因此此弹主要以gcc编辑器为主。

预处理功能主要包括宏定义,文件包含,条件编译,去注释等。预处理指令是以#号开头的代码行。

  1. 宏定义和宏替换:预处理器可以定义宏,并在源代码中使用宏进行替换,这样可以提高代码的可维护性和可读性。

  2. 文件包含:预处理器可以通过#include指令将其他文件中的内容包含到当前源文件中,这样可以方便地组织代码和复用代码。

  3. 条件编译:预处理器可以根据条件编译指令(如#ifdef、#ifndef、#if、#elif、#else、endif等)控制编译过程中是否包含某些代码段。

  4. 去注释:将写的注释去掉。

  5. 行控制:预处理器可以通过#line指令改变编译器输出的行号和文件名,这在调试时可以帮助开发者追踪代码。

下面我们来演示预处理这个阶段程序所发生的变化

命令:gcc --E test.c --o test.i //让test.c文件预处理结束后停止编译,并输出test.i文件。

gcc:表示用gcc这款编译器来编译test.c这个C语言程序

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

选项 -o:是指目标文件,.i为后缀的文件为已经过预处理的C原始程序。

通过代码看效果:

复制代码
[jkl@VMCentos7 lesson3]$ vim test.c  # 创建test.c文件并编辑
[jkl@VMCentos7 lesson3]$ gcc -E test.c -o test.i  # 对test.c文件进行预处理,输出test.i文件
[jkl@VMCentos7 lesson3]$ ls 
test.c  test.i
[jkl@VMCentos7 lesson3]$ vim test.i # 查看test.i文件

test.c文件内容如下:

复制代码
 #include<stdio.h>                                                                                                   
 #define SUM 100
 
 #define MAX 1000
 
 int main()
 {
     printf("hello linux\n");//打印linux
     printf("MAX=%d\n",MAX);//打印最大值
    return 0;
 }

test.c文件与test.i文件对比如下图(test.i文件只截取了下半部分,因为内容太多了):

2.2、编译

在这个阶段中 ,gcc 首先要检查代码的规范性、是否有语法错误等 , 以确定代码的实际要做的工作 , 在检查 无误后,gcc 把代码翻译成汇编语言。

用户可以使用 "-S" 选项来进行查看 , 该选项只进行编译而不进行汇编 , 生成汇编代码。

命令: gcc -S test.i -o test.s //将test.i文件汇编成test.s文件

命令如下:

复制代码
[jkl@VMCentos7 lesson3]$ gcc -S test.i -o test.s # 将test.i文件汇编成test.s文件
[jkl@VMCentos7 lesson3]$ ls
test.c  test.i  test.s
[jkl@VMCentos7 lesson3]$ vim test.s # 查看该文件

test.s代码如下:

2.3、汇编

汇编阶段是把编译阶段生成的 ".s" 文件转成目标文件

读者在此可使用选项 "-c" 就可看到汇编代码已转化为 ".o" 的二进制目标代码(人肉眼看不懂的那种)了。

命令: gcc -c test.s -o test.o //将test.s文件编译成test.o文件

命令如下:

复制代码
[jkl@VMCentos7 lesson3]$ gcc -c test.s -o test.o  # 将test.s文件编译成test.o文件
[jkl@VMCentos7 lesson3]$ ls
test.c  test.i  test.o  test.s
[jkl@VMCentos7 lesson3]$ vim test.o # 查看该文件

test.o代码如下:

2.4、链接

在成功编译之后 , 就进入了链接阶段。

链接的时候需要把⼀堆文件链接在⼀起才生成可执行程序。

命令: gcc test.o -o test.exe //将test.o文件链接成test.exe可执行程序

注意:如果我们不使用-o选项来指定文件生成的名字时,生成的默认文件的名字就是 a.out,这里我们依然和上面保持一致,自己来命名生成的文件的名称。

命令如下:

复制代码
[jkl@VMCentos7 lesson3]$ gcc test.o -o test.exe  # 将test.o文件链接成test.exe文件
[jkl@VMCentos7 lesson3]$ ls
test.c  test.exe  test.i  test.o  test.s
[jkl@VMCentos7 lesson3]$ ./test.exe # 执行该可执行程序,以下为输出结果
hello linux  
MAX=1000

4、函数库

我们的C程序中,并没有定义"printf"的函数实现,且在预编译中包含的"stdio.h"中也只有该函数的声明,而没有定义函数的实现,那么是在哪里实现"printf"函数的呢?

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

函数库一般分为静态库动态库两种。

C和C++的静态库需要我们自行安装。

sudo yum install -y glibc-static # C语言静态库
sudo yum install -y libstdc++-static # C++静态库

语法:

命令: gcc 源文件 -o 目标文件 -static

4.1、静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为".a"

4.2、动态库

动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为".so",如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。

gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

复制代码
[jkl@VMCentos7 lesson3]$ file test.exe
test.exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=693fe604748eab45a6e911660b8e6a2afe6b1a61, for GNU/Linux 3.2.0, not stripped

4.3、静态库和动态库的优缺点

静态链接成功,我们的程序不需要依赖任何库,自己就可以独立运行。

动态链接成功,我们的程序还是需要依赖动态库,一旦动态库缺失,我们的程序便无法运行。

静态库由于是自生拷贝的问题,所以比较浪费空间。

动态库因为可以做到被大家所共享方法,所以真正的实现永远都是在库中。程序内部只有地址,比较节省空间。

静态库 VS 动态库:Linux默认使用的是动态链接和动态库

5、gcc常见选项

-E : 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面

-S : 编译到汇编语言不进行汇编和链接

-c : 编译到目标代码

-o : 文件输出到 文件

-static : 此选项对生成的文件采用静态链接

-g : 生成调试信息。GNU 调试器可利用该信息。

-shared : 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.

-O0 -O1 -O2 -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高

-w : 不生成任何警告信息。

-Wall : 生成所有警告信息。

总结

本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

相关推荐
神秘人X70724 分钟前
Linux高效备份:rsync + inotify实时同步
linux·服务器·rsync
轻松Ai享生活30 分钟前
一步步学习Linux initrd/initramfs
linux
轻松Ai享生活34 分钟前
一步步深入学习Linux Process Scheduling
linux
绵绵细雨中的乡音2 小时前
网络基础知识
linux·网络
Peter·Pan爱编程3 小时前
Docker在Linux中安装与使用教程
linux·docker·eureka
无你想你3 小时前
利用vscode时进行调试,即使设置justMyCode为False仍然失败,如何解决?
ide·vscode·编辑器·justmycode
kunge20133 小时前
Ubuntu22.04 安装virtualbox7.1
linux·virtualbox
清溪5493 小时前
DVWA中级
linux
MUY09904 小时前
应用控制技术、内容审计技术、AAA服务器技术
运维·服务器
楠奕4 小时前
elasticsearch8.12.0安装分词
运维·jenkins