Ubuntu入门(三) GCC编译器 Makefile基础 Shall编程

Bliss ·
更新时间:2024-09-20
· 782 次阅读

目录1.GCC编译器1.1.VIM设置1.2.编译代码2.Makefile基础2.1.实验程序2.2.Makefile概念和基本操作步骤2.3.Makefile规则格式2.4.Makefile变量2.5.Makefile模式规则&自动化变量2.6.Makefile条件判断3.Shall编程3.1.Shall脚本基础3.2.Shall脚本条件判断&函数&循环 1.GCC编译器 1.1.VIM设置 用vi打开文件/etc/vim/vimrc,设置TAB键为4个空格:set ts=4。 设置显示行号:set nu。 “esc”+“:”+“”q保存退出。 1.2.编译代码

查看gcc版本:gcc -v。
编译命令:gcc xxx.c -o xxx
主要选项:
在这里插入图片描述
编译流程: 预处理、编译、汇编和链接。预处理就是展开所有的头文件、替换程序中的宏、解析条件编译并添加到文件中。编译是将经过预编译处理的代码编译成汇编代码,也就是我们常说的程序编译。汇编就是将汇编语言文件编译成二进制目标文件。链接就
是将汇编出来的多个二进制目标问价链接在一起,形成最终的可执行文件,链接的时候还会涉及到静态库和动态库等问题。可以使用gcc命令生成可执行文件,并没有先将 c 文件编译成.o文件再链接在一起。

2.Makefile基础 2.1.实验程序

实验共有5个文件:main.c,input.c,calcu.c,input.h,calcu.h。

//main.c #include #include "input.h" #include "calcu.h" int main(int argc, char *argv[]) { int a, b, num; input_int(&a, &b); num = calcu(a, b); printf("%d + %d = %d\r\n", a, b, num); } //input.c #include #include "input.h" void input_int(int *a, int *b) { printf("input two num:"); scanf("%d %d", a, b); printf("\r\n"); } //calcu.c #include "calcu.h" int calcu(int a, int b) { return (a + b); } //input.h #ifndef _INPUT_H #define _INPUT_H void input_int(int *a, int *b); #endif //calcu.h #ifndef _CALCU_H #define _CALCU_H int calcu(int a, int b); #endif

实验完成的功能是获取键盘输入的两个数,打印它们的和。input_int函数的参数是两个int类型指针变量,调用的时候需要定义两个int类型数字,去它们的地址作为函数输入参数。输入命令“gcc main.c calcu.c input.c -o main”进行编译和链接,再使用“./main”执行即可,但这样的缺点是gcc命令要输入所有c文件名,且修改一个文件也要全部重新编译。

2.2.Makefile概念和基本操作步骤

Makefile特性:

如果工程没有编译过,那么工程中的所有.c 文件都要被编译并且链接成可执行程序。 如果工程中只有个别 C 文件被修改了,那么只编译这些被修改的 C 文件即可。 如果工程的头文件被修改了,那么需要编译所有引用这个头文件的 C 文件,并且链接成可执行文件。

操作步骤:

在工程目录创建名为“Makefile”的文件。 修改/etc/vim/vimrc。
在这里插入图片描述 编写Makefile文件,缩进一定要用“Tab”。 输入命令“make”编译和链接文件。 2.3.Makefile规则格式

规则格式:
目标…:依赖文件集合……
命令 1
命令 2……
make命令会为Makefile中的每个以TAB开始的命令创建一个Shell进程去执行。

Makefile文件内容规则分析:
在这里插入图片描述

更新第一条规则中的main,其中的目标成为默认目标,只要默认目标更新了就认为完成了Makefile的工作。第一次编译时由于main还不存在,因此第一条规则会执行,第一条规依赖于文件main.o、input.o和calcu.o这个三个.o 文件目前还都没有,因此必须先更新这三个文件。make会查找以这三个.o文件为目标的规则并执行。 以main.o为例,发现更新main.o的是第二条规则,因此会执行第二条规则,第二条规则里面的命令为“gcc –c main.c”,即编译 main.c,生成 main.o。 执行第一条规则时,当发现目标文件存在,或者目标所依赖的文件不比目标文件新(即最后修改时间比目标文件早)就会不执行后面的编译命令。 最后一个规则目标是 clean,它没有依赖文件,因此会默认为依赖文件都是最新的,不会执行对应命令。想要执行clean可以直接使用命令“make clean”。 2.4.Makefile变量 $ (变量名): Makefile中变量的引用方法是“$(变量名)”,下图在定义变量objects时用“=”对其进行赋值。
在这里插入图片描述 **赋值符“=”:**使用“=”在给变量的赋值的时候,借助另外一个变量,可以将变量的真实值推到后面去定义,即变量的真实值取决于它所引用的变量的最后一次有效值。在Makefile输出字符使用“echo”,就像C中的“printf”,在前面加上“@”就不会输出命令执行过程。
在这里插入图片描述
在这里插入图片描述 赋值符“:=”: 不会使用后面定义的变量,只能使用前面已经定义好的。
在这里插入图片描述
在这里插入图片描述 赋值符“?= ”: 如果变量前面没有被赋值,那么此变量就等于“?=”后面的值,如果前面已经赋过值了,那么就使用前面赋的值。 变量追加“+=”: Makefile中的变量是字符串,有时候需要给前面已经定义好的变量添加一些字符串进去,就要使用到“+=”。 2.5.Makefile模式规则&自动化变量

格式:%.o : %.c
(Tab)命令

通过模式规则可以使用一条规则将所有的.c文件编译为对应的.o文件。目标中的“%”表示对文件名的匹配,“%”表示长度任意的非空字符串,比如“%.c”就是所有的以.c 结尾的文件。“a.%.c”表示以 a.开头,以.c 结束的所有文件。

自动化变量: 上面讲的模式规则中,每一次对模式规则进行解析的时候都会是不同的目标和依赖文件,而命令只有一行。使用自动化变量可以通过一行命令来从不同的依赖文件中生成对应的目标。所谓自动化变量就是它会把模式中所定义的一系列的文件自动的挨个取出。自动化变量只应该出现在规则的命令中,常用的自动化变量如下表:
在这里插入图片描述
使用规则模式和自动化变量后,Makefile可以修改为:
在这里插入图片描述

2.6.Makefile条件判断

语法格式:

endif //以及 else endif

4个关键字: ifeq、ifneq、ifdef 和 ifndef。

3.Shall编程 3.1.Shall脚本基础

简介: shell脚本是纯文本文件,一行一行的执行,shell脚本扩展名为.sh,其第一行必须是 “#!/bin/bash”

交互式shell脚本(实验一):
编写好shell脚本后运行的时候发现权限不够,使用“ls xxx.sh -l”发现脚本文件没有可执行权限,因此使用chmod命令将脚本文件的权限全部打开,就可以正常执行了。
在这里插入图片描述
在这里插入图片描述
shell脚本数值计算(实验二): shell仅支持整形,数值计算使用$((表达式))。注意total后不能加等于号。
在这里插入图片描述
test命令(实验三):

test命令用于查看文件是否存在,以及权限等信息,可以进行述职,字符,文件三方面的测试 &&命令:cmd1&&cmd,当cmd1正确执行后cmd2才能执行;若cmd1执行错误则cmd2不执行。 ||命令:当cmd1正确执行则cmd2不执行;若cmd1执行错误则执行cmd2。

下图的例子中需要输入文件名,若文件存在打印“||”左边的,不存在则打印“||”右边的内容。
在这里插入图片描述
在这里插入图片描述
默认变量(实验四):
$0~ $n:表示shell脚本参数,包括shell脚本命令本身(本身为$0)。
$#:#表示最后一个参数的标号。
$@:表示$1,$2,$3…
在这里插入图片描述
在这里插入图片描述

3.2.Shall脚本条件判断&函数&循环

条件判断(实验一):
在这里插入图片描述
case语句(实验二):
在这里插入图片描述
函数调用(实验三):
在这里插入图片描述
在这里插入图片描述
函数传参(实验四):
在这里插入图片描述
在这里插入图片描述
while do done循环(实验五): 条件成立时一直循环,实验中若输入不为“close”则一直循环。
在这里插入图片描述
在这里插入图片描述
until do done循环(实验六): 条件不成立时循环,条件成立退出循环。
在这里插入图片描述
for循环(实验七):
在这里插入图片描述
在这里插入图片描述
for循环处理数据(实验八):
在这里插入图片描述
在这里插入图片描述

参考正点原子嵌入式linux开发指南


作者:wjq97



gcc编译器 ubuntu makefile gcc

需要 登录 后方可回复, 如果你还没有账号请 注册新账号