目录
4、make和makefile怎么知道可执行程序是比较新的呢?
问题:我们这里为什么不把伪目标加到生成可执行文件上,而是加到clean上呢?
1、make和makefile有什么用?
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率,但目前我觉的这两个工具就是用来像编译器那样在Linux环境下去编译程序。
2、如何使用这两个工具:
2.1创建mekefile文件
我们首先需要创建一个makefile文件,注意文件名必须是makefile,只有首字母m可以是大小写,其他必须保持一致!
makefile文件内容如上所示。
2.2输入make指令
然后我们直接保存退出makefile文件,然后在命令行直接输入make,就可以直接将test.c源文件变成可执行程序!
上述就是项目的自动化清理,我们也要又项目的自动化清理
2.3输入make clean指令
下面的clean就是我们的项目自动化清理,make就是我们的编译生成mybin可执行文件,make clean就是将我们的mybin清理掉,下面这张图就是将mybin进行了清理
3、makefile文件如何编译程序
我们首先要明确make是一个指令,而makefile是一个文件(依赖关系和依赖方法)
什么是依赖关系和依赖方法:
依赖关系:我为什么要帮你
依赖方法:怎么帮
具体实例:
TIP:
1、Makefile和make形成目标文件的时候,默认是从上到下扫描makefile文件的。
2、默认只形成一个
所以有了上面的特性,我们这里默认都是将mybin放在第一个。
如果将clean和mybin交换位置,我们就需要写make mybin,因此我们就需要将mybin放在首位,只需要输入make即可。
4、make和makefile怎么知道可执行程序是比较新的呢?
答:这个是通过对比时间比出来的,只要可执行程序的最近修改时间比所有源文件的最近修改时间新,说明它就是最新的!
认识一下时间:(ACM)
stat关键字查询文件的时间
文件 = 内容 + 属性
这里一共有三个时间,具体文件的时间与modify(文件内容)一致。
- access表示进入文件的时间(可能不会实时)
- modify表示修改文件内容的具体时间
- change表示修改文件属性的具体时间
下面的各个点都表示文件的属性,因此modify修改,change一定会修改;而change(属性)修改,modify(内容)不一定修改!!!
5、.PHONY修饰目标文件成为伪目标
我们可不可以在文件内容没有更新的情况下强制执行命令呢?
可以,这里需要另一个语法 .PHONY:
Makefile1拒绝了执行clean, 因为文件clean存在。而Makefile2却不理会文件clean的存在,总是执行clean后面的规则。由此可见,.PHONY clean发挥了作用。
没有加上.PHONY,就会导致与文件夹中的clean文件冲突
加上了.PHONY表示后面的clean是一个伪目标,并不是文件!
这里的$@对应的mybin可执行文件,$^对应的目标文件,相当于一个简写
其中mybin也可以这样书写,相当于宏替换,就是以$加上()的形式进行替换
问题:我们这里为什么不把伪目标加到生成可执行文件上,而是加到clean上呢?
假设我们有一个大项目,里面包含了几百个源文件,如果我们只修改其中的几个源文件,这时加上伪目标,仍然生成几百个可执行文件,就大大浪费时间空间等资源,我们只需要生成我们修改过的源文件即可。
而清理工作是必须的!
6、Linux第一个小程序——进度条
第一个小技巧:
我们以后再写程序之前,先把makefile跑通之后再写test.c的内容。
6.1、预备的两个小知识
a、缓冲区
输出结果没有立刻输出 you can see me
而是等了3秒钟,才将结果输出,难道是先执行sleep(3) 吗?
我们时刻铭记程序的执行顺序一定是顺序结构的!
因此正确的解释就是printf已经跑完,输出的字符串一定是被保存起来了。被保存的地点就是缓冲区。在退出程序的时候,才刷新出来。
b、回车和换行
回车和换行本质上来说是两个东西。
在老式的键盘中,enter键长这样。
换行就是将内容换到下一行。
回车是将光标放在这一行的最初始位置。
先换行再回车,才有了enter的效果。
普通版本
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5 {
6 int cnt = 9;
7 while(cnt>=0)
8 {
9 printf("%d\r", cnt);
10 fflush(stdout);//强制刷新标准输出流
11 cnt--;
12 sleep(1);
13 }
14
15 return 0;//程序就开始结束
16 }
\r表示回车,就是将光标重新放在第一位,也就是表示回车
其中fflush将缓冲区的数据流进行刷新,防止标准输出流没有显示
进阶版本:
#include "processbar.h"
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM 103
#define Body '='
#define Head '>'
#define FILESIZE 1024*1024*1024
//模拟一种场景,表示一种下载的任务
void download(callback_t cb) // 回调函数的形式
{
srand(time(NULL)^1023);
int total = FILESIZE;
while(total){
usleep(10000); //下载动作
int one = rand()%(1024*1024*10);
total -= one;
if(total < 0) total = 0;
// 当前的进度是多少?
int download = FILESIZE - total;
double rate = (download*1.0/(FILESIZE))*100.0; // 0 23.4 35.6, 56.6
cb(rate);
//process_flush(rate);
//printf("download: %f\n", rate); // rate出来了,应该让进度条刷新
}
}
//version 2: 进度是多少,你进度条能知道吗?另外,什么进度?依附于其他应用的,比如下载
char buffer[NUM] = {0};
void process_flush(double rate)
{
static int cnt = 0;
int n = strlen(lable);
if(rate <= 1.0) buffer[0] = Head;
printf("[\033[4;32;44m%-100s\033[0m][%.1f%%][%c]\r", buffer, rate, lable[cnt%n]);
fflush(stdout);
buffer[(int)rate] = Body;
if((int)rate+1 < 100) buffer[(int)(rate+1)] = Head;
if(rate>=100.0) printf("\n");
cnt++;
cnt%=n;
}
int main()
{
//process();
download(process_flush);
return 0;
}
6.2如何在Linux环境下实现多文件编写:
我感觉用Linux编写程序项目比较爽的一点就是可以将不同的文件进行分屏,这样写起来比较爽。
我们可以在命令行用 vs + 文件名就可以添加文件进入分屏编写代码;然后CTRL+W就是替换不同的文件编写!
这里是多文件编译的时候,makefile文件书写的方式,这里是在同一个目录下的情况。不同目录,make指令只会执行当前目录下的makefile文件!
标签:文件,mybin,Makefile,make,makefile,int,clean,Linux From: https://blog.csdn.net/hanwangyyds/article/details/141790140