Loading

开发工具


返回 我的技术栈(Technology Stack)



集成开发工具(Integrated Development Environment,IDE)

IDE开发程序非常方便,因为它们提供了程序的编译、运行、调试、项目管理一条龙的服务,
使用IDE的唯一缺陷就是这些IDE安装文件往往很大,编译创建工程时候生成的临时文件很多。略显笨重和臃肿,
大量的封装确实容易上手和使用,方便用户编程,但是也掩盖了底层编译、调试的过程,不利于新手学习。


代码编辑工具:Vim、gedit

在Linux环境下,使用Vim之前首先要安装,
虽然现在大多数UNIX、GNU/Linux操作系统默认安装Vim,但是也有一些操作系统,如Ubuntu,系统自带的默认文本编辑工具是Vi,Vi是 visual interface的简写,
以前系统编辑文本都使用行编辑器ex命令,后来才有了Vi工具,作为ex的可视化操作接口,可以直接可视化编辑文本,比使用纯命令行处理文本方便了很多,

Vi有很多不完善的地方,比如只能单步撤销、不能使用方向键等,所以就出现了Vi的加强版——Vi Improved,即Vim。
Vim针对Vi做了很多的改进,比如增加了多级撤销、多窗口操作、关键字自动补全等功能,甚至可以通过插件来扩展和配置更多的功能。

Vim安装命令:

# apt-get install vim    //Ubuntu操作系统的安装命令,#开头表示当前命令是以root权限运行的
$ sudo apt-get install vim    //Ubuntu操作系统的安装命令,$开头表示当前命令是以普通用户权限运行的
# yum install vim     //Fedora操作系统的安装命令
# brew install vim    //macOS操作系统的安装命令

使用vim -v查看是否安装成功!


程序编译工具:GCC、make

C语言的GCC编译过程

注意:GCC并不是真正的C编译器,它是GNU C编译器工具中的一个二进制工具,
在编译程序时候,GCC会首先运行,然后由GCC分别调用预处理器编译器汇编器连接器等工具来完成整个GCC编译过程

GCC的编译器参数(控制编译过程):

  • -E :只对C源程序进行预处理,不编译。即宏定义展开、头文件展开、条件编译等,同时将代码中的注释删除,这里并不会检查语法
  • -S :只编译到汇编文件。即检查语法,将预处理后文件编译生成汇编文件
  • -c :只编译生成目标文件,不进行链接。即将汇编文件生成目标文件(二进制文件)
  • -o :指定输出的可执行文件。因为C语言写的程序是需要依赖各种库的,所以编译之后还需要把库链接到最终的可执行程序中去,最终生成一个可执行目标文件(或者简称为可执行文件),可以被加载到内存中,由系统执行。
  • -g :生成带有调试信息的debug文件
  • -O2 :代码编译优化等级,一般选择2
  • -W :在编译中开启警告(warming)信息
  • -I :大写的I,在编译时候指定头文件的路径
  • -l : 小写的L,指定程序使用的函数库
  • -L :大写的L,指定函数库的路径

GCC编译程序非常方便,但是也有弊端:
例如,在一个多文件的项目中,如果C源文件过多,如编译Linux内核源码,大概有30 000 多个源文件,使用GCC命令编译,则是这样的
# gcc -o vmlinux main.c usb.c device.c hub.c ...
后面得跟上30 000多个源文件名,这显然是不合理的

所以,针对多文件的编译,可以使用make命令
make其实也是一个编译工具,只不过make在编译程序的时候,需要依赖一个Makefile的文件:生成一个可执行文件所依赖的所有C源文件都在这个Makefile文件中指定。

在Makefile中,通过定义一个个规则,来描述各个要生成的目标文件所依赖的源文件及编译命令,最后链接器将这些目标文件组装在一起,生成可执行文件。

make具体的原理流程:
当使用make编译一个工程时,make首先会解析Makefile,根据Makefile文件中定义的规则和依赖关系,分析出生成可执行文件和各个目标文件所依赖的源文件,并根据这些依赖关系构建出一个依赖关系树。然后根据这个依赖关系和Makefile定义的规则一步一步依次生成这些目标文件,最后将这些目标文件链接在一起,生成最终的可执行文件。

举一个例子:

假设一个项目有两个源文件:main.c和sum.c

//main.c
#include<stdio.h>
int add(int a, int b);
int main(void)
{
	int sum = 0;
	sum = add(3,4);
	printf("sum:%d\n",sum);
	return 0;
}
//sum.c
int add(int a,int b)
{
	return a+b;
}

如果使用GCC编译的话,命令如下所示:
# gcc -0 hello main.c sum.c

如果使用make工具来编译,那么首先我们需要编写一个Makefile文件:
一个Makefile通常是由一个个规则构成的,规则是构成Makefile的基本单元。一个规则通常由目标、目标依赖和命令3部分组成

目标:目标依赖
	命令
  • 目标:一般是我们要生成的可执行文件或各个源文件对应的目标文件
  • 目标依赖:生成目标所需要依赖的源文件
  • 命令:可以编译命令、链接命令或Shell命令,命令必须以Tab键开头

具体的书写:

.PHONY: all clean
all:hello
hello:main.o sum.o
	gcc -o hello main.o sum.o
main.o:main.c
	gcc -c main.c
sum.o:sum.c
	gcc -c sum.c
clean:
	rm -f main.o sum.o hello

解释:
Makefile 文件中使用 .PHONY 声明的目标是一个伪目标,伪目标并不是一个真正的文件名,可以看作一个标签。伪目标比较特殊,一般无依赖,主要用来无条件执执行一些命令,如清理编译结果和中间零时文件。
一个规则可以像伪目标那样无目标依赖,无条件地执行一些命令操作,也可以没有命令,只表示单纯的依赖关系,如上面Makefile文件中的all伪目标。
执行的时候,需要将Makefile与main.c和sum.c放置同一目录下,然后再命令环境下输入make命令直接编译项目

# make
gcc -c main.c
gcc -c sum.c
gcc -o hello main.o sum.o

也可以使用 make clean 命令清理程序的编译结果和生成的零时中间文件

make clean
rm -f hello main.o sum.o

Makefile 文件名的第一个字母一般大写,小写也不会出错,因为make在编译程序的时候,会首先查找当前目录下的Makefile文件,找不到再去找makefile或GNUmakefile文件,当这三个都找不到的时候,make就会报错!


项目管理工具:Git

版本控制系统一般分为集中式版本控制系统分布式版本控制系统

  • 集中式版本控制系统

    • 软件的各个版本的代码快照只保存在服务器;
      用户想要查看某个版本的代码,需要从版本库中拉取到本地计算机上,查看和修改后,再保存到服务器上。
    • 缺点:
      因为存储在服务器上,使用时需要联网;
      一般收费;
      可能被员工删库跑路。
    • 典型代表:
      小乌龟 TortoiseSVN
  • 分布式版本控制系统

    • 不再将整个版本库保存在一个服务器上,而是保存在每个员工的计算机上。
    • 优点:
      免费;
      老板不怕被删库跑路。
    • 典型代表:
      Git

早期使用TortoiseSVN的比较多,自从Linux内核作者Linus开发出Git这款免费的版本控制工具后,Git变得越来越流行。


参考:
[1]嵌入式C语言自我修养:从芯片、编译器到操作系统/王利涛编著.——北京:电子工业出版社,2021.4


posted @ 2021-07-28 11:21  言非  阅读(243)  评论(0编辑  收藏  举报