97人妻精品一区二区三区软件,人妻偷拍在线,插丝袜美女小穴视频,美女午夜福利在线

      • <i id="89dc3"></i>
        當(dāng)前位置: 首頁 >應(yīng)用方案 >技術(shù)應(yīng)用 >

        Makefile基礎(chǔ)知識(shí)詳解

        這篇文章并不是介紹怎編寫Makefile, 是理解 “基于目標(biāo)分層” 的方式理解來理解一個(gè)工具,定義一個(gè)設(shè)計(jì)或者部署一套代碼的。

        關(guān)于程序編譯

        說明一下,Makefile最初是用來解決C語言的編譯問題的,所以和C的關(guān)系特別密切,但并不是說Makefile只能用來解決C的編譯問題。你用來處理Java一點(diǎn)問題沒有,但對(duì)于Java,顯然ant比Makefile處理得更好。但是那是細(xì)節(jié),你理解了Makefile,理解ant就沒有什么難度了。Makefile本身的格式也不是什么標(biāo)準(zhǔn),不同的make工具對(duì)Makefile本身怎么寫細(xì)節(jié)是不一樣的。本文介紹的是這個(gè)工具的思想原理,細(xì)節(jié)你要自己看對(duì)應(yīng)的手冊(cè)。

        Makefile解決的是編譯的問題。編譯有什么問題呢?比如說,你有3個(gè)C文件。foo.c, bar.c, main.c三個(gè)C文件,你要編譯成一個(gè)app.exe,則會(huì)有這樣的命令:

        gcc -Wall -c foo.c -o foo.o

        gcc -Wall -c bar.c -o bar.o

        gcc -Wall -c main.c -o main.o

        gcc main.o foo.o bar.o -lpthread -o app.exe

        Unix程序員的慣例,凡是要一次次重新執(zhí)行的命令,都應(yīng)該寫成腳本,變成“一個(gè)動(dòng)作”。所以,你會(huì)把上面這個(gè)命令序列寫成一個(gè)build.sh,每次編譯你只要執(zhí)行這個(gè)腳本問題就解決了。

        但是,這個(gè)腳本依然有問題,假設(shè)我修改了foo.c,但我沒有修改bar.c和main.c,那么執(zhí)行這個(gè)腳本是很浪費(fèi)的,因?yàn)樗鼤?huì)無條件也重新編譯bar.c和main.c。

        所以,這個(gè)腳本更合理的寫法應(yīng)該是這樣的:

        [ foo.o -ot foo.c ] && gcc -Wall -c foo.c -o foo.o

        [ bar.o -ot bar.c ] && gcc -Wall -c bar.c -o bar.o

        [ main.o -ot main.o] && gcc -Wall -c main.c -o main.o

        [ app.executable -ot main.o ] && [ app.executable -ot foo.o ] && [ app.executable -ot bar.o ] && gcc main.o foo.o bar.o -lpthread -o app.executable

        這很復(fù)雜是不是?同樣按Unix程序員的一般作風(fēng),如果你面對(duì)一個(gè)問題,不要嘗試重新去定義這個(gè)問題,而是看它和原來的問題相比,多出來的問題是什么,嘗試解決那個(gè)多出來的問題就好了。那么這里,多出來的問題就是文件修改時(shí)間比較。這個(gè)就是Makefile要解決的基本問題了。我們定義一種新的“腳本語言”(只是不用sh/bash/tch來解釋,而是用make來解釋),可以用很簡(jiǎn)單的方法來說明我們需要做的文件比較。這樣上面的腳本就可以寫成這個(gè)樣子了:

        foo.o: foo.c

         gcc -Wall -c foo.c -o foo.o

        bar.o: bar.c

         gcc -Wall -c bar.c -o woo.o

        main.o: main.c

         gcc -Wall -c main.c -o main.o

        app.executable: foo.o bar.o main.o

        這就是Makefile解決的原始問題。Makefile不是必須的,但它能減少你很多麻煩。

        Makefile工作原理

        Make工具需要一個(gè)稱為makefile的文件來告訴Make如何工作。一般來說,makefile告訴Make如何去編譯并且鏈接一個(gè)程序。

        Makefile工作原理

        了解以上四個(gè)原則是很有必要的,當(dāng)我們編寫makefile的時(shí)候,應(yīng)該依照以上原則編寫。

        最基本的Makefile規(guī)則語法形式如下:

        target... : prerequisites...

        recipe

        ...

        ...

        每條規(guī)則一般都由一個(gè)或者多個(gè)target(目標(biāo))、prerequisites(依賴)以及recipe(處方)組成。當(dāng)Make通過比較target和prerequisites的新舊來決定是否執(zhí)行本條規(guī)則內(nèi)的recipe,如果prerequisites比target的修改日期更新,則recipe被執(zhí)行,否則不執(zhí)行規(guī)則內(nèi)的recipe。有一條值得注意:每一個(gè)recipe前面一定要先加一個(gè)tab制表符.

        1、在目標(biāo)為edit的規(guī)則中,使用了''將一個(gè)長(zhǎng)行分隔為兩行以方便閱讀。

        2、默認(rèn)情況下,Make默認(rèn)從Makefile的第一條規(guī)則開始執(zhí)行,也就是說,當(dāng)我們?cè)趕hell中只敲下"make"并回車,make將會(huì)自動(dòng)尋址當(dāng)前目錄下的Makefile并從其中的第一條規(guī)則開始執(zhí)行。當(dāng)然,我們也可以指定開始執(zhí)行的規(guī)則

        Example: make clean //從目標(biāo)為clean的規(guī)則開始執(zhí)行

        3、在默認(rèn)開始執(zhí)行第一條規(guī)則edit時(shí),由于目標(biāo)依賴一些.o文件,而這些.o文件又有自己的更新規(guī)則,于是會(huì)先觸發(fā)執(zhí)行.o文件自己的更新規(guī)則,最后再回過頭來執(zhí)行edit。你可以將它理解為一個(gè)遞歸的過程。
        4、很明顯,由于clean這個(gè)目標(biāo)并不是任何其他目標(biāo)的依賴同時(shí)也不是第一條規(guī)則的目標(biāo),那么除非指定從這個(gè)規(guī)則開始執(zhí)行,否則這個(gè)規(guī)則永遠(yuǎn)不會(huì)被執(zhí)行;同樣的,由于clean的規(guī)則沒有任何依賴,這個(gè)規(guī)則執(zhí)行時(shí)永遠(yuǎn)不會(huì)觸發(fā)其他規(guī)則的執(zhí)行。

        編寫規(guī)則

        規(guī)則是Makefile的重要組成部分,Make通過讀取Makefile中的規(guī)則來決定如何更新工程文件。一般來說,一條規(guī)則分為三個(gè)部分:target、prerequisites和recipe.

        如果沒有特別指定從哪條規(guī)則開始執(zhí)行,Make總是執(zhí)行文件中的第一條規(guī)則,除此之外,其他規(guī)則的書寫順序?qū)?zhí)行的先后沒有影響(Make只在需要的時(shí)候執(zhí)行需要的規(guī)則,而不是按書寫順序的先后執(zhí)行).

        雖然Makefile中的第一條規(guī)則是最先執(zhí)行的,卻往往是最后執(zhí)行完的,因?yàn)榈谝粭l規(guī)則中的依賴部分經(jīng)常有自己的更新規(guī)則,而那更新規(guī)則里的依賴又有對(duì)應(yīng)的更新規(guī)則,這樣層層遞歸,第一條規(guī)則觸發(fā)了其他規(guī)則的執(zhí)行,其他規(guī)則執(zhí)行完后,再轉(zhuǎn)回第一條規(guī)則繼續(xù)執(zhí)行。我們編譯一份程序的時(shí)候也是這樣,總是先編譯每個(gè)子文件,再回過頭將它們連接起來組成程序,因此,Makefile中的第一條規(guī)則一般是用于觸發(fā)整個(gè)程序的編譯(并且第一條規(guī)則的目標(biāo)一般起名為:all,意指更新整個(gè)工程)

        toolchain=gcc

        OBJS=main.o modbus_cmd_generation.o software_crc.o

        all:$(OBJS)

           gcc modbus_cmd_generation.o main.o software_crc.o -o app

        modbus_cmd_generation.o:modbus_cmd_generation.c modbus_cmd_generation.h software_crc.o

           gcc modbus_cmd_generation.c -c

        software_crc.o:software_crc.c software_crc.h

           gcc software_crc.c -c

        main.o:main.c

           @echo

           @echo compile the toolchain: $(toolchain)

           @echo

           gcc main.c -c

        clean:

           rm $(OBJS) app

        在規(guī)則中,可以通過'$'來調(diào)用定義好的變量(如果希望真的打一個(gè)'$'而不是做變量引用,需要打"$$".

        編寫Recipes

        每條規(guī)則都有自己的recipes,其由一條或者多條shell指令組成,按照書寫順序執(zhí)行。通常執(zhí)行的結(jié)果是使得target被更新,默認(rèn)調(diào)用/bin/sh來執(zhí)行shell指令,可以手動(dòng)更改.

        也就是說,在Makefile中既有shell的指令,又有makefile自己的語句,所以說makefile遵循兩種語法:在recipes中使用shell的語法,在其他部分遵循makefile自己的語法。make對(duì)于makefile中的recipes只進(jìn)行有限的處理,然后就會(huì)丟給shell執(zhí)行。

        編寫recipes時(shí)需要注意的事項(xiàng):

        今天的分享就到這里啦,EBYTE人每一天都致力于更好的助力物聯(lián)化、智能化、自動(dòng)化的發(fā)展,提升資源利用率,更多產(chǎn)品更多資料,感興趣的小伙伴可以登錄我們的億佰特官網(wǎng)進(jìn)行了解,還有客服小姐姐在線答疑哦!


        點(diǎn)擊撥打: 億佰特官網(wǎng) 4000-330-990