当前位置: 首页 > article >正文

Linux主要开发工具之gcc、gdb与make

此系列还有两篇,大家想完整掌握可以阅读另外两篇

Linux文本编辑与shell程序设计-CSDN博客

Linux基础知识详解与命令大全(超详细)-CSDN博客 

1.gcc编译系统

1.1 文件名后缀

文件名后缀

文 件 类 型

文件名后缀

文 件 类 型

.c

C源文件

.s

汇编程序文件

.i

预处理后的C源文件

.o

目标文件

.ii

预处理后的C++源文件

.a

静态链接库

.h

头文件

.so

动态链接库

.C   .cc  .cp .cpp  .c++   .cxx

C++源文件

.out

可执行程序文件

1.2 C语言编译过程

        1.预处理阶段

        预处理是常规编译之前预先进行的工作,故此得名。它读取C语言源文件,对其中以“#”开头的指令(伪指令)和特殊符号进行处理。主要包括文件包含、宏定义和条件编译指令。

 

2.编译阶段

编译程序(Compiler)对预处理之后的输出文件进行词法分析和语法分析,试图找出所有不符合语法规则的部分

3.汇编过程

汇编过程是汇编程序(Assembler)把汇编语言代码翻译成目标机器代码的过程

4.连接阶段

连接程序(Linker)要解决外部符号访问地址问题

连接模式分为静态连接和动态连接 

1.3 gcc命令行选项

Linux 系统中, C/C++ 程序编译命令是 gcc ,例如:

            $ gcc  f1.c f2.c  (针对C语言源程序)

      执行完成后,生成默认的可执行文件a.out

1.预处理选项

    C语言预处理程序通常称为cpp,它是宏处理程序,由C编译程序自动调用,在真正的编译过程之前对程序进行转换。

常用选项:

          -o file  

      2.编译程序选项 

选项 

功能

-c

只生成目标文件,不进行连接。用于对源文件的分别编译

-E

只生成预处理文件,不进行编译

-S

只进行编译,不做汇编,生成汇编代码文件格式,其名与源文件相同,但扩展名为.s

-o file

将输出放在文件file中。如果未使用该选项,则可执行文件放在a.out

-g

指示编译程序在目标代码中加入供调试程序gdb使用的附加信息

-v

在标准出错输出上显示编译阶段所执行的命令,即编译驱动程序及预处理程序的版本号

  3 连接程序选项

选项格式

功能

-c   -S    -E

如果使用其中任何一个选项,那么都不运行连接程序,而且目标文件名不应该用做参数

-llibrary

连接时搜索由library命名的库。连接程序按照在命令行上给定的顺序搜索和处理库及目标文件。实际的库名是liblibrary,但按默认规则,开头的lib和后缀(.a.so)可以被省略

-static

在支持动态连接的系统中,它强制使用静态链接库,而阻止连接动态库;而在其他系统中不起作用

-Ldir

把指定的目录dir加到连接程序搜索库文件的路径表中,即在搜索-l后面列举的库文件时,首先到dir下搜索,找不到再到标准位置下搜索

-o file

指定连接程序最后生成的可执行文件名称为file,不是默认的a.out

 1.4 动态链接库与静态链接库

Linux 下库文件的命名有一个约定,所有的库名都以 lib 开头。形如:

      libx.a        其中,x是指定的库名 

.a (归档, archive )结尾的库是静态库,以 .so (共享目标, shared object )结尾的库是动态库
生成静态库的方法实际上可分为两步:

  ① 将各函数的源文件编译成目标文件

  ② 使用ar工具将目标文件收集起来,放到一个归档文件中

动态链接库的生成

          gcc  -c  getdate.c  -shared  -o  libgetdate.so

      静态链接库的生成

          gcc  -c  getdate.c  -o  getdate.o

          ar  -rcs  libgetdate.a  getdate.o

     链接库的使用

    动态:gcc  main.c  -L/root/testgcc  -lgetdate  -o main.out

    静态:gcc  main.c  -static  -L/root/testgcc  -lgetdate  -o main.out

2 gdb程序调试工具

程序中的错误可按性质分为三种:

  1)编译错误,即语法错误。

  2)运行错误。

  3)逻辑错误。

    查找程序中的错误,诊断其准确位置,并予以改正,这就是程序调试,分为人工查错与机器调试。  

2.1 启动gdb和查看内部命令

当程序执行过程中忽然中止,屏幕上显示××××-core dumped消息,然后显示提示符,其中,××××表示出错原因

为了发挥 gdb 的全部功能,需要在编译源程序时使用 -g 选项 。如:

    $ gcc  -g  prog.c  -o  prog  (针对C语言源程序prog.c

    $ gcc  -g  program.cpp  -o  program  (针对C++源程序program.cpp

      启动gdb的方法有以下几种:

    (1) 直接使用shell命令gdb

    (2) 以一个可执行程序作为gdb的参数

       一旦启动gdb,就显示gdb提示符:

    (gdb

      并等待用户输入相应的内部命令

2.2 显示源程序和数据

  1.显示和搜索源程序

1)显示源文件

  利用 list 命令可以显示源文件中指定的函数或代码行

  list                                    list [file:] num  

  list  start , end                  list [file:]function

2)模式搜索

  forward-search  regexp    

  search  regexp  

  reverse-search  regexp

2.查看运行时数据

1print命令     一般使用格式是 :print  [/fmt]  exp

当被调试的程序停止时,可以用 print 命令(简写为 p )或同义命令 inspect 来查看当前程序中运行的数据,比如: print i*j

2gdb所支持的运算符

     用&运算符取出变量在内存中的地址,如:print  &i ,  print  &array[i]

     { type }adrexp表示一个数据类型为type、存放地址为adrexp的数据。

     file :: var  (或者 function :: var )   表示文件file(或者函数function)中变量var的值

3)输出格式

                在print  / fmt  exp 命令中,“ /”之后的fmt是表示输出格式的字母,它由表示格式的字母和表示数据长度的字母组成 。如:
                表示格式 的字母:o    x    d    u    t    f    a    i     c    s
                表示长度的字母:    b      w     h      g

4whatis命令显示出变量的数据类型,如:whatis i

5x命令可以查看内存地址中数据的值 。其使用格式是:

     x  [/fmt]  address

6display命令可以预先设置一些要显示的表达式。其一般格式是:

    display  [/fmt]  exp

   要取消对先前设置的某些表达式的自动显示功能,可以使用以下命令:

     undisplay  [disnum]

     delete display [disnum]

2.3 控制程序的执行

断点(breakpoint),观察点(watchpoint),捕捉点(catchpoint),它们统称为停止点

1.设置和显示断点

(1)设置断点:用break命令(其缩写形式为b)设置断点:

break  linenum              break  linenum  if  condition 

break  function              break  file:linenum

break  file:function         break  *address                  break    

(2)显示断点

info  breakpoints  [num]

info  break  [num]

2.设置和显示观察点

(1)设置观察点

  watch expr              rwatch expr             awatch expr

(2)显示观察点

  info breakpoints             info watchpoints

3.设置捕捉点

  命令catch的格式是: catch  event

4.维护停止点

  delete             clear            disable           enable

5.运行程序

  run命令的格式: run  [args]

6.程序的单步跟踪和连续执行

(1)单步跟踪

实行单步跟踪的命令是stepnext,其格式是:

 step  [N]

next  [N]

(2)连续执行

 continuecfg命令

7.函数调用

 call  expr                         return  [expr]

3 程序维护工具make

 3.1 make工作机制

 GNU的make的工作过程如下:

 ① 依次读入各makefile文件;

 ② 初始化文件中的变量;

 ③ 推导隐式规则,并分析所有规则;

 ④ 为所有的目标文件创建依赖关系链;

 ⑤ 根据依赖关系和时间数据,确定哪些目标文件要重新生成;

 ⑥ 执行相应的生成命令。

6.1:某个正在开发的程序由以下内容组成:

(1) 三个C语言源文件:x.cy.cz.c。设x.cy.c都使用了defs.h中的声明;

(2) 汇编语言源文件assmb.s被某个C语言源文件调用;

(3) 使用了在/home/mqc/lib/libm.so中的一组例程。

设最后生成的可执行文件名为prog

 

 3.2 makefile文件

make被调用后会依次查找名为GNUmakefilemakefileMakefile的文件

一个示例 :

prog: x.o  y.o  z.o  assmb.o

        gcc x.o  y.o  z.o  assmb.o  -L/home/mqc/lib -lm  -o prog

x.o:x.c  defs.h

        gcc  -c  x.c

y.o: y.c  defs.h

        gcc  -c  y.c

z.o:z.c

        gcc  -c  z.c

assmb.o:assmb.s

        as  -o  assmb.o  assmb.s

clean:

                rm prog  *.o

Makefile规则有以下通用形式

目标文件:[相依文件…]

<tab>命令1[#注释]

<tab>命令n[#注释]

在格式上应注意

依赖行从一行的开头开始书写
各命令行单独占一行,每个命令行的第一个字符必须是制表符 <tab> ,而不能使用 8 个空格 
# 号后的内容为注释
在依赖行上,目标文件和相依文件之间要用一个或两个冒号分开

依赖关系图

  1. 使用make的一个核心问题是确定好各文件之间的依赖关系。一般来说,生成一个目标文件可能有多个不同的途径,根据这些途径能够指定不同的依赖关系。
  2. make是依据“关系图深度优先搜索”的算法来核查目标文件及相依文件的修改时间,深度相等时,可由左到右依次进行。
  3. 适当地引入中间结果,合理地构造依赖关系图,可以省去一部分编译工作量。但并非层次越多越好,要考虑目标文件的生成过程及其所起的作用。

使用变量:

      变量定义和引用

       1 make的变量(又称做宏定义)一般均由大写字母和数字组成。

        定义变量的一般格式是:

       <变量名>=<字符串>

例如,下面都是合法的变量定义:

      OBJECT=x.o y.o z.o

      LIBES=-lm

引用make变量的方式与引用shell变量类似,即:把变量用圆括号括起来,并在前面加上“$”符号。例如: $(OBJECT)          $(LIBES)

2 make命令有丰富的命令行选项。 例如:

      -C dir       把目录改到dir     

      -d            输出所有的调试信息      

      -e            指明环境变量优先于makefile文件中的变量     

      -f file       使用file文件作为makefile文件     

      -I         忽略在执行重新生成文件的命令的过程中出现的所有错误     

      -I dir –Idir           指定一个包含makefile文件的搜索目录

  3.预定义变量

归档库 :               AR        ARFLAGS
汇编命令:          AS        ASFLAGS
C 编译命令:        CC        CPP         CFLAGS      CPPFLAGS
C++ 编译命令:   CXX       CXXFLAGS

隐式规则:

 在makefile文件中显式地指定了一些规则,称为显式规则

隐式规则就是一种惯例,即预先约定好了,不需要在makefile文件中写出来的规则。

几个常用的隐式规则:

 ① 编译C语言程序的隐式规则 

 ② 编译C++程序的隐式规则

 ③ 汇编和汇编预处理的隐式规则

相关文章:

Linux主要开发工具之gcc、gdb与make

此系列还有两篇&#xff0c;大家想完整掌握可以阅读另外两篇 Linux文本编辑与shell程序设计-CSDN博客 Linux基础知识详解与命令大全&#xff08;超详细&#xff09;-CSDN博客 1.gcc编译系统 1.1 文件名后缀 文件名后缀 文 件 类 型 文件名后缀 文 件 类 型 .c C源…...

排序算法(快速排序,选择排序......)【泪光2929】

hello&#xff0c;大家好&#xff01;今天给大家分享一下各种排序&#xff1a; 1&#xff0c;选择排序 首先从原始数组中 选择最小的1个数据&#xff0c;将其和位于第1个位置的数据交换。接着从剩下的n-1个数据中选择次小的1个元素&#xff0c;将其和第2个位置的数据交换然后…...

Conda使用方法详解

Conda是一个开源的包管理和环境管理系统&#xff0c;主要用于Python/R等科学计算领域&#xff0c;可以轻松管理不同项目的依赖关系。以下是Conda的详细使用方法&#xff1a; 一、安装与配置 1.安装Miniconda/Anaconda Miniconda是精简版&#xff0c;只包含conda和Python Ana…...

数据库的MVCC机制详解

MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09;是数据库系统中常用的并发控制机制&#xff0c;它允许数据库在同一时间点保存数据的多个版本&#xff0c;从而实现非阻塞的读操作&#xff0c;提高并发性能。 MVCC的核心思想是&…...

C++初阶-C++入门基础

目录 ​编辑 1.C的简介 1.1C的产生和发展 1.2C的参考文档 1.3C优势和难度 1.4C学习的建议 2.C的第一个程序 2.1打印Hello world 2.2头文件 2.3namespace命名空间 2.4&#xff1a;&#xff1a;作用域限定符 2.5namespace的延伸 2.6C的输入输出 3.总结 1.C的简介 …...

关于量化交易在拉盘砸盘方面应用的部分思考

关于“砸盘”的深层解析与操盘逻辑 ​​一、砸盘的本质与市场含义​​ ​​砸盘​​指通过集中抛售大量筹码导致价格快速下跌的行为&#xff0c;其核心目标是​​制造恐慌、清洗浮筹或实现利益再分配​​。不同场景下的砸盘含义不同&#xff1a; ​​主动砸盘&#xff08;操控…...

idea手动创建resources文件夹

有时maven没有构建成功可能造成&#xff0c;resources文件夹不创建的现象 此时我们可以手动创建 手动创建...

第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组题目试做(中)【本期题目:回文数组,挖矿】

OK&#xff0c;继续写我们的第十五届蓝桥杯大赛软件赛省赛Python 大学 C 组题目&#xff0c;后面的题目比较麻烦了&#xff0c;所以我们再分两期讲。 这一期的题有 &#xff1a; 回文数组&#xff0c;挖矿 文章目录 回文数组基本思路第一步&#xff0c;获取半个数组每个数需要…...

Qt动画 QAbstractAnimation

文章目录 简介QVariantAnimation 数值动画QPropertyAnimation 属性动画 QAnimationGroup 一组动画QParallelAnimationGroup 并行动画组QSequentialAnimationGroup 串行动画组 简介 QAbstractAnimation 是所有 Qt 动画的基类。 该类定义了所有动画应该都会有的功能函数。 要想实…...

SpringMvc的请求-获得请求参数

客户端请求参数的格式是: namevalue&namevalue..… 服务器端要获得请求的参数&#xff0c;有时还需要进行数据的封装&#xff0c;SpringMVC可以接收如下类型的参数: 基本类型参数 POJO类型参数 数组类型参数 集合类型参数 获得基本类型参数 Controller中的业务方法…...

flutter开发音乐APP(前提准备)

1、项目的一些环境&#xff1a; 2、接口文档&#xff1a; 酷狗音乐 NodeJS 版 API 3、接口数据结构化 Instantly parse JSON in any language | quicktype UI样式借鉴参考&#xff1a; Coffee-Expert/Apple-Music-New-UI: Apple Music Clone on Flutter, with redesigned UI…...

使用docker搭建redis镜像时云服务器无法访问到国外的docker官网时如何解决

下载redis镜像 docker redis:版本号 此时截图中无法访问到国外的docker官网 解决方案&#xff1a; 通过更换镜像源来正常下载redis镜像 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<EOF {"registry-mirrors": ["https://docker.1…...

双引擎驱动:解密音视频体验的QoS技术底座与QoE感官革命

QoS 定义&#xff1a;QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;衡量音视频传输技术层面的性能表现&#xff0c;聚焦网络传输和系统处理能力&#xff0c;通过客观指标量化服务质量。核心指标 码率/带宽&#xff1a;数据传输速率上限&#xff0c;直接…...

Qt之QNetworkInterface

简介 用于表示网络接口&#xff08;即网卡&#xff09;信息 常用接口 static QList<QNetworkInterface> allInterfaces(); static QList<QHostAddress> allAddresses(); QList<QNetworkAddressEntry> addressEntries() const;接口类型 用枚举InterfaceTy…...

pom导包成功,但是就是无法使用相关类,同时报错:Library:Maven ‘xxx‘ has broken path

开发环境&#xff1a;Intellij 2023 一、问题记录 在maven工程的pom文件导入如下某一依赖(JGit)。没有显示导包的错误&#xff0c;同时在maven仓库里面找到对应的包是正常下载到相应jar的。 但是就是无法引入相关的类。打开Project Structure&#xff0c;在Dependencies中发现…...

大数据技术之Scala

Spark运行架构核心是一个计算引擎 核心组件 1. Driver&#xff08;驱动器&#xff09; 角色&#xff1a;Spark作业的“大脑”&#xff0c;负责解析用户代码、生成任务并调度执行。 功能&#xff1a; 将用户程序转换为作业&#xff08;Job&#xff09;。 …...

LeetCode刷题常见的Java排序

1. 字符串排序(字母排序) 首先,你的代码实现了根据字母表顺序对字符串中的字母进行排序,忽略了大小写并且保留了非字母字符的位置。关键点是: 提取和排序字母:通过 Character.isLetter() 判断是否为字母,并利用 Character.toLowerCase() 来忽略大小写进行排序。保留非字…...

mysql的下载和安装2025.4.8

mysql下载和安装 MySQL的下载网址&#xff1a; https://www.mysql.com/downloads/ 点击进入Windows版本下载&#xff1a;我们可以选择需要的MySQL版本以及所需的操作系统&#xff0c;这里选择离线安装&#xff1a; 注意&#xff1a;MySQL 8.0 是带有 MySQL Installer 的最后一…...

QML Loader:延迟加载与动态切换

目录 引言相关阅读工程结构LoaderDelay.qml - 延迟加载实现完整代码HeavyComponent.qml代码解析运行效果 LoaderSwitch.qml - 动态切换组件完整代码代码解析运行效果 Main.qml - 主界面实现完整代码主界面结构代码解析 总结下载链接 引言 QML的Loader组件提供了一种强大的机制…...

Python和MicroPython的解释器区别

Python和MicroPython的解释器不是同一个&#xff0c;它们在设计目标、实现方式和运行环境上都有显著的区别。以下是它们的主要区别&#xff1a; 1. 底层实现 Python解释器&#xff08;CPython&#xff09;&#xff1a; Python的标准解释器是CPython&#xff08;C语言实现的Pyt…...

Git 的进阶功能和技巧

1、分支的概念和使用 1.1、什么是分支&#xff1f; 分支&#xff08;Branch&#xff09;是在版本控制中非常重要的概念。几乎所有版本控制系统都支持某种形式的分支。在 Git 中&#xff0c;分支是 Git 强大功能之一&#xff0c;它允许我们从主开发线分离出来&#xff0c;在不…...

解析HiveQL的ALTER TABLE ADD/REPLACE COLUMNS语句

阅读以下ALTER TABLE的ADD/REPLACE COLUMNS语句的语法,用C#编写解析函数,一个一个字符解析,所有关键字不区分大小写,一个或多个空格、Tab和换行的组合都可以是关键词之间的分隔,表名和字段名可能包含空格和Tab,语句中可以用`包裹表名和字段名,解析以下HiveQL语句在所有可…...

Spark Core编程

一 Spark 运行架构 1 运行架构 定义 Spark 框架的核心是一个计算引擎&#xff0c;整体来说&#xff0c;它采用了标准 master-slave 的结构 如图所示 2 核心组件 Spark 框架有两个核心组件: 1)Driver 2)Spark 驱动器节点&#xff08;用于执行 Spark 任务中的 main 方法&…...

在Ubuntu内网环境中为Gogs配置HTTPS访问(通过Apache反向代理使用IP地址)

一、准备工作 确保已安装Gogs并运行在HTTP模式(默认端口3000) 确认服务器内网IP地址(如192.168.1.100) 二、安装Apache和必要模块 sudo apt update sudo apt install apache2 -y sudo a2enmod ssl proxy proxy_http rewrite headers 三、创建SSL证书 1. 创建证书存储目录…...

Kafka和RocketMQ相比有什么区别?那个更好用?

Kafka和RocketMQ相比有什么区别?那个更好用? Kafka 和 RocketMQ 都是广泛使用的消息队列系统&#xff0c;它们有很多相似之处&#xff0c;但也有一些关键的区别。具体选择哪个更好用&#xff0c;要根据你的应用场景和需求来决定。以下是它们之间的主要区别&#xff1a; 1. …...

无人机装调与测试

文章目录 前言一、无人机基本常识/预备知识&#xff08;一&#xff09;无人机飞行原理无人机硬件组成/各组件作用1.飞控2.GPS3.接收机4.电流计5.电调6.电机7.电池8.螺旋桨9.UBEC&#xff08;稳压模块&#xff09; &#xff08;二&#xff09;飞控硬件简介&#xff08;三&#x…...

JavaScript Hook JSON.stringify和JSON.parse:逆向与修改实战指南

在JavaScript逆向工程中&#xff0c;Hook JSON.stringify和JSON.parse方法是一种重要的技术&#xff0c;可以用来捕获、修改或分析JSON数据的序列化和反序列化过程。本文将结合具体案例&#xff0c;详细讲解如何实现这些方法的Hook操作。 一、Hook JSON.stringify和JSON.parse…...

【图书管理系统】全栈开发图书管理系统获取图书列表接口(后端:计算图书页数、查询当前页展示的书籍)

图书列表 实现服务器代码(计算图书总数量查询当前页需要展示的书籍) 后端响应时&#xff0c;需要响应给前端的数据 records&#xff1a;第 pageNum 页要展示的图书有哪些&#xff08;存储到List集合中&#xff09;total&#xff1a;计算一共有多少本书&#xff08;用于告诉前…...

正则表达式补充——python

简介 本章是对前面正则表达式的补充。 一、复杂的查找替换等任务 content 张三是脑卒中病 李四&#xff0c;是高血脂 苏齐&#xff0c;是肺结核病 六六&#xff0c;是血血血血import re p re.compile(r...病) for one in p.findall(content):print(one) 运行结果&#xf…...

Kotlin日常使用函数记录

文章目录 前言字符串集合1.两个集合的差集2.集合转数组2.1.集合转基本数据类型数组2.2.集合转对象数组 Map1.合并Map1.1.使用 操作符1.2.使用 操作符1.3.使用 putAll 方法1.4.使用 merge 函数 前言 记录一些kotlin开发中&#xff0c;日常使用的函数和方式之类的&#xff0c;…...