没志青年
发布于 2025-06-14 / 22 阅读
0

Makefile

Makefile 主要使用在没有集成开发环境时,对工程文件进行自动化编译的工具。

Makefile的本质是一个文件,需要配合make命令进行自动化编译。文件名常首字母大写.

Makefile文件的命名:makefile或者Makefile。 (推荐首字母大写的用法)

make是一个命令工具,用来解释makefile文件中的代码,从而实现自动化编译。编译使用的编译器本质上还是gcc。

Makefile文件中定义了一系列的规则来指定, 哪些文件需要先编译, 哪些文件需要后编译, 哪些文件需要重新编译, 甚至于进行更复杂的功能操作。

安装 Make 工具

sudo apt-get install make

语法

规则

Makefile 由多条规则组成,每条规则三个部分:

  • 目标:要生成的目标文件,如 app.o

  • 依赖:目标文件由哪些文件生成

  • 命令:用来生成目标的具体 shell 命令

目标: 依赖
<Tab>命令

命令前必须使用Tab,不能使用空格!

变量

自动变量

  • $@:目标文件

  • $^:所有依赖文件

  • $<:第一个依赖文件

普通变量定义:

CC = gcc
CFLAGS = -Wall -O2

使用:

$(CC) $(CFLAGS) -c main.c -o main.o

伪目标

有些目标不是文件,而是动作,比如 clean:

.PHONY: clean
clean:
	@rm -f *.o app

有些人不加 .PHONY,但是这个是十分必要的,可以避免文件名冲突,如果目录下有个文件叫 clean

  • 不写:不会执行 rm

  • 写了:无论目录下有没有文件 clean,都会执行 rm

模式规则

用于简化重复规则,比如所有 .c → .o

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

内置变量和函数

常用内置变量:

变量

说明

CC

C 编译器

CXX

C++ 编译器

CFLAGS

C 编译选项

LDFLAGS

链接选项

常用内置函数:

1、当前目录下所有 c 文件

SRC = $(wildcard *.c)

2、把 SRC 里的 .c 文件名,批量替换成 .o

OBJ = $(patsubst %.c, %.o, $(SRC))

CC = gcc
CFLAGS = -Wall -O2

SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
TARGET = app

$(TARGET): $(OBJ)
	$(CC) $(OBJ) -o $@

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

.PHONY: clean
clean:
	rm -f $(OBJ) $(TARGET)

例如

func.h

#ifndef __FUN_H__
#define __FUN_H__

#include <stdio.h>

extern int global;

extern void print_value();

#endif

func.c

#include "fun.h"
#include <stdio.h>

int global = 20;

void print_value()
{
    printf("global = %d\n",global);
    return;
}

main.c

#include "fun.h"

int main()
{
    print_value();
    return 0;
}

Makefile

main_exec : main.o fun.o
    gcc main.o fun.o -o main_exec

fun.o : fun.c
    gcc -c fun.c -o fun.o

main.o : main.c
    gcc -c main.c -o main.o
    
clean:
    rm -rf *.o main_exec

执行命令

make           #执行默认的生成第一个目标的命令

make main_exec #执行生成main_exec目标的命令

make clean     #执行clean目标的命令

Make 工作流程

首次编译

更新

Make