日期:2019/3/31
内容:makefile分析;
一、makefile分析
如下相当于makefile的main函数。
# create ucore.img UCOREIMG := $(call totarget,ucore.img)
$(UCOREIMG): $(kernel) $(bootblock) $(V)dd if=/dev/zero of=$@ count=10000 $(V)dd if=$(bootblock) of=$@ conv=notrunc $(V)dd if=$(kernel) of=$@ seek=1 conv=notrunc
$(call create_target,ucore.img)
第一个dd:向ucore.img文件写入5120000bytes,每个byte都是0 第二个dd:拷贝bootlock到ucore.img,但是不截断ucore.img。(如果没有notrunc则相当于cp bootlock ucore.img) 第三个dd:跳过kernal的第一个block(512bytes)同时不截断ucore.img |
/dev/zero是一个特殊的文件,当你读它的时候,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。
$@表示目标文件$(UCOREIMG)
V在makefile的第6行定义为@,$(V)相当于给每个命令加了一个@前缀。
为了生成ucore.img,首先需要生成bootblock、kernel。
生成bootlock的makefile部分。
# create bootblock bootfiles = $(call listf_cc,boot) $(foreach f,$(bootfiles),$(call cc_compile,$(f),$(CC),$(CFLAGS) -Os -nostdinc))
bootblock = $(call totarget,bootblock)
$(bootblock): $(call toobj,$(bootfiles)) | $(call totarget,sign) @echo + ld $@ $(V)$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 $^ -o $(call toobj,bootblock) @$(OBJDUMP) -S $(call objfile,bootblock) > $(call asmfile,bootblock) @$(OBJCOPY) -S -O binary $(call objfile,bootblock) $(call outfile,bootblock) @$(call totarget,sign) $(call outfile,bootblock) $(bootblock)
$(call create_target,bootblock) # ------------------------------------------------------------------- |
二、makefile函数
函数定义在lab1/tools/function.mk
2.1 totarget函数
函数定义
totarget = $(addprefix $(BINDIR)$(SLASH),$(1)) |
其中BINDIR(80行)和SLASH(4行)在Makefile定义。
BINDIR := bin SLASH := / |
totarget函数的作用:给参数1的字符串加上"bin/"的前缀。(addprefix是makefile提供的函数)
2.2 create_target函数
函数定义
create_target = $(eval $(call do_create_target,$(1),$(2),$(3),$(4),$(5))) |
Note
-
命令前缀+,-,@
不用前缀:输出执行的命令以及命令执行的结果, 出错的话停止执行
前缀 @:只输出命令执行的结果, 出错的话停止执行
前缀 -:命令执行有错的话, 忽略错误, 继续执行
例子
V := @ run : $(V)echo before 'rm' $(V)rm test1 test2 $(V)echo after 'rm' 如果有test1和test2
如果test1和test2至少一个没有 |
-
$@,$^,$<,$?的区别
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表
-
=,:=,?=,+=区别
= 是最基本的赋值
:= 是覆盖之前的值
?= 是如果没有被赋值过就赋予等号后面的值
+= 是添加等号后面的值