Linux开发工具【gcc/g++】

Linux开发工具之【gcc/g++】

上文我们已经学习了vim编辑器的相关操作和使用,已经可以在Linux下编写代码了,有了代码就需要编译运行,此时就需要用到Linux中的编译工具gcc/g++了,其中gccC语言的编译器,g++C++的编译器,下面我们一起来学习一下吧


文章目录:

  • Linux开发工具之【gcc/g++】
  • 1. Linux编译器gcc/g++使用
    • 1.1 目标文件
    • 1.2 预处理
    • 1.3 编译
    • 1.4 汇编
    • 1.5 链接
  • 2. 库
    • 2.1 动态库
    • 2.2 静态库
  • 3. 自动化构建工具make/Makefile
    • 3.1 概念引入
    • 3.2 Makefile文件
    • 3.3 make指令
    • 3.4 .PHONY伪目标
  • 4. sudo提权
    • 4.1 sudo使用
    • 4.2 sudo配置

1. Linux编译器gcc/g++使用

下面以gcc为例来进行讲解,学会了gccg++也自然不在话下,这两个编译器的选项都是通用的,上手比较简单

1.1 目标文件

将代码编译链接生成可执行程序,默认生成可执行文件a.out

gcc/g++ 源文件

当然也可以通过-o选项,来生成指定的可执行文件

-o 目标文件:生成指定目标文件

gcc/g++ -o 目标文件 源文件
gcc/g++ 源文件 -o 目标文件

注意:-o选项后必须跟要生成的目标文件,这个选项放在源文件前面或者后面都是可以的

1.2 预处理

在之前说到过,程序的翻译分为:预处理、编译、汇编、链接四个阶段,下面我们就通过gcc的学习来具体看看每个阶段都做了些什么

首先是预处理,主要功能包括包括宏定义,文件包含,条件编译,去注释等,经过预处理后文件的后缀为.i

通过-E选项,可以使编译器在执行完预处理后停下来,配合-o生成指定文件

gcc/g++ -E 源文件 -o 目标文件(.i)

1.3 编译

第二步是编译,在这个阶段gcc/g++会对代码进行语法分析、词法分析、语义分析、符号汇总等,然后将合法的代码转为汇编代码,经过编译后文件的后缀为.s

通过-S选项,可以使编译器在执行完编译后就停下来,配合-o生成指定文件

-S 源文件 -o 目标文件(.s)  //也可以直接从.i文件开始执行

1.4 汇编

第三步是汇编,这个阶段是将汇编代码转化为二进制,并生成符号表,也就是把编译阶段生成的.s文件转成目标文件,经过汇编后的文件后缀为.o

符号表相当于每个函数独自的地址,在Linux 中,C语言的符号表通常是 _函数名,如 _Add ,C++的符号表通常为 _Z函数名长度+函数名+参数1+参数2

通过 -c 选项,可以使 编译器在执行完汇编阶段后就停下来,配合-o生成指定文件

gcc/g++ -c 源文件 -o 目标文件(.o)  //也可以从.i/.s文件开始执行

二进制文件是elf格式,用vim直接查看是乱码,可以用readelf工具查看,没有的可以自行下载

1.5 链接

最后一步是链接,这个阶段会进行合并段表,符号表的合并和重定位等操作,会将程序运行所需的各种函数链接起来,包括与库函数的链接,Linux 中一般是动态链接,链接后生成可执行文件,默认为a.out,也可以自己指定

gcc/g++ 源文件 -o 目标文件  //也可以从.i/.s/.c文件开始执行

以上就是gcc/g++的全部讲解和操作了,希望对各位有帮助

2. 库

每种编程语言都有自己的库,比如c语言的stdiostdlib等,我们在调用库函数时,就是在调用标准库中的函数,Linux下C语言的标准库都在/usr/include路径下,这个文件就是C语言的动态库

2.1 动态库

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

Linux中默认使用动态链接,通过指令ldd可以列出一个程序所需要的动态链接库(动态链接库也称共享链接库)

ldd 文件名  //查看文件链接情况

这里libc.so.6就是动态链接的标志,其中lib是前缀,.so是后缀,去掉前后缀,最终为c,即为文件最终调用的库

file命令查看文件详细信息

file 文件名  //查看文件的详细信息

动态链接主要依赖不同函数在库中的位置信息进行调用,只有一份代码库,比较节省空间

举个生活中的例子帮助记忆:

  • 动态库就好像是网咖,全村的人都可以去网咖上网,还可以选择自己喜欢的机位和配置

2.2 静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a,如果想采用 静态链接的方式编译程序,需要在编译时加上 -static 选项”

没有静态库可以自行下载

yum install -y glibc-static  //下载C语言静态库
yum install -y glibc-static libstdc++-static  //下载c++语言静态库

静态库名称为libXXX.a,其中lib是前缀,.a是后缀,去掉前后缀,就是最终调用的库

由于静态链接是直接讲所需代码拷贝到程序中,所以最终生成的文件相对动态链接会大很多

接着上面的例子:

  • 静态库就像是你觉得村里的网吧太远了,自己买了一台电脑放到家里玩(调用某个库),不过如果买了很多台,家里就没地方放了(空间不足)

总结

  • 库分为动态库和静态库,静态库让编译器对用户程序进行静态链接,动态库让编译器对用户程序进行动态链接
  • 静态库和静态链接:链接的时候,如果是静态链接,找到静态库,拷贝静态库中的所需要的实现功能的代码到自己的可执行程序中
  • 动态库和动态链接:链接的时候,如果是动态链接,找到动态库,拷贝动态库中的所需要的实现功能的代码的地址到自己的可执行程序中。
  • 静态链接成功:程序不依赖任何库,可以独立运行
  • 动态链接成功:程序依赖动态库,一旦动态库缺失,程序无法运行。一般的云服务器,默认的只有动态库

优缺点

动态库优点

  • 可以实现不同进程间的资源共享
  • 因为自身拷贝地址,相比静态库节省很大空间
  • 不调用函数时可以不加载动态库

动态库缺点

  • 需要调用函数,加载速度较慢
  • 程序依赖动态库,一旦动态库缺失,程序无法运行

静态库优点

  • 所需函数直接拷贝至程序中,运行速度快
  • 程序不依赖任何库,可以独立运

静态库缺点

  • 因为自身拷贝实现功能代码问题,浪费空间

3. 自动化构建工具make/Makefile

3.1 概念引入

  • makefile带来的好处就是—“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

3.2 Makefile文件

make命令和Makefike文件是配合使用的,Makefile文件中用来编写任务,任务由依赖关系 + 依赖方法组成

那么什么是依赖关系和依赖方法呢?

比如源文件myfile.c,通过gcc test.c -o myfile命令编译后生成mytfile文件,此时两个文件之间的依赖关系为 myfile:myfile.c ,而依赖方法就是 gcc myfile.c -o myfile

然后将依赖关系和依赖方法写入Makefile文件中

编写完成后,我们就得到了一个基本的自动化任务,输入 make myfile 就可以直接编译 myfile.c 文件,生成 myfile

注意:任务刷新策略

  • 同一个自动化任务,执行成功后,如果相关文件最近没有发生改变,那么无法再次执行该任务
  • 想要再次执行任务,需要对源文件做出修改,或者直接 touch 源文件就行了,两种行为都会修改文件的最近修改时间,使源目标文件不是最新时间

3.3 make指令

直接输入 make 指令时,会默认执行 Makefile 中的第一个自动化任务,当任务成功执行后,不再继续执行后续任务

而使用make 任务名,则可以调用Makefile文件中的任意任务,这里的任务名就是依赖关系中:左侧的名字

3.4 .PHONY伪目标

.PHONYMakefile 文件中的一个关键字,用于对某对象生成伪目标,这样可以无视任务刷新策略,重复执行任务

.PHONY 关键字,对于源文件编译来说,没什么意义,一般是用来修饰 clean 任务,生成清理任务,实现如下

小知识:make 指令的工作原理是去 Makefile 文件中查找任务执行,设计者为了保证适用性,命名为Makefilemakefile都是可以的

4. sudo提权

4.1 sudo使用

当普通用户想去执行某些操作时,会提示权限不够,需要使用root身份,比如一个简单的下载软件操作,就有些麻烦了,为了解决这一情况,可以使用sudo进行提权,也就是暂时借助root的身份去完成某个命令

sudo 命令

当遇到权限拒绝的场景时,只需要使用sudo 命令 ,然后输入密码,就可以暂时root的身份无视权限完成指令了,这里不需要输入root密码,而是输入普通用户的密码,这样可以做到保护root的情况下执行指令

4.2 sudo配置

普通用户默认是没有赋予提权权限的,还是需要切到root用户下进行配置

配置步骤:

  1. 切换到root用户下
  2. 打开/etc/sudoers文件
  3. 翻到最下面,找到指定区域,将需要提权的用户添加进去
//root用户下
vim /etc/sudoers  //进入配置文件,按照下图修改即可


退出底行模式的时候需要使用wq!指令,这是因为是系统级配置文件所以修改需要慎重,所以必须强制修改


Linux开发工具gcc/g++,到这里就介绍结束了,本篇文章对你由帮助的话,期待大佬们的三连,你们的支持是我最大的动力!

文章有写的不足或是错误的地方,欢迎评论或私信指出,我会在第一时间改正

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/15039.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分销架构总结

概述 对于过往分销系统的经验总结。视角上会不区分实物及虚拟服务的分销。 分销定义:将产品从生产者转移到消费者。 分销职责:获客,服务(售前,售中,售后)。核心是通过不同分销渠道将产品能卖出去。 在整体分销网络…

go-zero的rpc服务案例解析

go-zero的远程调用服务是基于gRpc的gRPC教程与应用。 zero使用使用gRpc需要安装protoc插件,因为gRpc基于protoc插件使用protocol buffers文件生成rpc服务器和api的代码的。 gRPC 的代码生成还依赖 protoc-gen-go,protoc-gen-go-grpc 插件来配合生成 Go…

小程序本地生活

2023年7月1号 感觉就是视频要快点看不完 不然哪天接口又失效了 Page({/*** 页面的初始数据*/data: {// 存放轮播图的数据swiperList:[],// 存放九宫格的数据gridList:[]},/*** 生命周期函数--监听页面加载*/onLoad(options) {this.getSwiperList()this.getGridList()},// 获…

YApi-高效、易用、功能强大的可视化接口管理平台——(二)YApi 分组权限

YApi 分组权限 认识 YApi角色划分项目权限分组权限分组操作创建分组项目列表添加成员分组删除 认识 YApi YApi 是一个开源的接口管理平台,可以方便地管理和测试 API 接口,支持接口文档自动生成、Mock 数据生成、接口测试和接口监控等功能。YApi 支持多人…

cmake列表

目录 cmake多行注释 求list长度 demo 获取list的值 demo 插入list demo 追加list demo 查找列表中的字符 demo 删除list list向前删除和向后删除数据 demo 字符串反转 demo 特殊操作 Readinglist(LENGTH <list> <out-var>)list(GET <list> &…

C++图形开发(11):小球碰到方块的判定

文章目录 1.有哪些情况&#xff1f;1.1 小球在方块左侧1.2 小球在方块上面1.3 小球在方块右侧 2.解决 1.有哪些情况&#xff1f; 今天来实现下小球碰到方块的判定 那么我们首先要明确的就是在什么时候&#xff0c;小球会碰到方块&#xff1f; 1.1 小球在方块左侧 第一个就是…

SendGrid 无法注册,Create Account 按钮灰色无法点击

问题描述&#xff1a; 注册SendGrid的时候&#xff0c;账号密码都输好了&#xff0c;就是没办法点【Create Account】。 解释思路&#xff1a; 其实空白处有一个reCAPTCHA 验证码&#xff0c;但是被隐去了。所以我们的思路是如何让网页中的reCAPTCHA 验证码顺利显示出来。 问…

如何使用 OpenCV 去除图像背景

文末附源代码的免费下载链接 在本教程中,我们将学习如何使用 OpenCV 使用一种名为背景减法的技术来去除视频中的背景。 背景扣除是计算机视觉中用于检测视频中移动物体的常用技术。对于安全、监视、交通监控等来说,这是一种非常有用的技术。 背景减法的基本思想是通过从前景…

Socket编程接口API并实现简单的TCP网络编程

#include <sys/types.h> #include <sys/socket.h> socket()创建套接字&#xff0c;成功返回套接字的文件描述符&#xff0c;失败返回-1 domain: 设置套接字的协议簇&#xff0c; AF_UNIX AF_INET AF_INET6 type: 设置套接字的服务类型 SOCK_STREAM SOCK_DGRAM prot…

怎么用爱问转换工具在线拆分PDF文件

我们平时在工作中会用到很多PDF文件&#xff0c;有的PDF文件内容很多&#xff0c;里面也有许多分类类别&#xff0c;其实对于这种内容多的PDF文件&#xff0c;可以使用拆分的方式&#xff0c;来获取自己需要的材料&#xff0c;那么&#xff0c;如何快速拆分PDF文件呢&#xff1…

Mybatis-xml和动态sql

xml映射方式 除了之前那种 select(语句) public void ...();通过注解定义sql语句&#xff0c;还可以通过xml的方式来定义sql语句 注意 在resource创建的是目录&#xff0c;要用斜线分隔 创建出文件后 先写约束 <?xml version"1.0" encoding"UTF-8"…

HAProxy负载均衡集群

目录 1.1 常用的负载均衡调度器 1.2 Haproxy的简介 2.LVS、Nginx、HAproxy的区别&#xff1a; nginx LVS HAProxy 3.Haproxy搭建 Web 群集 3.1 haproxy 服务器部署 1.关闭防火墙&#xff0c;将安装Haproxy所需软件包传到/opt目录下 2.编译安装 Haproxy 3.Haproxy服务…