liunx之make/makefile的使用

1.make和makefile的基本介绍

1.make是一个命令/makefile是一个文件(要自己创建)

makefile内部:

复制代码
 code(目标文件):code.c(依赖文件列表,可以有很多个,也可以一个也没有)//这里叫做依赖关系
  //这里是tab键    gcc -o code code.c       //这里叫做依赖方法

还有一种:

复制代码
.PHONY:clean//这里是伪目标                                                                                                                                                                   
   clean://这里是可以有文件的
      rm -f code

右边依赖文件列表没有文件或该关系是伪目标时该关系可以被反复执行,否则不行。

复制代码
[fengyouyinli@VM-0-2-centos lesson]$ make
gcc -o code code.c
[fengyouyinli@VM-0-2-centos lesson]$ make
make: `code' is up to date.

原因:老代码不做重新编译

时间属性中:

1.access:查找文件内容就更新

2.modify:修改文件内容就更新

3.change:修改文件属性就更新

access又有着查找一定次数才更新的特殊情况(防止频繁更新占用大量cpu内存)

此时可以解释了

当code的modify时间在code.c之后时,code的时间比code.c新,此时就无法继续make了,但当code.c发生了更新使其的modify比code新时就可以继续更新了。而依赖文件列表没有文件时,这种比较关系不会发生,自然不会有矛盾。

或该关系是伪目标时,就可以强行忽视时间的矛盾继续make。

(touch的功能本质时修改一个文件的所有时间)

复制代码
[fengyouyinli@VM-0-2-centos lesson]$ stat code.c
  File: 'code.c'
  Size: 71        	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 666057      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/fengyouyinli)   Gid: ( 1001/fengyouyinli)
Access: 2026-04-06 12:24:21.978458195 +0800
Modify: 2026-04-06 12:24:20.846453787 +0800
Change: 2026-04-06 12:24:20.846453787 +0800
 Birth: -
[fengyouyinli@VM-0-2-centos lesson]$ touch code.c
[fengyouyinli@VM-0-2-centos lesson]$ stat code.c
  File: 'code.c'
  Size: 71        	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 666057      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/fengyouyinli)   Gid: ( 1001/fengyouyinli)
Access: 2026-04-06 13:03:56.977551872 +0800
Modify: 2026-04-06 13:03:55.102544826 +0800
Change: 2026-04-06 13:03:55.102544826 +0800
 Birth: -

makefile中使用#来注释代码

2.依赖关系链与入栈逻辑

复制代码
code:code.o 
    gcc code.o -o code
code.o:code.s
    gcc code.o -o code.o
code.s:code.i
    gcc code.i -o code.s
code.i:code.c 
    gcc code.c -o code.i

每一个依赖关系当右侧的文件列表不存在时,会先入一个类似于栈的地方,直到右侧的文件列表存在为止,如果走完关系链右侧的文件列表还不存在就会报错。

3.定义变量(和#define很像)

复制代码
   BIN = test#将右侧定义一个新名字
   CC = gcc
   SRC = test.c
   FLAGS = -o
   RM = rm -f
   
   $(BIN):$(SRC)
       @echo"set $(BIN)"
     //@代表后面的内容不打印
      $(CC) $(FLAGS) $(BIN) $(SRC)
  //$代表里面的内容使用内部变量的数据(类似于解引用)
  .PHONY:clean
  clean:
      $(RM) $(BIN)
      echo"remove $(BIN)"

在依赖方式中@永远代表了要被生成的文件,^代表了所有被指定的文件且命令方式是可以有很多行的。

复制代码
$(BIN):$(SRC)
$(CC) $(FLAGS) $@ $^
     //     $@为$(BIN) $^为$(SRC)
echo "linking &^ to $@"
//字符内部的也会被替换
复制代码
%.o:%.c
$(CC) $(FLAGS) $<
//%.c表示makefile所在路径的所有.c文件
//%.o表示所有生成的文件后缀为.o
//$<表示依次将***.c文件转换为***.o(同名文件)

1步可以说一次性的将所有的.o文件转换为可执行文件。

2步可以说一次性将所有的.c文件转换为.o文件。

makefile中也可以执行命令,要加shell前缀(SRC和QBJ都为开头定义的变量名)

复制代码
SRC = $(shell ls *.c)
SRC = $(wildcard *.c)//这条是特定拿取当前路径所有.c文件的

QBJ = $(SRC:.c=.o)
自动得到SRC.o文件

2.进度条的实现

回车换行是两个动作:回车是回到当前行的第一个字符,换行是去到下一行。

\r回车 \n换行(vim 中的)

fflush():刷新缓冲区的函数(\n也有刷新缓冲区的功能,\r没有)

printf的底层是fprintf(stdout , ...);本质就是向显示器这个文件写入。

usleep():一微秒为单位睡眠。

sleep的头文件为unistd.h.

核心代码:

复制代码
void flushprint(double current,double total)//从外部传进来,以便实时更新
{
char buffer[101];
//留一个保'\0';
memset(buffer,0,sizeof(buffer);
//实时更新,覆盖之前的字符
const char lable*  = "/\-|";
//右侧加载界面
int len = strlen(lable);
static int cnt = 0;
//记录lable的旋转情况
int num  = (int)(current*100/total);
for(int a  =0;a < num;a++)
{
buffer[a] = '#';
//体现当前的下载情况
}
double rate = current/total;
cnt %= len;
printf("[%-100s][%/lf%%][%c]\r",buffer,rate*100,lable[cnt]);
cnt++;
fllush(stdout);
}
相关推荐
AnalogElectronic26 分钟前
linux 测试网络和端口是否连通的命令详解
linux·网络·php
Edward111111111 小时前
4月28日防火墙问题
linux·运维·服务器
子琦啊2 小时前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法
AOwhisky3 小时前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes
小龙在慢慢变强..3 小时前
目录结构(FHS 标准)
linux·运维·服务器
2035去旅行3 小时前
嵌入式开发,如何选择C标准库
linux·arm开发
刘延林.3 小时前
win11系统下通过 WSL2 安装Ubuntu 24.04 使用RTX 5080 GPU
linux·运维·ubuntu
CodeOfCC5 小时前
Linux 嵌入式arm64安装openclaw
linux·运维·服务器
宵时待雨6 小时前
linux笔记归纳3:linux开发工具
linux·运维·笔记
magrich6 小时前
安装NoMachine并解决无外接显示器桌面黑屏
linux·运维·服务器