?Architecture Lab(下简称ArchLab)对应CS:APP的Chap 4——处理器体系结构。
读完README之后还是对实验包中的文件一头雾水,看到使用make命令,则今天学习一下相关内容。
这是ArchLab的PartA对应的Makefile文件
CC=gcc
CFLAGS=-Wall -O1 -g
LCFLAGS=-O1
LEX = flex
YACC=bison
LEXLIB = -lfl
YAS=./yas
all: yis yas hcl2c
# These are implicit rules for making .yo files from .ys files.
# E.g., make sum.yo
.SUFFIXES: .ys .yo
.ys.yo:
$(YAS) $*.ys
# These are the explicit rules for making yis yas and hcl2c and hcl2v
yas-grammar.o: yas-grammar.c
$(CC) $(LCFLAGS) -c yas-grammar.c
yas-grammar.c: yas-grammar.lex
$(LEX) yas-grammar.lex
mv lex.yy.c yas-grammar.c
isa.o: isa.c isa.h
$(CC) $(CFLAGS) -c isa.c
yas.o: yas.c yas.h isa.h
$(CC) $(CFLAGS) -c yas.c
yas: yas.o yas-grammar.o isa.o
$(CC) $(CFLAGS) yas-grammar.o yas.o isa.o ${LEXLIB} -o yas
yis.o: yis.c isa.h
$(CC) $(CFLAGS) -c yis.c
yis: yis.o isa.o
$(CC) $(CFLAGS) yis.o isa.o -o yis
hcl2c: hcl.tab.c lex.yy.c node.c outgen.c
$(CC) $(LCFLAGS) node.c lex.yy.c hcl.tab.c outgen.c -o hcl2c
hcl2v: hcl.tab.c lex.yy.c node.c outgen.c
$(CC) $(LCFLAGS) -DVLOG node.c lex.yy.c hcl.tab.c outgen.c -o hcl2v
hcl2u: hcl.tab.c lex.yy.c node.c outgen.c
$(CC) $(LCFLAGS) -DUCLID node.c lex.yy.c hcl.tab.c outgen.c -o hcl2u
lex.yy.c: hcl.lex
$(LEX) hcl.lex
hcl.tab.c: hcl.y
$(YACC) -d hcl.y
clean:
rm -f *.o *.yo *.exe yis yas hcl2c mux4 *~ core.*
rm -f hcl.tab.c hcl.tab.h lex.yy.c yas-grammar.c
> sudo apt install make
> make --version
在大型程序编译时,命令复杂,每次写一遍十分麻烦。所以make这个东西就是要求命令行“制作”出我们需要的文件的命令。而“做法”,就写在Makefile中。
下面给出一个最简单的例子:在hello.c的同目录下新建makefile文件,写如下内容:
hello:hello.c
gcc -o hello hello.c
在该目录下输入make命令,发现生成hello文件,可正确运行。
makefile文件也可写为如下,即编译和链接分开来写:
hello.o:hello.c
gcc -c hello.c
hello:hello.o
gcc -o hello hello.o
<target> : <prerequisites>
[tab] <commands>
默认查找三个文件作为makefile文件(有优先顺序):GNUmakefile(仅GNU make会识别)、makefile、Makefile(推荐)
指定:
make -f myname
或
make --file=myname
手动指定后,不再默认查找。
?make强大的地方:
1.隐式
2.时间戳判断
默认第一个目标。也可指定,如下:
.DEFAULT_GOAL = myname
.PHONY:clean?
没有目标文件的目标/无论是否为最新,每次make都想重新生成,就在.PHONY之后声明即可。
.SILENT: myname
含义是生成myname这个目标时不回显。?
.ONESHELL:
在一个进程内执行所有shell命令
竖线左侧:普通依赖
竖线右侧:order only?prerequisites
一些特殊符号的使用:
@? ? ? ? ? ? ? ? ? 不回显
-(减号)? ? ? ? ? 忽略错误继续执行
$()?????????????????变量展开
$$ ????????????????$号
=? ? ? ? ? ? ? ? ? 延迟展开赋值
:= ::= ???????? ? 立即展开赋值
+=????????????????追加
?=????????????????条件赋值
!=? ? ? ? ? ? ? ? ?shell运行赋值
not end(2024/1/16)
————ref————
1. 阮一峰 Make命令教程
2. bilibili @无限十三年 从零开始学Makefile