【linux】Linux项目自动化构建工具-make/Makefile

make/makefile

背景
会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂
的功能操作makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

在这里插入图片描述
1.创建文件makefile
2.vim 操作makefile写入内容
在这里插入图片描述
3.vim 操作obj.c写入内容
在这里插入图片描述
4.make操作
make操作是一个命令,执行第一个依赖方法
在这里插入图片描述
6.查看内容myobj
在这里插入图片描述

7.make clean (删除myobj)
在这里插入图片描述


总结:make是一个命令,makefile是一个文件。
在这里插入图片描述
2.make会根据makefile的内容,完成编译或者清理的工作。


这里的.PHONY怎么理解呢??
先看一段程序
在这里插入图片描述
1.make使用两次,他会报myobj可执行程序是最新的,再次编译的时候编译器会拦截不然你在编译,当我们vim修改了obj.c的时候,又可以make了

在这里插入图片描述
2.为什么makefile对最新的可执行程序,默认不想重新生成呢?
这样可以提高编译效率,假如说一家大公司一个项目代码很多,编译起码要一两个小时,如果不断的编译的话,编译效率会很低。
3.makefile怎么知道我的程序需要被编译了呢?
对比可执行文件最近修改时间和源文件最近的修改时间,谁更新。如果源文件修改时间更新的话,可以继续编译make,反之,就会体现你可执行程序是最新的了。
所以我们.PHONY:依赖文件列表,这样就不会提醒可执行程序最新了
在这里插入图片描述

在这里插入图片描述


2.makefile还能怎么玩??
在这里插入图片描述
3.还能这么玩?
我们可以用变量代替目标文件,依赖文件列表,并且将依赖方法的功能可以起名一个别称
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
4.makefile/make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有相关的依赖方法
在这里插入图片描述

我们要生成my.exe,必须要找到my.o的依赖方法,makefile会向下执行找my.o
这里类似于递归,直到翻译都执行完了。
在这里插入图片描述

如果顺序是乱的,务必把目标文件my.exe放第一个

Linux第一个小程序-进度条

准备工作

在这里插入图片描述
1.bar.h用于函数声明
2.bar.c用于函数定义
3.main.c用于测试
4.makefile 用于文件的编译以及清理

版本1

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码分析
我们要实现一个进度条,首先有个字符数组来充当进度条,先对其进行初始化,全部初始化为反斜杠0,防止打印时候出现乱码,大小为101,最后一个为字符串结尾反斜杠0,然后定义logo变量,用来进度条显示,routh字符常量数组用来模拟进度条后面旋转的.(上面图片里面的求routh数组长度的改为srelen,写错了)
在这里插入图片描述

进度条

版本2(模拟下载问题)

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
代码分析:
doneload函数中定义了一个要下载文件的总大小,一个当前已经下载了的大小,一个下载的速度,循环中,已经下载的大小小于总大小说明还没下完,doneload函数会给bar函数提供一个filesize,和current,可以让bar函数直到当前下载了百分之多少,下载了百分之多少就循环多少次,也就是字符串中+了多少个#,假如说当前是30%,那么count=30,循环30次,字符串lenth中有30个#,然后打印即可,如果下次到31%,cnt又重新开始从0开始。

版本3(多文件下载问题)

多文件下载

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
代码分析:通过不同文件大小
根据不同文件大小不同,传参文件大小

版本4(进度条加载通讯录里面)

进度条2

contanct.cpp

#include"contanct.h"
//#include<windows.h>
#include<graphics.h>//包含图形库头文件
//#include<mmsystem.h>//包含多媒体设备接口头文件
//#pragma comment(lib,"winmm.lib")//加载静态库
void DestroyContanct(pp* p)
{free(p->arr);p->arr = NULL;p->size = 0;p->sz = 0;printf("销毁成功\n");
}
void Addbig(pp* p)
{if (p->sz == p->size){peoinfo* tmp = (peoinfo*)realloc(p->arr, (p->size + 2) * sizeof(peoinfo));if (tmp != NULL){p->arr = tmp;}p->size+= 2;printf("增容 + 2\n");}
}
void Loadcontact(pp* p)
{FILE* fp=fopen("contact.txt", "r");if (fp == NULL){perror("Loadcontact:");return;}peoinfo tmp = { 0 };while (fread(&tmp,sizeof(peoinfo),1,fp)){Addbig(p);p->arr[p->sz] = tmp;p->sz++;}fclose(fp);fp = NULL;
}
void Savecontact(pp* p)
{FILE* fp = fopen("contact.txt", "wb");if (fp == NULL){perror("Savecontact:");return;}int i = 0;for (i = 0; i < p->sz; i++){fwrite(p->arr+i, sizeof(peoinfo), 1, fp);}fclose(fp);fp = NULL;printf("保存成功\n");
}
void Initcontanct(pp* p)
{/*p->sz = 0;memset(p->arr, 0, sizeof(p->arr));*/p->sz = 0;p->size = SIZE;p->arr = (peoinfo*)malloc(p->size * sizeof(peoinfo));if (p->arr == NULL){perror(" Initcontanct:malloc");return;}memset(p->arr, 0, p->size * sizeof(peoinfo));Loadcontact(p);}void Addcontanct(pp* p)
{Addbig(p);printf("请输入姓名\n");scanf("%s", p->arr[p->sz].name);printf("请输入性别\n");scanf("%s", p->arr[p->sz].sex);printf("请输入年龄\n");scanf("%d", &(p->arr[p->sz].age));printf("请输入电话\n");scanf("%s", p->arr[p->sz].tel);printf("请输入地址\n");scanf("%s", p->arr[p->sz].addr);p->sz++;printf("录入成功\n");}
void Printcontanct(pp* p)
{int i = 0;printf("******************************************************\n");printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");printf("******************************************************\n");for (i = 0; i < p->sz; i++){printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr);printf("******************************************************\n");}
}
int find(pp* p, char name[])
{int i = 0;for (int i = 0; i < p->sz; i++){if (!strcmp(p->arr[i].name, name))return i;}return -1;
}
void Delcontanct(pp* p)
{char name[MAX_NAME];printf("请输入要删除朋友的名字\n");scanf("%s", name);if (find(p, name) == -1){printf("查无此人\n");}else{int k = find(p, name);for (int j = k; j < p->sz - 1; j++){p->arr[j] = p->arr[j + 1];}p->sz--;printf("删除成功\n");}
}
void findcontanct(pp* p)
{char name[MAX_NAME];if (p->sz == 0){printf("通讯录为空\n");return;}printf("请输入要查找朋友的名字\n");scanf("%s", name);if (find(p, name) == -1){printf("查无此人\n");}else{int k = find(p, name);printf("******************************************************\n");printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr);printf("******************************************************\n");}
}
void modifycontanct(pp* p)
{char name[MAX_NAME];printf("请输入修改朋友的名字\n");scanf("%s", name);if (find(p, name) == -1){printf("查无此人\n");}else{int k = find(p, name);printf("请输入要修改朋友的信息\n");printf("修改性别->");scanf("%s", p->arr[k].sex);printf("修改年龄->");scanf("%d", &(p->arr[k].age));printf("修改电话->");scanf("%s", p->arr[k].tel);printf("修改地址->");scanf("%s", p->arr[k].addr);printf("修改成功\n");}
}
int int_cmp_age(const void* p1, const void* p2)//按年龄比较
{return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age;
}
void Sortcontanct(pp* p)
{qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age);printf("按年龄排序成功,快去打印吧\n");
}
void bgm()
{    //打开音乐mciSendString("open ./music.MP3", 0, 0, 0);//后面参数不用管//播放音乐mciSendString("play ./music.MP3", 0, 0, 0);//后面参数不用管
}
void bar(double total, double current){char lenth[105];char logo = '>';const char* routh ="-/|\\";int len = strlen(routh);int cnt = 0;memset(lenth,'\0',105);double rate = (current * 100.0) / total;int count = (int)rate;while (cnt <= count){lenth[cnt++] = logo; }printf("[%-101s][%.1lf%%][%c]\r", lenth, rate, routh[cnt % len]);fflush(stdout);}

contanct.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<windows.h>
#include<graphics.h>//包含图形库头文件
#include<mmsystem.h>//包含多媒体设备接口头文件
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#pragma comment(lib,"winmm.lib")//加载静态库
#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TEL 12
#define MAX_ADDR 20
#define SIZE 3
enum opion
{EXIT,ADD,DEL,SEARCH,MODIFY,SORT,PRINT,SAVE,MUSIC,DESTROY
};
typedef struct peoinfo {char name[MAX_NAME];char sex[MAX_SEX];int age;char tel[MAX_TEL];char addr[MAX_ADDR];}peoinfo;typedef struct pp {struct peoinfo *arr;int sz;int size;}pp;
void Initcontanct(pp* p);
void Addcontanct(pp* p);
void Printcontanct(pp* p);
void Delcontanct(pp* p);
void findcontanct(pp* p);
void modifycontanct(pp* p);
void Sortcontanct(pp* p);
void Addbig(pp* p);
void Loadcontact(pp* p);
void Savecontact(pp* p);
void bgm();
void DestroyContanct(pp* p);
void bar(double total, double current);

test.cpp

#include"contanct.h"
#include <string.h>
double width = 4;
void doneload(double filesize)
{double  current = 0;while (current <= filesize){bar(filesize, current);current += width;Sleep(1);}printf("\n");
}
void menu()
{printf("#######################################\n");printf("#*********    1.add    ***************#\n");printf("#*********    2.del    ***************#\n");printf("#*********    3.search ***************#\n");printf("#*********    4.modify ***************#\n");printf("#*********    5.sort   ***************#\n");printf("#*********    6.print  ***************#\n");printf("#*********    7.save   ***************#\n");printf("#*********    8.music  ***************#\n");printf("#*********    9.Destroy***************#\n");printf("##########    0.exit   ################\n");}
void test()
{pp pro;Initcontanct(&pro);int input;do {menu();scanf_s("%d", &input);doneload(1024);system("cls");switch (input){case  ADD:Addcontanct(&pro);break;case DEL:Delcontanct(&pro);break;case SEARCH:findcontanct(&pro);break;case MODIFY:modifycontanct(&pro);break;case SORT:Sortcontanct(&pro);break;case PRINT:Printcontanct(&pro);break;case SAVE:Savecontact(&pro);break;case MUSIC:bgm();break;case DESTROY:DestroyContanct(&pro);break;case EXIT:printf("退出通讯录\n");break;default:printf("输入错误,请重新输入\n");break;}} while (input);
}void main()
{test();}

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

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

相关文章

Java笔记 --- 二、Stream流

二、Stream流 结合Lambda表达式&#xff0c;简化集合、数组的操作 获取Stream流对象 单列集合获取Stream流 双列集合获取Stream流 数组获取Stream流 一堆零散的数据获取Stream流 Stream流的静态方法of的形参是一个可变参数&#xff0c;可以传递零散数据&#xff0c;也可以传递…

【计算机网络】IP协议及动态路由算法

对应代码包传送门 IP协议及动态路由算法代码包及思科模拟器资料说明 相关文章 【计算机网络】中小型校园网构建与配置 【计算机网络】Socket通信编程与传输协议分析 【计算机网络】网络应用通信基本原理 目的&#xff1a; 1、掌握IP协议&#xff0c;IP分片&#xff0c;DH…

04. OSPF

文章目录 一. 初识OSPF1.1. OSPF概述1.2. OSPF特性1.3. OSPF的专业术语1.4. OSPF维护的3张表1.5. OSPF报文类型1.6. OSPF的邻居状态 二. 实验题2.1. 实验1&#xff1a;点到点链路上的OSPF2.1.1. 实验目的2.1.2. 实验拓扑图2.1.3. 实验步骤&#xff08;1&#xff09;IP地址配置&…

【无标题】Gateway API 实践之(五)FSM Gateway 的会话保持功能

网关的会话保持功能是一种网络技术&#xff0c;旨在确保用户的连续请求在一段时间内被定向到同一台后端服务器。这种功能在需要保持用户状态或进行连续交互的场景中特别重要&#xff0c;例如在维护在线购物车、保持用户登录状态或处理多步骤事务时。 会话保持通过提供一致的用…

java判空工具类 java判断对象属性是否全部为空

java判空工具类 java判断参数是否为空工具类 java判断对象属性是否全部为空 。 可以判断字符串数组&#xff0c;字符串类型&#xff0c;List对象集合&#xff0c;Map集合map<String,object>&#xff0c;map和多个String参数&#xff0c;对象类型&#xff0c;是否为空。…

数据结构C++队列(数组模拟)

队列也是比较简单的数据结构了&#xff0c;队列的特点是先进先出 下面代码中hh是队头&#xff0c;tt是队尾。 默认是从队尾插入数据&#xff0c;队头弹出数据。 代码中的数据结构可以使用这图片来解释&#xff0c;整个区间是数组q。hh和tt分别控制队头和队尾。 例题&#x…

AI作画工具 stable-diffusion-webui 一键安装工具(A1111-Web-UI-Installer)

安装 下载最新版本确保你的 NVIDIA 显卡驱动程序是最新的&#xff08;起码不能太老&#xff09;启动安装程序在欢迎屏幕上单击下一步在屏幕上&#xff0c;选择要安装的内容如果你已经安装了 Python 3.10 和 Git&#xff0c;那么可以取消选中如果你不知道这些是什么&#xff0c…

[01 LinuxShell ] 清华大学电子系科协软件部2023暑期培训

清华大学电子系科协软件部2023暑期培训_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV11N4y187ZE/?spm_id_from333.1007.top_right_bar_window_custom_collection.content.click&vd_source3ef6540f8473c7367625a53b7b77fd66 本视频为清华大学电子系科协软件部2023…

简单介绍----微服务和Spring Cloud

微服务和SpringCloud 1.什么是微服务&#xff1f; 微服务是将一个大型的、单一的应用程序拆分成多个小型服务&#xff0c;每个服务负责实现特定的业务功能&#xff0c;并且可以通过网络通信与其他服务通信。微服务的优点是开发更灵活&#xff08;不同的微服务可以使用不同的开…

nginx使用stream模块代理端口

今天原本准备将本地金仓的54321端口进行代理的&#xff0c;但是发现代理后总是无法访问。后来突然发现之前使用nginx代理的是一个地址而不是端口。因此做以下笔记用来做记录。 一、stream安装与配置 假设nginx在usr/local/nginx中 1. 测试当前nginx是否有stream模块 ./usr/…

FPGA 通过 UDP 以太网传输 JPEG 压缩图片

FPGA 通过 UDP 以太网传输 JPEG 压缩图片 简介 在 FPGA 上实现了 JPEG 压缩和 UDP 以太网传输。从摄像机的输入中获取单个灰度帧&#xff0c;使用 JPEG 标准对其进行压缩&#xff0c;然后通过UDP以太网将其传输到另一个设备&#xff08;例如计算机&#xff09;&#xff0c;所有…

代码随想录算法刷题训练营day17

代码随想录算法刷题训练营day17&#xff1a;LeetCode(110)平衡二叉树 LeetCode(110)平衡二叉树 题目 代码 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(…

计算机二级C语言的注意事项及相应真题-6-程序填空

目录 51.将参数num按升序插入到数组xx中52.在数组中找出两科成绩之和最高的学生并返回其在数组中的下标53.删除所有串长超过k的字符串&#xff0c;输出剩下的字符串54.根据所给的一组学生的成绩&#xff0c;计算出平均成绩&#xff0c;并计算低于平均成绩的学生的平均成绩55.将…

AlexNet,ZFNet详解

1 AlexNet 网络结构 对于AlexNet网络来说&#xff0c;因为当时资源环境受限&#xff0c;他从第一步卷积开始就把一个图像分到两个GPU上训练&#xff0c;然后中间进行组合最后进行融合成全连接成1000个置信度 1 得到一张3x224x224的图像&#xff0c;然后进行11x11的卷积&…

山海鲸智慧医疗解决方案:让医疗数据说话

在医疗领域&#xff0c;数据可视化对于提高诊疗效率、辅助医学研究和提升患者就医体验具有重要意义。作为山海鲸可视化软件的开发者&#xff0c;我们致力于利用先进的数据可视化技术&#xff0c;为医疗行业提供高效、智能的解决方案&#xff0c;本篇文章就带大家一起了解一下这…

【Linux】开始使用 vim 吧!!!

Linux 1 what is vim &#xff1f;2 vim基本概念3 vim的基本操作 &#xff01;3.1 vim的快捷方式3.1.1 复制与粘贴3.1.2 撤销与剪切3.1.3 字符操作 3.2 vim的光标操作3.3 vim的文件操作 总结Thanks♪(&#xff65;ω&#xff65;)&#xff89;感谢阅读下一篇文章见&#xff01;…

Power ModeII 插件的下载与使用-----idea

下载 Marketplace里面搜索下载即可 使用 下载后重启软件就可以用了 下面是一些关于Power ModeII &#xff0c;我的个性化设置截图 以及相关设置解释 插件或扩展的设置面板【用于给代码编辑器或集成开发环境&#xff08;IDE&#xff09;添加视觉效果】 主要设置 ENTER POWE…

数学知识第三期 欧拉函数

前言 相信大家在高中的时候接触过欧拉函数&#xff0c;希望大家通过本篇文章能够进一步理解欧拉函数&#xff01;&#xff01;&#xff01; 一、什么是欧拉函数&#xff1f; 欧拉函数是一个在数论中用于描述特定正整数的互质数的概念。具体来说&#xff0c;对于一个正整数n&…

华为机考入门python3--(0)模拟题3-计算字符串重新排列数

分类&#xff1a;排列组合 知识点&#xff1a; 计算字符串中每个字符出现的次数 Counter(string) 计算列表中每个元素出现的次数 Counter(list) 阶乘 math.factorial(num) 排列去重 题目来自【华为招聘模拟考试】 先把每个字符当成唯一出现过一次&#xff0c;计算所有排列…

keepalived+nginx双主热备(有问题私信)

keepalivednginx双主热备 前言keepalivednginx双主热备keepalivednginx双主热备部署安装nginx安装keepalived修改master节点的keepalived配置文件 修改backup节点的keeepalived配置文件配置keepalived主备配置keepalived双主热备 前言 有关keepalived和nginx的一些工作原理&am…