(一)為什麼要編寫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的過程,要分步驟寫,和...