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

简介: 【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();
}
目录
相关文章
|
2月前
|
Linux C++
Linux c/c++之makefile的基础使用
Linux下C/C++项目中makefile的基本使用,包括基础、进阶和高级用法,以及如何创建和使用makefile来自动化编译过程。
22 0
Linux c/c++之makefile的基础使用
|
2月前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
|
5月前
|
Java Linux C++
【Linux】Make和Makefile快速入门
【Linux】Make和Makefile快速入门
37 0
|
5月前
|
Java Linux 编译器
编写和使用Linux Makefile
编写和使用Linux Makefile
|
6月前
|
Linux
【make/Makefile】Linux下进度条的设计与实现
【make/Makefile】Linux下进度条的设计与实现
|
Linux 开发工具 C语言
韦东山Linux教学视频中的makefile文件详细介绍
韦东山Linux教学视频中的makefile文件详细介绍
202 0
|
Linux Windows 程序员
|
1月前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
101 8