11Makefile脚本

一、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,译音八分贝,道友,下期见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bardb

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值