linux-自动化构建工具与进度条程序的实现
背景
会不会写 makefile ,从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中, makefile 定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作makefile 带来的好处就是 ——“ 自动化编译 ” ,一旦写好,只需要一个 make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。make 是一个命令工具,是一个解释 makefile 中指令的命令工具,一般来说,大多数的 IDE 都有这个命令,比如: Delphi 的 make , Visual C++ 的 nmake , Linux 下 GNU 的 make 。可见, makefile 都成为了一种在工程方面的编译方法。make 是一条命令, makefile 是一个文件,两个搭配使用,完成项目自动化构建。
进度条的实现
在完成进度条之前,需要会一个标识符,\n,能够将光标返回当前行的开始位置。
并且需要了解缓冲区的概念:
数据传入的的时候会暂时存在缓冲区当中,保证了不会频繁的传输。
如果想要让数据立即显示在屏幕上,需要用到函数fflush(),参数是数据流。
实现进度条可以创建三个文件,分别是声明文件,功能实现文件,执行文件
进度条代码:
test.c:
#include"progress.h"
2 int main(){
3 progress(50000);
4 return 0;
5 }progress.c:
#include"progress.h"
2 void progress(int n){
3 char arr[110] = {0};
4 int cnt = 0;
5 while(cnt<=100){
6 printf("[%-100s][\%%%d]\r",arr,cnt);
7 arr[cnt] = '-';
8 cnt++;
9 usleep(n);
10 fflush(stdout);
11 }
12 printf("\n");
13 return;
14 }
progress.h:#include<stdio.h>
2 #include<unistd.h>
3 void progress(int n);
用进度条的代码来举例
test:test.c progress.c
2 gcc -o $@ $^
3 .PHONY:clean
4 clean:
5 rm -rf test
$@可以代表可执行文件,$^代表的是依赖文件。
自动化构建工具
试例
#include <stdio.h>int main(){printf("hello Makefile!\n");return 0;}
依赖关系上面的文件 hello , 它依赖 hell.ohello.o , 它依赖 hello.shello.s , 它依赖 hello.ihello.i , 它依赖 hello.c依赖方法gcc hello.* - option hello.* , 就是与之对应的依赖关系
原理make 是如何工作的 , 在默认的方式下,也就是我们只输入 make 命令。那么,1. make 会在当前目录下找名字叫 “Makefile” 或 “makefile” 的文件。2. 如果找到,它会找文件中的第一个目标文件( target ),在上面的例子中,他会找到 “hello” 这个文件,并把这个文件作为最终的目标文件。3. 如果 hello 文件不存在,或是 hello 所依赖的后面的 hello.o 文件的文件修改时间要比 hello 这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成 hello 这个文件。4. 如果 hello 所依赖的 hello.o 文件不存在,那么 make 会在当前文件中找目标为 hello.o 文件的依赖性,如果找到则再根据那一个规则生成 hello.o 文件。(这有点像一个堆栈的过程)5. 当然,你的 C 文件和 H 文件是存在的啦,于是 make 会生成 hello.o 文件,然后再用 hello.o 文件声明make 的终极任务,也就是执行文件 hello 了。6. 这就是整个 make 的依赖性, make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么 make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功, make 根本不理。8. make 只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
项目清理工程是需要被清理的#include <stdio.h>int main(){printf("hello Makefile!\n");return 0;}.PHONY:cleanclean:rm -f hello.i hello.s hello.o hello像 clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要 make 执行。即命令 ——“make clean” ,以此来清除所有的目标文件,以便重编译。但是一般我们这种 clean 的目标文件,我们将它设置为伪目标 , 用 .PHONY 修饰 , 伪目标的特性是,总是被执行的。可以将我们的 hello 目标文件声明成伪目标,测试一下。