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 $@
$@
和$<
到底作什么? html
$@
和$<
称为自动变量 。 变量$@
表明已建立文件的名称(即目标),而$<
表明建立输出文件所需的第一个先决条件。
例如: 数据库
hello.o: hello.c hello.h gcc -c $< -o $@
在这里, hello.o
是输出文件。 这就是$@
扩展到的内容。 第一个依赖项是hello.c
。 这就是$<
扩展到的内容。 函数
-c
标志生成.o
文件; 有关详细说明,请参见man gcc
。 -o
指定要建立的输出文件。 spa
有关更多详细信息,您能够阅读有关Linux Makefiles的文章 。 调试
另外,您能够查看GNU make
手册 。 这将使制做文件和调试它们变得更加容易。 code
若是运行此命令,它将输出makefile数据库: htm
make -p
$@
是要生成的文件的名称, $<
是第一个前提条件(一般是源文件)。 您能够在GNU Make手册中找到全部这些特殊变量的列表。 对象
例如,考虑如下声明: get
all: library.cpp main.cpp
在这种状况下: 编译器
$@
对all
求值 $<
评估为library.cpp
$^
评估为library.cpp main.cpp
$@
和$<
是特殊宏。
哪里:
$@
是目标的文件名。
$<
是第一个依赖项的名称。
从使用GNU Make,第3版管理项目 (受GNU Free Documentation License许可 ):
匹配规则后,由
make
设置自动变量 。 它们提供对目标和先决条件列表中元素的访问,所以您没必要显式指定任何文件名。 它们对于避免代码重复很是有用,可是在定义更通用的模式规则时相当重要。有七个“核心”自动变量:
$@
:表明目标的文件名。
$%
:归档成员规范的文件名元素。
$<
:第一个必备条件的文件名。
$?
:比目标更新的全部先决条件的名称,用空格分隔。
$^
:全部必备组件的文件名,以空格分隔。 此列表已删除重复的文件名,由于对于大多数用途(例如编译,复制等),不须要重复的文件名。
$+
:相似于$^
,这是用空格分隔的全部必备组件的名称,除了$+
包含重复项。 该变量是为特定状况建立的,例如连接器的参数,其中重复的值具备含义。
$*
:目标文件名的主干。 词干一般是没有后缀的文件名。 不建议在模式规则以外使用它。此外,上述每一个变量都有两个变体,以便与其余品牌兼容。 一个变体仅返回值的目录部分。 这是经过在符号
$(@D)
,$(<D)
等后面附加一个“ D”来表示的。另外一个变体仅返回值的文件部分。 这经过在符号$(@F)
,$(<F)
等后面附加一个“ F”来表示。请注意,这些变体名称的长度超过一个字符,所以必须用括号括起来。 GNU make经过dir和notdir函数提供了更具可读性的替代方法。
若是main.cpp
, hello.cpp
, factorial.cpp
任何一个更改,Makefile都会生成hello
可执行文件。 实现该规范的最小可能的Makefile多是:
hello: main.cpp hello.cpp factorial.cpp g++ -o hello main.cpp hello.cpp factorial.cpp
为了改进上述内容,咱们仅编译那些已编辑的C ++文件。 而后,咱们仅将结果对象文件连接在一块儿。
OBJECTS=main.o hello.o factorial.o hello: $(OBJECTS) g++ -o hello $(OBJECTS) main.o: main.cpp g++ -c main.cpp hello.o: hello.cpp g++ -c hello.cpp factorial.o: factorial.cpp g++ -c factorial.cpp
为了对此进行改进,咱们能够用一个.cpp.o
规则替换全部目标文件规则:
OBJECTS=main.o hello.o factorial.o hello: $(OBJECTS) g++ -o hello $(OBJECTS) .cpp.o: g++ -c $< -o $@
在这里, .cpp.o
规则定义如何创建anyfile.o
从anyfile.cpp
。
$<
匹配第一个依赖项,在这种状况下为anyfile.cpp
$@
匹配目标,在这种状况下为anyfile.o
。 Makefile中存在的其余更改是: