原文地址:簡單通用的Makefile(轉)做者:黑暗幽靈 html
本人是一個剛接觸嵌入式的菜鳥,由於最近寫完程序老要編譯,老是要寫Makefile, sql
因此找了一個通用的Makefile, app
做者:楊碩,華清遠見嵌入式學院講師。 性能
下面這個Makefile就能夠知足這個要求: 學習
SRCS = $(wildcard *.c) ui
OBJS = $(SRCS:.c = .o) spa
CC = gcc sqlite
INCLUDES = -I/home/noah/build_sqlite3/include htm
LIBS = -L/home/noah/build_sqlite3/lib -lsqlite3 blog
CCFLAGS = -g -Wall -O0
my_app : $(OBJS)
$(CC) $^ -o $@ $(INCLUDES) $(LIBS)
%.o : %.c
$(CC) -c $< $(CCFLAGS)
clean:
rm *.o
你們看這個Makefile和前一個比起來是否是簡潔不少,固然理解起來不如上一個那麼直觀。實際上編寫Makefile就是爲了提升咱們的工做效率,而不是增長咱們的工做量。所以Makefile爲咱們提供了不少強大的功能,好比定義變量,使用通配符等等。只要合理利用,就能夠達到事半功倍的效果。
下面咱們一條一條分析這個Makefile:
SRCS = $(wildcard *.c)
這條語句定義了一個變量SRCS,它的值就是當前面目錄下面全部的以.c結尾的源文件。
OBJS = $(SRCS:.c = .o)
這裏變量OBJS的值就是將SRCS裏面全部.c文件編譯出的.o目標文件
CC = gcc
變量CC表明咱們要使用的編譯器
INCLUDES = -I/home/noah/build_sqlite3/include
LIBS = -L/home/noah/build_sqlite3/lib -lsqlite3
這裏指定除了編譯器默認的頭文件和庫文件的路徑以外須要額外引用的頭文件路徑以及庫的路徑。
CCFLAGS = -g -Wall -O0
CCFLAGS變量存放的是編譯選項
my_app : $(OBJS)
$(CC) $^ -o $@ $(INCLUDES) $(LIBS)
my_app依賴於全部的.o文件,$^表明$(OBJS),$@表明my_app
%.o : %.c
$(CC) -c $< $(CCFLAGS)
將全部的.c源代碼編譯成.o目標文件,這樣寫是否是很省事?
clean:
rm *.o
在執行make clean以後刪除全部編譯過程當中生成的.o文件。
這個Makefile就具有靈活的通用性,咱們只要對它稍做修改就能夠用在本身的工程裏面。固然Makefile還有不少強大的功能,須要咱們進一步學習。
補充1:= := ?= +=
makefile 中 = := ?= +=的意義:
= 是最基本的賦值
:= 是覆蓋以前的值
?= 是若是沒有被賦值過就賦予等號後面的值
+= 是添加等號後面的值
補充2:.PHONY
install:foo
install -m 644 foo /usr/bin
.PHONY: install
看以上makefile的片斷,使用了.PHONY這個目標,下面詳細介紹她的用法.
來源:點擊打開連接
.PHONY是一個特殊工做目標(special target)
它用來指定一個假想的工做目標,也就是說它後面的並非一個實際文件,並且確定要視爲未更新(也就是說條件老是知足,須要處理)
PHONY 目標並不是實際的文件名:只是在顯式請求時執行命令的名字。有兩種理由須要使用PHONY 目標:避免和同名文件衝突(防止存在和PHONY執行目標的名稱相同的文件,雖然在寫比較小的makefile工程的時候看不出來.PHONY的好處,可是當面對一些大工程的時候,.PHONY則顯得至關有用),改善性能。