make是一个命令,makefile是一个文件 ;两个搭配使用可以完成程序的自动化构建。
在vs下可以添加多个源文件头文件,但是只能有一个可执行程序。如果想生成多个可执行程序,或者有更复杂的需求时,vs就不能胜任。
1.makefile原理--为了构建项目
(1)依赖关系:相关性!
mycode --目标文件/要形成的可执行文件 :--依赖关系 mycode.c --依赖文件列表
(2)依赖方法:要做什么!
Tab 如何根据依赖关系从依赖文件形成可执行 gcc mycode.c -o mycode
(3)清理一个项目
依赖关系:右侧可以为空,clean不依赖任何文件,Tab rm -f mycode ;执行指令:make clean
.PHONY来修饰,表明clean是一个伪目标---->该目标总是被执行的。在Makefile中,如果依赖文件mycode.c没有修改的话,当make去调用依赖方法gcc去执行过后,再次make就不会再执行了。
(4)为什么make能知道mycode.c已经被gcc过了且没被修改不用再执行呢?
文件的三个时间:stat mycode.c
注意:当内容变化时属性时间往往会随之变化,而文件是经常被访问的,如果时间更改的太频繁对系统增加负担,Linux新内核对访问时间做出修改,访问一定次数后才会更改访问时间。
---所以,注意先有的mycode.c源文件,再有的可执行文件mycode;make只需要比较源文件的修改时间是否 早/晚于 可执行文件的修改时间,即可得知源文件在编译之后是否被修改。此时我们可以用指令touch mycode.c来更新mycode.c的时间(touch可以创建一个新文件也可以来更新旧文件)
(5)make / make mycode / make clean
make默认碰到第一个文件可以省略,默认从上到下扫描只形成一个可执行文件就不再往下执行,默认不指明的情况下执行的是第一个。
2.Makefile的推导规则--依赖关系列表
当mycode去找依赖文件mycode.o时发现它并不存在,向下递归寻找依赖文件mycode.s依旧不存在...知道找到mycode.c发现它存在,执行依赖方法gcc -E mycode.c -o mycode.i,向上递归.......
3.编写一个进度条小程序
#include<stdio.h>
#include<unisted.h>
int main()
{//按照顺序执行,先打印you can...
printf("you can see me.......\n");//有\n会刷新这一行
//printf已经打印完了,只是没有立即显示出来
// fflush(stdout);//刷新stdout---标准输出
sleep(2);//程序休眠两秒
//在休眠期间,printf打印了输出在缓冲区,还没有输出在显示器上
//休眠结束后才刷新的数据,printf显示在显示器
return 0;
}
回车换行:\r -> 表示回车(回到该行的起始位置);\n -> 表示换行(换到下一行光标与该行对应的位置)。而在语言层面我们的 \n 表示的就是 \r\n 回车换行。
显示器为什么能显示各种符号?---因为显示器面板上有各种像素点,点亮显示器上对应的像素点。凡是显示到显示器上,都是字符;
完成倒计时-->利用系统特性,将写好的字符清掉,显示下一个字符。
#include<stdio.h>
#include<unistd.h>
int main()//倒计时小程序
{
int x = 10;
for(int i=0;i<10;i++)
{
printf("剩余时间:%2d\r",x--);//x一次占用两个位置
fflush(stdout);
sleep(1);
}
return 0;
}
完成进度条
注意:头文件的搜索有两条路径,第一条是当前路径,第二条是库路径;所以写多个依赖文件时只写这几个源文件,不用写头文件,头文件在当前目录下,编译器可以找到。
void ProcessOn()
{
int cnt = 0;
char bar[NUM];//用来存储NUM个进度符号的字符数组
memset(bar,'\0',sizeof(bar));//'\0'表示空字符,先将bar都置成空
//reverse
const char *label = "|\\-/";//其中\\只表示一个字符\、
//101 times
while(cnt <= 100)
{//\r表示回车每次从第一个字符开始,格式是[%100d][%3d][%c]
printf("[%100d][%3d][%c]\r",bar[cnt],cnt,label[cnt%4]);
fflush(stdout);//刷新一下缓冲区
bar[cnt++] = style[N];//每次给bar多添加一个字符
usleep(50000);//5s/100 = 50000us
}
printf("\n");
}