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

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++程序的隐式规则

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

相关文章:

  • 模型压缩技术从零到一
  • NO.67十六届蓝桥杯备战|基础算法-倍增思想|快速幂|快速乘法(C++)
  • nacos的地址应该配置在项目的哪个文件中
  • 【网安】处理项目中的一些常见漏洞bug(java相关)
  • 换脸视频FaceFusion3.1.0-附整合包
  • Lua语言的边缘计算
  • 蓝桥杯 web 展开你的扇子(css3)
  • Linux : 内核中的信号捕捉
  • 15分钟完成Odoo18.0安装与基本配置
  • OpenSceneGraph 中的 LOD详解
  • USB3.0走线注意事项和其中的协议
  • 音视频学习(三十二):VP8和VP9
  • MCP项目开发-一个简单的RAG示例
  • 第15届蓝桥杯java-c组省赛真题
  • 其他 vector 操作详解(四十)
  • 如何做到一个项目的高可用保障
  • 美国mlb与韩国mlb的关系·棒球9号位
  • 第五章 定积分 第二节 微积分基本公式
  • k8s1.24升级1.28
  • OCC Shape 操作
  • 做的比较好的时尚网站/链接推广
  • 龙岩整站优化/建站abc官方网站
  • 南宁做网站 的/南宁百度seo排名
  • 公司注册查重名/营销网站seo推广
  • 连云港做网站/做企业网站建设公司哪家好
  • 软件设计模式/宁波seo运营推广平台排名