一般整個工程的makefile分為3類:
1. 頂層目錄的makefile
2. 頂層目錄的makefile.build
3. 各級子目錄的makefile
(1)頂層目錄的makefile:
它除了定義obj-y來指定根目錄下要編程序式去的檔案、子目錄外,主要是定義工具鏈、編譯引數、鏈結引數──就是檔案中用export匯出的各變數。
部分示例**如下:
# 編譯器在編譯時的一些通用引數設定
cflags := -wall -o2 -g -ddebug
# 新增標頭檔案路徑,不新增的話include目錄下的標頭檔案編譯時找不到
cflags += -i $(shell pwd)/include -i/opt/libdecode/include
# 鏈結器的鏈結引數設定
ldflags := -ljpeg -lz -lpng -l/opt/libdecode/lib
export cflags ldflags
(2)頂層目錄的makefile.build:
這是最複雜的部分,它的功能就是把某個目錄及它的所有子目錄中、需要編程序式去的檔案都編譯出來,打包為built-in.o
部分示例**如下:
all:
make -c ./ -f $(topdir)/makefile.build
$(cc) $(ldflags) -o $(target) built-in.o
(3)各級子目錄的makefile:
它最簡單,形式如下:
obj-y += file.o
obj-y += subdir/
"obj-y += file.o"表示把當前目錄下的file.c編程序式裡,
"obj-y += subdir/"表示要進入subdir這個子目錄下去尋找檔案來編程序式裡,是哪些檔案由subdir目錄下的makefile決定。
注意: "subdir/"中的斜槓"/"不可省略
(4)怎麼使用這套makefile:
1.把頂層makefile, makefile.build放入程式的頂層目錄
2.修改頂層makefile
2.1 修改工具鏈
2.2 修改編譯選項、鏈結選項
2.3 修改obj-y決定頂層目錄下哪些檔案、哪些子目錄被編程序式
2.4 修改target,這是用來指定編譯出來的程式的名字
3. 在各乙個子目錄下都建乙個makefile,形式為:
obj-y += file1.o
obj-y += file2.o
obj-y += subdir1/
obj-y += subdir2/
(1)偽目標不是為了得到某個檔案或東西,而是單純為了執行這個目標下面的命令。
(2)偽目標一般都沒有依賴
(3)但是有時候為了明確宣告這個目標是偽目標會在偽目標的前面用.phony來明確宣告它是偽目標。
示例**如下: 可以在cp上一行加上 .phony:clean all cp
標明下,更清楚
cp:cp ../testproject/ /root/rootfs/ -rf
clean:
rm -f $(shell find -name "*.o")
rm -f $(target)
(1)建立上層目錄
比如當然 /root 目錄下沒有任何目錄
mkdir -p /root/test/test
這樣就在 /root 目錄下建立了 test 目錄 ,並在 /root/test目錄下還建立了 /root/test/test 目錄
(1)= 最簡單的賦值
用=賦值的變數,在被解析時他的值取決於最後一次賦值時的值,所以看變數引用的值時不能只往前面看,還要往後面看。
(2):= 一般也是賦值
用:=來賦值的,則是就地直接解析,只用往前看即可。
(3)?= 如果變數前面並沒有賦值過則執行這條賦值,如果前面已經賦值過了則本行被忽略。
(4)+= 用來給乙個已經賦值的變數接續賦值,意思就是把這次的值加到原來的值的後面。(在shell makefile等檔案中,可以認為所有變數都是字串,+=就相當於給字串stcat接續內容)(注意乙個細節,+=續接的內容和原來的內容之間會自動加乙個空格隔開)
(5)* 若干個任意字元
(6)? 1個任意字元
(7)[ ] 將中的字元依次去和外面的結合匹配
(8)$(src:%.c=%.o) 將src變數中所有以.c結尾的檔名替換成對應的以.o結尾的檔名,然後賦回給src
(9)一般我們可以使用「$(wildcard *.c)」來獲取工作目錄下的所有的.c檔案列表
(1)常見自動變數:
$@ 規則的目標檔名
$< 規則的依賴檔名
$^ 依賴的檔案集合
cross_compile = /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-
as = $(cross_compile)as
ld = $(cross_compile)ld
cc = $(cross_compile)gcc
cpp = $(cc) -e
ar = $(cross_compile)ar
nm = $(cross_compile)nm
strip = $(cross_compile)strip
objcopy = $(cross_compile)objcopy
objdump = $(cross_compile)objdump
# export匯出的變數是給子目錄下的makefile使用的
export as ld cc cpp ar nm strip objcopy objdump
# 編譯器在編譯時的引數設定 (比如列印出所有警告、除錯資訊)
cflags := -wall -o2 -g -ddebug
# 新增標頭檔案路徑,不新增的話include目錄下的標頭檔案編譯時找不到
cflags += -i $(shell pwd)/include
# 鏈結器的鏈結引數設定
ldflags :=
export cflags ldflags
topdir := $(shell pwd)
export topdir
# 定義將來編譯生成的可執行程式的名字
target := imageplayer
# 新增專案中所有用到的原始檔,有頂層目錄下的.c檔案,和子資料夾
# 新增頂層目錄下的.c檔案
obj-y += main.o
# 新增頂層目錄下的子資料夾(注意目錄名後面加乙個/)
obj-y += display/
all:
make -c ./ -f $(topdir)/makefile.build
$(cc) $(ldflags) -o $(target) built-in.o
cp:
(../ 當前目錄是在makeflie裡面,需要../才能進入與makefile同級的目錄下)
cp ../lbwproject /root/porting_x210/rootfs/rootfs/ -rf
clean:
rm -f $(shell find -name "*.o")
rm -f $(target)
distclean:
rm -f $(shell find -name "*.o")
rm -f $(shell find -name "*.d")
rm -f $(target)
乙個通用的makefile(一)
最近在編寫android編譯系統時,需要遍歷每乙個目錄下每乙個資料夾下的makefile,網上的方法有些繁瑣 就直接貼上自己遍歷子目錄深度為1 for temporary 之後會繼續更新 下面是我的乙個簡單例項工程 資料夾目錄層次 獲取當前目錄下的子目錄名字 2 subdir shell ls l ...
乙個通用Makefile的編寫
我們在linux環境下開發程式,少不了要自己編寫makefile,乙個稍微大一些的工程下面都會包含很多.c的原始檔。如果我們用gcc去乙個乙個編譯每乙個原始檔的話,效率會低很多,但是如果我們可以寫乙個makefile,那麼只需要執行乙個make就ok了,這樣大大提高了開發效率。但是makefile的...
編寫乙個簡單通用的makefile
author 李超 date 2012 05 06 縱然makefile 的規則還是相當多的,編寫乙個大規模的軟體,良好的 makefile 架構是方便維護程式編譯的關鍵。學習 makefile 的時間週期還是比較長的,為了寫出規範的 需要在很短的時間內編寫乙個 makefile 這裡給給出乙個 m...