歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> Linux業界 >> Linux操作系統下makefile和make規則

Linux操作系統下makefile和make規則

日期:2017/3/2 13:45:39   编辑:Linux業界

  首先介紹make實用程序的語法和常用選項,然後細剖makefile文件的組成。

  make命令

  make [選項] [目標] [宏定義]

  通過命令行參數中的target,可指定make要編譯的目標,並且允許同時定義編譯多個目標,操作時按照從左向右的順序依次編譯target選項中指定的目標文件。如果命令行中沒有指定目標,則系統默認target指向描述文件中第一個目標文件。

  -d 顯示調試信息

  -n 不運行任何makefile文件,只打印需要執行的命令

  -p 輸出所有宏定義和目標文件描述

  -s 靜止狀態下運行,不顯示任何命令行信息

  -f file 通知make程序從file中讀取內部依賴說明,缺省情況下會讀取makefile或者Makefile文件處理,文件名-表示讀取標准輸入,在Linux中,GNU make工具在當前工作目錄中按照GNUmakefile、makefile、Makefile的順序搜索makefile文件

  注意:在源文件沒有被修改的情況下,運行make命令會生成一條消息,說源文件的可執行文件是最新的,不需要用make命令重新編譯和鏈接。要強制再創建可執行代碼,需要改變源文件的上次更新時間,可以使用touch命令,然後再次運行make命令。

  touch [選項] 文件或目錄

  -r 文件或目錄 把指定文件或目錄的日期時間,設成和參考文件或目錄的日期時間相同

  -d 日期時間 使用指定的日期時間,而非現在的時間

  makefile規則

  make程序基於文件之間的依賴性,需要建立的目標文件,以及建立目標文件時要執行的命令,以上所有被稱為規則,存放在文件makefile中。定制規則的語法如下:

  目標列表 : 關聯性列表

  命令列表

  注意:

  1.可以在關聯性列表和命令列表中使用shell文件名模式匹配字符,例如?、*、[]等等。

  2.如果目標的命令列表中某個命令前面帶有@,那麼當make程序執行時,該命令是不會有反應的,在程序運行完畢之後,所有前面帶@的命令按照反序執行。可以通過執行make -n命令顯示這些命令以供查看。

  3.如果目標的命令列表中某個命令前面帶有-,說明如果該命令執行有誤,會跳過該命令並繼續執行。

  make程序使用makefile中的規則決定程序中需要重新編譯的文件,並再次鏈接生成可執行代碼。如果源文件上修改的時間戳比目標文件上的時間戳更新,那麼make重新編譯build中包含的源文件。例如,如果修改了一個.h頭文件,make程序就會重新編譯所有包含該頭文件的源文件,前提是頭文件在這些源文件的目標文件的關聯性列表中;再如某.c源文件被修改,那麼該源文件被重新編譯,生成對應的新的目標文件。

  myprog : foo.o bar.o

  gcc –o myprog foo.o bar.o

  foo.o : foo.c foo.h bar.h

  gcc –o foo.o –c foo.c

  bar.o : bar.c bar.h

  gcc –o bar.o –c bar.c

  上述規則中,只要目標文件比冒號後面的文件任何一個舊,將會執行下一行的命令;但是在檢查foo.o和bar.o的時間之前,會往下查找那些把foo.o和bar.o作為目標文件的規則;以此類推,並最終回到myprog規則。

  如何得到每個C文件的輸出規則呢?可使用-M和-MM編譯選項。注意:使用-M和-MM編譯選項時,僅在shell中輸出規則信息,不能用於產生可執行文件,即不能寫成gcc -o hello -M hello.c這樣的形式。

  gcc –M hello.c //輸出hello.c和該文件中所有<>和””包含的頭文件

  gcc –MM hello.c //僅輸出hello.c和該文件中所有””包含的頭文件

  後綴(隱含)規則

  make -p命令顯示了所有後綴規則列表。為了建立一個目標,make使用程序會遍歷一連串的依賴關系,從而決定從何處開始建立。如果沒有找到目標文件,make程序按照優先順序查找源文件,首先查找.c、.f或.s後綴的文件,然後再查找SCCS(帶.c~後綴)文件,如果沒有找到任何一個源文件,make程序就會報告一個異常。

  make程序知道調用gcc -c xxx.c -o xxx.o的預定義命令,而且還知道目標文件通常和源文件是相同的,這種功能稱作標准依賴性,所以foo.o : foo.c foo.h bar.h這樣的語句可以簡寫成foo.o : foo.h bar.h。同時,如果把生成foo.o和bar.o的命令從規則中刪除,make將自動查找它的隱含規則(gcc -M/MM輸出的代碼),然後找到一個適當的命令,命令中會使用一些變量,並且按照一定步驟設定。

  因此,上述makefile的內容可以根據後綴規則簡寫成:

  myprog : foo.o bar.o

  gcc –o myprog foo.o bar.o

  foo.o : foo.h bar.h

  bar.o : bar.h

  宏定義(變量)

  makefile中的變量定義可以存儲文件名列表、可執行文件名以及編譯器標識等,主要是使用如下方法:

  VAR=name 變量定義

  define VAR

  name

  endef 同上

  $(VAR) 使用變量,如果變量名為單字符,可以不使用圓括號或花括號

  ${VAR} 同上

  $@ 當前目標文件

  $* 刪除了後綴的目標名

  $< 依賴列表中,比當前目標更新的當前依賴名稱(即第一個依賴文件)

  $^ 整個依賴列表

  $? 依賴列表中,比當前目標更新的當前依賴列表

  CFLAGS 通常默認值是-O,但是可以被修改

  未使用後綴規則的makefile文件變成如下:

  OBJS=foo.o bar.o

  SOURCES=foo.c bar.c

  HEADERS=foo.h bar.h

  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 $@

Copyright © Linux教程網 All Rights Reserved