【Linux开发工具】自动化构建-make/Makefile

news2024/12/24 14:42:18

🔥个人主页🔥:孤寂大仙V
🌈收录专栏🌈:Linux
🌹往期回顾🌹:【Linux开发工具】gcc和g++
🔖流水不争,争的是滔滔不


  • 一、make和Makefile简介
    • 1.1 什么是 make 和 Makefile?
    • 2.1 Makefile 简介
  • 二、make和Makefile的使用
    • 2.1 简单使用自动化构建
    • 2.2 编译链接过程
    • 2.3 扩展语法
  • 三、一个简单的利用自动化构建的程序---进度条

一、make和Makefile简介

1.1 什么是 make 和 Makefile?

make 是一个自动化构建工具,常用于 C/C++ 项目的编译和管理。它通过读取 Makefile 文件,自动处理文件依赖和编译过程,避免重复编译,提高效率。

2.1 Makefile 简介

Makefile 是一个文本文件,包含了构建规则和依赖关系,告诉 make 如何从源代码生成目标文件。一个简单的 Makefile 包括:

  • 目标(target):编译后生成的文件。
  • 依赖(dependencies):目标文件所依赖的源文件。
  • 命令(commands):如何生成目标的命令。

makefile带来的好处就是⸺“自动化编译”,一旦写好,只需要⼀个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是⼀条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

二、make和Makefile的使用

2.1 简单使用自动化构建

实现代码

#include<stdio.h>
int main()
{
    printf("hbx\n");
    return 0;
}

Makefile文件

code:code.c
        gcc -o code code.c
.PHONY:clean
clean:
        rm -f code

code:code.c 称为依赖关系。 gcc -o code code.c 称为依赖方法

.PHONY:clean
自动化构件中,工程是需要被清理的。
像clean这种,没有被第⼀个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令⸺“make clean”,以此来清除所有的目标文件,以便重编译。
但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。

make命令扫描Makefile文件的时候,从上而下扫描,默认形成第一个目标文件。
在这里插入图片描述

⽂件 = 内容 + 属性
Modify: 内容变更,时间更新
Change:属性变更,时间更新
Access:常指的是文件最近⼀次被访问的时间。在Linux的早期版本中,每当文件被访问时,其atime
都会更新。但这种机制会导致大量的IO操作。具体更新原则,不做过多解释。

对上述总是被执行进行解释:make因为有时间轴这一个概念,make 的时间轴基于文件的修改时间来决定是否需要重新编译和生成目标文件。它通过对比目标文件和依赖文件的时间戳,确保在文件发生变化时,只重新构建受影响的部分,避免重复的编译工作,提高了构建效率。.PHONY 是一个伪目标(phony target)的声明,用来告诉 make 某些目标并不是实际存在的文件,而只是一个命令或操作。这些伪目标不会与文件的修改时间进行比较,因为它们并不是用来生成实际文件的。。

2.2 编译链接过程

在Makefile文件中

code:code.o
        gcc code.o -o code
code.o:code.s
        gcc -c code.s -o code.o
code.s:code.i
        gcc -S code.i -o code.s
code.i :code.c
        gcc -E code.c -o code.i

.PHONY:clean
        re -f *.i *.s *.0 code

编译后
在这里插入图片描述
在这里插入图片描述
只输入make命令:

  1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  2. 如果找到,它会找文件中的第⼀个目标文件(target),在上面的例子中,他会找到 code 这个文件,并把这个文件作为最终的目标文件。
  3. 如果 code文件不存在,或是 code 所依赖的后面的 code.o 文件的文件修改时间要比 code 这个文件新(可以用touch 测试),那么,他就会执行后面所定义的命令来生成code 这个文件。
  4. 如果 code 所依赖的 code.o 文件不存在,那么 make 会在当前文件中找目标为code.o 文件的依赖性,如果找到则再根据那⼀个规则生成 code.o 文件。(这有点像⼀个堆栈的过程)
  5. 当然,你的C文件和H文件是存在的啦,于是 make 会生成 code.o 文件,然后再用 myproc.o 文件声明 make 的终极任务,也就是执行文件 hello 了。
  6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第⼀个目标文件。
  7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
  8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

2.3 扩展语法

Makefile还可以这样写
1

BIN=code
CC =gcc
SRC=code.c
FLAGS=-o
RM=rm -f

$(BIN):$(SRC)
        $(CC) $(FLAGS) $@ $^ 
.PHONY: 
clean:  
        $(RM) $(BIN)

2

BIN=code
SRC=code.c
CC=gcc
FLAGS=-o
RM =rm -f

$(BIN):$(SRC)
        @$(CC) $(FLAGS) $@ $^
        @echo "linking ... $^ to $@"
.PHONY:
clean:
        @$(RM) $(BIN)
        @echo "remove ... $(BIN)"


.PHONY:test
test:
        @echo $(BIN)
        @echo $(CC)
        @echo $(SRC)
        @echo $(FLAGS)
        @echo $(RM)

3

BIN=code
SRC=$(wildcard *.c)//当前目录下所有的.c文件名
OBJ=$(SRC:.c=.o)//把当前目录下的。c文件->。o文件

$(BIN):$(SRC)
        gcc -o $@ $^
%.o:%.c           //根据前面讲的可知中间编译过程很复杂,通过这个简化步骤
        gcc -c $<

.PHONY:
claen:
        rm -f $(OBJ) $(BIN)


三、一个简单的利用自动化构建的程序—进度条

在这里插入图片描述

\r 是 回车符(Carriage Return),通常用来将光标移动到当前行的开头。
还有一个缓冲区问题,先解释一下这个缓冲区的概念,我们打印的数据会存在一个缓冲区中,打印一段话后面跟一个\n就是进行行刷新。但是我们要写的进度条用#表示下载了多少,也就是每下载一点就要有显示。每有一个#就要打印在显示屏上,但是因为有缓冲区这个概念,看似不可行。这时可以用fflush(stdout)来解决这个问题。
在这里插入图片描述
首先要新建,头文件、源文件、main。
main.c

#include"process.h"

double total=1024.0;
double speed=1.0;
double current=0;
void DownLoad()
{
        while(current<=total)
        {
                process_v1(total,current);
                usleep(50000);
                current+=speed;
        }
        printf("\n");
        printf("DownLoad %0.1f MB Done",current);
}
int main()
{
        DownLoad();
        return 0;
}

模拟实现一下下载数据的过程。
process.h

#include<stdio.h>
#include<string.h>
#include<unistd.h>

void process_v1(double total,double current);

函数声明
process.c

#include"process.h"

#define NUM 101
#define STYNE '#'

void process_v1(double total,double current)
{
        char buffer[NUM];
        memset(buffer,0,sizeof(buffer));
        int num=(int)(current*100/total);
        const char* lable ="|/-\\";
        int len=strlen(lable);
        double rate=current/total;
        int i=0;
        static int cnt=0;
        for(i=0;i<num;i++)
        {
                buffer[i]=STYNE;
        }
        cnt%=len;
        printf("[%-100s][%0.1f%%][%c]\r",buffer,rate*100,lable[cnt]);
        cnt++;
        fflush(stdout);
}

开空间,进行计算每下载一点的数据占要下载数据的总量的多少,在利用for循环进行#的转化。比率问题,直接除。还有一个转圈只要程序没执行完就一直转,所以创建一个静态变量,cnt%=len,永远是0-6循环。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2264774.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch安装和数据迁移

Elasticsearch安装和数据迁移 Elasticsearch安装 下载并解压Elasticsearch 首先下载Elasticsearch的tar.gz文件&#xff0c;并将其解压&#xff1a; wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.8.2-linux-x86_64.tar.gz tar -xzf elastics…

dockerfile文档编写(1):基础命令

目录 Modelscope-agentARGFROMWORKDIRCOPYRUNENVCMD run_loopy Modelscope-agent ARG BASE_IMAGEregistry.cn-beijing.aliyuncs.com/modelscope-repo/modelscope:ubuntu22.04-cuda12.1.0-py310-torch2.1.2-tf2.14.0-1.12.0FROM $BASE_IMAGEWORKDIR /home/workspaceCOPY . /hom…

【论文阅读笔记】Learning to sample

Learning to sample 前沿引言方法问题声明S-NET匹配ProgressiveNet: sampling as ordering 实验分类检索重建 结论附录 前沿 这是一篇比较经典的基于深度学习的点云下采样方法 核心创新点&#xff1a; 首次提出了一种学习驱动的、任务特定的点云采样方法引入了两种采样网络&…

置换密码程序设计

实验目的与要求 1. 帮助学生掌握置换密码的加密解密过程&#xff0c;能够利用所学过的编程语言&#xff0c;实现加解密算法。使学生掌握编程实现实际问题中的方法&#xff0c;提高专业技能和专业素养。 2. 要求学生掌握算法的程序实现的方法,能应用密码算法的特点&#xff0c…

Android修行手册 - 移动端几种常用动画方案对比

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

【计算机视觉基础CV-图像分类】03-深度学习图像分类实战:鲜花数据集加载与预处理详解

本文将深入介绍鲜花分类数据集的加载与处理方式&#xff0c;同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向&#xff0c;为读者提供从数据组织、预处理、加载到可视化展示的完整过程&#xff0c;并为后续模型训练打下基础。 前言 在计算机视觉的深…

Windows查看MD5

如何在Windows&#xff0c;查看一个文件的MD5 1、ctrlr&#xff0c;输入cmd 2、执行命令certutil -hashfile 文件路径&#xff08;按住将文件拖进来就行&#xff09; MD5 3、执行命令certutil -hashfile 文件路径&#xff08;按住将文件拖进来就行&#xff09;SHA1 可查看SHA…

【优化算法】莲花效应优化算法(LEA):一种基于莲花自然启发的工程设计优化算法

目录 1.摘要2.算法原理3.结果展示4.参考文献5.代码获取 1.摘要 本文提出了一种新的进化算法——莲花效应算法&#xff08;LEA&#xff09;&#xff0c;该算法结合了蜻蜓算法中的高效操作算子&#xff0c;例如蜻蜓在花朵授粉中的运动方式用于探索&#xff0c;以及水在花叶上的自…

Next.js v15 - 服务器操作以及调用原理

约定 服务器操作是在服务器上执行的异步函数。它们可以在服务器组件和客户端组件中调用&#xff0c;用于处理 Next.js 应用程序中的表单提交和数据修改。 服务器操作可以通过 React 的 “use server” 指令定义。你可以将该指令放在 async 函数的顶部以将该函数标记为服务器操…

DataV的安装与使用(Vue3版本)

1、DataV(vue3)地址&#xff1a;DataV Vue3TSVite版 | DataV - Vue3 2、使用 npm install kjgl77/datav-vue3 安装 3、全局引入。 4、此时就可以按需使用了~

隐藏指定文件/文件夹和自动提示功能消失解决方案

一. 隐藏指定文件/文件夹 Idea中隐藏指定文件或指定类型文件 Setting → File Types → Ignored Files and Folders输入要隐藏的文件名&#xff0c;支持*号通配符回车确认添加 二. 自动提示功能消失解决方案 指定SpringBoot配置文件 File → Project Structure → Facets选…

Echarts连接数据库,实时绘制图表详解

文章目录 Echarts连接数据库&#xff0c;实时绘制图表详解一、引言二、步骤一&#xff1a;环境准备与数据库连接1、环境搭建2、数据库连接 三、步骤二&#xff1a;数据获取与处理1、查询数据库2、数据处理 四、步骤三&#xff1a;ECharts图表配置与渲染1、配置ECharts选项2、动…

Springboot应用开发:配置类整理

目录 编写目的 一、线程池 1.1 setCorePoolSize 1.2 setMaxPoolSize 1.3 setQueueCapacity 1.4 setKeepAliveSeconds 1.5 setThreadNamePrefix 1.6 setRejectedExecutionHandler 1.7 示例代码 二、Durid数据库连接池 2.1 ServletRegistrationBean 2.2 FilterRegist…

AI新书推荐:深度学习和大模型原理与实践(清华社)

本书简介 在这个信息爆炸、技术革新日新月异的时代&#xff0c;深度学习作为人工智能领域的重要分支&#xff0c;正引领着新一轮的技术革命。《深度学习和大模型原理与实践》一书&#xff0c;旨在为读者提供深度学习及其大模型技术的全面知识和实践应用的指南。 本书特色在于…

java如何使用poi-tl在word模板里渲染多张图片

1、poi-tl官网地址 http://deepoove.com/poi-tl/ 2、引入poi-tl的依赖 <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version></dependency>3、定义word模板 释义&#xf…

电力通信规约-104实战

电力通信规约-104实战 概述 104规约在广泛应用于电力系统远动过程中&#xff0c;主要用来进行数据传输和转发&#xff0c;本文将结合实际开发实例来讲解104规约的真实使用情况。 实例讲解 因为个人技术栈是Java&#xff0c;所以本篇将采用Java实例来进行讲解。首先我们搭建一…

linux socket编程之udp_dict_serve服务端--引入配置文件

注意&#xff1a;本篇博客只是对上一篇博客功能的增加 1.创建配置文件(翻译) Dict.txt apple: 苹果 banana: 香蕉 cat: 猫 dog: 狗 book: 书 pen: 笔 happy: 快乐的 sad: 悲伤的 run: 跑 jump: 跳 teacher: 老师 student: 学生 car: 汽车 bus: 公交车 love: 爱 hate: 恨 hell…

stm32定时器输出比较----驱动步进电机

定时器输出比较理论 OC(Output Compare)输出比较输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形每个高级定时器和通用定时器都拥有4个输出比较通道高级定时器的前3个通道额外拥有死区生成和互补输出…

ArrayList 类 (顺序表)

目录 一. ArrayList 基本介绍 二. ArrayList 中的法及其应用 1. 添加元素 (1) add() (2) addAll() 2. 删除元素 (1) remove() (2) removeAll() 3. 遍历元素 (1) for 循环遍历 (2) for - each 遍历 (3) 迭代器遍历 (4) 列表迭代器遍历 4. 判断 (1) cotains() (2…

ubuntu22.04安装PaddleX3

PaddleOCR 安装过程可以参考PaddleX本地安装教程 我的电脑环境配置&#xff1a; ubuntu22.04 cuda11.8&#xff08;之前安装的是12.4没有匹配的paddle-gpu;这里改成11.8&#xff09; 一、安装基础环境 1、 conda create -n ppx1 python3.10 2、 conda activate ppx1 3、…