2011年12月7日 星期三

Makefile的一些用法


make 內建變數的涵義 
Target:Prequeite

$@ Target的檔名
$% 程式庫成員中的檔名元素
$< 第一個prequeite的檔名
$? Timestamp 在Target之後的Prequeite
$^ 所有的Prequeite的檔名 但不包含重複部分
$+ 所有的Prequeite的檔名
$* Target的主檔名
$(@D) $(<D) 指的是Target的檔案路徑
$(@F) $(<F) 指的是Target的檔案名稱

OBJS = foo.o bar.o
CC = gcc
CFLAGS = -Wall -O -g

myprog : $(OBJS)
$(CC) $^ -o $@

foo.o : foo.c foo.h bar.h
$(CC) $(CFLAGS) -c $< -o $@
bar.o : bar.c bar.h
$(CC) $(CFLAGS) -c $< -o $@



.clean:   
rm edit $(objects)

更安全的作法PHONY表示clean為一個偽裝目標,也就是說,不管clean這個目標發生什麼問題,都繼續執行 
.PHONY : clean
clean :   
-rm edit $(objects)

patsubst是把第二個參數換成第一個參數中所指定的pattern,而第三個參數則是代表所有要代換的東西
%.o:%.c ${CC} ${CLAGS} -o ${patsubst %.o,%,$@} ${STATIC_LIBS}
${CC} ${CLAGS} -o ${@:.o=.cgi} ${STATIC_LIBS}

通配符自動在規則中進行。但是在變量賦值的和函數的參數中通配符不會擴展,如果在這些情況下需要通配符擴展,
必須使用'wildcard'函數。語法如下:
$(wildcard PATTERN...)
這個在makefile任何地方出現的字符串,會被匹配任何一個文件名格式的以空格隔開的現有文件列表替換。
如果沒有任何文件匹配一個模式,這個模式從'wildcard'的輸出中忽略,注意,這和上述的通配符的處理是不一樣的。
『wildcard'函數的一個功能是找出目錄中所有的'.c'文件:
$(wildcard *.c)
可以通過替換後綴'.c'為'.o'從C文件列表得到目標文件的列表:
$(patsubst %.c,%.o,$(wildcard *.c))
這樣,上節中的makefile改寫為:
objects := $(patsubst %.c,%.o,$(wildcard *.c))
foo : $(objects) cc -o foo $(objects)

這個makefile利用了編譯C程序的隱含規則,所以不需要對編譯寫出顯式的規則。
(':='是'='的一個變體) 注意:'PATTERN'是大小寫敏感的。

沒有留言: