网上有很多写Makefile的文件
看起来很费事又伤脑筋,简单的写的话
假设由3个文件, films3.c list.c list.h
正常有gcc手动编译的话是 gcc films3.c list.c -o film -Wall -g
写成Makefile文件,如下
CC = gcc //表示用的编译器
CC_FLAGS = -Wall -g //表示编译时的动作,-Wall 小心的, -g可调试的。
all:film //目标文件
film:films3.c list.c
$(CC) $(CC_FLAGS) $^ -o $@ //执行动作
clean:
rm -f film *.o *.exe
符号 | 意义 |
---|---|
$@ | 匹配目标文件 |
$% | 与$@类似,但$%仅匹配“库”类型的目标文件 |
$< | 依赖中的第一个目标文件 |
$^ | 所有的依赖目标,如果依赖中有重复的,只保留一份 |
$+ | 所有的依赖目标,即使依赖中有重复的也原样保留 |
$? | 所有比目标要新的依赖目标 |
进阶之路:
1. 如下:tree目录编写Makefile
2. Makefile demo
#定义变量
#ARCH默认为x86,使用gcc编译器,
#否则使用arm编译器
ARCH ?= x86
TARGET = hello_main
#存放中间文件的路径
BUILD_DIR = build
#存放源文件的文件夹
SRC_DIR = sources
#存放头文件的文件夹
INC_DIR = includes .
#源文件
# wildcard函数用于获取文件列表,并使用空格分隔开。它的格式如下: $(wildcard 匹配规则)
SRCS = $(wildcard $(SRC_DIR)/*.c)
#目标文件(*.o)
# patsubst函数功能为模式字符串替换。它的格式如下: $(patsubst 匹配规则, 替换规则, 输入的字符串)
# notdir函数用于去除文件路径中的目录部分。它的格式如下:$(notdir 文件名)
# %是一个通配符,功能类似”*”,如”%.o”表示所 有以”.o”结尾的文件。
OBJS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(notdir $(SRCS)))
#头文件
DEPS = $(wildcard $(INC_DIR)/*.h)
#指定头文件的路径
CFLAGS = $(patsubst %, -I%, $(INC_DIR))
#根据输入的ARCH变量来选择编译器
#ARCH=x86,使用gcc
#ARCH=arm,使用arm-gcc
ifeq ($(ARCH),x86)
CC = gcc
else
CC = arm-linux-gnueabihf-gcc
endif
#目标文件
$(BUILD_DIR)/$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(CFLAGS)
#*.o文件的生成规则
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(DEPS)
#创建一个编译目录,用于存放过程文件
#命令前带“@”,表示不在终端上输出
@mkdir -p $(BUILD_DIR)
$(CC) -c -o $@ $< $(CFLAGS)
#伪目标
.PHONY: clean cleanall
#按架构删除
clean:
rm -rf $(BUILD_DIR)
3. 获取多个文件夹下 C文件
sub_dir := \
main \
test1 \
test2
obj_c = $(foreach dir,$(sub_dir),$(wildcard $(dir)/*.c))