Linux下Makefile的快速編寫

(一)為什麼要編寫Makefile

我們自己平常在linux下編譯源文件時,當然可以使用gcc -Wall -g main.c -o main這樣的命令一個一個編譯,但是一個工程中的源文件不計其數,其按類型、功能、模塊分別放在若干個目錄中,我們一個個編譯是極其花費時間的,也是不可取的。

makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。

makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要後編譯,哪些文件需要重新編譯,甚至於進行更復雜的功能操作,因為 makefile就像一個Shell腳本一樣,其中也可以執行操作系統的命令。

(二)Makefile的基本規則

Mackfile基本規則

Target ...: Dependencies ...

Command ...

說明:

1)目標(TARGET):即最終想要產生的文件,如:可執行文件,目標文件或中間文件等;目標也可以是要執行的動作,如clean,也稱為偽目標(用.PHONY指定偽目標)。

2)依賴(DEPENDENCIES):為了產生目標文件而依賴的文件列表,一個目標通常依賴於多個文件。

3)命令(COMMAND):是make執行的動作(shell命令或是可在shell下執行的程序,如echo)。注意:每個命令行的起始字符必須為TAB字符!

如果DEPENDENCIES中有一個或多個文件更新的話,COMMAND就要執行,這就是Makefile最核心的內容。

(三)簡單Makefile的編寫

1.單級目錄下的Makefile編寫

我們只需要使用vi Makefile命令創建一個新的Makefile文件,等我們編寫好後,只需要使用make 命令就可執行編譯操作。這裡我們創建兩個.c文件,使用他們生成目標文件:

[cpp]view plaincopy

.PHONY:clean

OBJECTS=01.o02.o

main:$(OBJECTS)

gcc-Wall-g$^-o$@

01.o:01.c

gcc-Wall-g-c$02.o:02.c

gcc-Wall-g-c$clean:

rm-fmain$(OBJECTS)上面是相對簡練的寫法,我們一個個來解釋:

1.使用變量來代替01.o 02.o ,方便後文使用。

2.使用自動化變量簡化一些操作

$@ 規則的目標文件名

$< 規則的第一個依賴文件名

$^ 規則的所有依賴文件列表

3.使用make clean 命令即可執行刪除操作

2.多級(二級)目錄生成可執行文件的Makefile的編寫

01 02 文件夾下分別有01.c 02.c ,並且和文件夾同級目錄的有03.c,main是由這三個.c文件共同生成的,如何編寫?

[cpp]view plaincopy

.PHONY:cleanall

CC=gcc

CFLAGS=-Wall-g

BIN=main

SUBDIR=$(shellls-d*/)

ROOTSRC=$(wildcard*.c)

SUBSRC=$(shellfind$(SUBDIR)-name'*.c')

SUBOBJ=$(SUBSRC:%.c=%.o)

$(BIN):$(ROOTOBJ)$(SUBOBJ)

$(CC)$(CFLAGS)$(ROOTOBJ)$(SUBOBJ)-o$(BIN)

.c.o:

$(CC)$(CFLAGS)-c$clean:

rm-f*.o$(BIN)$(ROOTOBJ)$(SUBOBJ)1.SUBDIR=$(shell ls -d */) 使用shell命令,將當前目錄下所有的子目錄賦給SUBDIR

2.ROOTSRC=$(wildcard *.c) ROOTSRC代表當前目錄下符合匹配模式的所有文件

3.SUBOBJ=$(SUBSRC:%.c=%.o) 生成.c對應的.o文件

以上就是這三個內嵌函數的使用方式。

3.多級(二級)目錄下生成多個可執行文件

緊接上例,01文件下生成01可執行文件,02文件夾下生成02可執行文件,要求使用Makefile一個make命令完成。

這就需要我們在每個文件夾下編寫自己的Makefile文件,最後使用文件夾目錄的Makefile完成操作。

[cpp]view plaincopy

01文件夾下的Makefile

CC=gcc

BIN=01

OBJS=01.o

.PHONY:allcleanprint

all:print$(BIN)

print:

@echo"----makeallin$(PWD)-----"

#$(BIN):$(OBJS)

#$(CC)$(OBJS)-o$@

%.o:%.c

$(CC)-c$clean:

@echo"----makecleanin$(PWD)---"

rm-f$(BIN)$(OBJS)[cpp]view plaincopy

02文件夾下的Makefile

(這裡02文件夾下為.cpp文件)

CXX=g++

BIN=02

OBJS=02.o

CPPFLAGS=-Wall-g

.PHONY:allcleanprint

all:print$(BIN)

print:

@echo"-----makeallin$(PWD)----"

$(BIN):$(OBJS)

$(CXX)$(CPPFLAGS)$(OBJS)-o$@

%.o:%.cpp

$(CXX)-c$clean:

@echo"----makecleanin$(PWD)----"

rm-f$(BIN)$(OBJS)[cpp]view plaincopy

文件夾同級目錄下的Makefile文件

SUBDIRS=0102

.PHONY:defaultallclean$(SUBDIRS)

default:all

allclean:

$(MAKE)$(SUBDIRS)TARGET=$@

$(SUBDIRS):

$(MAKE)-C$@$(TARGET)

上面兩個很好理解,最後的這個Makefile文件中,$(MAKE)代表make命令,TARGET默認是第一個即all,$(MAKE)-C(大寫)代表進入到0102的Makefile中,執行參數為TARGET的操作。

Linux下Makefile的快速編寫

當我們執行makeclean時,TARGET即為clean

Linux下Makefile的快速編寫



分享到:


相關文章: