【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();
}
目录
相关文章
|
8天前
|
Unix Linux C语言
【Linux】 Linux makefile 教程
本文详细介绍了 Linux 环境下 Makefile 的基本结构、语法和使用方法,并通过一个简单的 C++ 项目示例演示了 Makefile 的实际应用。Makefile 是一个强大而灵活的工具,通过合理配置,可以极大地简化项目的编译和管理过程,提高开发效率。希望本文能帮助您更好地理解和应用 Makefile,在实际项目中高效管理代码的编译和构建。
43 16
|
9天前
|
Unix Linux C语言
【Linux】 Linux makefile 教程
本文详细介绍了 Linux 环境下 Makefile 的基本结构、语法和使用方法,并通过一个简单的 C++ 项目示例演示了 Makefile 的实际应用。Makefile 是一个强大而灵活的工具,通过合理配置,可以极大地简化项目的编译和管理过程,提高开发效率。希望本文能帮助您更好地理解和应用 Makefile,在实际项目中高效管理代码的编译和构建。
39 20
|
13天前
|
监控 安全 Ubuntu
Linux下如何安装配置Fail2ban防护工具
通过以上步骤,可以在Linux系统中成功安装和配置Fail2ban,从而有效保护服务器免受暴力破解等攻击。Fail2ban通过实时监控日志文件,自动更新防火墙规则,为系统安全提供了一层重要的保护。
69 36
|
22天前
|
网络协议 Unix Linux
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
34 11
|
25天前
|
Linux 网络性能优化 网络安全
Linux(openwrt)下iptables+tc工具实现网络流量限速控制(QoS)
通过以上步骤,您可以在Linux(OpenWrt)系统中使用iptables和tc工具实现网络流量限速控制(QoS)。这种方法灵活且功能强大,可以帮助管理员有效管理网络带宽,确保关键业务的网络性能。希望本文能够为您提供有价值的参考。
79 28
|
27天前
|
Rust Ubuntu Java
[Linux工具] Makefile
Makefile是Linux环境下用于自动化编译和链接程序的配置文件,常用于简化大型项目的编译流程。通过定义目标文件、依赖文件及生成命令,Makefile能高效管理编译任务。它不仅适用于C语言项目,还可扩展到其他编程语言和非编程任务中。
53 20
[Linux工具] Makefile
|
9天前
|
Linux
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
50 23
Linux系统之whereis命令的基本使用
|
2月前
|
Linux
linux查看目录下的文件夹命令,find查找某个目录,但是不包括这个目录本身?
通过本文的介绍,您应该对如何在 Linux 系统中查看目录下的文件夹以及使用 `find` 命令查找特定目录内容并排除该目录本身有了清晰的理解。掌握这些命令和技巧,可以大大提高日常文件管理和查找操作的效率。 在实际应用中,灵活使用这些命令和参数,可以帮助您快速定位和管理文件和目录,满足各种复杂的文件系统操作需求。
143 8
|
2月前
|
Ubuntu Linux
Linux 各发行版安装 ping 命令指南
如何在不同 Linux 发行版(Ubuntu/Debian、CentOS/RHEL/Fedora、Arch Linux、openSUSE、Alpine Linux)上安装 `ping` 命令,详细列出各发行版的安装步骤和验证方法,帮助系统管理员和网络工程师快速排查网络问题。
214 20