Makefile简单学习
什么是Makefile?
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令.
为什么要使用Makefile?
就像前面提到的,一个工程的源文件可能不计其数,编写makefile,使用make命令来构建工程,会使原本复杂繁琐的工作简化许多,极大地提高了效率。
Makefile 基础结构
一个典型的 Makefile 由规则(rules)组成,每个规则描述了如何生成特定的目标文件。规则的一般格式如下:
target: dependencies...
command1
command2
...
- target:目标文件,可以是可执行文件、库文件或中间目标(如
.o
文件)。通常,第一个目标被视为默认目标。 - dependencies:依赖文件,列出生成目标所需的文件(通常是源文件或其他目标文件)。
- command:命令行指令,告诉
make
如何从依赖文件生成目标文件。注意每条命令前必须有制表符(不是空格),这是 Makefile 的语法要求。
下面来看一个具体的例子:
首先建立三个文件
add.c文件
int add(int a, int b)
{
return a + b;
}
fun.h文件
#ifndef FUN_H
#define FUN_H
#include <stdio.h>
int add(int a, int b);
#endif // FUN_H
main.c文件
#include "fun.h"
int main()
{
int a = 12, b = 6, c;
c = add(a, b);
printf("%d\n", c);
return 0;
}
makefile中的内容
add: main.o add.o
gcc -o add main.o add.o
main.o: main.c fun.h
gcc -c main.c
add.o: add.c
gcc -c add.c
clean:
rm -f main.o add.o add
使用过程可能碰到的错误
在我通过make命令后发生报错: Makefile:2:*** missing separator. Stop.
这个是编辑 makefile 时出现格式错误
使用vim编译器进入makefile文件中调整格式就好了
如果是正确的格式,命令行的颜色会不一样
注:紫色命令行的前面只用了一个(tab)
解决这个问题后再次使用make命令
使用成功
讲解
Makefile 基础结构
一个典型的 Makefile 由规则(rules)组成,每个规则描述了如何生成特定的目标文件。规则的一般格式如下:
target: dependencies...
command1
command2
...
- target:目标文件,可以是可执行文件、库文件或中间目标(如
.o
文件)。通常,第一个目标被视为默认目标。 - dependencies:依赖文件,列出生成目标所需的文件(通常是源文件或其他目标文件)。
- command:命令行指令,告诉
make
如何从依赖文件生成目标文件。注意每条命令前必须有制表符(不是空格),这是 Makefile 的语法要求。
示例 Makefile 分析
我们来看一下你提供的 Makefile 并进行解释:
add: main.o add.o
gcc -o add main.o add.o
main.o: main.c fun.h
gcc -c main.c
add.o: add.c
gcc -c add.c
clean:
rm -f main.o add.o add
目标 add
add: main.o add.o
gcc -o add main.o add.o
- 这个规则说明了如何创建最终的可执行文件
add
。 - 它依赖于两个对象文件
main.o
和add.o
。 - 如果这两个文件中的任何一个比
add
更新(即它们在最近被修改过),或者add
不存在,那么就会运行后面的命令来创建add
。
目标 main.o
main.o: main.c fun.h
gcc -c main.c
- 这个规则定义了如何创建
main.o
。 - 它依赖于
main.c
和fun.h
,这意味着如果main.c
或fun.h
发生变化,main.o
就需要重新编译。 -c
选项告诉 GCC 只编译不链接,生成.o
文件。
目标 add.o
add.o: add.c
gcc -c add.c
- 类似地,这个规则定义了如何创建
add.o
。 - 它仅依赖于
add.c
,因此如果add.c
发生变化,add.o
需要重新编译。
特殊目标 clean
clean:
rm -f main.o add.o add
clean
不是一个普通的目标,而是一种约定俗成的特殊目标,用来清理生成的文件。- 运行
make clean
会删除所有由构建过程生成的文件,包括目标文件和可执行文件,使项目回到初始状态。 -f
选项用于rm
命令,表示即使文件不存在也不会报错。
Makefile 的其他重要特性
-
变量:可以在 Makefile 中定义变量以存储常用的路径或命令。例如:
CC = gcc CFLAGS = -Wall -g OBJS = main.o add.o add: $(OBJS) $(CC) -o add $(OBJS) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@
这里使用了变量
CC
,CFLAGS
, 和OBJS
来简化命令,并且引入了模式规则(pattern rule)%.o: %.c
,它告诉make
如何根据.c
文件创建相应的.o
文件。 -
隐式规则:GNU Make 支持许多隐式规则,这些规则允许你在没有显式指定规则的情况下自动处理常见的任务。例如,如果你有一个
.c
文件但没有为对应的.o
文件编写规则,make
仍然知道如何编译它。 -
函数:Make 提供了一些内置函数,如
$(wildcard *.c)
用于匹配文件名,$(patsubst %.c,%.o,$(SRCS))
用于替换文件扩展名等。 -
条件语句:可以使用
ifeq
,ifneq
,ifdef
, 和ifndef
来实现条件逻辑。 -
包含其他 Makefile:可以使用
include
指令来包含其他的 Makefile 文件,这有助于组织大型项目的构建脚本。
提供了一些内置函数,如 $(wildcard *.c)
用于匹配文件名,$(patsubst %.c,%.o,$(SRCS))
用于替换文件扩展名等。
-
条件语句:可以使用
ifeq
,ifneq
,ifdef
, 和ifndef
来实现条件逻辑。 -
包含其他 Makefile:可以使用
include
指令来包含其他的 Makefile 文件,这有助于组织大型项目的构建脚本。
通过理解和正确运用这些特性,你可以创建更加复杂和灵活的 Makefile,从而更高效地管理项目的构建过程。
标签:文件,gcc,Makefile,目标,学习,add,简单,main From: https://blog.csdn.net/uifmlj/article/details/144596115