(makefile) 使用基础

文章目录

  • makefile 文件
  • 指令
  • 规则
    • 基本模板
    • 变量
    • 模式匹配
    • 函数
    • 伪目标
  • END

Make - GNU Project - Free Software Foundation

makefile 文件

无后缀的两种模式,任一字母大小写错误即错误

  • makefile
  • Makefile

指令

# 在makefile文件同级目录
# linux下
# Built for x86_64-pc-linux-gnu
make

# windows下
# Built for x86_64-w64-mingw32
mingw32-make

# 执行指定规则
make 完整规则名

规则

下面列出示例文件目录。

众所周知,头文件不属于源文件,因此下文不会涉及。

.
├── add.c
├── head.h
├── main.c
├── makefile
└── sub.c

main.c

#include 

#include "head.h"

int main() {
    printf("1 + 2 = %d\n", add(1, 2));
    printf("1 - 2 = %d\n", sub(1, 2));
}

head.h

#ifndef HH
#define HH

int add(int, int);
int sub(int, int);

#endif

add.c

int add(int x, int y) {
    return x + y;
}

sub.c

int sub(int x, int y) {
    return x - y;
}

基本模板

目标(s) : 依赖(s)的规则形式

然后作用域内是以tab开头。

一个makefile的第一个规则是主规则,后续规则是在主规则有需要时才执行。

# 目标(s) : 依赖(s)
# 此处的目标由下方规则生成
my_target.out : main.o add.o sub.o
	gcc main.o add.o sub.o -o my_target.out

# 为第一条规则服务
main.o add.o sub.o : main.c add.c sub.c
	gcc -c main.c -o main.o
	gcc -c add.c -o add.o
	gcc -c sub.c -o sub.o

变量

变量分为三类

  1. 自定义变量
  2. 预定义变量
  3. 自动变量

具体使用将在下文的例子中展示。

自定义变量必须有值,自动变量根据目标和依赖而定。

自动变量

自动变量 含 义
$* 目标文件的名称,不包含目标文件的扩展名
$@ 目标文件的名称,包含文件扩展名
$^ 所有不重复的依赖文件,这些文件之间以空格分开
$< 依赖项中第一个依赖文件的名称
$? 依赖项中,所有比目标文件时间戳晚的依赖文件,依赖文件之间以空格分开
$+ 所有的依赖文件,这些依赖文件之间以空格分开,按照出现的先后为顺序,其中可能 包含重复的依赖文件

模式匹配

# 使用自动变量
my_target.out : main.o add.o sub.o
	gcc $^ -o $@

# 模式匹配
# %是makefile中的通配符
%.o : %.c
	gcc $< -c
my_obj += main.o
my_obj += sub.o
my_obj += add.o
my_target = my_target.out
# 使用自定义变量
# $() 或 ${}
$(my_target) : $(my_obj)
	gcc $(my_obj) -o $(my_target)
	
%.o : %.c
	gcc $< -c

函数

为了展示函数效果,这里把目录结构变一下

.
├── head.h
├── main.c
├── makefile
└── src
    ├── add.c
    └── sub.c
  • 搜索路径
    • 变量名 = $(wildcard 路径1 路径2)
  • 改变后缀
    • 变量名 = $(patsubst 原后缀, 新后缀, 源)
# 根据路径搜索文件
my_file = $(wildcard *.c ./src/*.c)
# 后缀名的替换
my_obj = $(patsubst %.c, %.o, $(my_file))
my_target = my_target.out

${my_target} : ${my_obj}
	gcc ${my_obj} -o ${my_target}

# 不写-o $@ 默认生成当前目录下
%.o : %.c
	gcc -c $< -o $@

效果

.
├── head.h
├── main.c
├── main.o
├── makefile
├── my_target.out
└── src
    ├── add.c
    ├── add.o
    ├── sub.c
    └── sub.o

伪目标

从上面的效果看到,我们会获得很多的.o文件和一个.out文件。

当我们需要清除的时候,除了写shell还能用makefile。

添加.PHONY : clear这样在同路径下若有clear同名文件也能执行这个规则。

# 根据路径搜索文件
my_file = $(wildcard *.c ./src/*.c)
# 后缀名的替换
my_obj = $(patsubst %.c, %.o, $(my_file))
my_target = my_target.out

${my_target} : ${my_obj}
	gcc ${my_obj} -o ${my_target}

%.o : %.c
	gcc -c $< -o $@

# 用于删除的脚本
# 伪目标,不比较依赖和目标的时间戳
.PHONY : clear
clear : 
	rm $(my_obj) $(my_target)

END

参考:Makefile | 爱编程的大丙 (subingwen.cn)

你可能感兴趣的:(linux,c++,linux,gnu)