文章目录
前言
一般的,可以分为三种makefile:
1.顶层目录下makefile
2.顶层目录下的makefile.build
3.各级子目录下的makefile
一、.各级子目录下的makefile
形式如下:
EXTRA_CFLAGS := #
CFLAGS_file.o :
obj-y += file.o #表示把当前目录下的file.c 编译
obj-y += subdir/ #表示要进入subdir这个子目录下去寻找文件来编进程序里,是哪些文件由subdir目录下的Makefile决定。
二、顶层makefile
1需要obj-y 来指定根目录下要编进去的文件
主要是定义工具链前缀CROSS_COMPILE,
定义编译参数CFLAGS,
定义链接参数LDFLAGS,
这些参数就是文件中用export导出的各变量。
三、顶层makefile.build
把某个目录及它的所有子目录中、需要编进程序去的文件都编译出来,打包为built-in.o。
四、使用
1.把顶层Makefile, Makefile.build放入程序的顶层目录 在各自子目录创建一个空白的Makefile
2.确定编译哪些源文件 修改顶层目录和各自子目录Makefile的obj-y :
obj-y += xxx.o 这表示要编译当前目录下的xxx.c
obj-y += yyy/ , 要编译当前目录下的yyy子目录
3. 确定编译选项、链接选项 修改顶层目录Makefile的CFLAGS,这是编译所有.c文件时都要用的编译选项;
修改顶层目录Makefile的LDFLAGS,这是链接最后的应用程序时的链接选项;
修改各自子目录下的Makefile: “EXTRA_CFLAGS”, 它给当前目录下的所有文件(不含其下的子目录)设置额外的编译选项, 可以不设置 “CFLAGS_xxx.o”,
它给当前目录下的xxx.c设置它自己的编译选项, 可以不设置
4. 使用哪个编译器?
修改顶层目录Makefile的CROSS_COMPILE, 用来指定工具链的前缀(比如arm-linux-)
5. 确定应用程序的名字:
修改顶层目录Makefile的TARGET, 这是用来指定编译出来的程序的名字
6. 执行"make"来编译,执行"make clean"来清除,执行"make distclean"来彻底清除
五、例子
(1)顶层makefile
提供项目make命令执行入口,提供所有编译的目标;
定义全局变量、项目编译选项、链接选项; 通过obj-y指定要搜索的子目录;
切换目录,递归执行make命令,并执行根目录下的Makefile.build文件
CROSS_COMPILE ?=
#定义延时变量
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
#export 全局变量,供其他makefile 使用
export AS LD CC CPP AR NM
export STRIP OBJCOPY OBJDUMP
CFLAGS := - wALL -02 -g
CFLAGS += -I &(shell pwd)/include
LDFLAGS := -lpthread -lfreetype -lm
export CFLAGS LDFLAGS
TOPDIR := $(shell pwd)
export TOPDIR
TARGET := test
obj-y += display/
# obj-y += unittest/
#obj-y += input/
#obj-y += font/
obj-y += ui/
obj-y += page/
obj-y += config/
obj-y += business/
all : start_recursive_build $(TARGET)
@echo $(TARGET) has been built!
start_recursive_build:
@echo $@
@echo obj-y = $(obj-y)
make -C ./ -f $(TOPDIR)/Makefile.build
$(TARGET) : built-in.o
$(CC) -o $(TARGET) built-in.o $(LDFLAGS)
clean:
rm -f $(shell find -name "*.o")
rm -f $(TARGET)
distclean:
rm -f $(shell find -name "*.o")
rm -f $(shell find -name "*.d")
rm -f $(TARGET)
(2)顶层makefile.build
包含(include)顶层目录下的Makefile文件;
取出每个子Makefile中定义的.o文件,再根据%.o:%.c 模式规则,自动寻找.c源码文件;
取出每个子Makefile中定义的子目录,再用make -C命令切换到子目录,从而实现递归目录编译;
为每个.o文件,生成依赖文件(.d),并包含进Makefile.build;
为每个子目录(含有Makefile)生成一个built-in.o文件,便于根目录下的Makefile文件编译、链接;
设置伪目标;
PHONY := __build echo_obj
__build:
obj-y :=
subdir-y :=
EXTRA_CFLAGS :=
#包含当前执行目录的Makefile,当在子目录时候,导入的是子目录的makefile
include Makefile
# obj-y := a.o b.o c/ d/
# $(filter %/, $(obj-y)) : c/ d/
# __subdir-y : c d
# subdir-y : c d
# $(filter %/, $(obj-y)) 从变量obj-y中过滤出以"/"结尾的目录名
# $(patsubst %/,%,$(filter %/, $(obj-y))) 去掉obj-y中以"/"结尾的目录名中的"/"
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
# c/built-in.o d/built-in.o
# foreach(var,list,text), 意为foreach var in list, change it to text
# 将子目录列表subdir-y中, 每一项(每个文件名)f, 都修改为f/built-in.o
# 也就是说, 每个子目录, 都会对应生成一个名为 "子目录名/built-in.o"的文件 (.o文件是链接文件)
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)
# a.o b.o
# 从obj-y中过滤掉目录名(名称以"/"结尾), 只剩下普通文件(.o文件)
cur_objs := $(filter-out %/, $(obj-y))
dep_files := $(foreach f,$(cur_objs),.$(f).d)
# 如果依赖文件存在, 就列出来重新赋值给dep_files
dep_files := $(wildcard $(dep_files))
# 如果依赖文件列表不为空, 就直接包含(include)依赖文件列表
ifneq ($(dep_files),)
include $(dep_files)
endif
# 每个子目录名(不含"/")追加到伪目标
PHONY += $(subdir-y)
echo_obj:
@echo "******************** echo_obj *************************"
@echo obj-y:$(obj-y)
@echo __subdir-y:$(__subdir-y)
@echo subdir-y:$(subdir-y)
@echo subdir_objs:$(subdir_objs)
@echo cur_objs:$(cur_objs)
@echo "**********************************************************"
__build: echo_obj $(subdir-y) built-in.o
#用顶层Makefile.build的规则去子目录去编译
#make -c 后跟目录,表示到子目录下执行子目录的makefile
#make -f
$(subdir-y):
@echo subdir-y = $@
make -C $@ -f $(TOPDIR)/Makefile.build
# 定义built-in.o依赖规则,当subdir-y为空了才开始执行
# cur_objs 从obj-y过滤出的普通文件(.o文件)
# subdir_objs 子目录下的built-in.o
built-in.o : $(cur_objs) $(subdir_objs)
$(LD) -r -o $@ $^
#延时变量, generate dep_file
dep_file = .$@.d
%.o : %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -Wp,-MD,$(dep_file) -c -o $@ $<
.PHONY : $(PHONY)
(3)子目录makefile
EXTRA_CFLAGS :=
CFLAGS_file.o :=
obj-y += disp_manager.o
obj-y += framebuffer.o
六、debug
start_recursive_build
obj-y = display/ ui/ page/ config/ business/
make -C ./ -f /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/Makefile.build
make[1]: Entering directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command'
******************** echo_obj *************************
obj-y: display/ ui/ page/ config/ business/
__subdir-y:display ui page config business
subdir-y: display ui page config business
subdir_objs:display/built-in.o ui/built-in.o page/built-in.o config/built-in.o business/built-in.o
cur_objs:
**********************************************************
subdir-y = display
make -C display -f /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/Makefile.build
make[2]: Entering directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/display'
******************** echo_obj *************************
obj-y: disp_manager.o framebuffer.o
__subdir-y:
subdir-y:
subdir_objs:
cur_objs:disp_manager.o framebuffer.o
**********************************************************
gcc -Wall -O2 -g -I /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/include -Wp,-MD,.disp_manager.o.d -c -o disp_manager.o disp_manager.c
gcc -Wall -O2 -g -I /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/include -Wp,-MD,.framebuffer.o.d -c -o framebuffer.o framebuffer.c
ld -r -o built-in.o disp_manager.o framebuffer.o
make[2]: Leaving directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/display'
subdir-y = ui
make -C ui -f /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/Makefile.build
make[2]: Entering directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/ui'
******************** echo_obj *************************
obj-y: button.o
__subdir-y:
subdir-y:
subdir_objs:
cur_objs:button.o
**********************************************************
gcc -Wall -O2 -g -I /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/include -Wp,-MD,.button.o.d -c -o button.o button.c
ld -r -o built-in.o button.o
make[2]: Leaving directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/ui'
subdir-y = page
make -C page -f /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/Makefile.build
make[2]: Entering directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/page'
******************** echo_obj *************************
obj-y: main_page.o page_manager.o
__subdir-y:
subdir-y:
subdir_objs:
cur_objs:main_page.o page_manager.o
**********************************************************
gcc -Wall -O2 -g -I /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/include -Wp,-MD,.main_page.o.d -c -o main_page.o main_page.c
main_page.c:198:16: warning: ‘GetButtonByInputEvent’ defined but not used [-Wunused-function]
198 | static Button* GetButtonByInputEvent(InputEvent *pInputEvent)
| ^~~~~~~~~~~~~~~~~~~~~
main_page.c:103:13: warning: ‘GenerateButtons’ defined but not used [-Wunused-function]
103 | static void GenerateButtons(void)
| ^~~~~~~~~~~~~~~
gcc -Wall -O2 -g -I /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/include -Wp,-MD,.page_manager.o.d -c -o page_manager.o page_manager.c
ld -r -o built-in.o main_page.o page_manager.o
make[2]: Leaving directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/page'
subdir-y = config
make -C config -f /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/Makefile.build
make[2]: Entering directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/config'
******************** echo_obj *************************
obj-y: config.o
__subdir-y:
subdir-y:
subdir_objs:
cur_objs:config.o
**********************************************************
gcc -Wall -O2 -g -I /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/include -Wp,-MD,.config.o.d -c -o config.o config.c
ld -r -o built-in.o config.o
make[2]: Leaving directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/config'
subdir-y = business
make -C business -f /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/Makefile.build
make[2]: Entering directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/business'
******************** echo_obj *************************
obj-y: main.o
__subdir-y:
subdir-y:
subdir_objs:
cur_objs:main.o
**********************************************************
gcc -Wall -O2 -g -I /media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/include -Wp,-MD,.main.o.d -c -o main.o main.c
main.c: In function ‘main’:
main.c:12:9: warning: unused variable ‘err’ [-Wunused-variable]
12 | int err;
| ^~~
ld -r -o built-in.o main.o
make[2]: Leaving directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command/business'
ld -r -o built-in.o display/built-in.o ui/built-in.o page/built-in.o config/built-in.o business/built-in.o
make[1]: Leaving directory '/media/cvitek/robin.lee/my_test/study/weidongshan/imx6study/project/electronic_test_tools/31_improve_command'
gcc -o test built-in.o -lpthread -lfreetype -lm
test has been built!