接着分析contiki系統的makefile。
之前分析到Makefile.cc2530dk的這個地方
%.upload: %.hex
$(PROG) -P $<
這裏這個PROG變量現在還不明確,-P爲選項,$<爲%.hex文件名
sensinode.serialdump:
$(SERIALDUMP)
僞目標sensinode.serialdump爲調試所用,它調用命令SERIALDUMP,這個變量所代表的的意思猜測應該是打開串口,向其中打印數據。
CONTIKI_CPU=$(CONTIKI)/cpu/cc253x
include $(CONTIKI_CPU)/Makefile.cc253x
這裏定義CONTIKI_CPU爲$(CONTIKI)/cpu/cc253x 然後讀取該目錄下面的Makefile.cc253x,這裏先不展開,因爲在上篇文章中只是打開Makefile.cc2530dk,但是make沒有真正執行到裏面。
回溯到Makefile.include文件中
# Check if the target makefile exists, and create the object directory if necessary.
ifeq ($(strip $(target_makefile)),)
${error The target platform "$(TARGET)" does not exist (maybe it was misspelled?)}
else
ifeq (${wildcard $(OBJECTDIR)},)
DUMMY := ${shell mkdir $(OBJECTDIR)}
endif
ifneq (1, ${words $(target_makefile)})
${error More than one TARGET Makefile found: $(target_makefile)}
endif
include $(target_makefile)
endif
ifeq語句開始調用strip函數去掉變量target_makefile的多餘空格,然後比較是否爲空,有前面可知target_makefile的值爲$(CONTIKI)/platform/cc2530dk/Makefile.cc2530dk,不爲空,執行else語句
我們知道OBJECTDIR值爲obj_cc2530dk,調用wildcard函數在當前目錄中搜索匹配該值的文件名,此時該目錄中還沒有該文件,所以其值爲空,執行ifeq下面一句,調用shell命令mkdir在當前文件夾下建立OBJECTDIR所代表的目錄即obj_cc2530dk目錄。然後將其值返回給DUMMY,那麼這個值是什麼呢? 如果命令執行成功就爲0,如果不成功則返回非零,通過此值,我們可以知道此命令調用失敗的原因。
繼續下面ifneq的語句,它調用了words函數,此函數是統計後面字串中的單詞個數,我們知道target_makefile爲
$(CONTIKI)/platform/cc2530dk/Makefile.cc2530dk,那麼它有多少單詞呢?顯然是1個了。
ifneq判斷,兩者相等則判斷爲假,不執行下面的語句。
最後包含此Makefile.cc2530dk,make去讀取此文件中的內容,該文件的內容在上篇文章中已經分析了,固這裏就不做解釋了。繼續往下
COMMA := ,
CFLAGS += ${addprefix -D,${subst $(COMMA), ,$(DEFINES)}}
定義逗號變量,再將DEFINES所代表的字串中逗號全部替換爲空格,然後在每一個單詞前加前綴-D表示定義該宏。在cc2530dk中沒有DEFINES變量,那麼這句相當於什麼也不做。
CONTIKI_TARGET_DIRS_CONCAT = ${addprefix ${dir $(target_makefile)}, \
$(CONTIKI_TARGET_DIRS)}
CONTIKI_CPU_DIRS_CONCAT = ${addprefix $(CONTIKI_CPU)/, \
$(CONTIKI_CPU_DIRS)}
第一句:先取target_makefile變量$(CONTIKI)/platform/cc2530dk/Makefile.cc2530dk文件的目錄名即$(CONTIKI)/platform/cc2530dk/,注意最後一個斜槓別漏了。然後再將$(CONTIKI)/platform/cc2530dk/添加到CONTIKI_TARGET_DIRS變量的值前面,該值爲多少呢?在Makefile.cc2530dk中表示的是.dev,是嗎?
在上面我們包含了Makefile.cc2530dk,然後讀取它,在該文件中的最後包含了Makefile.cc253x,也要讀取它,只不過我前面沒有分下,下面我們就分析一下這個文件的內容。此文件內容略多,不過我們先看其中部分
CC = sdcc
LD = sdcc
AS = sdcc
AR = sdcclib
OBJCOPY = objcopy
STRIP = strip
這寫和編譯相關的變量,我們編譯鏈接併產生可執行文件所用的編譯器爲sdcc,該編譯器的安裝網上可以找到。
下面和編譯器相關的變量這裏就不提,用到的時候再提,
CLEAN += *.lnk *.lk *.sym *.lib *.ihx *.rel *.mem *.rst *.asm *.hex
CLEAN += *.omf *.cdb *.banks *.flags *.banked-hex
CLEAN += symbols.c symbols.h
定義CLEAN變量,此變量代表的是所有CPU所依賴的清除文件。我們用make clean的時候清楚所有這些文件。
CONTIKI_CPU_DIRS = . dev
定義變量CONTIKI_CPU_DIRS值爲. dev,注意這裏是兩個值,一個爲表示當前目錄,一個表示dev目錄
CONTIKI_SOURCEFILES += soc.c clock.c
CONTIKI_SOURCEFILES += uart0.c uart1.c uart-intr.c
CONTIKI_SOURCEFILES += dma.c dma_intr.c
CONTIKI_SOURCEFILES += cc2530-rf.c
CONTIKI_SOURCEFILES += watchdog.c rtimer-arch.c
CONTIKI_ASMFILES +=
這裏追加了當前工作目錄中的一些源文件到CONTIKI_SOURCEFILES中。CONTIKI_ASMFILES爲空。
CONTIKI_ASMOBJECTFILES = $(addprefix $(OBJECTDIR)/,$(CONTIKI_ASMFILES:.S=.rel))
這句意思很明顯了,在obj_cc2530dk目錄中添加相應的以.rel爲後綴的目標文件,此地方設計到了makefile中變量的高級用法。$(CONTIKI_ASMFILES:.S=.rel))此變量表示CONTIKI_ASMFILES所表示的所有以.S結尾的文件名替換成以.rel爲結尾的文件名,然後這個變量值就是替換後的文件名列表。
那麼CONTIKI_ASMOBJECTFILES的值爲obj_cc2530dk/*.S ......
CONTIKI_CASMOBJECTFILES = $(addprefix $(OBJECTDIR)/, $(CONTIKI_CASMFILES:.cS=.rel))
這句和上面句意思一樣,只不過後綴名換了!
CONTIKI_PLATFORM_DIRS = $(PLATFORM_APPDIRS) \
$(addprefix $(CONTIKI)/platform/$(TARGET)/, $(CONTIKI_TARGET_DIRS))
定義CONTIKI_PLATFORM變量,經分析其值爲$(CONTIKI)/platform/cc2530dk/.dev
CONTIKI_CPU_DIRS_LIST = $(addprefix $(CONTIKI_CPU)/, $(CONTIKI_CPU_DIRS))
定義變量CONTIKI_CPU_DIRS_LIST值爲$(CONTIKI)/cpu/cc253x/.dev
oname = $(patsubst %.c,%.rel,$(patsubst %.S,%.rel,$(1)))
自定義函數oname,在前面文章中已經分析了此函數的作用,這裏就不贅餘了!
CONTIKI_OBJECTFILES = $(addprefix $(OBJECTDIR)/, $(call oname, $(CONTIKI_SOURCEFILES)))
調用上面自定義的函數,那麼CONTIKI_OBJECTFILES的值就不言而喻了。這一句覆蓋了在Makefile.include文件中
CONTIKI_OBJECTFILES = $(addprefix $(OBJECTDIR)/, $(call oname, $(CONTIKI_SOURCEFILES))),因爲CONTIKI_SOURCEFILE變量中添加了一些源文件。
PROJECT_OBJECTFILES = $(addprefix $(OBJECTDIR)/, $(call oname, $(PROJECT_SOURCEFILES)))
同上!
接下來是一些編譯的規則,我們暫且不看它。
回到剛開始的那個問題CONTIKI_TARGET_DIRS的變量值爲.dev嗎,經過上述並沒有看到改變此變量的語句,顯然它就是.dev。
下篇就對後面的繼續深入分析!