tft每日頭條

 > 科技

 > linux怎麼新建makefile文件

linux怎麼新建makefile文件

科技 更新时间:2024-10-21 09:15:33
Make簡介:
  • 工程管理器,顧名思義,是指管理較多的文件
  • Make工程管理器也就是個“自動編譯管理器”,這裡的“自動”是指它能夠根據文件時間戳自動發現更新過的文件而減少編譯的工作量,同時,它通過讀入makefile文件的内容來執行大量的編譯工作
  • ==Make将隻編譯改動的代碼文件,而不用完全編譯。==

會不會寫makefile,從一個側面說明了一個人是否具備完成大型工程的能力,makefile關系到了整個工程的編譯規則。一個工程中的源文件不計數,其按類型、功能、模塊分别放在若幹個目錄中,makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要後編譯,哪些文件需要重新編譯,甚至于進行更複雜的功能操作,因為makefile就像一個Shell腳本一樣,其中也可以執行操作系統的命令。makefile帶來的好處就是——“自動化編譯”,一旦寫好,隻需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率

Makefile基本結構:
  • Makefile是Make讀入的唯一配置文件 由make工具創建的目标體(target),通常是目标文件或可執行文件要創建的目标體所依賴的文件(dependency_file)創建每個目标體時需要運行的命令(command)

==注意:== 命令行前面必須是一個”**==TAB==** 鍵”,否則編譯錯誤為:*** missing separator. Stop.

例如:

linux怎麼新建makefile文件(LinuxC基礎)1

Makefile格式:

target : dependcy_files <TAB>command

target //目标 : target也就是一個目标文件,可以是Object File,也可以是執行文件。還可以是一個标簽(Label)

dependcy_files //生成目标所要的目标文件: dependcy_files 就是,要生成那個target所需要的文件或是目标。

command也就是make需要執行的命令。(任意的Shell命令)

這是一個文件的依賴關系,也就是說,target這一個或多個的目标文件依賴于dependcy_files中的文件,其生成規則定義在command中。**==說白一點就是說,dependcy_files中如果有一個以上的文件比target文件要新的話,command所定義的命令就會被執行。這就是Makefile的規則。也就是Makefile中最核心的内容。==**

==【注】==:在看别人寫的Makefile文件時,你可能會碰到以下三個變量:$@,$^,$<代表的意義分别是:

他們三個是十分重要的三個變量,所代表的含義分别是:

**$@:目标文件,$^: 所有的依賴文件,$<: 第一個依賴文件**。

這個變量的問題,我們在下面繼續講解。

複雜一些的例子:

sunq:kang.o yul.o gcc kang.o yul.o -o sunq kang.o:kang.c kang.h gcc -Wall -O -g-c kang.c -o kang.o yul.o:yul.c yul.h gcc -Wall -O -g-c yul.c -o yul.o clean: rm *.o test

注釋: —Wall : 表示允許發出gcc所有有用的報警信息。 —c : 隻是編譯不連接,生成目标文件" .o " —o file : 表示把輸出文件輸出到file裡

我們可以把這個内容保存在文件為“Makefile”或“makefile”的文件中,然後在該目錄下直接輸入命令“make”就可以生成執行文件sunq。如果要删除執行文件和所有的中間目标文件,那麼,隻要簡單地執行一下“make clean”就可以了。在這個makefile中,==目标文件(target)包含:執行文件sunq和中間目标文件(*.o),依賴文件(prerequisites)就是冒号後面的那些 .c 文件和 .h文件。每一個 .o 文件都有一組依賴文件,而這些 .o 文件又是執行文件 sunq的依賴文件。依賴關系的實質上就是說明了目标文件是由哪些文件生成的==,換言之,目标文件是哪些文件更新的。

在定義好依賴關系後,後續的那一行定義了如何生成目标文件的操作系統命令,**==一定要以一個Tab鍵作為開頭==**。記住,make并不管命令是怎麼工作的,他隻管執行所定義的命令。make會比較targets文件和dependcy_files文件的修改日期,如果dependcy_files文件的日期要比targets文件的日期要新,或者target不存在的話,那麼,make就會執行後續定義的命令。

1. make是如何工作的

大多數的make都支持“makefile”和“Makefile”這兩種默認文件名,你可以使用别的文件名來書寫Makefile,比如:“Make.Linux”,“Make.Solaris”,“Make.AIX”等,如果要指定特定的Makefile,你可以使用make的“-f”和“--file”參數,如:**make -f Make.Linuxmake --file Make.AIX**。

在默認的方式下,也就是我們隻輸入make命令。 那麼,

  1. make會在當前目錄下找名字叫“Makefile”或“makefile”的文件。
  2. 如果找到,它會找文件中的第一個目标文件(target),在上面的例子中,他會找到“sunq”這個文件,并把這個文件作為最終的目标文件。
  3. 如果sunq文件不存在,或是sunq所依賴的後面的 .o文件的文件修改時間要比sunq這個文件新,那麼,他就會執行後面所定義的命令來生成sunq這個文件。
  4. 如果sunq所依賴的.o文件不存在,那麼make會在當前文件中找目标為.o文件的依賴性,如果找到則再根據那一個規則生成.o文件。(這有點像一個堆棧的過程)
  5. 當然,你的C文件和H文件是存在的啦,于是make會生成 .o 文件,然後再用 .o 文件聲明make的終極任務,也就是執行文件sunq了。

這就是整個make的依賴性,make會一層又一層地去找文件的依賴關系,直到最終編譯出第一個目标文件。在找尋的過程中,如果出現錯誤,比如最後被依賴的文件找不到,那麼make就會直接退出,并報錯,而對于所定義的命令的錯誤,或是編譯不成功,make根本不理。make隻管文件的依賴性,即,如果在我找了依賴關系之後,冒号後面的文件還是不在,那麼對不起,我就不工作啦。

make工作時的執行步驟入下:(想來其它的make也是類似)

讀入所有的Makefile。

讀入被include的其它Makefile。

始化文件中的變量。

推導隐晦規則,并分析所有規則。

為所有的目标文件創建依賴關系鍊。

根據依賴關系,決定哪些目标要重新生成。

執行生成命令。

1-5步為第一個階段,6-7為第二個階段。第一個階段中,如果定義的變量被使用了,那麼,make會把其展開在使用的位置。但make并不會完全馬上展開,make使用的是拖延戰術,如果變量出現在依賴關系的規則中,那麼僅當這條依賴被決定要使用了,變量才會在其内部展開。

2.makefile文件中的依賴關系理解

假設當前工程目錄為object/,該目錄下有6個文件,分别是:main.c、abc.c、xyz.c、abc.h、xyz.h和Makefile。其中main.c包含頭文件abc.h和xyz.h,abc.c包含頭文件abc.h,xyz.c包含頭文件xyz.h,而abc.h又包含了xyz.h。它們的依賴關系如圖。

linux怎麼新建makefile文件(LinuxC基礎)2

Makefile應該寫成這個樣子(假設生成目标main):

main:main.o abc.o xyz.o gcc main.o abc.o xyz.o -o main main.o:main.c abc.h xyz.h gcc -c main.c –o main.o -g abc.o:abc.c abc.h xyz.h gcc -c abc.c –o abc.o -g xyz.o:xyz.c xyz.h gcc -c xyz.c -o xyz.o -g .PHONY:clean clean: rm main main.o abc.o xyz.o -f

3. Makefile書寫規則

規則包含兩個部分,一個是==依賴關系==,一個是==生成目标的方法==。

在Makefile中,規則的順序是很重要的,因為,**==Makefile中隻應該有一個最終目标==,其它的目标都是被這個目标所連帶出來的,所以 ==一定要讓make知道你的最終目标是什麼== 。一般來說,定義在Makefile中的目标可能會有很多,但是第一條規則中的目标将被确立為最終的目标==如果第一條規則中的目标有很多個,那麼,第一個目标會成為最終的目标==。make所完成的也就是這個目标。**

3.1 規則舉例

foo.o: foo.c defs.h # foo模塊 cc -c -g foo.c

看到這個例子,各位應該不是很陌生了,前面也已說過,foo.o是我們的目标foo.c和defs.h是目标所依賴的源文件,而隻有一個命令“cc -c -g foo.c”(以Tab鍵開頭)。這個規則告訴我們兩件事

  1. 文件的依賴關系,foo.o依賴于foo.c和defs.h的文件,如果foo.c和defs.h的文件日期要比foo.o文件日期要新,或是foo.o不存在,那麼依賴關系發生。
  2. 如果生成(或更新)foo.o文件。也就是那個cc命令,其說明了,如何生成foo.o這個文件。(當然foo.c文件include了defs.h文件)
4. Makefile 基礎的使用

接下來我們做個實例來學習下怎麼寫 Makefile

寫兩個c程序

linux怎麼新建makefile文件(LinuxC基礎)3

linux怎麼新建makefile文件(LinuxC基礎)4

寫一個head.h 頭文件,用來聲明上面的函數

linux怎麼新建makefile文件(LinuxC基礎)5

寫一個main程序

linux怎麼新建makefile文件(LinuxC基礎)6

linux怎麼新建makefile文件(LinuxC基礎)7

如果這樣的方式寫,要是改動其中文件的時候,若文件過多,會很麻煩。

所以Makefile的使用會帶來很大的驚喜。

Makefile

test:fun1.o fun2.o main.o gcc fun1.o fun2.o main.o -o test fun2.o:fun2.c gcc -c -Wall fun2.c -o fun2.o fun1.o:fun1.c gcc -c -Wall fun1.c -o fun1.o main.o:main.c gcc -c -Wall main.c -o main.o

Makefile内部流程

linux怎麼新建makefile文件(LinuxC基礎)8

linux怎麼新建makefile文件(LinuxC基礎)9

若我要改動其中的c文件 改動fun2.c

linux怎麼新建makefile文件(LinuxC基礎)10

改動好後,再make 發現隻有fun2.c被重新生成fun2.o ,因為fun2.o是新生成的,也要新生成 test。

linux怎麼新建makefile文件(LinuxC基礎)11

結果

linux怎麼新建makefile文件(LinuxC基礎)12

Makefile後文件夾内會生成很多中間文件

linux怎麼新建makefile文件(LinuxC基礎)13

我們需要清理時呢,我們 ==往往通過make相關命令來清理== ,而不是rm一個一個删除。

clean:rm *.o test

linux怎麼新建makefile文件(LinuxC基礎)14

make 目标名

linux怎麼新建makefile文件(LinuxC基礎)15

這樣中間文件都被清理了

linux怎麼新建makefile文件(LinuxC基礎)16

僞目标:肯定會被執行的文件,重名了

linux怎麼新建makefile文件(LinuxC基礎)17

重名後,發現clean不工作了,默認為它沒被改動,所以它不工作。 如何避免這個問題呢?

在Makefile中加.PHONY:command==.PHONY:隐含說明== “.PHONY”表示,clean是個僞目标文件。

.PHONY:clean

linux怎麼新建makefile文件(LinuxC基礎)18

這樣就不會被重名耽誤運行了

linux怎麼新建makefile文件(LinuxC基礎)19

清空目标文件的規則 每個Makefile中都應該寫一個清空目标文件(.o和執行文件)的規則,這不僅便于重編譯,也很利于保持文件的清潔。 一般的風格都是:

clean: rm edit $(objects)

更為穩健的做法是:

.PHONY : clean clean : -rm edit $(objects)

前面說過,.PHONY意思表示clean是一個“僞目标”,。而在rm命令前面加了一個小減号的意思就是,也許某些文件出現問題,但不要管,繼續做後面的事。 當然,clean的規則不要放在文件的開頭,不然,這就會變成make的默認目标,相信誰也不願意這樣。不成文的規矩是——“clean從來都是放在文件的最後”。

3.makefile文件中的依賴關系理解

假設當前工程目錄為object/,該目錄下有6個文件,分别是:main.c、abc.c、xyz.c、abc.h、xyz.h和Makefile。其中main.c包含頭文件abc.h和xyz.h,abc.c包含頭文件abc.h,xyz.c包含頭文件xyz.h,而abc.h又包含了xyz.h。它們的依賴關系如圖。

linux怎麼新建makefile文件(LinuxC基礎)20

Makefile應該寫成這個樣子(假設生成目标main):

main:main.o abc.o xyz.o gcc main.o abc.o xyz.o -o main main.o:main.c abc.h xyz.h gcc -c main.c –o main.o -g abc.o:abc.c abc.h xyz.h gcc -c abc.c –o abc.o -g xyz.o:xyz.c xyz.h gcc -c xyz.c -o xyz.o -g .PHONY:clean clean: rm main main.o abc.o xyz.o -f

4. 創建和使用變量

為了makefile的易維護,在makefile中我們可以使用變量。makefile的變量也就是一個字符串,理解成C語言中的宏可能會更好。

上面makefile例子:

test:fun1.o fun2.o main.o gcc fun1.o fun2.o main.o -o test fun2.o:fun2.c gcc -c -Wall fun2.c -o fun2.o fun1.o:fun1.c gcc -c -Wall fun1.c -o fun1.o main.o:main.c gcc -c -Wall main.c -o main.o .PHONY:clean clean rm *.o test

比如,我們聲明一個變量,叫objects,能夠表示obj文件就行了。我們在makefile一開始就這樣定義:

objects = fun1.o fun2.o main.o

于是,我們就可以很方便地在我們的makefile中以“**$(objects)**”的方式來使用這個變量了,于是我們的改良版makefile就變成下面這個樣子:

objects = fun1.o fun2.o main.o test:$(objects) gcc fun1.o fun2.o main.o -o test fun2.o:fun2.c gcc -c -Wall fun2.c -o fun2.o fun1.o:fun1.c gcc -c -Wall fun1.c -o fun1.o main.o:main.c gcc -c -Wall main.c -o main. .PHONY:clean clean rm *.o test

于是如果有新的 .o 文件加入,我們隻需簡單地修改一下 objects 變量就可以了

我們簡單的總結一下:

2.1 創建變量的目的:

用來代替一個文本字符串:

系列文件的名字

傳遞給編譯器的參數

需要運行的程序

需要查找源代碼的目錄

你需要輸出信息的目錄

你想做的其它事情。

2.2 如何定義變量:

變量定義的兩種方式

遞歸展開方式VAR=VAR

簡單方式VAR:=var

變量使用$(VAR) =========================

用 ” 則用$ ” 來表示

類似于編程語言中的宏

我們再來舉一個例子:

sunq:kang.o yul.o gcc kang.o yul.o -o sunq kang.o:kang.c kang.h gcc -Wall -O -g-c kang.c -o kang.o yul.o:yul.c yul.h gcc -Wall -O -g-c yul.c -o yul.o .PHONY:clean clean rm *.o test

用變量來替換:

OBJS = kang.o yul .o CC = gcc CFLAGS = -Wall -O -g sunq : $(OBJS) $(CC)$(OBJS) -o sunq kang.o : kang.c kang.h $(CC)$(CFLAGS)-c kang.c -o kang.o yul.o : yul.c yul.h $(CC)$(CFLAGS)-c yul.c -o yul.o .PHONY:clean clean rm *.o test

  • 遞歸展開方式VAR=var例子:

foo = $(bar) bar = $(ugh) ugh = Huh?

的值為

(foo)來進行查看

優點: 它可以向後引用變量 缺點: 不能對該變量進行任何擴展,

例如 CFLAGS = $(CFLAGS)-0會造成死循環

  • 簡單方式VAR:=var

m := mm x:=$(m) y:= $(x) bar x:=later echo $(x) $(y)

如:m變量的值為mm ,m的值賦給給x

(這個變量的方式更像是c語言)

==用?=定義變量==

dir :=/foo/bar FOO?=bar FOO是?

?含義是,如果FOO沒有被定義過,那麼變量FO0的值就是“bar”,如果FOO先前被定義過,那麼這條語将什麼也不做,其等價于:

ifeq ($(origin FOO),undefined) FOO=bar endif

  • 為變量添加值

你可以通過 = 為已定義的變量添加新的值

Main=hello.o hello-1.o Main =hello-2.o

  • 預定義變量

-AR 庫文件維護程序的名稱,默認值為ar。AS彙編程序的名稱默認值為as。 -CC C編譯器的名稱,默認值為cc。CPPC預編譯器的名稱,默認值 為$(CC) -E。 -CXX C 編譯器的名稱,默認值為g 。 -FC FORTRAN編譯器的名稱,默認值為 f77 -RM 文件删除程序的名稱,默認值為rm -f

  • 自動變量

- $* 不包含擴展名的目标文件名稱 -$ 所有的依賴文件,以空格分開,并以出現的先後為序,可能包含重複的依賴文件 -$< 第一個依賴文件的名稱 -$? 所有時間戳比目标文件晚的的依賴文件,并以空格分開 -$@ 目标文件的完整名稱 -$^ 所有不重複的目标依賴文件,以空格分開 -$% 如果目标是歸檔成員,則該變量表示目标的歸檔成員名稱

**$@:目标文件,$^: 所有的依賴文件,$<: 第一個依賴文件**。這三個變量十分常見且重要

objects = fun1.o fun2.o main.o test:$(objects) gcc fun1.o fun2.o main.o -o test fun2.o:fun2.c gcc -c -Wall fun2.c -o fun2.o fun1.o:fun1.c gcc -c -Wall fun1.c -o fun1.o main.o:main.c gcc -c -Wall main.c -o main.o .PHONY:clean clean rm *.o test

變量修改:

objects = fun1.o fun2.o main.o CFLAGS=-c -Wall test:$(objects) gcc $(objects) -o test fun2.o:$< gcc $(CFLAGS) fun2.c -o $@ fun1.o:$< gcc $(CFLAGS) fun1.c -o $@ main.o:$< gcc $(CFLAGS) main.c -o $@ .PHONY:clean clean rm *.o test

環境變量

  • make在啟動時會自動讀取系統當前已經定義了的環境變量,并且會創建 與之具有相同名稱和數值的變量
  • 如果用戶在Makefile中定義了相同名稱的變量,那麼用戶自定義變量将會覆蓋同名的環境變量

==直接運行make選項==

-C dir讀入指定目錄下的Makefile -f file讀入當前目錄下的file文件作為Makefile -i 忽略所有的命令執行錯誤 -I dir指定被包含的Makefile所在目錄 -n 隻打印要執行的命令,但不執行這些命令 -p 顯示make變量數據庫和隐含規則 -s 在執行命令時不顯示命令 -w 如果make在執行過程中改變目錄,打印當前目錄名

-C : dir讀入指定目錄下的Makefile

make -C Makefile/文件下的makefile

linux怎麼新建makefile文件(LinuxC基礎)21

linux怎麼新建makefile文件(LinuxC基礎)22

-f : file 讀入當前目錄下的file文件作為Makefile

c make -f Refuel.debugmake -f Refuel.debug clean

就可以把Refuel.debug當作Makefile來用

-i :忽略所有的命令執行錯誤假如我們在寫代碼時候, gcc -c -Wall fun2.c o $@寫-o忘記了- 這種時候,我們 make -i ,它會把小錯誤先忽略,把代碼中能正常執行的先執行,錯誤的提示出來,不執行

-n :隻打印要執行的命令,但不執行這些命令 不是真的執行了命令,而是像模拟了執行命令

U-Boot中我們會看到一些内核的Makefile,config.mk 這樣的文件中羅列了一些變量的聲明

5. Makefile的隐含規則
  • ==隐含規則1:== 編譯C程序的隐含規則——讓make自動推導

它可以自動推導文件以及文件依賴關系後面的命令,于是我們就沒必要去在每一個[.o]文件後都寫上類似的命令,因為,我們的make會自動識别,并自己推導命令。 隻要make看到一個[.o]文件,它就會自動的把[.c]文件加在依賴關系中,如果make找到一個whatever.o,那麼whatever.c,就會是whatever.o的依賴文件。并且 cc -c whatever.c 也會被推導出來,于是,我們的makefile再也不用寫得這麼複雜。

objects = fun1.o fun2.o main.o test:$(objects) gcc $(objects) -o test fun2.o:fun2.c fun1.o:fun1.c main.o:main.c .PHONY:clean clean rm *.o test

這種方法,也就是make的“隐晦規則”。上面文件内容中,“.PHONY”表示,clean是個僞目标文件。

總結: “<n>.o”的目标的依賴目标會自動推導為“<n>.c”,并且其生成命令是 “**$(CC) -c $(CPPFLAGS) $(CFLAGS)**”

linux怎麼新建makefile文件(LinuxC基礎)23

  • 隐含規則2: 鍊接0bject文件的隐含規則

“<n>” 目标依賴于“<n>.o”,通過運行C的編譯器來運行鍊接程序生成(一般是“1d”),其生成命令是:“$(CC)$(LDFLAGS) <n>.0 $(LOADLIBES)$(LDLIBS)”。這個規則對于隻有一個源文件的工程有效,同時也對多個 Object文件(由不同的源文件生成)的也有效。例如如下

規則: x : x.o y.o z.o 并且“ x.c ”、“ y.c ”和 “ z.c ” 都存在時,隐含規則将執行如下命令:cc -c x.c -o x.o cc -c y.c -o y.o cc -c z.c -o z.o cc x.o y.o z.o -o x

如果沒有一個源文件(如上例中的x.c)和你的目标名字(如上例中的x)相關聯,那麼,你最好寫出自己的生成規則,不然,隐含規則會報錯的

fun1 : fun1.o fun2.o main.o

這樣就不會報錯。

Makefile 總述

Makefile裡主要包含了五個東西:顯式規則、隐晦規則、變量定義、文件指示和注釋。

顯式規則。顯式規則說明了,如何生成一個或多的的目标文件。這是由Makefile的書寫者明顯指出,要生成的文件,文件的依賴文件,生成的命令。

隐晦規則。由于我們的make有自動推導的功能,所以隐晦的規則可以讓我們比較粗糙地簡略地書寫Makefile,這是由make所支持的。

變量的定義。在Makefile中我們要定義一系列的變量,變量一般都是字符串,這個有點你C語言中的宏,當Makefile被執行時,其中的變量都會被擴展到相應的引用位置上。

文件指示。其包括了三個部分,一個是在一個Makefile中引用另一個Makefile,就像C語言中的include一樣;另一個是指根據某些情況指定Makefile中的有效部分,就像C語言中的預編譯#if一樣;還有就是定義一個多行的命令。有關這一部分的内容,我會在後續的部分中講述。

注釋。Makefile中隻有行注釋,和UNIX的Shell腳本一樣,其注釋是用“#”字符,這個就像C/C 中的“//”一樣。如果你要在你的Makefile中使用“#”字符,可以用反斜框進行轉義,如:“#”。

VPATH的用法1. Makefile的 VPATH

VPATH: 虛路徑

  • 在一些大的工程中,有大量的源文件,我們通常的做法是把這許多的源文件分類,并存放在==不同的目錄中==。所以,當make需要去找尋文件的依賴關系時,你可以在文件前加上路徑,但 ==最好的方法是把一個路徑告訴make,讓make在自動去找==。
  • Makefile文件中的特殊變量“VPATH”就是完成這個功能的,如果沒有指明這個變量,make隻會在當前的目錄中去找尋依賴文件和目标文件。如果定義了這個變量,那麼,make就會在當當前目錄找不到的情況下,到所指定的目錄中去找尋文件了。
  • VPATH = src:../headers
  • 上面的的定義指定兩個目錄,“src”和“../headers”,make會按照這個順序進行搜索。目錄由“冒号”分隔。(當然,當前目錄永遠是最高優先搜索的地方)

另一個設置文件搜索路徑的方法是使用make的“vpath”關鍵字(注意,它是全小寫的),這不是變量,這是一個make的關鍵字,這和上面提到的那個VPATH變量很類似,但是它更為靈活。它可以指定不同的文件在不同的搜索目錄中。這是一個很靈活的功能。它的使用方法有三種:

1. vpath < pattern> < directories> //為符合模式< pattern>的文件指定搜索目錄<directories>。 2. vpath < pattern> //清除符合模式< pattern>的文件的搜索目錄。 3. vpath //清除所有已被設置好了的文件搜索目錄。

vapth使用方法中的< pattern>需要包含“%”字符。“%”的意思是匹配零或若幹字符,例如,“%.h”表示所有以“.h”結尾的文件。< pattern>指定了要搜索的文件集,而< directories>則指定了的文件集的搜索的目錄。例如:

vpath %.h ../headers

該語句表示,要求make在“../headers”目錄下搜索所有以“.h”結尾的文件。(如果某文件在當前目錄沒有找到的話)

我們可以連續地使用vpath語句,以指定不同搜索策略。如果連續的vpath語句中出現了相同的< pattern>,或是被重複了的< pattern>,那麼,make會按照vpath語句的先後順序來執行搜索。如:

vpath %.c foo

vpath % blish

vpath %.c bar

其表示“.c”結尾的文件,先在“foo”目錄,然後是“blish”,最後是“bar”目錄。

vpath %.c foo:bar

vpath % blish 而上面的語句則表示“.c”結尾的文件,先在“foo”目錄,然後是“bar”目錄,最後才是“blish”目錄。

分布不同路徑的程序。 在不同的目錄下寫了程序,如果不用VPATH如何去寫makefile呢?

linux怎麼新建makefile文件(LinuxC基礎)24

linux怎麼新建makefile文件(LinuxC基礎)25

在這裡插入圖片描述

linux怎麼新建makefile文件(LinuxC基礎)26

linux怎麼新建makefile文件(LinuxC基礎)27

==不同文件我們怎麼删除不想要的中間文件呢?== 通過指令:find ./ -name "*.o",找到所有.o的文件 我們輸入指令:find ./ -name "*.o" -exec rm {} \;,意思為,我把找到的結果拿來給rm去删除,

linux怎麼新建makefile文件(LinuxC基礎)28

這樣.o文件就在不同的目錄下删除了

linux怎麼新建makefile文件(LinuxC基礎)29

2. Makefile 中 VPATH使用

linux怎麼新建makefile文件(LinuxC基礎)30

linux怎麼新建makefile文件(LinuxC基礎)31

linux怎麼新建makefile文件(LinuxC基礎)32

嵌套的Makefile

每個文件都一個自己的makefile,makefile互相調用子makefile 案例:

我們看到有許多目錄和外部makefile,在每個目錄下有.c程序和子makefile

linux怎麼新建makefile文件(LinuxC基礎)33

在第一個目錄f1中的子makefile是把f1.c 生成為f1.o放到了OBJS_DIR obj中

linux怎麼新建makefile文件(LinuxC基礎)34

linux怎麼新建makefile文件(LinuxC基礎)35

  • 我們注意到有一句@echo $(SUBDIRS)
  • @(RM)并不是我們自己定義的變量,那它是從哪裡來的呢? 就是make -f
  • make -C $@
  • export CC OBJS BIN OBJS_DIR BIN_DIR :是讓子makefile也可以調用
,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved