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 $@
Run Code Online (Sandbox Code Playgroud)
什么做的$@和$<准确呢?
bdo*_*lan 450
$@是生成的文件的名称,以及$<第一个先决条件(通常是源文件).您可以在GNU Make手册中找到所有这些特殊变量的列表.
例如,请考虑以下声明:
all: library.cpp main.cpp
Run Code Online (Sandbox Code Playgroud)
在这种情况下:
$@ 评估为 all$< 评估为 library.cpp$^ 评估为 library.cpp main.cppdex*_*ous 70
该$@和$<被称为自动变量.该变量$@表示已创建文件的名称(即目标),$<表示创建输出文件所需的第一个先决条件.
例如:
hello.o: hello.c hello.h
gcc -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
这hello.o是输出文件.这是$@扩展到的.第一个依赖是hello.c.这是$<扩展到的.
该-c标志生成该.o文件; 请参阅man gcc更详细的解释.该-o指定输出文件来创建.
有关更多详细信息,请阅读有关Linux Makefiles的文章.
另外,您可以查看GNU make手册.它可以更容易地制作Makefile并调试它们.
如果运行此命令,它将输出makefile数据库:
make -p
Run Code Online (Sandbox Code Playgroud)
ale*_*lex 57
来自使用GNU Make管理项目,第3版(它是在GNU自由文档许可下):
自动变量
make在匹配规则后设置.它们提供对目标和先决条件列表中元素的访问,因此您不必显式指定任何文件名.它们对于避免代码重复非常有用,但在定义更一般的模式规则时非常重要.有七个"核心"自动变量:
$@:表示目标的文件名.
$%:归档成员规范的filename元素.
$<:第一个先决条件的文件名.
$?:比目标更新的所有先决条件的名称,以空格分隔.
$^:所有先决条件的文件名,以空格分隔.此列表删除了重复的文件名,因为对于大多数用途,例如编译,复制等,不需要重复.
$+:类似于$^,这是由空格分隔的所有先决条件的名称,除了$+包含重复项.此变量是针对特定情况创建的,例如链接器的参数,其中重复值具有含义.
$*:目标文件名的主干.词干通常是没有后缀的文件名.不鼓励在模式规则之外使用它.此外,上述每个变量都有两个变体,以便与其他品牌兼容.一个变量仅返回值的目录部分.这是通过附加一个"d",以符号表示,
$(@D),$(<D)等.其它变体仅返回值的文件部分.这是通过附加一个"F"的符号来表示,$(@F),$(<F),等需要注意的是,这些不同名称的超过一个字符长,所以必须在括号括起来.GNU make使用dir和notdir函数提供了更具可读性的替代方案.
Ste*_*uan 18
Makefile的构建hello可执行文件,如果中的任何一个main.cpp,hello.cpp,factorial.cpp改变.实现该规范的最小可能Makefile可能是:
hello: main.cpp hello.cpp factorial.cpp
g++ -o hello main.cpp hello.cpp factorial.cpp
Run Code Online (Sandbox Code Playgroud)
为了改进上述内容,我们只编译那些已编辑的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
Run Code Online (Sandbox Code Playgroud)
为了改进这一点,我们可以使用单个.cpp.o规则替换所有对象文件规则:
OBJECTS=main.o hello.o factorial.o
hello: $(OBJECTS)
g++ -o hello $(OBJECTS)
.cpp.o:
g++ -c $< -o $@
Run Code Online (Sandbox Code Playgroud)
这里的.cpp.o规则定义如何建立anyfile.o从anyfile.cpp.
$< 匹配第一个依赖,在这种情况下, anyfile.cpp$@在这种情况下,匹配目标anyfile.o.Makefile中存在的其他更改包括: