完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
这里延续之前的分析:https://bbs.elecfans.com/forum.p ... =1098846&extra=
在上一篇文章中我们分析到了定义ShortcutRule函数,那么现在我们继续: define MakeLibrary DEP_LIBS_$(1) = $$(foreach lib,$$(filter %.a,$$(COMPONENTS_$(1))),$$(dir $$(lib))$$(LIBODIR)/$$(notdir $$(lib))) DEP_OBJS_$(1) = $$(foreach obj,$$(filter %.o,$$(COMPONENTS_$(1))),$$(dir $$(obj))$$(OBJODIR)/$$(notdir $$(obj))) $$(LIBODIR)/$(1).a: $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1)) $$(DEPENDS_$(1)) @MKDIR -p $$(LIBODIR) $$(if $$(filter %.a,$$?),mkdir -p $$(EXTRACT_DIR)_$(1)) $$(if $$(filter %.a,$$?),cd $$(EXTRACT_DIR)_$(1); $$(foreach lib,$$(filter %.a,$$?),$$(AR) xo $$(UP_EXTRACT_DIR)/$$(lib);)) $$(AR) ru $$@ $$(filter %.o,$$?) $$(if $$(filter %.a,$$?),$$(EXTRACT_DIR)_$(1)/*.o) $$(if $$(filter %.a,$$?),$$(RM) -r $$(EXTRACT_DIR)_$(1)) endef 这里定义MakeLibrary这个函数,这个函数中定义了DEP_LIBS_$(1)、DEP_OBJS_$(1)这些定义都太复杂了,我们慢慢的分析,要分析DEP_LIBS_$(1),首先就要分析他的调用语句:$(foreach lib,$(GEN_LIBS),$(eval $(call MakeLibrary,$(basename $(lib))))),这SDK根目录下并没有定义GEN_BINS,这个是在第三方软件上定义的,比如D:OracleshareSDKthird_partylwip目录下的makefile中定义了UP_EXTRACT_DIR = .. GEN_LIBS = liblwip.a COMPONENTS_liblwip = api/liblwipapi.a arch/liblwiparch.a core/liblwipcore.a core/ipv4/liblwipipv4.a core/ipv6/liblwipipv6.a netif/liblwipnetif.a,那么这里传给MakeLibrary的变量就是liblwip, 这里的$(1)代表的是第一个参数,这是首先$$(filter %.a,$$(COMPONENTS_$(1)))然后赋值给lib,那么这里的lib就是api/liblwipapi.a arch/liblwiparch.a core/liblwipcore.a core/ipv4/liblwipipv4.a core/ipv6/liblwipipv6.a netif/liblwipnetif.a其实这里只是滤除动作,没有进行其他的功能,最后调用$$(dir $$(lib))$$(LIBODIR)/$$(notdir $$(lib))对lib变量进行扩展,在之前我们知道LIBODIR := .outputeagledebuglib,那么最后得到api/.outputeagledebuglib/liblwipcore.a,这个就是自生成的目录,也就是最终库的组件库目录。那么这个foreach的意思就是根据liblwip指定每一个具体的组件库,接下来的DEP_OBJS_$(1)也是如此,下来就是用上面生成的两个变量在LIBODIR目录下生成相应的.a库文件。 @mkdir -p $$(LIBODIR) 其中的@放在行首,表示不打印此行。默认在编译的过程中,会把此行的展开效果字符串打印出来。这里先先创建.outputeagledebuglib,注意这里是在当前的makefile目录下创建,然后: $$(if $$(filter %.a,$$?),mkdir -p $$(EXTRACT_DIR)_$(1))其中$$?代表依赖文件列表中被改变过的所有文件,如果处在就会创建EXTRACT_DIR_xx.a,下来$$(if $$(filter %.a,$$?),cd $$(EXTRACT_DIR)_$(1); $$(foreach lib,$$(filter %.a,$$?),$$(AR) xo $$(UP_EXTRACT_DIR)/$$(lib);))这里进入刚才那个目录调用AR工具来创建静态库,这里生成到(UP_EXTRACT_DIR)/$$(lib)目录下,下来 $$(AR) ru $$@ $$(filter %.o,$$?) $$(if $$(filter %.a,$$?),$$(EXTRACT_DIR)_$(1)/*.o) 虽然他们都是运行AR但是路径应该是不一样的。最后: $$(if $$(filter %.a,$$?),$$(RM) -r $$(EXTRACT_DIR)_$(1)) 调用RM工具删除掉(EXTRACT_DIR)_$(1)目录,接下来的define MakeImage的定义和上面的相似,只不过用的是CC工具来编译: $$(CC) $$(LDFLAGS) $$(if $$(LINKFLAGS_$(1)),$$(LINKFLAGS_$(1)),$$(LINKFLAGS_DEFAULT) $$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1))) -o $$@ 因为我们不需要最终文件,所以这里也不看他的具体意思了。接下来: $(BINODIR)/%.bin: $(IMAGEODIR)/%.out @mkdir -p $(BIN_PATH) @mkdir -p $(BINODIR) 这里创建BIN_PATH和BINODIR这两个目录$(BINODIR)/%.bin,也就是~shareSDKet_app.outputeagledebugbin下的所有点bin,接下来: ifeq ($(APP), 0) @$(RM) -r $(BIN_PATH)/eagle.S $(BIN_PATH)/eagle.dump @$(OBJDUMP) -x -s $< > $(BIN_PATH)/eagle.dump @$(OBJDUMP) -S $< > $(BIN_PATH)/eagle.S else @mkdir -p $(BIN_PATH)/upgrade @$(RM) -r $(BIN_PATH)/upgrade/$(BIN_NAME).S $(BIN_PATH)/upgrade/$(BIN_NAME).dump @$(OBJDUMP) -x -s $< > $(BIN_PATH)/upgrade/$(BIN_NAME).dump @$(OBJDUMP) -S $< > $(BIN_PATH)/upgrade/$(BIN_NAME).S endif 这里根据APP这边变量进行反汇编我们这里传入的不是0,所以这里运行else分支,接下来: @$(OBJCOPY) --only-section .text -O binary $< eagle.app.v6.text.bin @$(OBJCOPY) --only-section .data -O binary $< eagle.app.v6.data.bin @$(OBJCOPY) --only-section .rodata -O binary $< eagle.app.v6.rodata.bin @$(OBJCOPY) --only-section .irom0.text -O binary $< eagle.app.v6.irom0text.bin 这里把相应的bin文件拷贝到最终程序的相应分支中,这样好像就不需要连接脚本了,接下来输出: @echo "" @echo "!!!" @echo "SDK_PATH: $(SDK_PATH)" 然后: ifeq ($(app), 0) @python $(SDK_PATH)/tools/gen_appbin.py $< 0 $(mode) $(freqdiv) $(size_map) @mv eagle.app.flash.bin $(BIN_PATH)/eagle.flash.bin @mv eagle.app.v6.irom0text.bin $(BIN_PATH)/eagle.irom0text.bin @rm eagle.app.v6.* @echo "BIN_PATH: $(BIN_PATH)" @echo "" @echo "No boot needed." @echo "Generate eagle.flash.bin and eagle.irom0text.bin successully in BIN_PATH" @echo "eagle.flash.bin-------->0x00000" @echo "eagle.irom0text.bin---->0x20000" else @echo "BIN_PATH: $(BIN_PATH)/upgrade" @echo "" ifneq ($(boot), new) @python $(SDK_PATH)/tools/gen_appbin.py $< 1 $(mode) $(freqdiv) $(size_map) @echo "Support boot_v1.1 and +" else @python $(SDK_PATH)/tools/gen_appbin.py $< 2 $(mode) $(freqdiv) $(size_map) ifeq ($(size_map), 6) @echo "Support boot_v1.4 and +" else ifeq ($(size_map), 5) @echo "Support boot_v1.4 and +" else @echo "Support boot_v1.2 and +" endif endif endif @mv eagle.app.flash.bin $(BIN_PATH)/upgrade/$(BIN_NAME).bin @rm eagle.app.v6.* @echo "Generate $(BIN_NAME).bin successully in BIN_PATH" @echo "boot.bin------------>0x00000" @echo "$(BIN_NAME).bin--->$(addr)" endif @echo "!!!" 这里依旧是执行else分支,这里最主要的工作就是输出关于这个bin地址的详细信息,注意上面的内筒都是在make all之后运行的,现在来看看make 第一个目标,make all: all: .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS) 看看第一个目标: .subdirs: @set -e; $(foreach d, $(SUBDIRS), $(MAKE) -C $(d);这里进入SUBDIRS定义的子目录中编译所有的程序,调用子目录的makefile进行编译工作,下来的$(OBJS)是编译所有的.o文件,根据所有的.c .CPP .S .s进行编译,OBJS在前边的定义如下: OBJS := $(CSRCS:%.c=$(OBJODIR)/%.o) $(CPPSRCS:%.cpp=$(OBJODIR)/%.o) $(ASRCs:%.s=$(OBJODIR)/%.o) $(ASRCS:%.S=$(OBJODIR)/%.o) 下来$(OLIBS)生成所有的库文件,接下来$(OIMAGES)生成所有的镜像文件,接下来OBINS生成所有的.bin文件,这里就会调用上面的$(BINODIR)/%.bin: $(IMAGEODIR)/%.out分支打印出bin的相关信息。最后$(SPECIAL_MKTARGETS)这里好像没有定义SPECIAL_MKTARGETS,所以这里不会运行。 最后这个makefile文件声明的变量有些不一样: $(foreach lib,$(GEN_LIBS),$(eval $(call ShortcutRule,$(lib),$(LIBODIR)))) $(foreach image,$(GEN_IMAGES),$(eval $(call ShortcutRule,$(image),$(IMAGEODIR)))) $(foreach bin,$(GEN_BINS),$(eval $(call ShortcutRule,$(bin),$(BINODIR)))) $(foreach lib,$(GEN_LIBS),$(eval $(call MakeLibrary,$(basename $(lib))))) $(foreach image,$(GEN_IMAGES),$(eval $(call MakeImage,$(basename $(image))))) 其实这里就是从各个子目录中抽取变量了,这才是最关键的地方。整体来看就是通过上面的这四个for循环找出所有要进行编译的库,然后进行编译。 上面这篇文章说得还是不够清楚,等我沉淀一段时间我再来总结一下! |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
[小e体验板] 【小体积大智慧】关于体验板的技术问题,看这一篇就够了
2855 浏览 4 评论
【小e1开发板试用体验】分析程序架构四~/Share/SDK/makefile分析
3613 浏览 1 评论
6705 浏览 19 评论
29077 浏览 59 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 00:07 , Processed in 0.571113 second(s), Total 69, Slave 52 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号