日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

模仿u-boot的makefile结构

發(fā)布時(shí)間:2024/7/19 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模仿u-boot的makefile结构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

u-boot(2014.04)是通過頂層makefile調(diào)用各子目錄中的makefile來實(shí)現(xiàn)整個(gè)工程的編譯的,實(shí)際上子目錄的makefile是include進(jìn)來的。這里仿照這種結(jié)構(gòu)寫個(gè)模板測試一下。

目錄結(jié)構(gòu):

mytest:

  add:

    mul:

      Makefile

      mul.c

      mul.h

    add.c

    add.h

    Makefile

  main:

    main.c

    Makefile

  scripts:

    Makefile.build

    Makefile.clean

    Makefile.lib

  sub:

    div

      div.c

      div.h

      Makefile

    sub.c

    sub.h

    Makefile

頂層Makefile:

1 CC := gcc 2 LD := ld 3 4 CFLAGS := -g 5 6 PHONY := all 7 8 target := mainApp 9 10 # default target 11 all: $(target) 12 13 # dirs to be compiled 14 src-dirs += add/ 15 src-dirs += sub/ 16 src-dirs += main/ 17 18 # libs to be linked 19 libs-y := $(patsubst %/,%/built-in.o,$(src-dirs)) 20 21 src-dirs := $(patsubst %/,%,$(src-dirs)) 22 23 # include dirs 24 inc-dirs := $(addprefix -I,$(src-dirs)) 25 26 # the Makefile for building 27 build := -f scripts/Makefile.build obj 28 29 CFLAGS += $(inc-dirs) 30 export CC LD CFLAGS 31 32 33 PHONY += $(src-dirs) 34 35 # linking 36 $(target): $(src-dirs) 37 $(CC) -o $@ $(libs-y) 38 39 # compiling source dirs 40 $(src-dirs): 41 make $(build)=$@ 42 43 # Clean 44 clean-dirs := $(foreach f,$(src-dirs),$(if $(wildcard $f/Makefile),$f)) 45 clean-dirs := $(addprefix _clean_, $(clean-dirs)) 46 PHONY += clean $(clean-dirs) 47 48 # descending to subdirs for cleaning 49 $(clean-dirs): 50 make $(clean)=$(patsubst _clean_%,%,$@) 51 52 # just simply remove .o and target 53 clean: $(clean-dirs) 54 @find . \( -name '*.o' -o -name '$(target)' \) -type f | xargs rm -f 55 56 clean := -f scripts/Makefile.clean obj 57 .PHONY : $(PHONY)

頂層Makefile確定target,要編譯的源碼目錄,include的路徑。

第41行使用scripts/Makefile.build對(duì)各個(gè)源碼目錄進(jìn)行編譯,Makefile.build為實(shí)際編譯代碼的makefile,內(nèi)容如下:

1 src := $(obj) 2 3 PHONY := __build 4 5 obj-y := 6 7 # include the Makefile in the $(obj) dir 8 build-dir := $(src) 9 build-file := $(build-dir)/Makefile 10 include $(build-file) 11 12 # include scripts/Makefile.lib 13 include scripts/Makefile.lib 14 15 build := -f scripts/Makefile.build obj 16 17 ifneq ($(strip $(obj-y)),) 18 builtin-target := $(obj)/built-in.o 19 endif 20 21 # default target 22 __build: $(builtin-target) $(subdir) 23 @: 24 25 # compiling .c files 26 $(obj)/%.o: $(src)/%.c 27 $(CC) -c $(CFLAGS) $< -o $@ 28 29 # subdir object 30 $(subdir-obj-y): $(subdir) ; 31 32 # linking objs 33 $(builtin-target): $(obj-y) 34 $(LD) -r -o $@ $^ 35 36 PHONY += $(subdir) 37 38 # descending to subdirs 39 $(subdir): 40 make $(build)=$@ 41 42 .PHONY : $(PHONY)

obj變量為需要編譯的源碼目錄,例如add,第10行將add/目錄下的Makefile目錄包含進(jìn)來,add/Makefile內(nèi)容如下:

1 obj-y += add.o 2 obj-y += mul/

這里僅僅確定需編譯的文件以及子目錄,回到makefile.build,第13行,包含scripts/Makefile.lib文件,內(nèi)容如下:

1 subdir := $(patsubst %/,%,$(filter %/, $(obj-y))) 2 obj-y := $(patsubst %/,%/built-in.o, $(obj-y)) 3 subdir-obj-y := $(filter %/built-in.o, $(obj-y)) 4 5 subdir := $(addprefix $(obj)/,$(subdir)) 6 obj-y := $(addprefix $(obj)/,$(obj-y)) 7 subdir-obj-y := $(addprefix $(obj)/, $(subdir-obj-y))

obj-y表示要編譯的目標(biāo)文件,如果是目錄,如mul/,則表示mul/built-in.o;subdir表示要繼續(xù)編譯的子目錄;subdir-obj-y表示子目錄下的built-in.o

回到makefile.build,第18行,每個(gè)要編譯的源碼目錄編譯之后都將會(huì)產(chǎn)生一個(gè)built-in.o的文件,第27行,對(duì).c文件進(jìn)行編譯,即由obj-y變量所確定的文件。第40行,對(duì)子目錄執(zhí)行同樣的過程。第33行,對(duì)每個(gè)目錄鏈接出一個(gè)built-in.o文件,這個(gè)built-in.o由當(dāng)前目錄下.o文件和子目錄下的.built-in.o文件鏈接而成。

在所有的源碼目錄都經(jīng)過編譯之后,回到頂層makefile執(zhí)行最后的鏈接,得到target。

再看看clean目標(biāo),第49行,首先在需要進(jìn)行clean的目錄下使用scripts/Makefile.clean執(zhí)行clean,需要clean的目錄為含有makefile的源碼目錄。Makefile.clean內(nèi)容如下:

1 src := $(obj) 2 3 PHONY := __clean 4 5 # default target 6 __clean: 7 8 clean := -f scripts/Makefile.clean obj 9 10 # include the Makefile in the $(obj) dir 11 build-dir := $(src) 12 build-file := $(build-dir)/Makefile 13 include $(build-file) 14 15 # subdir to be cleaned 16 subdir := $(patsubst %/,%,$(filter %/,$(obj-y))) 17 subdir := $(addprefix $(obj)/,$(subdir)) 18 19 __clean-files := 20 __clean-files := $(addprefix $(obj),$(__clean-files)) 21 22 __clean-dirs := 23 __clean-dirs := $(addprefix $(obj),$(__clean-dirs)) 24 25 __clean: $(subdir) 26 ifneq ($(strip $(__clean-files)),) 27 rm -f $(__clean-files) 28 endif 29 30 ifneq ($(strip $(__clean-dirs)),) 31 rm -rf $(__clean-dirs) 32 endif 33 34 PHONY += $(subdir) 35 $(subdir): 36 make $(clean)=$@ 37 38 .PHONY: $(PHONY)

這里也是一個(gè)逐步往下clean的過程,要clean的文件由__clean-files變量指定。

回到頂層makefile,簡單的一個(gè)find操作,刪除目錄下所有.o文件和目標(biāo)。

關(guān)于include路徑,u-boot講所有頭文件都集中放在了某幾個(gè)目錄下,于是源碼中要包含其他頭文件的時(shí)候是這樣子做的xxx/xxx/xxx.h,我這里的main.c如下,其中對(duì)與mul和div的包含也是類似。

1 #include <stdio.h> 2 #include "add.h" 3 #include "sub.h" 4 #include "mul/mul.h" 5 #include "div/div.h" 6 7 void main(void) 8 { 9 int a = 1; 10 int b = 2; 11 printf("a = %d, b = %d\n", a, b); 12 printf("a + b = %d\n", add(a, b)); 13 printf("a - b = %d\n", sub(a, b)); 14 printf("a * b = %d\n", mul(a, b)); 15 printf("a / b = %d\n", div(a, b)); 16 }

u-boot的makefile對(duì)我來說還是太復(fù)雜了,這里僅僅是它的冰山一角,可是我已經(jīng)吃不消了。。。

轉(zhuǎn)載于:https://www.cnblogs.com/heyxiaotang/p/6438162.html

總結(jié)

以上是生活随笔為你收集整理的模仿u-boot的makefile结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。