Makefile工程管理器

1. Makefile是什么?

一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,也可以执行操作系统的命令。

2. gcc编译流程

会用Makefile首先要知道gcc编译流程
方法1:

  • 预处理:gcc -E test.c -o test.i (处理以#开头的文件)

  • 编译:gcc -S test.i -o test.s (生成汇编代码)

  • 汇编:gcc -c test.s -o test.o (将汇编语言转换成机器代码)

  • 链接:gcc test.o -o test (与其它的机器代码文件和库文件汇集生成一个可执行文件)

方法2:

  • 将前四步和四为一:gcc test.c -o test

3. Make工程管理器

make:工程管理器
make会在当前路径下找一个叫做Makefile的文件(注意:M大小写都可以,一般大写)。

3.1 Makefile的命名规范

目标文件1:依赖文件1
(Tab键)依赖文件1是如何生成目标文件1的
目标文件2:依赖文件2
(Tab键)依赖文件2是如何生成目标文件2的

注意:

  1. Tab键不能用空格代替
  2. 一个Makefile可以有多个目标文件
  3. 当目标文件1和目标文件2没有联系的时候,只会执行目标文件1,不会执行目标文件2
    在这里插入图片描述
  4. 在调用make时,需要指定我们运行的目标是什么,如果没有执行,默认执行目标文件1
    在这里插入图片描述

3.2 预定义变量和自定义变量

预定义变量:

  • CC:c编译器的名称,默认为cc
  • CFLAGS:c编译器的选项,无默认值
  • RM:文件删除默认名称,默认为rm -rf

自定义变量:

  • OBJ:存放可执行文件
  • OBJS:存放目标文件

3.3 自动变量

  • $@:目标文件
  • $<:第一个依赖文件
  • $^:所有的依赖文件

3.4 变量定义的两种方式

  1. 递归方式 VAR=var
    递归方式
    注意:后面的值会影响前面的结果
  2. 简单方式 VAR:=var
    简单方式

3.5 假目标

make clean指令是清除我们的.o文件,当我们的目录下有一个clean文件就会发生错误,所以我们要用.PHONY:clean来解决假目标的问题

案例:

下面是一个可以输入输出学生的姓名,年龄,成绩的简单程序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// 定义一个结构体,包含学生的姓名,年龄,成绩
typedef struct student
{
	char name[30];
	int age;
	float scorce;
} stu;
//输入函数,实现简单的输入功能
stu *input(stu *p)
{
	printf("请输入学生的姓名,年龄,成绩:\n");	
	scanf("%s",p->name);
	scanf("%d",&p->age);
	scanf("%f",&p->scorce);
	printf("输入成功\n");
}
//输出函数,实现输出功能
stu *output(stu *p)
{
	printf("学生的姓名是:%s,年龄是:%d,成绩是:%.1f\n",p->name,p->age,p->scorce);
}

int main()
{
	int n;
	//申请一个结构体大的空间
	stu *p = (stu *)malloc(sizeof(stu));
	//判断申请的空间是否成功
	if(NULL == p)
	{
		perror("malloc error");
		return -1;
	}
	//将申请的空间清0
	memset(p,0,sizeof(stu));
	while(1)
	{
		printf("1. 输入\n");
		printf("2. 输出\n");
		printf("4. 退出\n");
		scanf("%d",&n);
		if(4 == n)
		{
			break;
		}
		switch(n)
		{
			case 1:
				input(p);
				break;
			case 2:
				output(p);
				break;
		}
	}
	//释放空间
	free(p);
	return 0;
}

接下来使用Makefile

CC:=gcc
CFLAGS=-c
OBJ=sort
OBJS=sort.o
$(OBJ):$(OBJS)
	$(CC) $< -o $@
sort.o:sort.c
	$(CC) $(CFLAGS) $< -o $@
.PHONY:clean
clean:
	$(RM) *.o

Makefile实现
实现成功!
简单工程确实很麻烦,但是当我们工程大的时候,就会方便很多

4. 嵌套Makefile

  1. 创建文件夹
    include(存放头文件.h),src(存放.c文件),obj(存放.o文件),bin(可执行文件)
  2. 编写总控Makefile,先书写自定义文件变量或预定义变量
CC:=gcc
CFLAGS=-c
OBJ=sort
OBJS=sort.o
export CC CFLAGS OBJ OBJS

  1. 编写src中的Makefile,将所有的.c文件编译生成.o文件,并移动到obj目录中
ALL:$(OBJS)
	mv $^ ../obj
sort.o:sort.c
	$(CC) $(CFLAGS) $< -o $@
  1. 编写src中的Makefile,将所有的.c文件编译生成.o文件,并移动到obj目录中
ALL:$(OBJ)
	mv $^ ../bin
$(OBJ):$(OBJS)
	$(CC) $< -o $@
  1. 编写总控文件Makefile,先执行src中的Makefile文件(make -C src),再执行obj中的Makefile(make -C obj)
ALL:
	make -C src
	make -C obj
clean:
	$(RM)  obj/*.o bin/*

总结:Makefile其实提供了非常非常多的功能由于本人是个初学者,只把学到的知识分享了出来,还有很大的空间让我们去探索,要先把基础知识吃透再去延伸Makefile的其它知识。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

居合啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值