我想知道如何创建一个 Makefile 来编译hello.c
:
// for example
int main(int argc, char *argv[]) {
puts("Hello world");
return 0;
}
我知道我是通过帮助gcc hello.c -o hello
和运行方式来编译程序的,但这就是我目前所知道的。
答案1
GNU make 有一个非常实质性的在线手册,虽然在我看来,它在很多方面都令人恼火和迟钝,但它确实提供了一个不错的参考。正如其他人所说,只需四处寻找适合您的教程,并查阅手册,以便您熟悉它的组织方式等。
用于构建的基本(GNU make)makefilehello.c
可能如下所示:
CFLAGS += -Wall -g -O0
PROGS = hello
.PHONY: clean
%: %.c
$(CC) $(CFLAGS) $< -o $@
clean:
-rm $(PROGS)
$(CC)
是一个内置变量;如果你不重新定义它,默认值是cc
,在 GNU 系统上它将是 的符号链接gcc
。 %
表示一个模式规则;在这种情况下它将匹配任何事物,但如果目录中没有,配方anything.c
就会失败。 $<
并且$@
自动变量。所以如果你现在运行:
make hello
Make 将执行:
cc -Wall -g -O0 hello.c -o hello
与 `$(CFLAGS) 一起使用+=
可以让你做这样的事情:
CFLAGS="--std=c99" make hello
因此,它将-Wall -g -O0
被附加到--std=c99
,并用空格分隔。请注意,如果您使用make CFLAGS="--std=c99" hello
,该值将代替makefile 中的任何定义。
规则由三个基本部分组成,目标, 这先决条件,以及食谱(看这里)。该规则将在以下情况下运行:
- 目标文件不存在。
- 目标文件早于先决条件之一。
.PHONY
无论如何,目标都会运行。因此make clean
使用上面的 make 文件运行将执行:
rm hello
在这种情况下$(PROGS)
,不会在其他地方使用,尽管在更复杂的项目 make 文件中,它可能会用作其他内容的先决条件。例如,如果将此规则添加到顶部(在变量声明之后):
all: $(PROGS)
并附加到列表all
中.PHONY:
,您现在只需输入make
,列表中的所有内容$(PROGS)
都将使用该规则构建%: %.c
,因为这是 make 的先决条件all
,并且all
是文件中的第一个规则 - 如果您不指定,则默认使用一个(即,您仍然可以用来make hello
构建“hello”程序)。
答案2
要创建合适的 Makefile,需要满足以下两件事:
- 宏
- 规则
我们在 Makefile 中使用宏来缩短语法,并使文件发生更改时更容易编辑。例如:
C = gcc # sets the macro for the C compiler to C
所以$(C)
可以代替gcc
规则用于检查文件及其依赖项的更改。必须始终存在一条all
规则,以便在make
运行时首先检查该all
规则。就像 C 程序一样,main()
首先执行函数。
示例生成文件:
C = gcc
CFLAGS = -o
INPUT = hello
OUT = $(INPUT)
all: $(INPUT)
$(OUT): $(INPUT).c
$(C) $(INPUT).cpp $(CFLAGS) $(OUT)
可以通过给出其名称 + 分号(例如do_this:
),在其后面添加任何依赖文件或规则(例如another_rule $(DEPENDANDTFILE)
),然后在 TAB 后的下一行添加命令来声明规则。
注意:除非语句行开头有 TAB,否则规则将不起作用。