- target是目标文件
- 可以是一个执行文件,也可以是标签,或者伪目标
- 当有多个目标时,目标之间用空格分隔
- prerequisites是该文件所依赖的文件
- command是任意shell命令
- 只要targets不存在或prerequisites中有一个以上的文件比targets文件新,command所定义的命令就会被执行
- 伪目标总是会被执行
target ...: prerequisites ...
command1
command2
....
- make命令默认执行第一个目标文件
- 伪目标
- 声明为伪目标后,在执行对应的命令时,make 就不会检查是否存在target其对应的文件,而是每次都会运行对应的命令
- 若不声明:恰好存在同名的文件,则 make 将会认为 xx 文件已存在,没有重新构建的必要了
- 如果目录中含有或会生成和伪目标同名的文件,则需要通过**.PHONY**显示声明
- 例如:
.PHONY: clean test build
- 依赖
- 只有在目标文件的依赖比目标文件新的时候,才会更新目标文件
- 所以在生成.o文件的时候必须把所有头文件(包括隐式依赖的头文件)都放入依赖中
- 所谓隐式依赖就是a.c中include了a.h,而a.h中inlcude了b.h,则a.o的依赖是a.c, a.h 和 b.h
- 命令
- 如果第二行命令必须依赖第一行命令,则需要放在一行写,用分号隔开
- 默认如果命令执行错误则不执行后续命令
- 但是有些命令是可以错误的,此时需要在命令前加
-
- 例如
-mkdir dir1
, 如果错误则证明目录已经在了, 无需报错退出
- make 默认会打印每条命令,再执行
- 如果不想打印出命令本身,只想打印输出,则需要在命令前加上
@
例子
all: build
build: clean
./build.sh
online: build
./output/online/bootstrap.sh
boe: build
./output/test/bootstrap.sh
clean:
rm -rf ./output
test:
go test -v -count=1 -race ./...
cover:
go test -coverprofile=cover.out -count=1 ./... && go tool cover -html=cover.out && rm cover.out
lint:
golangci-lint run
CC = gcc
CFLAGS = -g -Wall -std=c11
TARGET = proxy
SOURCE = error.o http.o proxy.o robust_IO.o wrapper.o connect.o
all: $(TARGET)
@echo =====proxy successfully constructed=====
$(TARGET): $(SOURCE)
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCE)
connect.o: connect.c connect.h macro.h error.h
$(CC) $(CFLAGS) -c connect.c
error.o: error.c error.h macro.h
$(CC) $(CFLAGS) -c error.c
http.o: http.c http.h wrapper.h robust_IO.h macro.h error.h connect.h
$(CC) $(CFLAGS) -c http.c
proxy.o: proxy.c http.h macro.h connect.h wrapper.h
$(CC) $(CFLAGS) -c proxy.c
robust_IO.o: robust_IO.c robust_IO.h macro.h wrapper.h error.h
$(CC) $(CFLAGS) -c robust_IO.c
wrapper.o: wrapper.c wrapper.h macro.h error.h
$(CC) $(CFLAGS) -c wrapper.c
clean:
-rm -f $(TARGET) $(SOURCE)
.PHONY: all clean