Makefile的簡單編寫


當我們的工程越來越大的以后,每次都使用命令編譯顯得非常的麻煩.所以我們需要一個自動化編譯的工具來幫助我們編譯.在我們使用源碼安裝軟件的時候都會有make,make install等操作,這個就是使用Makefile來進行自動化編譯的工作的.

Makefile也是一個腳本文件和shell腳本非常的相似,但是也有很多的地方不一樣.

程序編譯通常會有一下幾個步驟,先是預編譯,然后將C語言代碼編譯成匯編,然后在將匯編編譯成二進制文件.o文件,然后將所有的.o文件連接起來就得到了可執行文件.

在編寫Makefile時,我們先將所有的c語言代碼編譯成二進制文件,然后將所有二進制文件鏈接起來.

和shell類似的,里面有變量,有命令,有循環,判斷等語句,所有的命令都需要另起一行,而且開始必須是tab鍵(所有開頭是tab鍵的行都會被認為是命令,哪怕不能執行),變量等必須頂行不能有空格等.

簡單的Makefile格式(不涉及循環,選擇等語句):

TARGET... : PREREQUISITES...
  COMMAND

a:main.o

  gcc -o main.o

main.o:main.c

  gcc -c main.c

這樣就是一個最簡單的Makefile

當然我們如果是文件多的話這樣寫就非常的麻煩,我們就可以使用 變量名 += .....來進行編輯,使用時直接$(變量名)來使用.(和shell一樣)

我們也常常會使用make clean的命令等,這個叫做偽目標,直接

clean:

  rm *.o

install:

  cp .. /bin

 

Makefile文件也可以應用其他的Makefile文件

include 文件名

 

在我們寫了.o文件名以后,當.o和.c文件是同名時,我們也可以不用.c文件,make會自動查找同名的文件,例如%.o:%.c.

以下是一些自動化變量:

$@
表示規則的目標文件名。如果目標是一個文檔文件(Linux中,一般稱.a文件為文檔文件,也稱為靜態庫文件) ,那么它代表這個文檔的文件名。在多目標模式規則中,它代表的是哪個觸發規則被執行的目標文件名。

$%
當規則的目標文件是一個靜態庫文件時,代表靜態庫的一個成員名。例如,規則的目標是 “foo.a(bar.o)” , 那么, “$%” 的值就為 “bar.o” , “$@” 的值為“foo.a” 。
如果目標不是靜態庫文件,其值為空。

$<
規則的第一個依賴文件名。 如果是一個目標文件使用隱含規則來重建, 則它代表由隱含規則加入的第一個依賴文件。

$?
所有比目標文件更新的依賴文件列表,空格分割。如果目標是靜態庫文件名,代表的是庫成員(.o文件) 。

$^
規則的所有依賴文件列表,使用空格分隔。如果目標是靜態庫文件,它所代表的只能是所有庫成員(.o文件)名。一個文件可重復的出現在目標的依賴中,變量“$^”只記錄它的一次引用情況。就是說變量“$^”會去掉重復的依賴文件。

$+
類似“$^” ,但是它保留了依賴文件中重復出現的文件。主要用在程序鏈接時庫的交叉引用場合。

$*
在模式規則和靜態模式規則中,代表“莖” 。 “莖”是目標模式中“%”所代表的部分 (當文件名中存在目錄時, “莖” 也包含目錄 (斜杠之前) ) 。例如:文件“dir/a.foo.b” ,當目標的模式為“a.%.b”時,“$*”的值為“dir/a.foo” 。 “莖”對於構造相關文件名非常有用

 

以下是一般的簡單的Makefile寫法:

COBJS += main.o

#CFLAGS += -O2 -Wall -DDEBUG
CFLAGS += -I./

LDFLAGS += -lmxml -lpthread

CROSS_COMPILE ?=

CC = $(CROSS_COMPILE)gcc

TARGET = tag

all:$(TARGET)
$(TARGET):$(COBJS)
$(CC) -o $@ $^ $(LDFLAGS)

%.o:%.c
$(CC) $(CFLAGS) -c -o $@ $^ $(LDFLAGS)

.PHONY:clean
clean:
rm -f $(COBJS)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM