欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 【Linux】基础开发工具

【Linux】基础开发工具

2025/4/19 10:10:01 来源:https://blog.csdn.net/Sakura_ding/article/details/147169278  浏览:    关键词:【Linux】基础开发工具

1. 软件包管理器

1-1 什么是软件包

在Linux下安装软件,一个通常的办法是下载到程序的源代码,并进行编译,得到可执行程序。但是这样太麻烦了,于是有些人把一些常用的软件提前编译好,做成软件包(可以理解成windows上的安装程序)放在一个服务器上,通过包管理器可以很方便地获取到这个编译好的软件包,直接进行安装。
在这里插入图片描述

软件包和软件包管理器,就好比“App”和“应用商店”这样的关系。

yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器。主要应用在Fedora、RedHat、Centos等发行版上。

Ubuntu主要使用apt(Advanced Package Tool)作为其包管理器。apt同样提供了自动解决依赖关系、下载和安装软件包的功能。

1-2 Linux软件生态

Linux下载软件的过程(Ubuntu、Centos、other):软件包1、软件包2、软件包3等向包管理器(yum/apt)发送查找、下载请求,包管理器在软件包服务器获取软件包,解决依赖关系后进行下载、安装或卸载操作,最后将结果返回给用户的云服务器。

操作系统的好坏评估涉及生态问题,包括社区论坛、官网文档、软件体系、维护更新速度、操作系统自身以及富有针对性的客户群体等方面。

软件包存在依赖问题,例如一个软件可能依赖libc.so、ssl.so、XXX.so等库文件。
在这里插入图片描述

1-3 yum具体操作

通过yum list命令可以罗列出当前一共有哪些软件包。由于包的数目可能非常之多,这里我们需要使用grep命令只筛选出我们关注的包。例如:
我这里是ubuntu系统

# Centos
$ yum list | grep lrzsz  
lrzsz.x86_64                      0.12.20-36.el7      @base           

注意事项:

  • 软件包名称:主版本号.次版本号.源程序发行号 - 软件包的发行号.主机平台.cpu架构。
  • “x86_64”后缀表示64位系统的安装包,“i686”后缀表示32位系统安装包。选择包时要和系统匹配。
  • “el7”表示操作系统发行版的版本。“el7”表示的是centos7/redhat7,“el6”表示centos6/redhat6。
  • 最后一列,base表示的是“软件源”的名称,类似于“小米应用商店”“华为应用商店”这样的概念。
  • Ubuntu有上述有详细介绍

通过yum,我们可以通过很简单的一条命令完成gcc的安装。

# Centos
$ sudo yum install -y lrzsz
# Ubuntu
$ sudo apt install -y lrzsz

yum/apt会自动找到都有哪些软件包需要下载,这时候敲“y”确认安装。出现“complete”字样或者中间未出现报错,说明安装完成。

注意事项:

  • 安装软件时由于需要向系统目录中写入内容,一般需要sudo或者切到root账户下才能完成。
  • yum/apt安装软件只能一个装完了再装另一个。正在yum/apt安装一个软件的过程中,如果再尝试用yum/apt安装另外一个软件,yum/apt会报错。
  • 如果yum / apt报错,请自行百度。

仍然是一条命令:

# Centos 
sudo yum remove [-y] lrzsz
# Ubuntu
sudo apt remove [-y] lrzsz

关于yum / apt的所有操作必须保证主机(虚拟机)网络畅通!!!可以通过ping指令验证,如:

ping www.baidu.com

当天yum / apt也能离线安装,但是和我们当前无关,暂不关心。

1-4 安装源

Centos安装源路径:

$ ll /etc/yum.repos.d/
total 16
-rw-r--r-- 1 root root 676 Oct 8 20:47 CentOS - Base.repo # 标准源
-rw-r--r-- 1 root root 230 Aug 27 10:31 epel.repo # 扩展源

Ubuntu安装源路径:

$ cat /etc/apt/sources.list # 标准源
$ ll /etc/apt/sources.list.d/ # 扩展源

更新安装源,现场说明原理即可。云服务器不用考虑,因为软件源都是国内的了。

好玩的命令

2.编辑器Vim

在这里插入图片描述

2-1 Linux编辑器-vim使用

vi/vim的区别简单点来说,都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于macos、windows。

2-2 vim的基本概念

课堂上我们讲解vim的三种模式(其实有好多模式,⽬前掌握这3种即可),分别是命令模式(command mode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:

  • 正常/普通/命令模式(Normalmode)
    控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入Insertmode下,或者到lastline mode

  • 插入模式(Insertmode)
    只有在Insertmode下,才可以做文字输入,按「ESC」键可回到命令行模式。该模式是我们后面使用的最频繁的编辑模式。

  • 末行模式(lastlinemode)
    文件保存或退出,也可以进行文件替换,找字符串,列出行号等操作。
    在命令模式下,shift+:即可进入该模式。要查看你的所有模式:打开vim,底行模式直接输⼊:help vim-mode
    在这里插入图片描述

2-3 vim的基本操作

  • 进入vim,在系统提示符符号输入vim及文件名后,就进入vim全屏幕编辑画面:

    • $ vim test.c
    • 不过有一点要特别注意,就是你进入vim之后,是处于[正常模式],你要切换到[插入模式]才能够输入文字。
  • [正常模式]切换至[插入模式]

    • 输入a
    • 输入i
    • 输入o
  • [插入模式]切换至[正常模式]

    • 目前处于[插入模式],就只能一直输入文字,如果发现输错了字,想用光标键往回移动,将该字删除,可以先按一下「ESC」键转到[正常模式]再删除文字。当然,也可以直接删除。
  • [正常模式]切换至[末行模式]

    • 「shift + ;」,其实就是输入「:」
  • 退出vim及保存文件,在[正常模式]下,按一下「:」冒号键进入「Last line mode」,例如:

    • :w (保存当前文件)
    • :wq (输入「wq」,存盘并退出vim)
    • :q! (输入q!,不存盘强制退出vim)

2-4 vim正常模式命令集

  • 插入模式
    • 按「i」切换进入插入模式「insert mode」,按“i”进入插入模式后是从光标当前位置开始输入文件;
    • 按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;
    • 按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。
  • 从插入模式切换为命令模式
    • 按「ESC」键。
  • 移动光标
    • vim可以直接用键盘上的光标来上下左右移动,但正规的vim是用小写英文字母「h」、「j」、「k」、「l」,分别控制光标左、下、上、右移一格
    • 按「G」:移动到文章的最后
    • 按「$」:移动到光标所在行的“行尾”
    • 按「^」:移动到光标所在行的“行首”
    • 按「w」:光标跳到下个字的开头
    • 按「e」:光标跳到下个字的字尾
    • 按「b」:光标回到上个字的开头
    • 按「#g」:光标移到该行的第#个位置,如: 5l,56l
    • 按「gg」:进入到文本开始
    • 按「shift + g」:进入文本末端
    • 按「ctrl + b」:屏幕往“后”移动一页
    • 按「ctrl + f」:屏幕往“前”移动一页
    • 按「ctrl + u」:屏幕往“后”移动半页
    • 按「ctrl + d」:屏幕往“前”移动半页
  • 删除文字
    • 「x」:每按一次,删除光标所在位置的一个字符
    • 「#x」:例如,「6x」表示删除光标所在位置的“后面(包含自己在内)”6个字符
    • 「X」:大写的X,每按一次,删除光标所在位置的“前面”一个字符
    • 「#X」:例如,「20X」表示删除光标所在位置的“前面”20个字符
    • 「dd」:删除光标所在行
    • 「#dd」:从光标所在行开始删除#行
  • 复制
    • 「yw」:将光标所在之处到字尾的字符复制到缓冲区中。
    • 「#yw」:复制#个字到缓冲区。
    • 「yy」:复制光标所在行到缓冲区。
    • 「#yy」:例如,「6yy」表示拷贝从光标所在的该行“往下数”6行文字。
    • 「p」:将缓冲区内的字符贴到光标所在位置。注意: 所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能。
  • 替换
    • 「r」:替换光标所在处的字符。
    • 「R」:替换光标所到之处的字符,直到按下「ESC」键为止。
  • 撤销上一次操作
    • 「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回复。
    • 「ctrl + r」:撤销的恢复
  • 更改
    • 「cw」:更改光标所在处的字到字尾处
    • 「c#w」:例如,「c3w」表示更改3个字
  • 跳至指定的行
    • 「ctrl + g」列出光标所在行的行号。
    • 「#G」:例如,「15G」,表示移动光标至文章的第15行行首。

2-5 vim末行模式命令集

在使用vim末行模式之前,请记住先按「ESC」键确定您已经处于正常模式,再按「:」冒号即可进入末行模式。

  • 列出行号
    • 「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号。
  • 跳到文件中的某一行
    • 「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。
  • 查找字符
    • 「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止。
    • 「?关键字」: 先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往前寻找到您要的关键字为止。
    • 问题: / 和?查找有和区别?操作实验一下
  • 保存文件
    • 「w」: 在冒号输入字母「w」就可以将文件保存起来
  • 离开vim
    • 「q」: 按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim。
    • 「wq」: 一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。

2-6 vim操作总结

  • 三种模式
    • 正常模式
    • 插入模式
    • 底行模式
    • 我们一共有12种总模式,大家下来可以研究一下
      在这里插入图片描述

参考资料

Vim从入门到牛逼(vimfromzerotohero)

3. 编译器gcc/g++

3-1 背景知识

  1. 预处理(进行宏替换/去注释/条件编译/头文件展开等)
  2. 编译(生成汇编)
  3. 汇编(生成机器可识别代码)
  4. 连接(生成可执行文件或库文件)

3-2 gcc编译选项

格式:gcc [选项] 要编译的文件 [选项] [目标文件]

  • 3-2-1 预处理(进行宏替换)
    • 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
    • 预处理指令是以#号开头的代码行。
    • 实例: gcc -E hello.c -o hello.i
    • 选项 “-E”,该选项的作用是让gcc在预处理结束后停止编译过程。
    • 选项 “-o” 是指目标文件,“.i” 文件为已经过预处理的C原始程序。
  • 3-2-2 编译(生成汇编)
    • 在这个阶段中,gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。
    • 用户可以使用 “-S” 选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
    • 实例: gcc -S hello.i -o hello.s
  • 3-2-3 汇编(生成机器可识别代码)
    • 汇编阶段是把编译阶段生成的 “.s” 文件转成目标文件。
    • 读者在此可使用选项 “-c” 就可看到汇编代码已转化为 “.o” 的二进制目标代码了。
    • 实例: gcc -c hello.s -o hello.o
  • 3-2-4 连接(生成可执行文件或库文件)
    • 在成功编译之后,就进入了链接阶段。
    • 实例: gcc hello.o -o hello

3-3 动态链接和静态链接

在实际开发中,不会将所有代码放在一个源文件中,会有多个源文件且存在依赖关系。每个源文件独立编译生成 “.o” 文件,为满足链接依赖关系,需将这些目标文件进行链接形成可执行程序,此过程即静态链接。静态链接缺点如下:

  • 浪费空间:每个可执行程序对所需目标文件都有副本,如多个程序调用printf()函数,都含printf.o副本。
  • 更新较难:库函数代码修改,所有依赖程序需重新编译链接。优点是可执行程序含运行所需全部内容,运行速度快。

动态链接基本思想是把程序按模块拆分,程序运行时链接成完整程序,而非像静态链接将所有程序模块链接成单个可执行文件。动态链接更常用,如查看hello可执行程序依赖动态库:

1 $ ldd hello
2     linux-vdso.so.1 =>  (0x00007fffeb1ab000)
3     libc.so.6 => /lib64/libc.so.6 (0x00007ff776af5000)
4     /lib64/ld-linux-x86-64.so.2 (0x00007ff776ec3000)
5 
6 # ldd命令用于打印程序或者库文件所依赖的共享库列表。

涉及概念“库”:C程序中未定义“printf”函数实现,“stdio.h” 只有声明,函数实现在libc.so.6库文件中,gcc默认到“/usr/lib” 查找并链接该库实现函数。

3-4 静态库和动态库

  • 静态库:编译链接时将库文件代码全部加入可执行文件,文件大,运行时无需库文件,后缀一般为 “.a”。
  • 动态库:编译链接时未将库文件代码加入可执行文件,程序执行时由运行时链接文件加载库,节省系统开销,后缀一般为 “.so”,gcc默认使用动态库。完成链接后,gcc生成可执行文件,如 gcc hello.o -o hello ,gcc默认生成动态链接二进制程序,可通过file命令验证。

注意1

  • Linux下,动态库XXX.so,静态库XXX.a
  • Windows下,动态库XXX.dll,静态库XXX.lib

注意2

一般云服务器C/C++静态库未安装,安装方法如下:

 # Centosyum install glibc-static libstdc++-static -y#ubuntusudo apt install libssl-dev

3-5 gcc其他常用选项 - 了解即可

  • -E 只激活预处理,不生成文件,需重定向到输出文件。
  • -S 编译到汇编语言,不进行汇编和链接。
  • -c 编译到目标代码。
  • -o 文件输出到指定文件。
  • -static 对生成文件采用静态链接。
  • -g 生成调试信息,GNU调试器可用。
  • -shared 尽量使用动态库,生成文件小,需系统有动态库。
  • -O0
  • -O1
  • -O2
  • -O3 编译器优化选项4个级别,-O0无优化,-O1为缺省值,-O3优化级别最高。
  • -w 不生成任何警告信息。
  • -Wall 生成所有警告信息。

4. 自动化构建-make/Makefile

4-1 背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
  • 一个工程中的源文件不计其数,按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

4-2 基本使用

实例代码

#include <stdio.h>int main()
{printf("hello Makefile!\n");return 0;
}

Makefile文件

myproc:myproc.cgcc -o myproc myproc.c
.PHONY:clean
clean:rm -f myproc

依赖关系

  • 上面的文件myproc,它依赖myproc.c。

依赖方法

  • gcc -o myproc myproc.c,就是与之对应的依赖关系。

项目清理

  • 工程是需要被清理的。
  • 像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean” ,以此来清除所有的目标文件,以便重编译。
  • 但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
  • 可以将我们的hello目标文件声明成伪目标,测试一下。

什么叫做总是被执行?

在这里插入图片描述

文件=内容+属性

  • Modify: 内容变更,时间更新
  • Change:属性变更,时间更新
  • Access:常指的是文件最近一次被访问的时间。在Linux的早期版本中,每当文件被访问时,其atime都会更新。但这种机制会导致大量的IO操作。

结论:.PHONY让make忽略源文件和可执行目标文件的M时间对比。

4-4 推导过程

Makefile推导示例

myproc:myproc.ogcc myproc.o -o myproc
myproc.o:myproc.sgcc -c myproc.s -o myproc.o
myproc.s:myproc.igcc -S myproc.i -o myproc.s
myproc.i:myproc.cgcc -E myproc.c -o myproc.i
.PHONY:clean
clean:rm -f *.i *.s *.o myproc

编译过程
在这里插入图片描述

$ make
gcc -E myproc.c -o myproc.i
gcc -S myproc.i -o myproc.s
gcc -c myproc.s -o myproc.o
gcc myproc.o -o myproc

make工作原理

  1. make会在当前目录下找名字叫“Makefile” 或“makefile” 的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,它会找到myproc这个文件,并把这个文件作为最终的目标文件。
  3. 如果myproc文件不存在,或是myproc所依赖的后面的myproc.o文件的文件修改时间要比myproc这个文件新(可以用touch测试),那么,他就会执行后面所定义的命令来生成myproc这个文件。
  4. 如果myproc所依赖的myproc.o文件不存在,那么make会在当前文件中找目标为myproc.o文件的依赖性,如果找到则再根据那一个规则生成myproc.o文件。(这有点像一个堆栈的过程)
  5. 当然,你的C文件和H文件是存在的啦,于是make会生成myproc.o文件,然后再用myproc.o文件声明make的终极任务,也就是执行文件hello了。
  6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
  7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
  8. make只管文件的依赖性,即,如果在找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

4-4 适度扩展语法

展示了更复杂的Makefile语法,包括变量定义、文件查找、目标和依赖规则等。如:

BIN=proc.exe          # 定义变量
CC=gcc
SRC=$(shell ls *.c)  # 采用shell命令行方式,获取当前所有.c文件名
OBJ=$(SRC:.c=.o)     # 将SRC的所有同名.c,替换成为.o,形成目标文件列表
FLAGS=
RM=rm -f             # 引入命令$(BIN):$(OBJ)@$(CC) $(FLAGS) $^ -o $@   # $@:代表目标文件名。$^: 代表依赖文件列表%.o:%.c@$(CC) $(FLAGS) $< -o $@   # $<: 对展开的.c文件,一个一个的交给gcc。.PHONY:clean
clean:@$(RM) $(OBJ) $(BIN)        # $(RM): 替换,用变量内容替换它.PHONY:test
test:@echo $(SRC)@echo $(OBJ)

5. 调试器 - gdb/cgdb使用

5-1 样例代码

// mycmd.c
#include <stdio.h>int Sum(int s, int e)
{int result = 0;for(int i = s; i <= e; i++){result += i;}return result;
}int main()
{int start = 1;int end = 100;printf("I will begin\n");int n = Sum(start, end);printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
}

5-2 预备

  • 程序的发布方式有两种,debug模式和release模式,Linux gcc/g++出来的二进制程序,默认是release模式。
  • 要使用gdb调试,必须在源代码生成二进制程序的时候,加上 -g选项,如果没有添加,程序无法被编译。
$ gcc mycmd.c -o mycmd  # 默认模式,不支持调试
$ file mycmd
mycmd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=82f5cbaada10a9987d9f325384861a88d278b160, for GNU/Linux 3.2.0, not stripped$ gcc mycmd.c -o mycmd -g  # debug模式
$ file mycmd
mycmd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3d5a2317809ef86c7827e9199cfe622e3c187f, for GNU/Linux 3.2.0, with debug_info, not stripped

5-3 常见使用

  • 开始: gdb binFile
  • 退出: ctrl + dquit 调试命令
命令作用样例
list/l显示源代码,从上次位置开始,每次列出10行list/l 10
list/l 函数名列出指定函数的源代码list/l main
list/l 文件名:行号列出指定文件的源代码list/l mycmd.c:1
r/run从程序开始连续执行run
n/next单步执行,不进入函数内部next
s/step单步执行,进入函数内部step
break/b [文件名:行号]在指定行号设置断点break 10
break test.c:10
break/b 函数名在函数开头设置断点break main
info break/b查看当前所有断点的信息info break
finish执行到当前函数返回,然后停止finish
print/p 表达式打印表达式的值print start+end
p 变量打印指定变量的值p x
set var 变量=值修改变量的值set var i=10
continue/c从当前位置开始连续执行程序continue
delete/d breakpoints删除所有断点delete breakpoints
delete/d breakpoints n删除序号为n的断点delete breakpoints 1
disable breakpoints禁用所有断点disable breakpoints
enable breakpoints启用所有断点enable breakpoints
info/i breakpoints查看当前设置的断点列表info breakpoints
display 变量名跟踪显示指定变量的值(每次停止时)display x
undisplay 编号取消指定编号的变量的跟踪显示undisplay 1
until X行号执行到指定行号until 20
backtrace/bt查看当前执行栈的各级函数调用及参数backtrace
info/i locals查看当前栈帧的局部变量值info locals
quit退出GDB调试器quit

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词