一、make和Makefile
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
make 一下 ,目录中就多出了 hello 这个可执行文件
二、写Makefile的好处
1、Makefile的背景
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,Makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
Makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具
2、工程文件的清理
mycode:mycode.c
gcc mycode.c -o mycode -g
.PHONY:clean
clean:
rm -f mycode
- -g代表可被调试。
mycode:mycode.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f mycode
$@代表生成的目标文件 mycode,$^代表依赖文件mycode.c 。
- .PHONY表示被该关键字修饰的对象是一个伪目标。(伪目标的特性:总是可被执行)
我们在编写完makefile后,make一下,就能生成对应的可执行程序。如果依赖的文件列表没有发生修改,gcc通过判断mycode.c的Modify time早于mycode的Modify time,说明依赖文件列表没有修改,那么再次make将会失败;反之,重新编译将会成功。
不过多次make clean却不会失败,因为clean被.PHONY修饰,变成了一个伪目标,所以clean总是可被执行。
3、文件的三个时间
- Access 指最后一次读取的时间(访问)
- Modify 指最后一次修改数据的时间(修改)
- Change 指最后一次修改元数据的时间(改变)
- Access\Modify\Change的初始时间记录都是文件被创建的时间文件的Access\Modify\Change时间
1、读取文件时,Access time被改变,而Modify、Change time不会被改变(为防止文件被频繁访问修改Access time,优化为多次访问才修改一次该时间)
2、修改文件时,三个时间都会被改变
3、修改属性时,Change time被改变,而Access、Modify time不会被改变
三、makefile的原理
依赖关系
- 上面的文件 hello ,它依赖 hell.o
- hello.o , 它依赖 hello.s
- hello.s , 它依赖 hello.i
- hello.i , 它依赖 hello.c
依赖方法
gcc hello.* -option hello.*
,就是与之对应的依赖方法
原理:
-
make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
-
make会自己逐步寻找依赖文件列表,如果没找到对于依赖文件,将会继续向下寻找该依赖文件的依赖方法。
这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。 -
make只管文件的依赖性,即在找寻的过程中,如果出现错误,或者在找了依赖关系之后,冒号后面的文件还是不在,那么那么make就会直接退出,并报错。而对于所定义的命令的错误,或是编译不成功,make根本不理。
四、在Linux下的写小程序
行缓冲区概念
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world\r"); //这里不是\n
fflush(stdout); //fflush会立即刷新缓冲区
sleep(3);
return 0;
}
- 如果没有\n或者fflush手动刷新缓冲区,hello world将会存放至缓冲区,程序结束后才执行打印。
1、倒计时
#include <stdio.h>
#include <unistd.h>
int main(){
int cnt = 10;
while(cnt){
printf("剩余时间:%2d\r",cnt);
fflush(stdout);
--cnt;
sleep(1);
}
return 0;
}
可以实现从10到计时的程序。
2、进度条
// process.h
#pragma once
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define NUM 101
#define STYLE '#'
extern void ProncessOn();
/*---------------------------------------------*/
// process.c
#include "process.h"
void ProcessOn(){
int cnt = 0;
char bar[NUM];
memset(bar,'\0',sizeof(bar));
char lables[]="|/-\\";
while(cnt<=100){
//printf("[%-100s][%-3d%][%c]\r",bar,cnt,lables[cnt%4]);
W> printf("\033[47m\033[30m[%-100s][%-3d%][%c]\r",bar,cnt,lables[cnt%4]);
bar[cnt++]=STYLE;
fflush(stdout);
usleep(50*1000);
}
printf("\033[40m\033[37m\n"); // 是控制printf输出颜色的代码
}
/*---------------------------------------------*/
// main.c
#include "process.h"
int main(){
ProcessOn();
return 0;
}
- 多文件编写的 Makefile 中不用写头文件,编译器自己会去找。