基础开发

Windows 下有例如 Visual Studio、IDEA 这样的集编写代码、编译代码、调试代码、运行代码、代码关系维护以及各种各样的复杂功能于一身的开发工具,叫做集成开发环境 IDE。Linux 下一般使用代码编辑工具 vi/vim,编译工具 gcc/g++,调试工具 gdb。

1. 编辑工具 vim

Linux 下编写代码使用 vi/vim,它是一款多模式的十分强大的文本编辑器,所有的类 unix 系统都会内置 vi 编辑器,目前使用较多的是 vim 编辑器,也就是 vi 的升级版。虽说 vim 是个文本编辑器,但它更专注于代码的编写,具有语法高亮等功能。

$ vim fileName

输入上述命令即可将使用 vim 打开文件,文件不存在则会创建文件。

1.1 vim 的基本模式

vim 基本的模式有三:命令模式(normal mode)插入模式(insert mode)底行模式(command mode),vim 刚启动时,就进入命令模式。

  • 命令模式下输入i可以进入输入模式,再按Esc键就可以回退到命令模式。

  • 命令模式下输入:即可进入底行模式,再按Esc键就可以回退到命令模式。

  • 底行模式下输入wq可以保存退出。

知悉上述基本的模式切换方法后,再逐个介绍模式。

命令模式(normal)

vim 刚启动时,就进入命令模式。此状态下敲击键盘动作会被 Vim 识别为命令,而非输入字符。可进行的操作有:控制光标移动,字符、单词或行的删改,移动或复制粘贴文本内容,切换到插入或底行模式。

底行模式(command)

命令模式只有一些最基本的命令,因此仍要依靠底线命令模式输入更多命令。命令模式下输入:即可进入底行模式,底线命令模式可以输入多个字符的命令,可用的命令非常多。

插入模式(insert)

文本编辑模式。一般要先退回到命令模式才能进到底行模式。

vim 总共有13种模式,但这三个基本模式已经能满足我们大部分需求,其他模式会在之后的使用中学习。

1.2 vim 正常模式命令集

切换模式
  1. 切换到插入模式i,a,o或底行模式Esc
  2. i选项是从光标的位置开始输入,a选项会将光标向后移动一位,o选项在光标的下方另起一行。
  3. Esc退回到命令模式后向前移动一位。
光标移动
  1. H、⬇J、⬆K、➡L,相当于方向键。
  2. 光标锚点跳至行首^、行尾$;跳至文章起始gg、末尾G;跳至指定行n+gg/n+G
  3. 移动到下一个单词的起始w,移动到下一个单词的末尾e,反向单词距移动b,字符、字母、字母数字组合都被视为单词。
  4. Ctrl+B光标向下翻页,Ctrl+F向上翻页;Ctrl+U向下移动半页,Ctrl+D向上移动半页。
删改内容
  1. 删除当前字符x,多个字符n+x;反向删除字符X,多个字符n+X
  2. 删除单词dw,删除当前行dd
  3. 替换当前字符r,多个字符n+r,进入替换模式R
  4. 修改当前单词cw,修改多个单词cnw
  5. 字母大小写转换~
移动或复制内容
  1. 复制光标位置当前单词yw,多个单词n+yw
  2. 复制当前行yy,复制多行n+yy
  3. 剪切/删除当前行dd,剪切多行n+dd
  4. 粘贴到当前行下方p,粘贴多次n+p

撤销操作u,恢复操作Ctrl+r

1.3 vim 底行模式命令集

保存退出
  • 底行模式下输入w可以保存文件,输入q可以退出程序。带上!表示强制执行。
显式行号
  • 显示行号set nu,取消行号set nonu
  • 跳转至某行,输入行号n即可。
多文件操作
  • 分屏操作多个文件vs fileName,切换操作文件/光标Ctrl+w+w
查找字符
  1. /Keyword,输入/再输入查找的字符,在按n可以跳转至下一个关键字所在位置。
  2. ?keyword,输入/再输入查找的字符,在按n可以跳转至上一个关键字所在位置。
  3. 可直接使用shift+*,查找当前光标所在的单词。

底行模式命令有很多,目前掌握这几个就行。

Vim 从入门到精通 (github.com)

最全 Vim 键位图 (runoob.com)


2. 编译工具 gcc/g++

gcc/g++ 分别是 C/C++ 的编译器,基本使用方法:

$ gcc [选项] 编译文件 [选项] 目标文件
$ g++ [选项] 编译文件 [选项] 目标文件

接下来将通过使用 gcc 分段编译程序,来熟悉 gcc/g++ 的使用。

2.1 C/C++编译基本步骤

前面已经学过 C/C++ 程序基本的编译过程,也使用过 gcc 进行查看程序的翻译步骤:

  1. 预处理(进行宏替换)
  2. 编译(生成汇编代码)
  3. 汇编(生成机器可识别的二进制文件)
  4. 链接(生成可执行文件或库文件)

预处理
  • 预处理的功能主要包括宏定义,文件包含,条件编译,删除注释等。预处理指令主要指以#开头的语句。
$ gcc -E test.c -o test.i # 完成预处理后停止
  • 选项-E让翻译在预处理结束后停下来,-o可以指定生成的目标文件名,预处理完的文件一般后缀为.i
编译
  • 编译时,gcc 会检查代码的规范性、是否有语法错误,已确定代码所做的工作,检查无误后 gcc 会生成汇编代码。
$ gcc -S test.i -o test.s # 完成编译后停止
  • 编译阶段会生成汇编代码,以供接下来的汇编阶段使用。一般编译结束生成的代码文件的后缀为.s
汇编
  • 汇编阶段将编译所形成的汇编代码生成目标文件,也就是二进制文件。
$ gcc -c test.s -o test.o # 完成汇编后停止

虽然生成的是二进制目标文件,但仍然不可直接运行,准确的来说该文件是可重定向目标文件。相当于Windows下的.obj文件。

链接

预处理、编译、汇编三个阶段统称为编译过程,完成了上述编译的过程,就到了翻译环境的最后一个阶段:链接。链接完成之后,就生成了可执行文件。

$ gcc test.o -o test # 完成链接

链接是将所有.c源文件所生成的目标文件与语言的链接库文件放到一起进行链接。如图所示:

通常写程序时,就include了语言本身所提供的链接库文件,至于链接库文件到底是什么,接下来会讲解。

当然编译 C/C++ 程序,不需要上述这么复杂,直接执行即可:

$ gcc test.c -o test # 1.
$ gcc -o test test.c # 2.

2.2 静态链接和动态链接

函数库的概念

语言本身会提供的库,库可以看成一套头文件和一套库文件。比如通常使用的printf,scanf等等库函数,都是实现在库文件中的,可以通过引用对应的头文件,来使用这些代码。

使用lld命令可以查看可执行程序所依赖的第三方库:

Linux 下的C语言的库文件一般叫作libc.alibc.so,分别是静态库和动态库。Windows 下的静态库和动态库的后缀分别为.lib.dll

将用户所写的程序文件和第三方库提供的方法关联起来,这就叫链接。很显然,链接又分为静态链接和动态链接。

由上图可以看出,gcc 默认形成的可执行程序,采用动态链接的方式,因为可执行程序依赖的是动态库。

$ gcc test.c -o test                  # 默认动态方式
$ gcc test.c -o test_static -static   # 采用静态方式

静态链接和动态链接两者最大的区别就在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时,下面来详细介绍这两种链接方式。

静态链接

一般开发时,会将代码分离编写到多个.c源文件中,而这多个源文件之间不是独立的,可能某个源文件要调用另一个源文件中的函数。

这个调用就发生在目标文件的链接过程中,由链接器在链接时将库的内容拷贝到可执行程序中。然后才能生成可执行程序文件,所以说静态链接发生在形成可执行程序之前

由上图可以看出,静态链接生成的文件比动态链接的体积大得多。

静态链接的优缺点

静态链接的缺点很明显:

  1. 浪费空间,链接时会将库中的内容放入目标文件中,所以文件的体积较大。如果有多个程序文件,那么每个程序中都会加入库文件的内容,包含相同的公共代码,造成浪费。
  2. 更新较为麻烦,每当库函数的代码修改了,此时就需要重新进行重新打包成lib文件,再去编译链接形成可执行程序。

静态链接的优点是,在可执行程序中已经具备了所有执行程序所需要的任何东西,不需要到其他文件中查找内容,在执行的时候运行速度快

动态链接

动态链接出现就是为了解决静态链接中的两个问题:空间浪费和更新困难。 动态链接把程序按照模块拆分成各个相对独立部分,并把链接这个过程推迟到了运行时再进行,由操作系统的装载程序加载库,将它们链接在一起形成一个完整的程序。

假设有两个程序都包含同一个库文件,运行程序1时会将程序1加载到内存中,然后再加载该库文件,再运行程序2时,内存中已有库文件就不会再次加载,直接链接到程序2中即可。

动态链接的优缺点

动态链接的优点是:

  1. 避免空间浪费,即使多个程序依赖于同一个库,但该库不会像静态链接那样在内存中存在多份副本,而是这多个程序执行时共享副本。
  2. 维护比较方便,更新时只需要替换原来的目标文件,程序再次运行时,新的目标文件会自动加载到内存并链接起来。库文件与可执行文件独立,更新库文件不会对程序文件造成影响,提高了可维护性和可扩展性。

动态链接也是有缺点的,因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一定损失,运行速度相对慢一点

深入浅出静态链接和动态链接 (csdn.net)

2.3 gcc 选项

  • -E激活预处理,需手动重定向输出文件;-S编译到汇编语言;-c编译到目标代码;-o文件输出到文件。
  • -static此选项对生成的文件采用静态链接。
  • -g生成调试信息,GNU 调试器可利用该信息。
  • -shared此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库。
  • -O0,-O1,-O2,-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高。
  • -w 不生成任何警告信息,-Wall 生成所有警告信息。

3. 调试工具 gdb

gdb 是 Linux 下用于调试代码的工具,这个工具成本高难度也不低且不是很方便直观但仍需掌握。

3.1 背景知识

程序的发布方式有两种模式:Debug 和 Release 模式。Linux 下 gcc/g++ 编译出的可执行程序,默认是 Release 模式。要使用 gdb 调试,必须在代码编译的时候加上调试信息。

$ gcc test.c -o test_debug -g # 加上调试信息
$ gdb test_debug              # 进入gdb调试
(gdb) quit                    # 退出gdb

3.2 gdb 选项

调试命令(debug)
名称 命令 解释
开始运行 run 相当于开始调试F5,会运行至程序结束
逐语句 step 相当于F11,有函数会进入函数内部
逐过程 next 相当于F10,不会进入函数内部,执行整条语句;

像逐过程、逐语句这样的命令一次输入之后,可直接回车仍会再次执行。

显示代码(list)
名称 命令 解释
可指定行号 list + [N] 从第 N 行开始显示10行代码,省略行号就默认从第一行开始打印,可接着上次的位置继续打印
可指定函数名 list + Name 从函数起始位置左右开始显示代码。

断点命令(breakpoint)
名称 命令 解释
可指定行号 b + N 在某行打上断点
可指定函数名 b + Name 在函数内起始位置打断点
查看断点信息 info + b 显示断点信息列表
删除断点 d + b [ + N] 删除序号为 N 的断点,省略序号就是删除所有断点
启用断点 enable + b [ + N] 启用序号为 N 的断点,省略序号就是启用所有断点
禁用断点 disable + b [ + N] 禁用序号为 N 的断点,省略序号就是禁用所有断点

变量命令(variable)
名称 命令 解释
监视变量 display + Name 以列表的形式常显示在屏幕下方,类似于vs中的监视
取消监视 undisplay + N 去掉监视列表中的序号为 N 的变量的常显示
查看变量 p + Name 打印变量的值,不会常显示
修改变量 set + Name 设置指定变量的值

特殊调试命令
名称 命令 解释
结束当前函数 finish finish 会直接结束当前函数的调用,并停止在函数返回位置,等待接下来的命令
继续调试 continue continue 继续运行至下一个断点,相当于F5
跳转至指定行 until + N 跳转至当前函数内部的第 N 行

上述三个命令可以快速确定到代码出错的大概范围。finishcontinue 结合在多个函数调用结束的位置检查结果是否正确,定位到出错函数后,可以使用until在函数内部查找出错位置。

其他命令
名称 命令 解释
调用堆栈 breaktrace/bt 查看程序各级栈帧的调用情况

4.构建工具 make/Makefile

之前在 IDE 中写代码时,没有关心过文件的编译顺序以及代码的依赖关系,因为 IDE 可以自动构建项目。

4.1 自动化构建工具理解

工程中的源文件不计其数,按类型、功能和模块放在若干目录中,Makefile 文件的内容指定了各个文件编译的先后顺序,甚至更复杂的操作。使用 make 指令就可以自动编译项目文件,但前提是要编写 Makefile 文件。

Makefile 的好处就是“自动化编译”,编写完成后,只需执行 Make 命令,整个项目工程就能够自动编译,极大地提高了软件开发的效率。所以写 Makefile 的能力,从侧面说明了其是否有完成大型项目的能力。

4.2 Makefile 的编写

target : prerequisitescommand

target 也就是目标文件,也可以是执行文件。prerequisites 就是,要生成那个 target 所需要的文件或是目标。command 也就是 make 需要执行的命令。开头第一行写明目标文件 : 依赖文件。第二行以 开头,写明所需命令。

准确地说 Makefile 指明了编译多个代码文件的两个要素:依赖关系和依赖方法。比如可执行文件依赖于源文件,这就是两个文件的依赖关系;通过 gcc 编译源文件可形成可执行文件,这是依赖方法。

mytest:mytest.c # 依赖关系    gcc -o mytest_make mytest.c -std=c99 # 依赖方法
.PHONY:clean
clean:    rm -f mytest_make

make 命令用于构建工程,相当于 vs 中的生成解决方案。make clean 用于清理工程,相当于清理解决方案,当然需要自主编写。

  • 默认 Makefile 文件第一个目标的是真目标,其他都是伪目标,输入 make 命令默认执行真目标。
  • .PHONY是一种关键字,表示其后的目标总是可执行的,一般常用来修饰伪目标。真目标项目为更改情况下只能执行一次,伪目标总是可执行的。

  • Makefile中可使用特殊符号:$@代表目标文件,$^代表其后指定的所有依赖文件。

  1. 如果工程没有编译过,那么所有C文件都要编译并被链接。
  2. 如果工程的某几个C文件被修改,那么只编译被修改的C文件,并链接目标程序。
  3. 如果个工程的头文件被改变了,那么需要编译引用了这几个头文件的C文件,并链接目标程序。

4.4 Makefile 的原理

依赖关系和依赖方法

由上图可以看出,

  1. 依赖关系:.out文件依赖.o文件,.o文件依赖.s文件,.s文件依赖.i文件,.i文件依赖.c文件。
  2. 依赖方法:gcc -option hello.* -o hello.*
mycode : mycode.ogcc -o mycode.o -c mycode.s
mycode.s : mycode.igcc -o mycode.s -S mycode.i
mycode.i : mycode.cgcc -o mycode.i -E mycode.c
.PHONY:clean
clean:rm -rf mycode.o mycode.s mycode.i

执行 .out 依赖 .o,执行 .o 依赖 .s,执行 .s 依赖 .i,执行 .i 依赖 .c 文件,找到 .c 后再一步一步反向编译到可执行文件。

Makefile 文件可以像上述这样将所有步骤写出来,但一般不这样写,写的越简单越好。

跟我一起写 Makefile (csdn.net)

5. 上传工具 git

创建命令 解释
git init 新建版本库
git clone 克隆版本库
提交命令 解释
git add 添加文件到暂存区
git commit -m ‘xx’ 将暂存区文件提交至本地仓库
git push 同步代码至远程仓库
git pull 下载代码至本地仓库
git rm 删除工作区文件。
查看命令 解释
git status 查看仓库当前的状态,显示有变更的文件
git log 查看仓库提交历史
git blame 以列表形式显示文件修改记录
git diff 比较暂存区和工作区文件的差异
分支命令 解释
git branch 查看本地所有分支
git branch -r 查看远程所有分支
git checkout 切换所有分支
git merge 合并分支
git branch -d 删除分支

github-git-cheat-sheet (runoob.com)

Git - Reference (git-scm.com)

git 简明指南 (runoob.com)

Linux系统:基本开发工具相关推荐

  1. 【Linux系统】开发工具(上) {软件包管理器yum,更新yum源,文本编辑器vim,vim的四种基本模式,vim指令集,代码编译器gcc/g++}

    一.软件包管理器:yum 1.1 yum是什么? Linux下软件的安装方法: 源码安装:下载源码,在本地自行编译,然后才能安装. rpm安装:红帽软件包管理工具,属于安装包安装. yum安装:本身会 ...

  2. windows不安装虚拟机如何使用Linux系统作为开发工具?

    哈喽,大家好,我是仲一.作为嵌入式开发程序员,常常需要在Linux环境下编译一些代码.安装虚拟机比较方便,但是,太占用内存了.性能不好的电脑开了一台虚拟机后,可能就干不了其他事情了.安装双系统也比较麻 ...

  3. Linux下C++开发工具介绍

    概述     就C++开发工具而言,与Windows下微软(VC, VS2005等)一统天下相比,Linux/Unix下C++开发,可谓五花八门,各式各样.Emacs, vi, eclipse, an ...

  4. 嵌入式linux系统应用开发

    关于嵌入式系统   平时大家说的嵌入式其实范围比较广的,是一种软硬件可裁剪,以应用为中心开发的专用系统,硬件平台可以是单片机,或者以ARM系列的处理器.单片机一般直接裸奔程序,不过现在有了好多基于单片 ...

  5. L1D1:嵌入式Linux C语言开发工具及基础命令

    嵌入式Linux C语言开发工具及基础命令 一.ubuntu环境搭建 请自行准备VMware workstation15安装包 及 ubuntu18.04.iso镜像文件.可参考链接:VMware W ...

  6. STM32MP157 Linux系统移植开发篇4: BootLoader(Uboot)移植

    本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...

  7. 2 Linux环境基础开发工具

    2 Linux环境基础开发工具 2.1 Linux软件包管理器yum 2.1.1 软件安装的方式 1. 源码安装 大多数开源的软件都是源码的形式.拿过来自己编译,安装. 优点:源码安装兼容性好. 缺点 ...

  8. STM32MP157 Linux系统移植开发篇17:Linux内核摄像头驱动移植

    本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...

  9. STM32MP157 Linux系统移植开发篇14:Linux内核RGB LCD驱动移植

    本文章为<STM32MP157 Linux系统移植开发篇>系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板).stm32mp157是ARM双核,2 ...

  10. 开发板通过usb连linux,虚拟机Linux系统和开发板通过USB转串口连接的两种方法

    通过USB转串口连接虚拟机中的Linux系统和开发板,开始时候总是出现错误,显示什么串口重叠,最后求助高手帮我通过其他连接方式解决了问题,今天在网上查找资料,终于明白了开始错误的原因:开发板提供的驱动 ...

最新文章

  1. css为元素添加样式,JQuery如何为元素添加样式
  2. 算术表达式求解背景_1.8 C++算术运算符与表达式
  3. ACL中的wildcard mask
  4. 遍历Repeater与ItemDataBound事件发现的几个问题。
  5. error LNK2001: unresolved external symbol _main
  6. html源码md风格,code/html.md at master · Rongx/code · GitHub
  7. 通过getSystemServices获取手机管理大全
  8. C#通过Redis实现分布式锁
  9. SQL语句中LEFT JOIN、JOIN、INNER JOIN、RIGHT JOIN的区别?
  10. leetcode 501. 二叉搜索树中的众数 思考分析
  11. tp获取referer里的域名_thinkPHP的redirect跳转和referer使用的问题
  12. 如果每天给你888元,只能看书学习,不能玩手机电脑,你能坚持多少天?
  13. linux v4l2 示例程序,linux驱动由浅入深系列:camera驱动之二(基于高通平台的V4L2结构及代码分析)...
  14. spring-boot-starter-parent 包maven依赖报错
  15. paip.租房宝付房租功能抓包总结
  16. 小白的web优化之路 一、使用redis来缓存信息
  17. creo扫描选择多条链作为轨迹_Proe/Creo曲面造型·蓝牙耳机纹理曲面纹理
  18. R语言检验独立性:卡方检验(Chi-square test)和费舍尔Fisher精确检验分析案例报告
  19. 【精选】VI手册设计模板合集,附带源文件、预览图、精细分类
  20. Linux的strings命令_拔剑-浆糊的传说_新浪博客

热门文章

  1. 阿里云OSS前端直传踩坑
  2. 知网下载论文CAJ格式转为PDF格式
  3. ADF实现主副控件联动的方法
  4. 分析对象竞是我自己?我在 9 月上班划水 1510 分钟!
  5. matlab语言fcm,【上海校区】FCM算法原理及MATLAB实现
  6. R语言绘图—主题选择
  7. ajax 与 php 简单聊天室
  8. xvid编码器的弹出窗口解决方法
  9. Quartus-II 三种方式进行D触发器仿真
  10. [译] SolidWorks的发展历史(1994~2007)