Linux开发工具——gcc篇

gcc的使用

文章目录

gcc的使用

历史遗留问题(普通用户sudo)

gcc编译过程

预处理(进行宏替换)

编译(生成汇编)

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

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

动静态库

动静态库的优缺点

gcc的使用

总结


我们前面已经学习了使用vim来编写代码,我们也知道了,Linux下的工具都是各自独立的,vim用来编写代码,我们如何执行代码呢?这就需要用到gcc/g++了,那么话不多说,开启我们今天的话题!


✈️ 历史遗留问题(普通用户sudo)

我们之前在 Linux权限详解 里面,遗留了一个问题,刚创建的普通用户是不能进行 sudo 操作的。要想使用sudo 操作,我们只有先在 root 账号下将对应的 配置文件(sudoers) 进行设置,普通用户才能进行sudo操作。

那么我们在root账号下,执行:

bash 复制代码
vim /etc/sudoers#进入到设置普通用户sudo的配置文件

我们可以看到,sudoers文件对于其他组是 不开放读写与执行权限 的,若我们在普通用户下执行这个命令:

  我们发现在普通用户下执行vim命令对sudoers文件操作,是看不到内容的。

而我们在root账号下对sudoers文件执行vim,我们会发现:

如果你打开的sudoers文件没有上面的行号,只需要先将模式切换为 末行模式 ,然后执行:

bash 复制代码
set nu

命令即可,这样就会显示行号了。

我们进入该文件之后,我们向下翻找,找到大概第100行左右的位置,找到 "Allow root to run any commands anywhere" 这句话。

如果你是第一次打开该文件,你会发现在这句话下面的一条语句:

bash 复制代码
root    ALL=(ALL)   ALL

这就是root账号下的sudo配置文件,仿照上述写法,在该条语句下添加:

bash 复制代码
普通用户用户名  ALL=(ALL)   ALL

然后我们保存文件,重新进行登录,切换为普通用户,这个时候我们就可以执行sudo命令了。

这样我们的普通用户就可以使用sudo命令了,我们切换回xzy用户,查看/etc/sudoers/:


✈️ gcc编译过程

gcc/g++是进行编译的工具,对于编译的过程,无外乎分为这么几个步骤:预处理 (进行宏替换)、编译 (生成汇编)、汇编 (生成机器可识别代码)、链接(生成可执行文件或库文件)。

🔎预处理(进行宏替换)
  • 预处理的过程包括宏定义,文件包含,条件编译,去注释等。
  • 预处理指令是以#开头的代码行。
  • 选项 " -E ",该选项的作用是让 gcc 在预处理结束后停止编译的过程。
  • 选项 " -O "是指目标文件(object),".i"文件为已经预处理过的原始程序。
bash 复制代码
gcc -E xxx.c -o xxx.i#将原文件进行预处理,为了得到预处理后的文件,我们加上"-o"选项,得到目标文件

创建一个C的源文件:

对该文件进行编写:

将该文件进行预处理得到目标文件:

我们查看目标文件的内容,会发现里面的代码有了800行左右,在预处理的过程展开了头文件。

🔎编译(生成汇编)
  • 在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码实际要做的工作,在检查无误后,gcc把代码翻译为汇编语言。
  • 用户可以直接使用 "-S" 选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
bash 复制代码
gcc -S xxx.i -o xxx.s#将-i目标文件进行编译生成汇编代码,用-o选项将.s文件保存

将-i文件编译为.s文件:

使用vim来查看.s的汇编代码:

🔎汇编(生成机器可识别代码)
  • 汇编阶段是把编译阶段生成的 " .s " 文件转成目标文件。
  • 读者在此可以使用选项 " -c " 就可以看到汇编代码转化为 " .o " 的二进制代码。
bash 复制代码
gcc -c xxx.s -o xxx.o#有汇编文件生成目标文件,再由-o接收为.o文件

我们使用vim查看.o目标文件:

我们打开.o文件之后,却是乱码,这是因为我们的打开这个文件就是二进制文件,是机器代码,这种二进制文件并不是以文本的形式来存储的,所以用vim打开.o文件我们看到的是乱码。

🔎链接(生成可执行文件或库文件)
  • 在成功编译之后,就进入到了链接阶段。
bash 复制代码
gcc xxx.o -o xxx#将目标文件进行链接,称为可执行文件

其中在链接的过程中,会把.o文件与库文件进行链接的。我们C语言中所使用的 printf函数、scanf函数等都是在C语言 libc.so.6 库里面 的,而头文件<stdio.h>只是 函数声明


✈️ 动静态库

我们在使用gcc进行编译的最后一步链接时,会按照系统默认路径 "user/lib " 下进行查找,也就是生成的 .o 文件与库文件 libc.so.6 进行链接。

那么我们是如何执行C语言文件的呢?我们可以使用 ldd 命令来查看对应可执行程序的库文件:

其实我们为什么可以直接运行C语言的代码是因为我们在Linux平台下 已经安装了对应的库文件以及标准头文件

因此,平台要支持开发就 必须提前在系统中安装好对应的头文件和库文件!

函数的库一般分为 动态库静态库 ,我们来简单认识一下:

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

静态库的工作状态:

1、在编译时,静态库的目标文件(.o文件)会被链接到可执行文件中。

2、静态库的函数和数据在可执行文件中是静态的,与.o文件进行 静态链接

3、静态库的大小会增加可执行文件的大小,因为库的代码会被完整地复制到可执行文件中。

动态库的工作状态:

1、在编译时,动态库的目标文件(.o文件)会被编译成共享对象文件(.so文件)

2、动态库的函数和数据在运行时才会被加载到内存中

3、动态库的使用需要运行时的加载和链接过程,因此执行速度相对较慢

4、动态库可以被多个可执行文件共享,节省了系统资源

🔎动静态库的优缺点

动态库优缺点:

优点

  • 比较节省资源,不会出现太多重复代码 --- 磁盘资源,内存,网络等资源。

缺点

  • 对库的依赖性比较强,一旦库丢失,所有依赖这个库的程序全部无法运行

静态库的优缺点:

优点

  • 不依赖库,同类型平台中都可以直接运行使用。

缺点

  • 可执行的程序体积比较大,比较浪费资源。

✈️ gcc的使用

gcc常用的一些选项

  • -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
  • -S 编译到汇编语言不进行汇编和链接
  • -c 编译到目标代码
  • -o 文件输出到 文件
  • -static 此选项对生成的文件采用静态链接
  • -g 生成调试信息。GNU 调试器可利用该信息。
  • -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
  • -w 不生成任何警告信息。
  • -Wall 生成所有警告信息。

一般我们编译C语言的代码直接使用:

bash 复制代码
gcc xxx.c -o 运行程序文件名#编译出来直接得到可执行程序

✈️ 总结

  • 普通用户想要进行sudo操作,需要root账号在sudoers文件里面将该普通用户进行对应的设置,重启即可使用sudo指令。
  • gcc是一款编译工具,而编译过程无外乎:预处理、编译、汇编、链接 这四个步骤,gcc也可以单独对这四个步骤进行编译。
  • gcc的一些常用选项,例如:-c,-o等,需要多加练习。

如果这篇文章对各位有帮助的话,还望三连支持一下博主~~

相关推荐
绵绵细雨中的乡音1 小时前
网络基础知识
linux·网络
Peter·Pan爱编程1 小时前
Docker在Linux中安装与使用教程
linux·docker·eureka
kunge20132 小时前
Ubuntu22.04 安装virtualbox7.1
linux·virtualbox
清溪5492 小时前
DVWA中级
linux
Sadsvit3 小时前
源码编译安装LAMP架构并部署WordPress(CentOS 7)
linux·运维·服务器·架构·centos
xiaok3 小时前
为什么 lsof 显示多个 nginx 都在 “使用 443”?
linux
苦学编程的谢4 小时前
Linux
linux·运维·服务器
G_H_S_3_4 小时前
【网络运维】Linux 文本处理利器:sed 命令
linux·运维·网络·操作文本
Linux运维技术栈4 小时前
多系统 Node.js 环境自动化部署脚本:从 Ubuntu 到 CentOS,再到版本自由定制
linux·ubuntu·centos·node.js·自动化
拾心214 小时前
【运维进阶】Linux 正则表达式
linux·运维·正则表达式