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

make/makefile

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

【linux】Linux项目自动化构建工具-make/Makefile_第1张图片
1.创建文件makefile
2.vim 操作makefile写入内容
【linux】Linux项目自动化构建工具-make/Makefile_第2张图片
3.vim 操作obj.c写入内容
【linux】Linux项目自动化构建工具-make/Makefile_第3张图片
4.make操作
make操作是一个命令,执行第一个依赖方法
【linux】Linux项目自动化构建工具-make/Makefile_第4张图片
6.查看内容myobj
【linux】Linux项目自动化构建工具-make/Makefile_第5张图片

7.make clean (删除myobj)
【linux】Linux项目自动化构建工具-make/Makefile_第6张图片


总结:make是一个命令,makefile是一个文件。
【linux】Linux项目自动化构建工具-make/Makefile_第7张图片
2.make会根据makefile的内容,完成编译或者清理的工作。


这里的.PHONY怎么理解呢??
先看一段程序
【linux】Linux项目自动化构建工具-make/Makefile_第8张图片
1.make使用两次,他会报myobj可执行程序是最新的,再次编译的时候编译器会拦截不然你在编译,当我们vim修改了obj.c的时候,又可以make了

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

【linux】Linux项目自动化构建工具-make/Makefile_第11张图片


2.makefile还能怎么玩??
【linux】Linux项目自动化构建工具-make/Makefile_第12张图片
3.还能这么玩?
我们可以用变量代替目标文件,依赖文件列表,并且将依赖方法的功能可以起名一个别称
【linux】Linux项目自动化构建工具-make/Makefile_第13张图片

【linux】Linux项目自动化构建工具-make/Makefile_第14张图片

【linux】Linux项目自动化构建工具-make/Makefile_第15张图片
4.makefile/make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有相关的依赖方法
【linux】Linux项目自动化构建工具-make/Makefile_第16张图片

我们要生成my.exe,必须要找到my.o的依赖方法,makefile会向下执行找my.o
这里类似于递归,直到翻译都执行完了。
【linux】Linux项目自动化构建工具-make/Makefile_第17张图片

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

Linux第一个小程序-进度条

准备工作

【linux】Linux项目自动化构建工具-make/Makefile_第18张图片
1.bar.h用于函数声明
2.bar.c用于函数定义
3.main.c用于测试
4.makefile 用于文件的编译以及清理

版本1

【linux】Linux项目自动化构建工具-make/Makefile_第19张图片

【linux】Linux项目自动化构建工具-make/Makefile_第20张图片
【linux】Linux项目自动化构建工具-make/Makefile_第21张图片
【linux】Linux项目自动化构建工具-make/Makefile_第22张图片
代码分析
我们要实现一个进度条,首先有个字符数组来充当进度条,先对其进行初始化,全部初始化为反斜杠0,防止打印时候出现乱码,大小为101,最后一个为字符串结尾反斜杠0,然后定义logo变量,用来进度条显示,routh字符常量数组用来模拟进度条后面旋转的.(上面图片里面的求routh数组长度的改为srelen,写错了)
【linux】Linux项目自动化构建工具-make/Makefile_第23张图片

进度条

版本2(模拟下载问题)

【linux】Linux项目自动化构建工具-make/Makefile_第24张图片
【linux】Linux项目自动化构建工具-make/Makefile_第25张图片

【linux】Linux项目自动化构建工具-make/Makefile_第26张图片
代码分析:
doneload函数中定义了一个要下载文件的总大小,一个当前已经下载了的大小,一个下载的速度,循环中,已经下载的大小小于总大小说明还没下完,doneload函数会给bar函数提供一个filesize,和current,可以让bar函数直到当前下载了百分之多少,下载了百分之多少就循环多少次,也就是字符串中+了多少个#,假如说当前是30%,那么count=30,循环30次,字符串lenth中有30个#,然后打印即可,如果下次到31%,cnt又重新开始从0开始。

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

多文件下载

【linux】Linux项目自动化构建工具-make/Makefile_第27张图片

【linux】Linux项目自动化构建工具-make/Makefile_第28张图片
【linux】Linux项目自动化构建工具-make/Makefile_第29张图片
代码分析:通过【linux】Linux项目自动化构建工具-make/Makefile_第30张图片
根据不同文件大小不同,传参文件大小

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

进度条2

contanct.cpp

#include"contanct.h"
//#include
#include//包含图形库头文件
//#include//包含多媒体设备接口头文件
//#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
#include//包含图形库头文件
#include//包含多媒体设备接口头文件
#include
#include 
#include 
#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 
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();

}

你可能感兴趣的:(Linux,运维)