生活随笔
收集整理的這篇文章主要介紹了
autoconf.mk详析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
uboot的頂層Makefile中有如下的一段代碼
[plain]?
view plaincopy #??#?Auto-generate?the?autoconf.mk?file?(which?is?included?by?all?makefiles)??#??#?This?target?actually?generates?2?files;?autoconf.mk?and?autoconf.mk.dep.??#?the?dep?file?is?only?include?in?this?top?level?makefile?to?determine?when??#?to?regenerate?the?autoconf.mk?file.??$(obj)include/autoconf.mk.dep:?$(obj)include/config.h?include/common.h??????@$(XECHO)?Generating?$@?;?\??????set?-e?;?\??????:?Generate?the?dependancies?;?\??????$(CC)?-x?c?-DDO_DEPS_ONLY?-M?$(CFLAGS)?$(CPPFLAGS)?\??????????-MQ?$(obj)include/autoconf.mk?include/common.h?>?$@????$(obj)include/autoconf.mk:?$(obj)include/config.h??????@$(XECHO)?Generating?$@?;?\??????set?-e?;?\??????:?Extract?the?config?macros?;?\??????$(CPP)?$(CFLAGS)?-DDO_DEPS_ONLY?-dM?include/common.h?|?\??????????sed?-n?-f?tools/scripts/define2mk.sed?>?$@.tmp?&&?\??????mv?$@.tmp?$@??[plain]?
view plaincopy #??#?Auto-generate?the?autoconf.mk?file?(which?is?included?by?all?makefiles)??#??#?This?target?actually?generates?2?files;?autoconf.mk?and?autoconf.mk.dep.??#?the?dep?file?is?only?include?in?this?top?level?makefile?to?determine?when??#?to?regenerate?the?autoconf.mk?file.??$(obj)include/autoconf.mk.dep:?$(obj)include/config.h?include/common.h??????@$(XECHO)?Generating?$@?;?\??????set?-e?;?\??????:?Generate?the?dependancies?;?\??????$(CC)?-x?c?-DDO_DEPS_ONLY?-M?$(CFLAGS)?$(CPPFLAGS)?\??????????-MQ?$(obj)include/autoconf.mk?include/common.h?>?$@????$(obj)include/autoconf.mk:?$(obj)include/config.h??????@$(XECHO)?Generating?$@?;?\??????set?-e?;?\??????:?Extract?the?config?macros?;?\??????$(CPP)?$(CFLAGS)?-DDO_DEPS_ONLY?-dM?include/common.h?|?\??????????sed?-n?-f?tools/scripts/define2mk.sed?>?$@.tmp?&&?\??????mv?$@.tmp?$@??先看第一個:?$(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h, 它表示autoconf.mk.dep依賴于config.h和common.h這兩個文件.
- @$(XECHO) Generating $@ ; \?這句話會在編譯階段輸出編譯信息?Generating?include/autoconf.mk.dep
- set -e ; \ 這句話表示, 當下面命令返回值不會0時, 整個腳本立即停止退出
- : Generate the dependancies ; \ ?沒有明白是啥意思~~
- $(CC) -x c -DDO_DEPS_ONLY -M $(CFLAGS) $(CPPFLAGS)?-MQ $(obj)include/autoconf.mk include/common.h > $@
- -DDO_DEPS_ONLY: 設置flag, 具體來說, 我們可以在common.h里面看見#ifdef DO_DEPS_ONLY這樣的語句, 這個-D就表示DO_DEPS_ONLY被定義了
- -M : 表示生成依賴關系. 我還專門做了個實驗, 如下
- gcc -M main.c?輸出結果為?main.o: main.c
- -MQ: 表示指定依賴關系中target的名稱, 看下面的實驗
- gcc -M -MQ newname.mk main.c?輸出結果為?newname.mk: main.c
- 這句話表示: 生成依賴關系?include/autoconf.mk: include/common.h, 結果最終輸出到include/autoconf.mk.dep
- 打開編譯后生成的include/autoconf.mk.dep, 可以查閱里面的內容. 至于為什么需要生成這個文件, 我現在還不清楚.
再看第二個:?$(obj)include/autoconf.mk: $(obj)include/config.h, 它表示autoconf.mk依賴于include/config.h這個文件
- @$(XECHO) Generating $@ ; \?這句話會在編譯階段輸出編譯信息Generating?include/autoconf.mk
- set -e; \ 同上
- $(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h |?sed -n -f tools/scripts/define2mk.sed > $@.tmp &&?mv $@.tmp $@
- -DDO_DEPS_ONLY: 同上
- -dM : 作用是輸出include/common.h中定義的所有宏
- | ? ? ?: shell中的管道, 表示將前面的結果傳遞給后面的命令
- define2mk.sed :?查找和處理以“CONFIG_”開頭的宏定義的功能, 將處理的結果輸出到include/autoconf.mk.tmp
- mv $@.tmp $@ : 重命名為include/autoconf.mk.?
- 最終就會生成include/autoconf.mk
- ?include/common.h文件包含了include/config.h文件,而include/config.h文件又包含了config_defaults.h等uboot下的通用頭文件, 還會包含<configs/${CONFIG_NAME}.h>, 這個.h是我們自己創建的, 可以在里面添加自己的"CONFIG_"宏定義. 已決定開啟哪些功能.
至此, 我們知道, 系統中所有的"CONFIG_"開頭的宏開關, 都被放到了include/autoconf.mk中.?
depend
在uboot的頂層Makefile中, 我們經常會看到類似的代碼片段
[plain]?
view plaincopy $(obj)spl/u-boot-spl.bin:???$(SUBDIR_TOOLS)?<span?style="color:?rgb(255,?0,?0);">depend</span>??????????$(MAKE)?-C?spl?all??[plain]?
view plaincopy $(obj)spl/u-boot-spl.bin:???$(SUBDIR_TOOLS)?<span?style="color:#ff00;">depend</span>??????????$(MAKE)?-C?spl?all??這個depend是什么意思呢, Makefile中有如下一段代碼
[plain]?
view plaincopy #?Explicitly?make?_depend?in?subdirs?containing?multiple?targets?to?prevent??#?parallel?sub-makes?creating?.depend?files?simultaneously.??depend?dep:?$(TIMESTAMP_FILE)?$(VERSION_FILE)?\??????????$(obj)include/spl-autoconf.mk?\??????????$(obj)include/tpl-autoconf.mk?\??????????$(obj)include/autoconf.mk?\??????????$(obj)include/generated/generic-asm-offsets.h?\??????????$(obj)include/generated/asm-offsets.h??????????for?dir?in?$(SUBDIRS)?$(CPUDIR)?$(LDSCRIPT_MAKEFILE_DIR)?;?do?\??????????????$(MAKE)?-C?$$dir?_depend?;?done??[plain]?
view plaincopy #?Explicitly?make?_depend?in?subdirs?containing?multiple?targets?to?prevent??#?parallel?sub-makes?creating?.depend?files?simultaneously.??depend?dep:?$(TIMESTAMP_FILE)?$(VERSION_FILE)?\??????????$(obj)include/spl-autoconf.mk?\??????????$(obj)include/tpl-autoconf.mk?\??????????$(obj)include/autoconf.mk?\??????????$(obj)include/generated/generic-asm-offsets.h?\??????????$(obj)include/generated/asm-offsets.h??????????for?dir?in?$(SUBDIRS)?$(CPUDIR)?$(LDSCRIPT_MAKEFILE_DIR)?;?do?\??????????????$(MAKE)?-C?$$dir?_depend?;?done??- depend dep : 它表示這個規則有兩個目標. 也就是你自己的目標依賴depend或者dep都會跑到這里來繼續.
- $(obj)include/spl-autoconf.mk \ : 表示depend依賴spl-autoconf.mk. 這個mk的生成規則也在Makefile中有定義. 細節方面參考上面的autoconf.mk
- $(obj)include/tpl-autoconf.mk \ : 同上
- $(obj)include/autoconf.mk \ ? ? : 同上
- $(obj)include/generated/generic-asm-offsets.h \ : 暫不分析
- $(obj)include/generated/asm-offsets.h : 暫不分析
- for dir in $(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR) ; do?$(MAKE) -C $$dir _depend ; done
- 這句話表示去上面各個目錄下執行 make _depend命令.
那我們看看對應子目錄下的Makefile, 例如$(CPUDIR) , 會看到如下的代碼片段
[plain]?
view plaincopy #?defines?$(obj).depend?target??include?$(SRCTREE)/rules.mk????sinclude?$(obj).depend??[plain]?
view plaincopy #?defines?$(obj).depend?target??include?$(SRCTREE)/rules.mk????sinclude?$(obj).depend??并沒有看到_depend這個目標, 那make _depend在這個目錄下如何執行呢? 來看看它include的rules.mk
[plain]?
view plaincopy _depend:????$(obj).depend????#?Split?the?source?files?into?two?camps:?those?in?the?current?directory,?and??#?those?somewhere?else.?For?the?first?camp?we?want?to?support?CPPFLAGS_<fname>??#?and?for?the?second?we?don't?/?can't.??PWD_SRCS?:=?$(filter?$(notdir?$(SRCS)),$(SRCS))??OTHER_SRCS?:=?$(filter-out?$(notdir?$(SRCS)),$(SRCS))????#?This?is?a?list?of?dependency?files?to?generate??DEPS?:=?$(basename?$(patsubst?%,$(obj).depend.%,$(PWD_SRCS)))????#?Join?all?the?dependencies?into?a?single?file,?in?three?parts??#???1?.Concatenate?all?the?generated?depend?files?together??#???2.?Add?in?the?deps?from?OTHER_SRCS?which?we?couldn't?process??#???3.?Add?in?the?HOSTSRCS??$(obj).depend:??$(src)Makefile?$(TOPDIR)/config.mk?$(DEPS)?$(OTHER_SRCS)?\??????????$(HOSTSRCS)??????cat?/dev/null?$(DEPS)?>$@??????@for?f?in?$(OTHER_SRCS);?do?\??????????g=`basename?$$f?|?sed?-e?'s/\(.*\)\.[[:alnum:]_]/\1.o/'`;?\??????????$(CC)?-M?$(CPPFLAGS)?-MQ?$(obj)?f?>>?$@?;?\??????done??????@for?f?in?$(HOSTSRCS);?do?\??????????g=`basename?$$f?|?sed?-e?'s/\(.*\)\.[[:alnum:]_]/\1.o/'`;?\??????????$(HOSTCC)?-M?$(HOSTCPPFLAGS)?-MQ?$(obj)?f?>>?$@?;?\??????done????MAKE_DEPEND?=?$(CC)?-M?$(CPPFLAGS)?$(EXTRA_CPPFLAGS_DEP)?\??????????-MQ?$(addsuffix?.o,$(obj)$(basename?$<))?$<?>$@??????$(obj).depend.%:????%.c??????$(MAKE_DEPEND)????$(obj).depend.%:????%.S??????$(MAKE_DEPEND)????$(HOSTOBJS):?$(obj)%.o:?%.c??????$(HOSTCC)?$(HOSTCFLAGS)?$(HOSTCFLAGS_$(@F))?$(HOSTCFLAGS_$(BCURDIR))?-o?$@?$<?-c??$(NOPEDOBJS):?$(obj)%.o:?%.c??????$(HOSTCC)?$(HOSTCFLAGS_NOPED)?$(HOSTCFLAGS_$(@F))?$(HOSTCFLAGS_$(BCURDIR))?-o?$@?$<?-c????#########################################################################??[plain]?
view plaincopy _depend:????$(obj).depend????#?Split?the?source?files?into?two?camps:?those?in?the?current?directory,?and??#?those?somewhere?else.?For?the?first?camp?we?want?to?support?CPPFLAGS_<fname>??#?and?for?the?second?we?don't?/?can't.??PWD_SRCS?:=?$(filter?$(notdir?$(SRCS)),$(SRCS))??OTHER_SRCS?:=?$(filter-out?$(notdir?$(SRCS)),$(SRCS))????#?This?is?a?list?of?dependency?files?to?generate??DEPS?:=?$(basename?$(patsubst?%,$(obj).depend.%,$(PWD_SRCS)))????#?Join?all?the?dependencies?into?a?single?file,?in?three?parts??#???1?.Concatenate?all?the?generated?depend?files?together??#???2.?Add?in?the?deps?from?OTHER_SRCS?which?we?couldn't?process??#???3.?Add?in?the?HOSTSRCS??$(obj).depend:??$(src)Makefile?$(TOPDIR)/config.mk?$(DEPS)?$(OTHER_SRCS)?\??????????$(HOSTSRCS)??????cat?/dev/null?$(DEPS)?>$@??????@for?f?in?$(OTHER_SRCS);?do?\??????????g=`basename?$$f?|?sed?-e?'s/\(.*\)\.[[:alnum:]_]/\1.o/'`;?\??????????$(CC)?-M?$(CPPFLAGS)?-MQ?$(obj) f?>>?$@?;?\??????done??????@for?f?in?$(HOSTSRCS);?do?\??????????g=`basename?$$f?|?sed?-e?'s/\(.*\)\.[[:alnum:]_]/\1.o/'`;?\??????????$(HOSTCC)?-M?$(HOSTCPPFLAGS)?-MQ?$(obj) f?>>?$@?;?\??????done????MAKE_DEPEND?=?$(CC)?-M?$(CPPFLAGS)?$(EXTRA_CPPFLAGS_DEP)?\??????????-MQ?$(addsuffix?.o,$(obj)$(basename?$<))?$<?>$@??????$(obj).depend.%:????%.c??????$(MAKE_DEPEND)????$(obj).depend.%:????%.S??????$(MAKE_DEPEND)????$(HOSTOBJS):?$(obj)%.o:?%.c??????$(HOSTCC)?$(HOSTCFLAGS)?$(HOSTCFLAGS_$(@F))?$(HOSTCFLAGS_$(BCURDIR))?-o?$@?$<?-c??$(NOPEDOBJS):?$(obj)%.o:?%.c??????$(HOSTCC)?$(HOSTCFLAGS_NOPED)?$(HOSTCFLAGS_$(@F))?$(HOSTCFLAGS_$(BCURDIR))?-o?$@?$<?-c????#########################################################################??這里有_depend目標, make _depend的時候, 執行的其實就是這里的_depend. 這個里面的細節不分析了, 大體來說有幾點
- $(obj).depend: obj一般為空, 所以這里會在當前目錄下生成一個.depend文件
- .depend里面的內容就是類似于 : main.o : main.c main.h .?
- 想深究的話可以參考這里 :?http://blog.csdn.net/panfengsoftware/article/details/7877864
最后在Makefile里面引用了當前目錄下的這個.depend
總結
以上是生活随笔為你收集整理的autoconf.mk详析的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。