您的位置:首页 > 其它

contiki2.6之Makefile详细解读四

2013-03-18 10:40 232 查看
上次分析到了这里:

CONTIKI_TARGET_DIRS_CONCAT = ${addprefix ${dir $(target_makefile)}, $(CONTIKI_TARGET_DIRS)}

CONTIKI_CPU_DIRS_CONCAT = ${addprefix $(CONTIKI_CPU)/, $(CONTIKI_CPU_DIRS)}

经分析CONTIKI_TARGET_DIRS_CONCAT的值为$(CONTIKI)/platform/cc2530dk/.dev

CONTIKI_CPU_DIRS_CONCAT的值为$(CONTIKI)/cpu/cc253x/. dev

SOURCEDIRS = . $(PROJECTDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \

$(CONTIKI_CPU_DIRS_CONCAT) $(CONTIKIDIRS) $(APPDIRS) ${dir $(target_makefile)}

定义SOURCEFIRS值为. 表示当前目录,$(PROJECTDIRS),没找到这个变量的值,然后是$(CONTIKI)/platform/cc2530dk/.dev$(CONTIKI)/cpu/cc253x/. dev$(CONTIKI)/core/dev $(CONTIKI)/core/lib $(CONTIKI)/core/net
.......

对于cc2530我们没有定义APPS 所以这里$(APPDIRS)为空 以及

$(CONTIKI)/platform/cc2530dk/

这个SOURCEFRS指定了需要被编译的所有源文件的目录

vpath %.c $(SOURCEDIRS)

vpath %.S $(SOURCEDIRS)

vpath关键字指定了makefile中出现某文件的搜索路径。在这里它指定了所有在Makefile文件中出现的以.c和.S为后缀的源文件的搜索路径为$(SOURCEDIRS) 。 这一步为我们后面的编译过程所用的模式规则做好准备。

CFLAGS += ${addprefix -I,$(SOURCEDIRS)}

指定了头文件的搜索路径,因为在很多源文件目录中有相应的头文件

RELSTR=${shell git describe --tags 2>/dev/null}

ifneq ($(RELSTR),)

CFLAGS += -DCONTIKI_VERSION_STRING=\"Contiki-$(RELSTR)\"

endif

这几行貌似有点多余 ,因为在contiki-version.h文件中已经指定了CONTIKI_VERSION_STRING为"Contiki 2.6"

ifneq ($(MAKECMDGOALS),clean)

-include ${addprefix $(OBJECTDIR)/,$(CONTIKI_SOURCEFILES:.c=.d) \

$(PROJECT_SOURCEFILES:.c=.d)}

endif

MAKECMDGOALS为make的环境变量,它会存放你所指定的终极目标的列表。那么上面几句表示如果执行的命令不是make clean 则包含include指定的makefile文件,这些文件是什么呢?obj_cc2530dk/....中以.d为后缀的文件

define FINALIZE_DEPENDENCY

cp $(@:.o=.d) $(@:.o=.$$$$); \

sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \

-e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.$$$$) >> $(@:.o=.d); \

rm -f $(@:.o=.$$$$)

endef

多行定义变量FINALIZE_DEPENDENCY,其值为下面三个命令。这三个命令具体是干啥的,下面用到的时候再说!

clean:

rm -f *~ *core core *.srec \

*.lst *.map \

*.cprg *.bin *.data contiki*.a *.firmware core-labels.S *.ihex *.ini \

*.ce *.co $(CLEAN)

-rm -rf $(OBJECTDIR)

clean伪目标用于删除所有编译链接产生的文件

下面都是一些编译源代码的一些规则。那么我们就从整个make执行的流程来看一下这个contiki系统是如何被编译,包括工程文件。

首先在工程目录中的makefile文件中找到终极目标为all,它依赖于 hello-world blink-hello timer-test sensors-demo

这四个文件,那么make就会去寻找第一个依赖文件的重建规则,hello-world,好像我们找了半天都没找到与它先关的规则,呵呵!那是因为在contiki系统中,所有重建过程都是用的模式规则,当然就看到以hello-world为目标的规则了!

我们按照make读取makefile文件的过程来分析,首先读取makefile.include,途中读取了makefile.cc2530dk,在此文件中也没发现与hello-world相关的规则,在makefile.cc2530dk文件中又引入了makefile.cc253x文件,在此文件中也没找到,那么make就回到makefile.include文件中继续寻找。返现在makefile.include文件的末尾有这两句:

%: %.c

注意这里的空行

%: %.$(TARGET)

@

单独一个%表示可以匹配任意字符,那么我们的目标hello-world当然可以匹配它了,所以就执行上面第一句。它的依赖文件为相应的hello-world.c文件,发现在工程目录中确实有这个文件,显然它比目标更新,所以执行下面语句!但是,居然为空命令,所以这一句相当于什么也不执行,但是make不服气啊?因为目标还没生成怎么就返回呢?所以继续找,那就是下面一个规则,它的依赖为hello-world.cc2530dk,那么这个文件显然在我们的目录中是没有的,所以make就去寻找建立它的规则。其实这里是多规则目标,一个hello-world对应两个规则,但是只能有一个规则有命令,其他的规则没有命令行,当要重建这个目标时,make会把它的依赖文件合并成一个依赖文件列表,然后执行那个有命令的规则!

为hello-world.cc2530dk找规则......

一个是在makefile.include中

ifndef CUSTOM_RULE_LINK

%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a

$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@

endif

一个是在makefile.cc2530dk中

%.$(TARGET): %.hex FORCE

cp $< $(<:.hex=.$(TARGET))

@echo "\nReport"

@echo "==============="

@echo 'Code footprint:'

@echo 'Area Addr Size' \

' Decimal'

@echo '---------------------------------- -------- --------' \

' --------'

@echo -n 'HOME,CSEG,CONST,XINIT,GS* $(HOME_START) '

@egrep ',CODE\)' $(<:.hex=.map) | egrep -v '(^BANK[1-9][^=])' | uniq | \

awk '{ SUM += $$5 } END { printf "%08X = %8d", SUM, SUM }'

@echo '. bytes (REL,CON,CODE)'

@egrep '(^BANK[1-9][^=])' $(<:.hex=.map) | uniq | sort

@egrep -A 5 'Other memory' $(<:.hex=.mem)

那么我们执行哪个呢?显然make搜索是从头开始,那么按照makefile的读取顺序,当然是下面那个规则先执行,况且上面那个规则中还判断CUSTOM_RULE_LINK是否定义了,经查证,它定义了,那么上面那个规则对于cc2530dk来说永远不会执行!所以看下面那个规则。

它依赖于helloworld.hex文件,这个文件在目录中显示是不存在的,那么make就继续寻找建立它的规则。

在makefile.cc253x中又找到了两个,但是实际上有一个规则使用了条件判断的。(没有定义UIP_CONF_IPV6,且

HAVE_BANKING=0) 所以:

%.hex: %.ihx

$(PACKIHX) $< > $@

根据上面说的make工作原理,这样一直找下去,直到找到能生成目标的规则!!!这应该给大家提供了一种read makefile的思路吧!

先休整一下,得去看看sdcc的东西,因为接下来大多都是sdcc编译器编译链接的事了!且听下回分解!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: