一小时,学了个寂寞。

阿里的demo就是专业。

#@:静默执行
Q := @

#pwd指令获取当前工作目录为顶层目录
TOP_DIR := $(shell pwd)
#demos目录
DEMOS_DIR := demos
#输出目录
OUT_DIR := output

#C Compiler
CC := gcc

#编译选项
BLD_CFLAGS := $(CFLAGS) -Wall -Werror
#输出
BLD_CFLAGS += -Os

#加入指定library pthread
BLD_LDFLAGS := $(LDFLAGS) -lpthread

#查找 当前目录下 格式为DIR 且名称不为demos 作为SRC_DIR
SRC_DIR := $(shell find . -type d \( ! -name demos \))

#设置Headers路径
HDR_DIR := $(SRC_DIR)
#编译选项添加Include目录:HDR_DIR
BLD_CFLAGS += $(addprefix -I,$(HDR_DIR))

#在SRC_DIR下寻找路径不为*/demos/*.c且名称为*.c的文件做源文件
SRC_FILES := $(shell find $(SRC_DIR) -not -path "*/demos/*.c" -name "*.c")
#将SRC_FILES的后缀名改为.o作为obj文件名
OBJ_FILES := $(SRC_FILES:.c=.o)
#将obj文件名加上输出目录前缀
OBJ_FILES := $(addprefix $(OUT_DIR)/,$(OBJ_FILES))

#查找demos/*_demo.c, 将.c去掉, 替换_为-作为输出文件名
PROG_TARGET := $(subst _,-,$(patsubst %.c,%,$(wildcard demos/*_demo.c)))

#执行: 后面两个依赖项中所有内容
all: prepare $(PROG_TARGET)

#创建一个output目录
prepare:
	$(Q)mkdir -p output

#编译目标, 依赖为OBJ_FILES
$(PROG_TARGET): $(OBJ_FILES)
	#说话
	$(Q)echo "+ Linking $(OUT_DIR)/$(notdir $@) ..."
	#建立具有目标名称的文件夹
	$(Q)mkdir -p $(dir $@)
	#执行gcc指令
	#gcc -o $(PROG_TARGET)
	$(Q)$(CC) -o $@ \
		# 将更名为.o的.c文件更名回来 删去路径
	    $(patsubst $(OUT_DIR)/%,%,$(addsuffix .c,$(subst $(notdir $@),$(subst -,_,$(notdir $@)),$@))) \
		#加入编译选项和库
	    $(BLD_CFLAGS) $^ $(BLD_LDFLAGS)
	#把编译完的文件移到输出目录
	$(Q)mv $@ $(OUT_DIR)

#编译目标.o文件, 依赖为.c
$(OUT_DIR)/%.o: %.c
	#说话
	$(Q)echo ": Compiling $< ..."
	#建立文件夹
	$(Q)mkdir -p $(OUT_DIR)/$(dir $<)
	#编译c文件
	$(Q)$(CC) -o $@ -c $< $(BLD_CFLAGS)

#make clean干这个
clean:
	$(Q)rm -rf $(OUT_DIR)