$@
表示目标文件$^
表示所有的依赖文件$<
表示第一个依赖文件
$@是目标的名字(目标就是冒号":"左边的文件名)。假如冒号左边有不止一个目标,那么$@等于触发当前规则的那个目标。
$<是第一个依赖项(依赖项就是冒号":"右边的文件名)。
当冒号“:”左边有多个目标时,$@一次只会对应一个目标
CC=gcc
%.o: %.cpp
$(CC) -c -o $@ $<
main: main.o fun.o
$(CC) -o $@ $^
$@对应%.o;而$<对应%.cpp
最后一行。$@取代了main,因为$@就代表main。$^取代了main.o fun.o。因为$^的作用就是代替冒号":"右边的所有依赖项(prerequisites)
例子与说明:
#目标 ... : 依赖 ...
# 命令1
# 命令2
# . . .
CC = gcc
# -Wall:选项可以打印出编译时所有的错误或者警告信息
# -O: 默认优化等级
# -O0: 表示编译时没有优化。
# -O1: 表示编译时使用默认优化。
# -O2: 表示编译时使用二级优化。
# -O3: 表示编译时使用最高级优化。
# -Os:相当于-O2.5优化,
CFLAGS = -Wall -O
PWD_DIR = $(shell pwd)
BSDIFF_DIR = $(PWD_DIR)/bsdiff
LIB_DIR = $(PWD_DIR)/lib
LZMA_DIR = $(PWD_DIR)/lzma
MAIN_DIR = $(PWD_DIR)/main
INCLUDE = -I$(PWD_DIR)/include -I$(BSDIFF_DIR) -I$(LIB_DIR) -I$(LZMA_DIR) -I$(MAIN_DIR) -I./
TARGET = bsdiff_lzma_recover
# wildcard 是GNU make程序预定义的一个函数,作用便是获取匹配模式文件名,原型为$(wildcard PATTERN)
# 获取目录下的所有.c文件
SRCS = $(wildcard $(BSDIFF_DIR)/*.c) \
$(wildcard $(LIB_DIR)/*.c) \
$(wildcard $(LZMA_DIR)/*.c) \
$(wildcard $(MAIN_DIR)/*.c) \
$(wildcard *.c)
# 模式替换函数patsubst函数原型为$(patsubst PATTERN,REPLACEMENT,TEXT)
# 把所有.c替换成.o
OBJS = $(patsubst %.c, %.o, $(SRCS))
# 这条语句把所以的目录路径导出,给子Makefile使用。
#export CC CFLAGS PWD_DIR FUNC_DIR MAIN_DIR OBJ_DIR INCLUDE
# $^ 表示所有的依赖文件
# $@ 表示生成的目标文件
# $< 代表第一个依赖文件
$(TARGET): $(OBJS)
$(info target: $@)
$(info all: $^)
$(CC) $^ -o $@ $(CFLAGS) $(INCLUDE)
# 它的含义是所有“.o”文件的依赖文件是对应的“.c”文件
%.o: %.c
$(info target: $@)
$(info first: $<)
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDE)
.PHONY: clean
# clean,手册里说:“make存在一个内嵌隐含变量“RM”,它被定义为:“RM = rm –f”。
# 因此在书写“clean”规则的命令行时可以使用变量“$(RM)”来代替“rm”,这样可以免出现一些不必要的麻烦!
# ”虽然不知道“必要的麻烦”是什么,但是小心不为过,照着手册做比较好
clean:
$(RM) $(TARGET)
$(RM) $(OBJS)
Makefile中打印日志信息
打印用info,Makefile提供了三个命令
$(warning "the value of LOCAL_PATH is$(FILE)")
$(info "the value of LOCAL_PATH is$(FILE)")
$(eror "the value of LOCAL_PATH is$(FILE)")