跟我一起學Makefile讀書筆記

一   .PHONY: 僞目標 
二  % 
三.靜態模式
    目標:目標模式:依賴模式
    $< 表示依賴目標集 $@ 表示目標集
四. @命令 顯示命令
 make [-n|--just-print] 只顯示命令,調試makefile
    -s --silent 全面禁止命令顯示
五. shell 命令用; 隔開才起作用
    "-" 忽略命令出錯 如-rm -f *.o
    make -i --ignore-errors 全局忽略出錯
    以 .IGNORE 爲目標的
    -k --keep-going 若規則出錯,終止該規則,繼續其他規則
六.嵌套執行
    export 變量
    -w 參數顯示目錄信息
七.定義命令包
    define 名字
    (Tab)   command
    endef
八.變量
    變量的命名字可以包含字符、數字,下劃線(可以是數字開頭),但不應該含有“:”,“#”,“=”或是空字
    符(空格、回車等)
    變量的變量 最好用":="定義, 因爲"="可以使用後面定義的變量 "+="追加變量值 "?="未定義變量就賦值
    使用 #的方法來定義一個空格變量
    變量替換: ${var:a=b}
    把變量的值再當變量 可以用在操作符的左右兩邊 
九.override 
    如果有變量是通常 make 的命令行參數設置的,那麼 Makefile 中對這個變量的賦值會被忽略。如果
    你想在 Makefile 中設置這類參數的值,那麼,你可以使用“override”指示符。
十.目標變量

十一.函數
    ${<function> <arguments>} 參數間以逗號“,”分隔,而函數名和參數之間以“空格”分隔
    1) subst
        $(subst <from>,<to>,<text>) 把字串<text>中的<from>字符串替換成<to>。
    2) patsubst
        $(patsubst <pattern>,<replacement>,<text>) 
        $(patsubst %.c,%.o,x.c.c bar.c)
        把字串“x.c.c bar.c”符合模式[%.c]的單詞替換成[%.o],返回結果是“x.c.o bar.o”
    3) strip
       $(strip <string>) 去掉<string>字串中開頭和結尾的空字符。
    4) findstring
       $(findstring <find>,<in>) 功能:在字串<in>中查找<find>字串。
                     返回:如果找到,那麼返回<find>,否則返回空字符串。
    5) filter
       $(filter <pattern...>,<text>) 以<pattern>模式過濾<text>字符串中的單詞,
                    保留符合模式<pattern>的單詞。可以有多個模式。
    6) filter-out
       $(filter-out <pattern...>,<text>) 以<pattern>模式過濾<text>字符串中的單詞,
                    去除符合模式<pattern>的單詞。可以有多個模式
    7) sort
       $(sort <list>) 給字符串<list>中的單詞排序(升序)。備註:sort 函數會去掉<list>中相同的單詞。
    8) word
       $(word <n>,<text>) 取字符串<text>中第<n>個單詞。(從一開始)
    9) wordlist
       $(wordlist <s>,<e>,<text>) 從字符串<text>中取從<s>開始到<e>的單詞串。<s>和<e>是一個數字。
    10) words
       $(words <text>) 統計<text>中字符串中的單詞個數。備註:如果我們要取<text>中最後的一個單
            詞,我們可以這樣:$(word $(words <text>),<text>)。
    11) firstword
       $(firstword <text>) 取字符串<text>中的第一個單詞。
    override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH)))
    如 果 我 們 的 “$(VPATH)” 值 是 “src:../headers” , 那 麼 
    “$(patsubst%,-I%,$(subst :, ,$(VPATH)))”將返回“-Isrc -I../headers”,
    這正是 cc 或 gcc 搜索頭文件路徑的參數。
    文件名操作函數
    1. dir
       $(dir <names...>) 從文件名序列<names>中取出目錄部分。
    2. notdir
       $(notdir <names...>) 從文件名序列<names>中取出非目錄部分。就是文件名
    3. suffix
       $(suffix <names...>) 從文件名序列<names>中取出各個文件名的後綴。
    4. basename
       $(basename <names...>) 從文件名序列<names>中取出各個文件名的後綴。
    5. addsuffix
       $(addsuffix <suffix>,<names...>) 把後綴<suffix>加到<names>中的每個單詞後面。
    6. addprefix
       $(addprefix <prefix>,<names...>) 把前綴<prefix>加到<names>中的每個單詞後面。
    7. join
       $(join <list1>,<list2>) 把<list2>中的單詞對應地加到<list1>的單詞後面。如果<list1>的單
       詞個數要比<list2>的多,那麼,<list1>中的多出來的單詞將保持原樣。如果<list2>的單個數要比
       <list1>多,那麼,<list2>多出來的單詞將被複制到<list2>中。
    8. foreach 函數
       $(foreach <var>,<list>,<text>) 
       names := a b c d
       files := $(foreach n,$(names),$(n).o)
       上面的例子中,$(name)中的單詞會被挨個取出,並存到變量“n”中,“$(n).o”每次
       根據“$(n)”計算出一個值,這些值以空格分隔,最後作爲 foreach 函數的返回,所以,
       $(files)的值是“a.o b.o c.o d.o”。
    9. if
       $(if <condition>,<then-part>) $(if <condition>,<then-part>,<else-part>)
       如果<condition>爲真(非空字符串),那個<then-part>會是整個函數的返回值,如果<condition>爲
       假(空字符串),那麼<else-part>會是整個函數的返回值,此時如果<else-part>沒有被定義,那麼,
       整個函數返回空字串。
    10. call
      $(call <expression>,<parm1>,<parm2>,<parm3>...) 
      如:
        reverse = $(2) $(1)
        foo = $(call reverse,a,b) 此時的 foo 的值就是“b a”。
    11. origin
       $(origin <variable>) 
       返回值:undefined, default, file, command line, override, automatic
    12. shell
    13. error and warning
十二.make 的運行
    1. make 的退出碼
     0 - succeed
      1 - failed
      2 - make -q 且一些目標不需要更新
    2. make -f 指定makefile
    3. 指定目標
     MAKECMDGOALS  是命令行指定的目標
     all clean install print(list changed files) tar dist TAGS check/test 
    4. 檢查規則
     -n --just-print 只打印命令
     -t --touch 更新目標文件的時間
     -q --question 若目標存在,什麼也不輸出,若不存在,打印錯誤信息
     -W <file> 可和-n參數一起使用,查看依賴文件的規則命令
    5.make 參數
     -b -m 忽略和其他版本的兼容性
     -B --always-make 重編譯
     -C <dir> --directory=<dir> 指定讀取makefile的目錄
     --debug[=<option>] 輸出make調試信息
        a   all,輸出所有信息
        b   basic,簡單信息
        v   verbose,在b選項之上,輸出信息包括哪個makefile被解析等
        i   implicit,隱含規則
        j   jobs,命令的詳細信息,如命令的PID,返回碼等
        m   makefile,輸出make讀取makefile,更新makefile,執行makefile信息
      -d --debug=a
      -e --environment-overrides 指明環境變量的值覆蓋makefile中定義的值
     -f <file> --file=<file> --makefile=<file>
      -h --help 顯示幫助
     -i --ignore-errors 在執行是忽略所有錯誤
     -I <dir> --include-dir=<dir> 指定makefile的搜索目錄,可多個
     -j [<jobsnum>] --jogs[=<jobsnum>] 指定同時運行的命令個數,若沒有,則make 能運行多少就運行多少
     -k --keep-going 出錯也不停止
     -l <load> 指定make運行的負載
     -o <file> --old-file=<file> --assume-old=<file>不重新生成指定的file
      -p --print-data-base 輸出所有數據包括行號,文件名,調試makefile
      -r --no-builtin-rules 禁止make使用隱含規則
     -R --no-builtin-variabes 禁止make使用任何作用於變量上的隱含規則
     -s --silent --quiet 在命令運行是不輸出命令輸出
     -S --stop 取消-k選項的作用
     -w --print-directory 輸出運行makefile之前和之後的信息,用於跟蹤嵌套調用make
      --no-print-directory 禁止-w選項
十三.隱含規則
    1. C++ n.o 自動推導爲n.cc 或n.C 最好用.cc
    2. 隱含規則使用的變量
     1) 命令相關的變量
        AR 函數庫打包程序,ar
        AS 彙編編譯,as
        CC C語言,cc
        CXX C++語言,g++
        CPP C程序的預處理器,$(CC) -E
        LEX Lex方法分析器程序,lex
        YACC Yacc文法分析器(     LEX Lex方法分析器程序,lex
        YACC Yacc文法分析器(C),yacc
        RM 刪除文件命令,rm -f
      2) 命令參數相關的變量
        ARFLAGS AR的參數,默認爲rv
        ASFLAGS AS
        CFLAGS
        CXXFLAGS 
        CPPFLAGS C預處理器參數
        LDFLAGS 鏈接器參數 ld
        LFLAGS YFLAGS
    3. 隱含規則鏈
     第一個不同是除非中間的目標不存在,纔會引發中間規則。
     第二個不同的是,只要目標成功產生,那麼,產生最終目標過程中,所產生的中間目標文件會被以“rm -f”刪除。
     .INTERMEDIATE: 顯示指定中間目標
     .SECONDARY: 阻止make自動刪除中間目標
    4. 定義模式規則
     在目標定義中有"%"字符。"%"展開發生在變量和函數展開之後,發生在運行時
     目標中的模式的"%"決定了依賴目標中"%"的樣子
    5. 自動化變量
     $@ 表示規則中的目標文件集。在模式規則中,如果有多個目標,那麼,"$@"就是匹配於目標中模式定義的集合。
      $% 僅當目標是函數庫文件時,表示規則中的目標成員名。
     $< 依賴目標中的第一個目標名字。如果依賴目標是以模式(即"%")定義的,
        那麼"$<"將是符合模式的一系列的文件集。注意,其是一個一個取出來的。
      $? 所有比目標新的依賴目標的集合。以空格分隔。
      $^ 所有的依賴目標的集合。以空格分隔。如果在依賴目標中有多個重複的,
        那個這個變量會去除重複的依賴目標,只保留一份。
      $+ 這個變量很像"$^",也是所有依賴目標的集合。只是它不去除重複的依賴目標。
      $* 這個變量表示目標模式中"%"及其之前的部分。
      當你希望只對更新過的依賴文件進行操作時,"$?"在顯式規則中很有用,例如,假設有
    一個函數庫文件叫"lib",其由其它幾個 object 文件更新。那麼把 object 文件打包的比較
    有效率的 Makefile 規則是:
        lib : foo.o bar.o lose.o win.o
            ar r lib $?        
      $@$<$%$*)在擴展時只會有一個文件,另三個則是文件列表。D和F 函數dir和notdir
十四.make 跟新庫函數文件
    1. archive(member)
        ar cr archive member
    2. make foo.a(bar.o) 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章