2012年11月22日 星期四

GNU Makefile 雜項語法備忘

一般的 tutorial 教得都差不多卻少了一些我想知道的語法, 以下是自己備忘用的語法, 對於讀別人的 Makefile 時有幫助

$ cat Makefile
var ?= xxx         # assign var = xxx if var is not assigned
.PHONY: all        # tell make that "all" is not a file
all:               # first target is the default target
    @echo make-all # @ means do not display the cmd
    @echo all: x $(x)

all: b             # all depends on b

b:
    @echo make-b   # must use TAB to indent actions
    @echo b: var $(var)


all: a             # now all depends on a and b

a: x:= 3           # set x = 3 only in this context
a:
    @echo make-a
    @echo a: x $(x)

reverse = $(2) $(1)  # define a function
c:
    @echo c: x y
    @echo c: $(call reverse, x, y)  # use "call" to use
                                    # defined functions

範例輸出

$ make
make-a
a: x 3
make-b
b: var xxx
make-all
all: x
$ var=ooo make b  # override var
make-b
b: var ooo
$ x=9 make  # set x = 9 globally
make-a
a: x 3   # note that x is still 3
make-b
b: var xxx
make-all
all: x 9
$ make c
c: x y
c: y x

注意 Makefile 自己有套變數, 想改變 g++ 的參數時, Makefile 必須寫成傳遞變數作為 g++ 參數, 比方說慣例上會用 CFLAGS, CXXFLAGS, LDFLAGS 之類的。若 Makefile 沒這麼定, 想改變 g++ 用的參數時, 就只能直接修改 Makefile 了。

2012-11-25 更新

Scott 提醒, 補上有用的參考資料:

2014-01-20 更新

更新連結, 還有補上 Scott 在留言裡補充的說明:

用『=』定義的變數像是建立一個數學關係式,每次用到該變數時會重新解譯、計算出新的值。

7 則留言:

  1. 你 Make 的功能選得滿好的,確實適合備忘。我建議:
    1. 註明是 GNU Make 的語法
    2. 加個 Link: http://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/Quick-Reference.html#Quick-Reference

    內含 GNU make 內建函式與語法的 quick reference

    3. 建議完全沒寫過 Makefile 的初學者讀 https://docs.google.com/file/d/0B_yUzRCVcjs3Ukp3R0FjVlV5ZHc/edit

    那篇是寫到無基礎可直接讀懂的。

    回覆刪除
    回覆
    1. 喔喔, 這兩個連結太好了, 馬上補上並在最近抽時間來細讀。都忘了你以前有寫過不少教學文件。

      ps. 這些語法都是我在讀別人複雜的 makefile 時, 邊讀邊猜邊試, 輔以一些搜尋, 最後得到的結論, 其實是相當不正式的結果 XD

      刪除
  2. 你好,我是因為要知道『:=』、『?=』、『=』三種assign的差別,找到這裡。
    感謝您的分享。
    另,上面Scott大大提供的『GNU make 基礎』連結已經失效。

    回覆刪除
  3. @France,
    我把『 GNU Make 基礎』擺在 http://itrs.tw/itrs-tutorials/make_tutorial.pdf
    我想明確指出一下, fcamel 此篇並沒有解釋『:=』與『=』的差異:用『=』定義的變數像是建立一個數學關係式,每次用到該變數時會重新解譯、計算出新的值。

    回覆刪除
    回覆
    1. 已更新連結, 順便抄一下你對 := 和 = 的解釋 :)

      刪除
  4. 我自己的 Make 備忘資料蒐集在 http://itrs.tw/wiki/GNU_Make

    回覆刪除

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...