IT评测·应用市场-qidao123.com

标题: Linux项目主动化构建工具 - make/Makefile 练习 进度条 倒计时 [打印本页]

作者: 冬雨财经    时间: 2025-3-17 08:27
标题: Linux项目主动化构建工具 - make/Makefile 练习 进度条 倒计时

make/Makefile的重要性




依赖关系和依赖方法
在使用make/Makefile前我们起首应该明白各个文件之间的依赖关系以及它们之间的依赖方法。
依赖关系: 文件A的变更会影响到文件B,那么就称文件B依赖于文件A。
例如,test.o文件是由test.c文件通过预处理、编译以及汇编之后天生的文件,所以test.c文件的改变会影响test.o,所以说test.o文件依赖于test.c文件。
依赖方法: 如果文件B依赖于文件A,那么通过文件A得到文件B的方法,就是文件B依赖于文件A的依赖方法。
例如,test.o依赖于test.c,而test.c通过gcc -c test.c -o
test.o指令就可以得到test.o,那么test.o依赖于test.c的依赖方法就是gcc -c test.c -o test.o。
   就相称于月末没钱,找父母要,其中依赖关系是我是你孩子,依赖方法就是要钱,缺一不可。
  
多文件编译
当你的工程当中有源文件的时候,应该怎样进行编译天生可执行程序呢?
gcc

起首,我们可以直接使用gcc指令对源文件进行编译,进而天生可执行程序。

单个文件:使用源文件直接天生可执行程序

但进行多文件编译的时候一般不使用源文件直接天生可执行程序,而是先用每个源文件各自天生本身的二进制文件,然后再将这些二进制文件通过链接天生可执行程序。

 1.先各自天生二进制文件
2.将二进制文件通过链接天生可执行程序
原因:
若是直接使用源文件天生可执行程序,那么其中一个源文件进行了修改,再天生可执行程序的时候就需要将所以的源文件重新进行编译链接。
而若是先用每个源文件各自天生本身的二进制文件,那么其中一个源文件进行了修改,就只需重新编译天生该源文件的二进制文件,然后再将这些二进制文件通过链接天生可执行程序即可。

make 和Makefile


但是随着源文件个数的增加,我们每次重新天生可执行程序时,所需输入的gcc指令的长度与个数也会随之增加。这时我们就需要使用make和Makefile(m可以大写或小写)了,这将大大淘汰我们的工作量
第一步:在源文件地点目录下创建一个名为Makefile/makefile的文件。

第二步 :用vim编写格式
第一种

 黄色的为依赖关系白色的为方法


make是怎样⼯作的,在默认的⽅式下,也就是我们只输⼊make命令。
那么: 1. make会在当前⽬录下找名字叫“Makefile”或“makefile”的⽂件。
2. 如果找到,它会找⽂件中的第⼀个⽬标⽂件(target),在上⾯的例⼦中,他会找到 myproc 这 个⽂件,并把这个⽂件作为最终的⽬标⽂件。
3. 如果 myproc ⽂件不存在,或是 myproc 所依赖的后⾯的 myproc.o ⽂件的⽂件修改时间要 ⽐ myproc 这个⽂件新(可以⽤ touch 测试),那么,他就会执⾏后⾯所定义的命令来⽣成 myproc 这个⽂件。
4. 如果 myproc 所依赖的 myproc.o ⽂件不存在,那么 make 会在当前⽂件中找⽬标为 myproc.o ⽂件的依赖性,如果找到则再根据那⼀个规则⽣成 myproc.o ⽂件。(这有点像⼀ 个堆栈的过程) 5. 固然,你的C⽂件和H⽂件是存在的啦,于是 make 会⽣成myproc.o ⽂件,然后再⽤myproc.o ⽂件声明 make 的终极任务,也就是执⾏⽂件 hello 了。
 6. 这就是整个make的依赖性,make会⼀层⼜⼀层地去找⽂件的依赖关系,直到最终编译出第⼀个 ⽬标⽂件。
7. 在找寻的过程中,如果出现错误,⽐如最后被依赖的⽂件找不到,那么make就会直接退出,并 报错,⽽对于所定义的命令的错误,或是编译不成功,make根本不理。
第二种 

 Makefile文件的简写方式:

变量定义部门

编译规则部门

模式规则部门

伪目标和清理规则部门

 Linux小练习 ———倒计时


 

   
  小练习——进度条


1. process.h 和 process.c 文件

宏定义

  1. #define NUM 101
  2. #define STYLE '='
复制代码

process_v1 函数

  1. void process_v1()
  2. {
  3.     char buffer[NUM];
  4.     memset(buffer, 0, sizeof(buffer));
  5.     const char *lable="|/-\";
  6.     int len = strlen(lable);
  7.     int cnt = 0;
  8.     while(cnt <= 100)
  9.     {
  10.         printf("[%-100s][%d%%][%c]\r", buffer, cnt, lable[cnt%len]);
  11.         fflush(stdout);
  12.         buffer[cnt]= STYLE;
  13.         cnt++;
  14.         usleep(50000);
  15.     }
  16.     printf("\n");
  17. }
复制代码

FlushProcess 函数

  1. void FlushProcess(double total, double current)
  2. {
  3.     char buffer[NUM];
  4.     memset(buffer, 0, sizeof(buffer));
  5.     const char *lable="|/-\";
  6.     int len = strlen(lable);
  7.     static int cnt = 0;
  8.     int num = (int)(current*100/total);
  9.     int i = 0;
  10.     for(; i < num; i++)
  11.     {
  12.         buffer[i] = STYLE;
  13.     }
  14.     double rate = current/total;
  15.     cnt %= len;
  16.     printf("[%-100s][%.1f%%][%c]\r", buffer, rate*100, lable[cnt]);
  17.     cnt++;
  18.     fflush(stdout);
  19. }
复制代码

2. main.c 文件

全局变量

  1. double total = 1024.0;
  2. double speed = 1.0;
复制代码

DownLoad 函数

  1. void DownLoad()
  2. {
  3.     double current = 0;
  4.     while(current <= total)
  5.     {
  6.         FlushProcess(total, current);
  7.         usleep(3000);
  8.         current += speed;
  9.     }
  10.     printf("\ndownload %.2lfMB Done\n", current);
  11. }
复制代码

main 函数

  1. int main()
  2. {
  3.     DownLoad();
  4.     DownLoad();
  5.     DownLoad();
  6.     DownLoad();
  7.     DownLoad();
  8.     DownLoad();
  9.     DownLoad();
  10.     DownLoad();
  11.     return 0;
  12. }
复制代码
多次调用 DownLoad 函数,模拟多次文件下载过程。
完备代码

 process.h
  1. #pragma once
  2. #include <stdio.h>
  3. // 声明进度条函数
  4. void process_v1();
  5. void FlushProcess(double total, double current);   
复制代码
process.c
  1. #include "process.h"#include <string.h>#include <unistd.h>#define NUM 101
  2. #define STYLE '='
  3. // 版本1:简单的进度条实现void process_v1() {    char buffer[NUM];    memset(buffer, 0, sizeof(buffer));    const char *lable = "|/-\";    int len = strlen(lable);    int cnt = 0;    while (cnt <= 100) {        printf("[%-100s][%d%%][%c]\r", buffer, cnt, lable[cnt % len]);        fflush(stdout);        buffer[cnt] = STYLE;        cnt++;        usleep(50000);    }    printf("\n");}// 版本2:根据总进度和当前进度更新进度条void FlushProcess(double total, double current) {    char buffer[NUM];    memset(buffer, 0, sizeof(buffer));    const char *lable = "|/-\";    int len = strlen(lable);    static int cnt = 0;    int num = (int)(current * 100 / total);    int i = 0;    for (; i < num; i++) {        buffer[i] = STYLE;    }    double rate = current / total;    cnt %= len;    printf("[%-100s][%.1f%%][%c]\r", buffer, rate * 100, lable[cnt]);    cnt++;    fflush(stdout);}   
复制代码
 main.c
  1. #include "process.h"#include <stdio.h>#include <unistd.h>double total = 1024.0;
  2. double speed = 1.0;
  3. // 模拟下载函数,调用进度条更新函数void DownLoad() {    double current = 0;    while (current <= total) {        FlushProcess(total, current);        usleep(3000);        current += speed;    }    printf("\ndownload %.2lfMB Done\n", current);}int main() {    // 多次调用下载函数    for (int i = 0; i < 8; i++) {        DownLoad();    }    return 0;}   
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4