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);
}
相关推荐
邪修king2 小时前
Re:Linux 系统篇(三十五):进程间通信Chapter2:从匿名管道到进程池:Linux 进程间通信实战(深度理解「先描述,再组织」)
java·linux·运维
2301_777998343 小时前
ARP协议进阶:ARP缓存、RARP与ARP欺骗原理解析
linux·服务器·网络·网络协议·缓存
Zenova EdgeOS10 小时前
Linux 内核日志 dmesg 进阶实战:从现场过滤到持久化闭环
linux·运维·服务器
郝亚军10 小时前
ec_private.pem的生成方法
linux·运维·服务器
NendoZen11 小时前
Arch Linux解决Grub无法SAVEDEFAULT问题(uki启动问题)
linux·运维·服务器
忆挽篱笙歌12 小时前
进程控制管理
linux·运维·服务器
Escalating_xu12 小时前
【Linux 网络编程】connect 的断线重连:用状态机写一个能恢复连接的 TCP 客户端
linux·网络·tcp/ip
Zucker n13 小时前
英语“论文”语法检查工具
linux·windows
苏宸啊14 小时前
Reactor反应堆模式
linux
骇客野人15 小时前
Linux 全套实操方案(含目录详解、文件传输、日志、文件规范、环境变量、Java 应用部署运维)
java·linux·运维