Linux下Makefile快速編寫入門

2021-07-23 18:52:45 字數 4000 閱讀 8914

(一)為什麼要編寫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 plain

copy

.phony:clean  

objects=01.o 02.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 -f main $(objects)  

上面是相對簡練的寫法,我們乙個個來解釋:

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

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

$@ 規則的目標檔名

$< 規則的第乙個依賴檔名

$^ 規則的所有依賴檔案列表

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

2.多級(二級)目錄生成可執行檔案的makefile的編寫

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

[cpp]view plain

copy

.phony:clean all  

cc=gcc  

cflags=-wall -g  

bin=main  

subdir=$(shell ls -d */)          

rootsrc=$(wildcard *.c)  

subsrc=$(shell find $(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 plain

copy

01資料夾下的makefile  

cc  =gcc  

bin =01  

objs =01.o  

.phony: all clean print  

all:print $(bin)  

print:  

@echo "----make all in $(pwd)-----"

#$(bin):$(objs)

#   $(cc) $(objs) -o $@

%.o:%.c  

$(cc) -c $

clean:  

@echo "----make clean in $(pwd)---"

rm -f $(bin) $(objs)  

[cpp]view plain

copy

02資料夾下的makefile  

(這裡02資料夾下為.cpp檔案)  

cxx =g++  

bin =02  

objs =02.o  

cppflags =-wall -g  

.phony: all clean print  

all:print $(bin)  

print:  

@echo "-----make all in $(pwd)----"

$(bin):$(objs)  

$(cxx) $(cppflags) $(objs) -o $@  

%.o:%.cpp  

$(cxx) -c $

clean:  

@echo "----make clean in $(pwd)----"

rm -f $(bin) $(objs)  

[cpp]view plain

copy

資料夾同級目錄下的makefile檔案  

subdirs =01 02  

.phony:default all clean $(subdirs)  

default:all  

all clean:  

$(make) $(subdirs) target=$@  

$(subdirs):  

$(make) -c $@ $(target)  

上面兩個很好理解,最後的這個makefile

檔案中,

$(make)

代表make

命令,target

預設是第乙個即

all,

$(make) -c(大寫)

代表進入到

01 02

的makefile

中,執行引數為

target

的操作。

當我們執行make clean

時,target

即為clean

更深入的內容請參考:

Linux下Makefile編寫語法

makefile樣例 all main.c foo1.c foo2.c foo3.c gcc main.c foo1.c foo2.c foo3.c o all targets prerequisites command 或者targets prerequisites command targets...

linux下的makefile程式設計

程式1 mytool1.c include mytool1.h include stdio.h void mytool1 print char print str 程式2 mytool1.h ifndef mytool 1 h define mytool 1 h void mytool1 print...

Linux下的MakeFile檔案

makefile是linux下的檔案管理工具,本質是檔案,載入執行需要make命令,make命令可以認為是執行shell指令碼檔案 我們建立乙個makefile檔案,注意,在linux中,m首字母大小寫不區分 呼叫vim makefile makefile內容是main的gcc的過程,要分步驟寫,和...