Linux基本开发工具

一、编译器——gcc、g++

gcc和g++的用法一样。主要就是gcc编译C语言的代码g++编译的C++代码也可以编译C语言但是不建议。所以下面的介绍以gcc为例。

1. 安装 gcc/g++

安装gcc

  • yum install -y gcc

安装g++

  • yum install -y gcc-g++ libstdc++-devel

2. 使用

语法gcc [选项] [要编译的文件] [选项] [目标文件]
选项

  • -o生成的可执行文件指定名称
  • -static对生成的文件采用静态链接链接库讲
  1. -E让gcc在预处理结束后停止编译生成的后缀为.i的文件是经过预处理的原始程序
  2. -S进行编译不进行汇编生成的后缀为.s的文件是编译生成的汇编语言
  3. -c进行汇编操作生成的后缀为.o的目标文件可重定位目标二进制文件是汇编后生成的二进制语言

在之前的程序运行和预处理博客中介绍了改内容可以回顾一下。

直接编译生成
直接编译生成

预处理
预处理

编译
编译
汇编
汇编

链接
链接

说明既然是链接形成那需要链接什么呢将函数的声明和函数的定义联系起来。例如在我们的代码中调用printf函数但是在stdio.h中只有函数的声明而函数的实现定义在链接函数库中。

软件
在这里插入图片描述

3. 链接库

源文件在生成可执行程序时这一步中重要步骤就是链接函数库。而链接库一般分为两种静态链接库动态链接库

C/C++静态库安装

C语言静态库安装yum install -y glibc-static
C++语言静态库安装yum install -y libstdc++-static

静态链接库

编译链接时把库文件的代码全部加入到可执行文件中因此生成的文件比较大。生成后链接库被删除依旧会正常运行。其后缀名一般为".a"

动态链接库

编译连接时没有把库文件的代码加入到可执行文件中而是程序运行时链接文件加载库。节省了系统开销但是一旦链接库被删除程序无法运行。其后缀名一般为".so"

产生的可执行文件体积比较
文件大小

后缀

动态库后缀静态库后缀
Linux.so.a
Windows.dll.lib

拓展

  1. libname.so.xxx 其中name就是库的名称
  2. C语言标准库本质就是文件
  3. 在CentOS7.6库文件存放在/usr/lib64路径下

注意

  1. Linux默认生成的二进制程序是使用动态库共享库想要使用静态库则在选项中加-static选项。eg:gcc [源文件] -o [目标程序] -static这个目标程序体积会变大。
  2. 如果没有动态库只有静态库不加-static也可以编译生成可执行文件。
    -static 本质改变优先级
  3. 一个程序可以混合使用动静态库但是加-static所有链接库要求全变成静态库。

4. 拓展命令od/file/ldd/readelf

od [filename]命令是一个在Linux系统上用于查看文件的八进制或十六进制表示的工具。它可以读取filename并以指定格式呈现filename内容用于分析filename的二进制表示特定的文件分析和调试任务比如查看文件的特定字节、检查文件的编码或字符集等

file [filename]命令用于确定给定文件的类型。它通过检查文件的魔术数字magic number或文件内容的特征来推断文件的类型。这对于确定一个文件是文本文件、二进制文件还是可执行文件非常有用。可以判断是静态链接还是动态链接
file

ldd [filename]命令用于显示一个可执行文件或共享库所依赖的共享库。可以列出一个二进制文件运行所需的所有动态链接共享库并提供它们的路径。可以解决缺失的动态链接库或版本冲突的问题。
ldd

readelf [选项] [filename]命令用于显示一个可执行文件或共享库的ELF可执行与链接格式格式信息。可以获取有关目标文件例如二进制文件或库的很多信息如文件类型、机器体系结构、节头表、符号表等。readelf命令用于调试和分析目标文件了解文件的内部细节和元数据。
readelf

注意 可执行程序形成的时候不是无序的二进制构成有自己的格式—ELF格式

二、自动化构建项目——make、makefile

1. 介绍

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

  1. make这一命令的作用是解释makefile中指令的命令工具。
  2. makefile作用就是“自动化编译”因为一个工程中源文件很多其按类型、功能和模块分别放在若干目录makefile制定了一些列的规则来指定文件编译的先后顺序是否需要重新编译等功能。一旦写好makefile一个make指令整个工程完全自动完成编译

2. 使用

例子

makefile文件包含依赖关系依赖方法
使用

touch——change file timestamps

stat——display file or file system status

语法stat [文件]
展示信息包括文件的跟踪信息、大小、链接数、所有者、组、权限、状态更改时间、访问时间等快速了解文件的基本属性
test属性

修改时间

语法touch [选项] [filename]
选项

  • -a修改Access时间
  • -m修改Modify时间
  • -d设定时间与日期可以使用各种不同的格式
  • -t 设定档案的时间记录格式与 date 指令相同

1. 更新Access时间 touch -a [filename]
Access

2. 更新Modify时间 touch -m [filename]
Modify

3. 修改Access和Modify为指定时间

  1. touch -d [filename]
    -d选项两种方式
  2. touch -t [filename]
    -t选项

点到为止这是为下一个.PHONY知识点服务的内容

.PHONY和makefile中常用符号@

引入.PHONY

1. 现象 连续的make没有被执行
在这里插入图片描述
2. 实验
实验
3. 结论
当test的Modify时间比依赖关系的源文件test.c的Modify时间更新make就不会执行反之就会继续执行。注意这里时间比较方式使用时间戳来比较

使用

如果不通过更改源文件Modify时间的方式能不能持续make呢答案肯定是可以的。

那就需要把它设置成为目标用.PHONY修饰。为目标的特性总是被执行的
语法.PHONY [目标文件]
演示当然具体使用时不是这样去使用
演示

一般使用这样clean就总是被执行了
使用

makefile中常用符号

$@替换了依赖关系中:左侧的内容
$^替换了依赖关系中:右侧的内容
注意我们日常需要编译的源文件可能很多如果自己添加会很麻烦使用符号代替就算新增或删除源文件等行为都不需要进行修改
符号

在依赖方法前添加@符号是在make执行是不在屏幕上进行回显
符号

使用效果:
在这里插入图片描述

3. 原理

当只输入make指令时的工作原理

  1. make命令会在当前目录下寻找makefile/Makefile这两个文件名都可以找得到文件。
  2. 找到之后会找makefile中第一个目标文件也就是上例中的test并把这个文件当作最终的目标文件
  3. 如果这个最终文件不存在并且所依赖的test.c文件的Modify的时间要比test文件新则它就会执行后面定义的依赖方法来生成test文件
  4. 如果test所依赖的test.c文件不存在那么make会在当前文件找test.c文件的依赖性如果找到则生成然后返回到上一步骤有点像堆栈调用

注意在寻找过程中如果依赖文件找不到则直接报错对于所定义的命令错误或编译不成功make根本不理。如果不需要依赖文件就如同上例中的clean就直接执行依赖方法。

三、调试器——gdb

1. 安装

yum install -y gdb

2. 使用

背景

  1. 程序的发布方式有两种debug模式和release模式。
    Linux gcc/g++默认生成的二进制程序就是release模式
  2. 要使用gdb调试必须在源代码生成二进制程序时加上-g选项

准备工作

安装gdbyum install -y gdb

被调试的代码
被调试的代码

makefile中的代码
makefile

查看可执行程序debug信息
查看可执行程序debug信息

调试

语法gdb [可执行文件]
调试时使用的命令

  • Ctrl + d 或 quitq退出
  • list(l) [行号]显示改行前后的代码一次显示十行。下次不输入指令直接回车接着上次的位置往下列。
  • list(l) [函数名]列出该函数的源代码
  • break(b) [行号]在改行设置断点
  • break(b) [函数名]在函数开头设置断点有效代码处
  • info break(b)查看断点信息
  • disable breakpoints禁用断点注意breakpoints是查看断点信息最前面Num那一列的数字
  • enable breakpoints启用断点
  • run( r )运行程序相当于vs 2019中的F5
  • continue( c )执行到下一个断点
  • next(n)单条执行相当于vs 2019中的F10 逐过程
  • step(s)进入函数调用相当于vs 2019中的F11逐语句
  • print( p ) [变量名]打印表达式的值通过表达式可以修改变量的值或调用函数
  • display [变量名]跟踪查看变量每次停下来都显示它的值监视窗口
  • undisplay取消对先前设置变量的跟踪可以指定编号——也是在最前面一列
  • until [行号]执行到改行
  • breaktrace(bt)查看函数栈帧
  • delete breakpoints删除所有断点可以跟序号指定删除某一断点
  • finish执行到当前函数返回
  1. list(l)
    list(l)

  2. break(b) / info break(b) / disable breakpoints / enable breakpoints / run( r ) / continue( c )
    断点

  3. next(n) / step(s)
    逐过程、逐语句

  4. print( p )
    p

  5. display / undisplay
    监视窗口

  6. until
    until

  7. breaktrace(bt)
    breaktrace

  8. delete breakpoints
    delete breakpoints

  9. finish
    finish

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6