【Linux】Linux上代码的编译与调试

目录

Linux上常用的编译器gcc\g++

如何使用gcc/g++

编译过程:

如何使用gcc编译?

进行预处理

进行编译

进行汇编

进行链接

函数库

函数库的分类

gcc选项

Linux调试器-gdb的使用

gdb的常用参数

Linux项目自动化构建工具make/Makefile

原理

利用上述知识做一个简单的进度条程序

Makefile

进度条函数的实现(.c文件)

进度条的头文件

进度条的主函数


Linux上常用的编译器gcc\g++

  • GCC(GNU Compiler Collection):GCC 是一个功能强大且广泛使用的编译器套件,在 Linux 系统中被广泛采用。它支持多种编程语言,如 C、C++、Objective-C、Fortran 等,是许多开源项目和软件的首选编译工具。

  • G++:G++ 实际上是 GCC 的 C++ 编译器版本,专门用于编译 C++ 代码。它提供了对 C++ 标准的良好支持,并且与 GCC 一起安装在许多 Linux 发行版中。

如何使用gcc/g++

  • 在了解如何使用gcc和g++编译代码之前,我们先了解一下编译的过程

编译过程:

  1. 预处理阶段:预处理阶段的主要任务是宏定义、文件包含、条件编译、去除注释(展开头文件、去注释、条件编译、宏替换)等。这时候会生成以.i为后缀的文件

  2. 编译阶段(生成汇编代码):这个阶段首先检查代码的规范性、是否有语法错误等,确定无误后将代码翻译为汇编语言。这时会将.i文件转换成.s文件

  3. 汇编(将汇编代码转换成机器码):将编译生成的.s文件转成目标文件。

  4. 链接:编译成功之后就进入链接阶段,这时会生成可执行文件或者库文件。

如何使用gcc编译?

  • 通用格式

gcc 【选项】 要编译的文件 【选项】 目标文件
  • 未编译前的状态,此时只有一个我们写好的.c文件

进行预处理

  • 我们使用下面的命令对文件进行预处理,其中选项【-E】的作用是让gcc在预处理结束后停止编译过程,【-o】是指目标文件,【.i】文件为已经预处理过的文件

gcc -E test.c -o test.i

进行编译

  • 我们使用下面的命令对文件进行编译,其中选项【-S】的作用是让gcc在编译结束后停止汇编过程,【-o】是指目标文件,【.s】文件为已经预处理过的文件

gcc -S test.i -o test.s

进行汇编

  • 我们使用下面的命令对文件进行汇编

gcc -c test.s -o test.o

进行链接

  • 我们使用下面的命令对文件进行链接

gcc test.o -o test

  • 如此我们便完成了程序的编译,文件后缀的变更顺序为iso(和摄影中的感光的一样)

函数库
  • 不知道大家有没有发现一个问题,我们的c程序中可并没有printf的函数实现,头文件stdio中也只有它的声明,并没有它的实现,它是在哪里实现的呢?

  • 系统把这些函数实现都放在libc.so.6的库文件中去了,在没有特别指定的情况下gcc回去系统默认的搜索路径/usr/lib下进行查找,这便是链接。

  • 通过ldd命令查看可执行程序所以来的库

函数库的分类
  • 函数库分为两类:静态库和动态库。

  • 静态库是指在编译链接时,把库文件的代码全部加入到可执行文件当中去,这样做的结果就是生成的文件会比较大,但运行时也不再需要库文件了,静态库一般后缀为.a

  • 动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序资兴市有运行时链接文件加载库,这样可以节省系统开销。动态库一般后缀为.so。gcc在编译时默认使用动态库。

gcc选项

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

  • 【-S】:编译到汇编语言而不进行汇编和连接操作

  • 【-c】:编译到目标代码

  • 【-o】:文件输出到文件

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

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

  • 【-shared】:此选项将尽量使用动态库,生成文件较小,但要保证有动态库

  • 【-O0/-O1/-O2/-O3】:编译器的四个优化选项,-O0表示没有优化,默认优化级别是O1,O3是级别最高的优化

  • 【-w】:不生成任何警告信息

  • 【Wall】:生成所有警告信息

Linux调试器-gdb的使用

  • 使用gcc/g++编译出来的程序默认是release版本

  • 想对一个文件使用gdb进行调试的话,首先要保证该文件是可以被调试的(编译的时候要带上【-g】)

gdb的常用参数

Linux项目自动化构建工具make/Makefile

  • Makefile的书写格式

  • target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。prerequisites就是,要生成那个target所需要的文件或是目标。command也就是make需要执行的命令。(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。

  • 一个工程中的源文件不计其数,按照类型、功能、模块分别放在若干个目录中,按照上文所讲的方法,无疑是对程序员的酷刑。

  • makefile定义了一系列规则来指定,那些文件需要被先编译,那些文件现需要后编译,甚至与进行更复杂的功能操作

  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大地提高了软件开发效率

  • make是一个命令工,makefile是一个文件,两者搭配使用,完成项目的自动化构建

原理

  1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello”这个文件,并把这个文件作为最终的目标文件。

  3. 如果hello文件不存在,或是hello所依赖的后面的hello.o文件的文件修改时间要比hello这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。

  4. 如果hello所依赖的hello.o文件不存在,那么make会在当前文件中找目标为hello.o文件的依赖性,如果找到则再根据那一个规则生成hello.o文件。(这有点像一个堆栈的过程)

  5. 当然,你的C文件和H文件是存在的啦,于是make会生成 hello.o 文件,然后再用 hello.o 文件声明make的终极任务,也就是执行文件hello了。

  6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

  7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

  8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

利用上述知识做一个简单的进度条程序

Makefile

progress_v2: progress_v2.c test_v2.cgcc $^ -o $@
.PHONY:clean
clean:rm -f progress_v2

进度条函数的实现(.c文件)

#include"progress_v2.h"void download()
{int haveDownload  = 0;while(haveDownload < ALLBYTE){progress_v2((haveDownload*100.0)/ALLBYTE);usleep(95000);haveDownload += PERDOWNLOAD;}progress_v2(100);printf("\n");
}void progress_v2 (double rate)
{static  char arr1[4]="/-\\";//模拟进度条运行static  char arr[101] = {0};//作为进度条显示数组arr[(int)rate] = '#';fflush(stdout);printf("[%-101s][%.1lf%%][%c]\r",arr,rate,arr1[(int)rate%4]);
}

进度条的头文件

#include<stdio.h>
#include<unistd.h>#define ALLBYTE 1000
#define PERDOWNLOAD 7
void download();void progress_v2(double rate);

进度条的主函数

#include"progress_v2.h"int main()
{download();return 0;
}

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

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

相关文章

MYSQL日志 redo_log更新流程 bin_log以及bin_log数据恢复

Redo_log写入策略 Redo log的Innodb_flush_log_at_trx_commit:: 这个参数有三个取值 取值为0&#xff1a;每次事务提交时&#xff0c;只是把redo_log留在 redo log buffer中&#xff0c;宕机会丢失数据&#xff1b; 取值为1&#xff08;默认值&#xff09;&#xff1a;每次事…

1.中医学习-总论

目录 1.为什么要学中医 2.什么是中医 介绍 中医例子1&#xff1a; 中医例子2: 中医最高境界“大道至简” 中医讲究的是本质 中医核心&#xff1a;阴阳、表里、寒热、虚实 ​编辑医不叩门 3.阴阳 1.一天中的阴阳 2.一年中的阴阳 3.阴阳之间的关系 4.阴阳四季的变化 …

解决:visio导出公式为pdf图片乱码问题

今天需要将Visio编辑好的以后的图输出pdf&#xff0c;但是点击保存后公式部分一直乱码&#xff0c;如下图所示 保存为pdf后会变成&#xff1a; 解决方案&#xff1a;保存时点击文件下方的快速打印&#xff0c;存到桌面&#xff0c;不要直接点击保存

代码随想录算法训练营第二十五天|216.组合总和III,17.电话号码的字母组合

216.组合总和III 题目 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数&#xff0c;并且每种组合中不存在重复的数字。 说明&#xff1a; 所有数字都是正整数。 解集不能包含重复的组合。 示例 1: 输入: k 3, n 7 输出: [[1,2,4]] 示例 2: 输入…

24计算机考研调剂 | 【官方】山东师范大学(22自命题)

山东师范大学2024年拟接收调剂 考研调剂信息 调剂专业目录如下&#xff1a; 计算机技术&#xff08;085404&#xff09;、软件工程&#xff08;085405&#xff09; 补充内容 我校2024年硕士研究生调剂工作将于4月8日教育部“中国研究生招生信息网”&#xff08;https://yz.ch…

【模板题】:并查集

【模板】并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作。 输入格式 第一行包含两个整数 N , M N,M N,M ,表示共有 N N N 个元素和 M M M 个操作。 接下来 M M M 行,每行包含三个整数 Z i , X i , Y i Z_i,X_i,Y_i Zi​,Xi​,Yi​ 。 当 Z i …

mysql 常见问题

1、count(*) 、 count(1) 和 count&#xff08;字段&#xff09;区别 在MySQL中&#xff0c;COUNT(*)、COUNT(1) 和 COUNT(字段) 是用于统计行数的函数&#xff0c;它们的主要区别在于&#xff1a; COUNT(*)&#xff1a;会统计符合条件的所有行的数量&#xff0c;不管这些行中…

深入了解JVM底层原理

一、JVM内存结构 1、方法区&#xff1a;存储编译后的类、常量等&#xff08;.class字节码文件&#xff09; 2、堆内存&#xff1a;存储对象 3、程序计数器&#xff1a;存储当前执行的指令地址&#xff08;计算机处理器&#xff08;CPU&#xff09;正在执行的下一条指令在内存…

缺失的数字(c++题解)

题目描述 给出一个0~n组成的数组[0, 1, 2, 3 ... n]&#xff0c;从中随机去掉一个数字&#xff0c;给你新的数组&#xff0c;求解被去掉的数字。比如给你[0, 1, 3]&#xff0c;返回2。 输入格式 第一行是n。 第二行有n个数字&#xff0c;每个数字用空格隔开&#xff0c;表示…

openwrt下部署clouddrive2

在启动项上增加启动参数 在exit 0前面增加 mount --make-shared /mnt/data480g注意&#xff0c;后面的/mnt/data480g要替换成你设置的共享映射券。 拉取镜像 docker pull cloudnas/clouddrive2启动镜像 一定要用ssh在后台用docker run命令启动&#xff0c;因为openwrt前台…

函数-Python

师从黑马程序员 函数初体验 str1"asdf" str2"qewrew" str3"rtyuio" def my_len(data):count0for i in data:count1print(f"字符串{data}的长度是{count}")my_len(str1) my_len(str2) my_len(str3) 函数的定义 函数的调用 函数名&a…

linux系统kubernetes的pod的概念

pod的基本概念 pod基本概念存在的意义容器可选的设置属性创建pod单容器pod策略 多容器podpod交互pod共享进程配置节点标签钩子函数exec执行指令容器中请求端口向容器发送http请求示例 pod 基本概念 pod是集群中最小的部署单元&#xff0c;将这个设计落实到API对象上&#xff…

基于Java的大学计算机课程管理平台(Vue.js+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 实验课程档案模块2.2 实验资源模块2.3 学生实验模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 实验课程档案表3.2.2 实验资源表3.2.3 学生实验表 四、系统展示五、核心代码5.1 一键生成实验5.2 提交实验5.3 批阅实…

面试笔记——Redis(缓存击穿、缓存雪崩)

缓存击穿 缓存击穿&#xff08;Cache Breakdown&#xff09;&#xff1a; 当某个缓存键的缓存失效时&#xff08;如&#xff0c;过期时间&#xff09;&#xff0c;同时有大量的请求到达&#xff0c;并且这些请求都需要获取相同的数据&#xff0c;这些请求会同时绕过缓存系统&a…

【GameFramework框架内置模块】8、文件系统(File System)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录&#xff1a; https://blog.csdn.net/q7…

登录-前端部分

登录表单和注册表单在同一个页面中&#xff0c;通过注册按钮以及返回按钮来控制要显示哪个表单 一、数据绑定和校验 &#xff08;1&#xff09;绑定数据&#xff0c;复用注册表单的数据模型&#xff1a; //控制注册与登录表单的显示&#xff0c; 默认false显示登录 true时显…

【MySQL】4. 表的操作

表的操作 1. 创建表 语法&#xff1a; CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;说明&#xff1a; field 表示列名 datatype 表示列的类型 character set 字符集&#xff0c…

java方法的引用传递和值传递

1、方法的值参数传递 下面代码&#xff0c;它会在控制台输出什么&#xff1f; public class ArrayTest {public static void main(String[] args) {int number 100;System.out.println(number);change(number);System.out.println(number);}public static void change(int n…

vue3使用qrcodejs2-fix生成背景透明的二维码

qrcodejs官方仓库&#xff1a;GitHub - davidshimjs/qrcodejs: Cross-browser QRCode generator for javascript qrcodejs2-fix 是一个用于生成QR码的JavaScript库&#xff0c;使用的时候先安装&#xff0c;然后通过设置前景色和背景色可以控制显示的二维码效果。想生成透明背…

手撕算法-二叉树的镜像

题目描述 操作给定的二叉树&#xff0c;将其变换为源二叉树的镜像。数据范围&#xff1a;二叉树的节点数 0≤_n_≤1000 &#xff0c; 二叉树每个节点的值 0≤_val_≤1000要求&#xff1a; 空间复杂度 O(n) 。本题也有原地操作&#xff0c;即空间复杂度 O(1) 的解法&#xff0c…