通用makefile知识点


前言

一般的,可以分为三种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!

在这里插入图片描述

  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值