CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
$@
和$<
到底做什么?
$@
是要生成的文件的名称,而$<
是第一个前提条件(通常是源文件)。您可以在GNU Make manual中找到所有这些特殊变量的列表。
例如,考虑以下声明:
all: library.cpp main.cpp
在这种情况下:
$@
等于all
$<
等于library.cpp
$^
等于library.cpp main.cpp
$@
和$<
被称为自动变量。变量$@
代表已创建文件的名称(即目标),$<
代表创建输出文件所需的第一个先决条件。例如:
hello.o: hello.c hello.h
gcc -c $< -o $@
这里,hello.o
是输出文件。这就是$@
扩展到的内容。第一依赖性是hello.c
。这就是$<
扩展到的内容。
-c
标志生成.o
文件;有关更多详细说明,请参见man gcc
。 -o
指定要创建的输出文件。
有关更多详细信息,您可以阅读this article about Linux Makefiles。
也可以检查GNU make
manuals。这将使制作Makefile和调试它们变得更加容易。
如果运行此命令,它将输出makefile数据库:
make
来自make -p
(在GNU自由文档许可证]下):
匹配规则后,由Managing Projects with GNU Make, 3rd Edition设置自动变量
。他们提供对目标和先决条件列表中元素的访问,因此您无需明确指定任何文件名。他们很有助于避免代码重复,但在定义时至关重要更通用的模式规则。有七个“核心”自动变量:
make
:代表目标的文件名。
$@
:存档成员规范的文件名元素。
$%
:第一个必备条件的文件名。
$<
:比目标更新的所有先决条件的名称,用空格分隔。
$?
:所有必备组件的文件名,以空格分隔。这个列表已删除重复的文件名,因为对于大多数用途,例如编译,复制等,不需要重复。
$^
:与$+
相似,这是所有先决条件的名称除$^
包含重复项外,其他均按空格分隔。这个变量是为特定情况创建,例如链接器的参数,其中重复值具有含义。
$+
:目标文件名的主干。词干通常是文件名没有后缀。它在模式规则之外的用法是不鼓励。此外,上述每个变量都有两个变体与其他品牌的兼容性。一种变体仅返回目录值的一部分。这是通过将“ D”附加到符号,
$*
,$(@D)
等。另一个变体仅返回文件值的一部分。这是通过将“ F”附加到符号,$(<D)
,$(@F)
等。请注意,这些变体名称比一个字符长,因此必须用括号括起来。 GNU make使用dir和notdir提供更具可读性的替代方法功能。
$(<F)
和$@
是特殊宏。
如果更改$<
,hello
,main.cpp
中的任何一个,则Makefile会生成hello.cpp
可执行文件。实现该规范的最小可能的Makefile可能是:
例如,如果您要编译源代码,但对象在不同目录中,则为: