Linux技術——makefile基礎

readyao發表於2016-04-03

make是一種控制編譯或者重複編譯軟體的工具。
make可以自動管理軟體的編譯內容、方式和時機,從而使程式設計師把更多的精力集中在編寫程式碼上。

make是怎麼完成工作的呢?

makefile是一個文字形式的指令碼檔案,其中包含一些規則告訴make編譯哪些檔案,怎麼樣編譯以及在什麼條件下編譯。(makefile檔名也可以是Makefile)
makefile規則遵循以下通用形式
target:dependency [dependency[…]]
command
command
[…]
每個command第一個字元必須是tab鍵,而不是空格鍵,不然make會報錯並停止。

用vi編輯一個簡單的makefile,內容如下:

start:
gcc -o hello hello.c

輸入make,makefile的內容執行了。

稍微複雜的makefile,內容如下:

start:hello.o
        gcc -o hello hello.o

hello.o:
        gcc -o hello.o -c hello.c

target start後面的hello.o代表其下的command依賴與hello.o這個target。所以make先執行了hello.o這個target下的command。

進一步完善的makefile,內容如下:

start:hello.o
        gcc -o hello hello.o

hello.o:
        gcc -o hello.o -c hello.c

clean:
        rm -f hello.o hello

增加了target clean。
輸入make clean,make會直接執行clean其下的command。

在makefile執行shell命令:

start:hello.o
        gcc -o hello hello.o
        @echo '---------------ok---------------'

hello.o:
        gcc -o hello.o -c hello.c

clean:
        rm -f hello.o

增加了target clean
增加了@echo,顯示編譯成功語句,為了不將語句本身輸出,所以前面加@符號。

為了簡化編輯和維護makefile,可以在makefile中使用變數。

varname=some_text
把變數用括號括起來,前面加
按照慣例makefile的變數都是大寫(只是習慣而已,不是必須的)。

在makefile使用變數:

CC=gcc

start:hello.o
        $(CC) -o hello hello.o
        @echo '---------------ok---------------'

hello.o:
        $(CC) -o hello.o -c hello.c

clean:
        rm -f hello.o

增加變數CC,每個引用變數CC的地方的展開成變數的值。

在makefile使用變數:

CC=gcc
SRCS=hello.c
OBJS=hello.o
EXEC=hello

start:hello.o
        $(CC) -o $(EXEC) $(OBJS) 
        @echo '---------------ok---------------'

hello.o:
        $(CC) -o $(OBJS) -c $(SRCS) 

clean:
        rm -f hello.o

增加變數SRCS、OBJS、EXEC,每個引用變數CC的地方的展開成變數的值。

在makefile使用變數:

CC=gcc
SRCS=hello.c
OBJS=$(SRCS:.c=.o)
EXEC=hello

start:hello.o
        $(CC) -o $(EXEC) $(OBJS) 
        @echo '---------------ok---------------'

hello.o:
        $(CC) -o $(OBJS) -c $(SRCS) 

clean:
        rm -f hello.o

OBJS=$(SRCS:.c=.o),意思是將SRCS變數中的.c替換為.o。

模式規則

.SUFFIXES:.c .o
表示任何x.c檔案與x.o關聯
.c.o:
表示make定義了一條規則,任何x.o檔案都從 x.c編譯而來
make定義了一些有用的預定義變數

$@ 規則的目標所對應的檔名
$< 規則中的第一個相關檔名

在makefile使用自動變數和模式規則的例子

.SUFFIXES:.c .o

CC=gcc
SRCS=hello.c
OBJS=$(SRCS:.c=.o)
EXEC=hello

start:$(OBJS)
        $(CC) -o $(EXEC) $(OBJS) 
        @echo '---------------ok---------------'

.c.o:
        $(CC) -o $@ -c $< 

clean:
        rm -f $(OBJS)

在makefile同時編譯多個原始檔的例子

.SUFFIXES:.c .o

CC=gcc
SRCS=hello.c\
    pub.c

OBJS=$(SRCS:.c=.o)
EXEC=hello

start:$(OBJS)
        $(CC) -o $(EXEC) $(OBJS) 
        @echo '---------------ok---------------'

.c.o:
        $(CC) -o $@ -c $< 

clean:
       rm -f $(OBJS)

常見的make出錯資訊:

1.No rule to make target ‘target’.Stop
2.makefile中沒有包含建立指定target所需要的規則,而且也沒有預設規則可用。
3.‘target’ is up to date
4.指定的target相關檔案沒有變化。
5.command:Command not found
make找不到命令,通常是因為命令被拼寫錯誤或者不在$PATH路徑下。

智慧的make

make工具會判斷filename.o 和 filename.c 檔案的最後修改時間,如果filename.o的最後修改時間比較新,說明filename.c沒有新的修改,那麼執行make的時候就不會重新編譯filename.c檔案。如果filename.c的最後修改時間比較新,說明filename.c檔案剛才被修改過,那麼執行make的時候會重新編譯filename.c檔案。

相關文章