一、makefile 脚本概念
当用户需编译众多个代码文件时,单纯使用gcc 编译命令去对这些进行管理太麻烦了,这时候用户就可以编写一个makefile文件对这些代码进行编译管理。
1、最简单的makefile脚本
1.新建一个makefile 文件
touch makefile
2.编辑makefile 脚本文件
格式如下
目标文件:依赖文件
tab键 编译命令
👇如下
main:file.c lcd.c list.c main.c touch.c
gcc main.c file.c lcd.c list.c touch.c -o main
3.执行makefile 脚本
make
2、带探测功能makefile
只需要把依赖文件格式从 .c 变成 .o 那么makefile脚本就会自动检查那个源文件发生变化进行重新单独编译。
目的:提高代码的编译速度!
main:file.o lcd.o list.o main.o touch.o
arm-linux-gcc main.o file.o lcd.o list.o touch.o -o main
#修改探测规则
main.o:main.c
arm-linux-gcc main.c -o main.o -c
lcd.o:lcd.c
arm-linux-gcc lcd.c -o lcd.o -c
list.o:list.c
arm-linux-gcc list.c -o list.o -c
touch.o:touch.c
arm-linux-gcc touch.c -o touch.o -c
file.o:file.c
arm-linux-gcc file.c -o file.o -c
3、添加编译规则
语法:
目标文件:依赖文件
编译命令
规则1:
命令1
规则2:
命令2
....
-----------------------------------------
main:file.o lcd.o list.o main.o touch.o
arm-linux-gcc main.o file.o lcd.o list.o touch.o -o main
#修改探测规则
main.o:main.c
arm-linux-gcc main.c -o main.o -c
lcd.o:lcd.c
arm-linux-gcc lcd.c -o lcd.o -c
list.o:list.c
arm-linux-gcc list.c -o list.o -c
touch.o:touch.c
arm-linux-gcc touch.c -o touch.o -c
file.o:file.c
arm-linux-gcc file.c -o file.o -c
#增加 clean 编译规则 ,当输入make clean 时会执行该规则
clean:
rm main
rm *.o
#增加send 规则,当输入 make send 时会执行该规则
send:
scp main root@192.168.59.235:/
4、添加变量
变量名=值 #定义变量
$(变量名) #引用变量
---------------------------------
#定义一个CC 编译器变量
CC=gcc
#目标变量
TARGET=main
#依赖文件变量
OBJ=file.o lcd.o list.o main.o touch.o
$(TARGET):$(OBJ)
$(CC) $(OBJ) -o $(TARGET)
#修改探测规则
main.o:main.c
$(CC) main.c -o main.o -c
lcd.o:lcd.c
$(CC) lcd.c -o lcd.o -c
list.o:list.c
$(CC) list.c -o list.o -c
touch.o:touch.c
$(CC) touch.c -o touch.o -c
file.o:file.c
$(CC) file.c -o file.o -c
#增加 clean 编译规则 ,当输入make clean 时会执行该规则
clean:
rm main
rm *.o
install:
cp main /home/gec
uninstall:
rm /home/gec/main
#增加send 规则,当输入 make send 时会执行该规则
send:
scp main root@192.168.59.235:/
5、添加自动化变量
6、自动化变量的编译规则
#修改探测规则
$(OBJ):%.o:%.c
$(CC) $^ -o $@ -c
#定义一个CC 编译器变量
CC=gcc
#目标变量
TARGET=main
#依赖文件变量
OBJ=file.o lcd.o list.o main.o touch.o fun.o
$(TARGET):$(OBJ)
$(CC) $(OBJ) -o $(TARGET)
#修改探测规则
$(OBJ):%.o:%.c
$(CC) $^ -o $@ -c
#增加 clean 编译规则 ,当输入make clean 时会执行该规则
clean:
rm main
rm *.o
install:
cp main /home/gec
uninstall:
rm /home/gec/main
#增加send 规则,当输入 make send 时会执行该规则
send:
scp main root@192.168.59.235:/
7、添加搜索功能
SRC=$(wildcard *.c) #搜索当前目录下的所有.c文件
OBJ=$(SRC:%.c=%.o) #把SRC 文件中的所有 .c 格式转换为 .o 格式
#搜索所有.c文件
SRC= $(shell find ./ -name '*.c')
8、万能makefile 文件
#定义一个CC 编译器变量
CC=gcc
#目标变量
TARGET=main
#搜索所有.c文件
#SRC=$(wildcard *.c)
#搜索所有.c文件
SRC= $(shell find ./ -name '*.c')
#把.c 转换为 .o
OBJ=$(SRC:%.c=%.o)
#编译命令
$(TARGET):$(OBJ)
$(CC) $(OBJ) -o $(TARGET)
#修改探测规则
$(OBJ):%.o:%.c
$(CC) $^ -o $@ -c
#执行shell命令
test:
@echo $(OBJ)
echo $(SRC)
#增加 clean 编译规则 ,当输入make clean 时会执行该规则
clean:
rm main
rm *.o
9LVGL图形库makefile
#包含 ./lvgl/lvgl.mk
include $(LVGL_DIR)/lvgl/lvgl.mk 👇
LVGL_PATH ?= ${shell pwd}/lvgl 👉获取绝对路径 /home/gec/lv_port_linux/lvgl
#/home/gec/lv_port_linux/lvgl/src
ASRCS += $(shell find $(LVGL_PATH)/src -type f -name '*.S') #ASRCS 保存所有 .s 文件
CSRCS += $(shell find $(LVGL_PATH)/src -type f -name '*.c') #CSRCS 保存工程所有C文件
CSRCS += $(shell find $(LVGL_PATH)/demos -type f -name '*.c')
CSRCS += $(shell find $(LVGL_PATH)/examples -type f -name '*.c')
CXXEXT := .cpp
CXXSRCS += $(shell find $(LVGL_PATH)/src -type f -name '*${CXXEXT}') #CXXSRCS所有的 C++ 文件
AFLAGS += "-I$(LVGL_PATH)"
CFLAGS += "-I$(LVGL_PATH)"
CXXFLAGS += "-I$(LVGL_PATH)"
#
# Makefile
#
#编译器变量
CC ?= gcc #如果变量尚未赋值,则将右边的值赋给变量
#CC = arm-linux-gcc
#LVGL工程文件名
LVGL_DIR_NAME ?= lvgl
#LVGL工程路径
LVGL_DIR ?= .
#立即将右边的值赋给变量,不考虑变量是否已经被赋值。
#警告参数
WARNINGS := -Wall -Wshadow -Wundef -Wmissing-prototypes -Wno-discarded-qualifiers -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith \
-fno-strict-aliasing -Wno-error=cpp -Wuninitialized -Wmaybe-uninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits \
-Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security \
-Wno-ignored-qualifiers -Wno-error=pedantic -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion -Wclobbered -Wdeprecated -Wempty-body \
-Wshift-negative-value -Wstack-usage=2048 -Wno-unused-value -std=gnu99
#编译标记 -O3:这是优化等级选项,告诉 GCC 使用最高级别的优化。 -g0 表示不生成任何调试信息。 -I头文件路径
CFLAGS ?= -O3 -g0 -I$(LVGL_DIR)/ $(WARNINGS)
#库名称 -lm 数学库 -lSDL2 SDL图形库
LDFLAGS ?= -lm -lSDL2
#可执行文件
BIN = main
#构建目录
BUILD_DIR = ./build
#依赖文件目录 xxx.o -> ./build/obj
BUILD_OBJ_DIR = $(BUILD_DIR)/obj
#可执行文件所在目录 -> ./build/bin
BUILD_BIN_DIR = $(BUILD_DIR)/bin
#安装路径
prefix ?= /usr
#可执行文件安装路径 /usr/bin
bindir ?= $(prefix)/bin
#Collect the files to compile 主函数文件名
MAINSRC = ./main.c
#包含 ./lvgl/lvgl.mk ,包所有的 .s ,.c , .cpp 查找出来
include $(LVGL_DIR)/lvgl/lvgl.mk
#CSRCS 所有.c 文件 ,追加 mouse_cursor_icon.c 鼠标图标文件
CSRCS +=$(LVGL_DIR)/mouse_cursor_icon.c
OBJEXT ?= .o
AOBJS = $(ASRCS:.S=$(OBJEXT)) #ASRCS 所有的.s 文件 .S=.o ,把所有.s 替换成 .o ,赋值给 AOBJS
COBJS = $(CSRCS:.c=$(OBJEXT)) #CSRCS 所有的.c 文件 .c=.o , 把所有.c 替换成 .o ,赋值给 COBJS
MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) # ./main.c -> main.o -> MAINOBJ
SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) #SRCS 所有的源文件
OBJS = $(AOBJS) $(COBJS) $(MAINOBJ) #OBJS 所有的 .o 文件
#patsubst 替换 addprefix 添加前缀 ./build/obj $(patsubst ./%, %, $(OBJS))
#TARGET 编译的目标路径 ./build/obj/main.o , ./build/obj/mouse_cursor_icon.o
TARGET = $(addprefix $(BUILD_OBJ_DIR)/, $(patsubst ./%, %, $(OBJS)))
## MAINOBJ -> OBJFILES
all: default
#修改探测规则 gcc xxxx.c -c -o xxxx.o , @mkdir -p $(dir $@) 创建文件的目录 ,@echo "CC $<" 打印编译器与依赖文件
$(BUILD_OBJ_DIR)/%.o: %.c
@mkdir -p $(dir $@)
@$(CC) $(CFLAGS) -c $< -o $@
@echo "CC $<"
# gcc xxxx.s -c -o xxxx.o
$(BUILD_OBJ_DIR)/%.o: %.S
@mkdir -p $(dir $@)
@$(CC) $(CFLAGS) -c $< -o $@
@echo "CC $<"
#默认规则 TARGET 所有目标完整路径名 ,./build/bin -> $(BUILD_BIN_DIR)/$(BIN) -> ./build/bin/main
default: $(TARGET)
@mkdir -p $(dir $(BUILD_BIN_DIR)/)
$(CC) -o $(BUILD_BIN_DIR)/$(BIN) $(TARGET) $(LDFLAGS)
#清空
clean:
rm -rf $(BUILD_DIR)
#安装
install:
install -d $(DESTDIR)$(bindir)
install $(BUILD_BIN_DIR)/$(BIN) $(DESTDIR)$(bindir)
#卸载
uninstall:
$(RM) -r $(addprefix $(DESTDIR)$(bindir)/,$(BIN))
至此,希望看完这篇文章的你有所收获,我是Bardb,译音八分贝,道友,下期见