Makefile常用模板

做開發的特別是C/C++開發者一般都會用到Makefile,然而多數時候在公司做項目都不需要自己去寫Makefile,僅僅停留在能看懂的基礎上。因爲make命令編譯實在是太方便了,所以自己寫寫小項目用一用還是挺好的。網上關於Makefile教程也很多,總結一下近幾年用到的常用腳本,方便自己查閱,如果能幫到別人那便是極好的^_^。

單文件項目

其實一個文件的項目也沒必要寫Makefile了,哈哈。便於理解就先從最基礎的開始吧,Makefile實際上就是寫有gcc等編譯鏈接語句的腳本,加上一些可以縮寫這些語句的規則。
假設有hello.c文件。

all: Hello
Hello:
    gcc -o Hello hello.c
clean:
    rm -rf Hello

多文件項目

假設一個工程下,有main.c和有多個.c源文件以及同名的.h頭文件,雖然可以類似上述例子一樣把每條gcc語句都寫出來,但是這麼就太囉嗦了。可以使用一些Makefile自帶的規則簡化着寫。

# 方便起見一般都會先定義編譯器鏈接器
CC = gcc 
LD = gcc

# 正則表達式表示目錄下所有.c文件,相當於:SRCS = main.c a.c b.c
SRCS = $(wildcard *.c)

# OBJS表示SRCS中把列表中的.c全部替換爲.o,相當於:OBJS = main.o a.o b.o
OBJS = $(patsubst %c, %o, $(SRCS))

# 可執行文件的名字
TARGET = Hello

# .PHONE僞目標,具體含義百度一下一大堆介紹
.PHONY:all clean

# 要生成的目標文件
all: $(TARGET)

# 第一行依賴關係:冒號後面爲依賴的文件,相當於Hello: main.o a.o b.o
# 第二行規則:$@表示目標文件,$^表示所有依賴文件,$<表示第一個依賴文件
$(TARGET): $(OBJS)
    $(LD) -o $@ $^

# 上一句目標文件依賴一大堆.o文件,這句表示所有.o都由相應名字的.c文件自動生成
%o:%c
    $(CC) -c $^

# make clean刪除所有.o和目標文件
clean:
    rm -f $(OBJS) $(TARGET)

多個文件,多個程序

這個用的比較少,網上的資料更少,當年我廢了老大勁最終才找到這個方法。因爲當時在一個目錄下寫了好多小程序,就是這個項目,可以點進去看一下。要把a.c/b.c/d.c都要編譯成可執行文件a/b/c。

C_SRC = $(wildcard *.c)
C_OBJ = $(patsubst %c, %o, $(C_SRC))
# 目標文件也是多個
TARGETLIST = $(patsubst %.c, %, $(C_SRC))

.PHONY:all clean
# 這句不寫規則的語句可以自動把相應的a.c b.c編譯成a b,神奇~
all:${TARGETLIST}

clean:  
    rm -f ${TARGETLIST} *.o 

指定頭文件目錄,庫文件及目錄

這個工程爲例,工程需要用到libs目錄下的libtomcrypt.a靜態庫和include目錄下libtom的頭文件。

CC = cc
LD = cc
SRCS = $(wildcard *.cpp)
OBJS = $(patsubst %cpp, %o, $(SRCS))
# -I指定頭文件目錄
INCLUDE = -I./include
# -L指定庫文件目錄,-l指定靜態庫名字(去掉文件名中的lib前綴和.a後綴)
LIB = -L./libs -ltomcrypt
# 開啓編譯warning和設置優化等級
CFLAGS = -Wall -O2

TARGET = LibtomDemo

.PHONY:all clean

all: $(TARGET)
# 鏈接時候指定庫文件目錄及庫文件名
$(TARGET): $(OBJS)
    $(LD) -o $@ $^ $(LIB)

# 編譯時候指定頭文件目錄
%o:%cpp
    $(CC) -c $^ $(INCLUDE) $(CFLAGS) 

clean:
    rm -f $(OBJS) $(TARGET)

注意事項

  1. 規則語句前面是製表符TAB,寫成空格會出錯!
  2. 賦值符號:=基本賦值,:=覆蓋之前的指,?=如果沒有值則賦值,+=繼續添加後面的值。

暫時沒了,想到時候再補充,有任何問題歡迎留言討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章