makefile

makefile 介绍

一个企业级项目,通常会有很多源文件,有时也会按功能、类型、模块分门别类的放在不同的目录中,有时候也会在一个目录里存放了多个程序的源代码。
这时,如何对这些代码的编译就成了个问题。Makefle就是为这个问题而生的,它定义了一套规则,决定了哪些文件要先编译,哪些文件后编译,哪些文件要重新编译。
整个工程通常只要一个make命令就可以完成编译、链接,甚至更复杂的功能。可以说,任何一个Linux源程序都带有一个Makefile文件。

基本原则

** 目标文件:依赖文件**

规则
每条规则要以tab键开头,如:

1
2
main.o:main.c
gcc -c main.c -o main.o

工作原理

  1. 目标生成

检查规则中的依赖文件是否存在,如果不存在寻找是否有生成该依赖文件的规则

  1. 目标更新

检查目标依赖文件,任何一个文件有更新,则重新生成目标;

如果目标文件比依赖文件时间晚,重新生成目标

变量

  1. $@ –> 规则中的目标
  2. $< –> 规则中的第一个依赖条件
  3. $^ –> 规则中的所有依赖条件
  4. CC,PWD,CFLAG系统自带变量

模式规则

模式规则是在目标及依赖条件中使用%来匹配对应的文件,比如在目录下有main.c, func1.c, func2.c三个文件,对这三个文件的编译可以由一条规则完成:

1
2
%.o:%.c
$(CC) –c $< -o $@

这条模式规则表示:

1
2
3
main.o由main.c生成,
func1.o由func1.c生成,
func2.o由func2.c生成

这就是模式规则的作用,可以一次匹配目录下的所有文件。

函数

wildcard:

用于查找指定目录下指定类型的文件,跟的参数就是目录+文件类型,比如:

1
src = $(wildcard ./src/*.c)

这句话表示:找到./src 目录下所有后缀为.c的文件,并赋给变量src。
命令执行完成后,src的值为:main.c func1.c fun2.c。

patsubst:

匹配替换,例如以下例子,用于从src目录中找到所有.c 结尾的文件,并将其替换为.o文件,并赋值给obj。

1
obj = $(patsubst %.c ,%.o ,$(src))

把src变量中所有后缀为.c的文件替换成.o。
命令执行完成后,obj的值为main.o func1.o func2.o

example

文档结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/*main.c*/
#include "func1.h"
#include "func2.h"

int main(void)
{
func1();
func2();
return 0;
}
/*func1.h*/
void func1(void);
/*func1.c*/
#include<stdio.h>
void func1(void)
{
printf("this is func1\n");
}
/*func2.h*/
void func2(void);
/*func2.c*/
#include<iostream>
using namespace std;
void func2(void)
{
cout<<"this func2"<<endl;
}

makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sor = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(sor))
tar = app
CFLAGS = -Wall -c
CC = g++
$(tar):$(obj)
$(CC) $(obj) -o $(tar)

%.o:%.c
$(CC) $< $(CFLAGS) -o $@
.PHONY:clean
clean:
rm -rf *.o *.out
rm -rf $(tar)

在命令行向Makefile中传入参数

1
2
3
4
# Makefile
dut=""
vcs:
vcs ${dut}

上面这个Makefile,用起来可以如下:

1
make dut=top.v

这样就将${dut}替换成top.v


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!