目錄
一,認識 make/makefile
二,實例代碼
1,依賴關系
2,原理
3,項目清理
4,測試講解
三,Linux第一個小程序-進度條
game.h
game.c
test.c
程序詳解
?
一,認識 make/makefile
會不會寫makefile,從一個側面說明了一個人是否具備完成大型工程的能力
一個工程中的源文件不計數,其按類型、功能、模塊分別放在若干個目錄中,makefile定義了一系列的 規則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進行更復雜的功能操作
makefile 帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。
make是一個命令工具,是一個解釋makefile中指令的命令工具,一般來說,大多數的IDE都有這個命 令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可見,makefile都成為了一 種在工程方面的編譯方法。
make是一條命令,makefile是一個文件,兩個搭配使用,完成項目自動化構建。
二,實例代碼
一般我們形成可執行程序都是這樣的:
今天我們用make/makefile 來實施;
創建文件的名稱一定要是 makefile 第一個字母大小寫都可以;
像這樣直接輸入指令 make 可執行文件就會自動形成,非常的方便;
1,依賴關系
上面的文件 mybin,它依賴 game.o
game.o , 它依賴 game.s
game.s , 它依賴 game.i
game.i , 它依賴 game.c
2,原理
make是如何工作的,在默認的方式下,也就是我們只輸入make命令。那么
1,make 會在當前目錄下找名字叫 “Makefile” 或 “makefile” 的文件。
2,如果找到,它會找文件中的第一個目標文件(target),在上面的例子中,他會找到“mybin”這個文件, 并把這個文件作為最終的目標文件。
3,如果mybin文件不存在,或是mybin所依賴的后面的game.o文件的文件修改時間要比mybin這? 個文件新(可以用 touch 測試),那么他就會執行后面所定義的命令來生成mybin這個文件。
4,如果如果hello所依賴的game.o文件不存在,那么make會在當前文件中找目標為game.o文件的依賴性,如果找到則再根據那一個規則生成game.o文件。(這有點像一個堆棧的過程)所依賴的game.o文件不存在,那么make會在當前文件中找目標為game.o文件的依賴性,如果找到則再根據那一個規則生成game.o文件。(這有點像一個堆棧的過程)
5,當然,你的C文件和H文件是存在的啦,于是make會生成game.o 文件,然后再用 game.o 文件聲明 make的終極任務,也就是執行文件mybin了。
6,這就是整個make的依賴性,make會一層又一層地去找文件的依賴關系,直到最終編譯出第一個目標文件。
7,在找尋的過程中,如果出現錯誤,比如最后被依賴的文件找不到,那么make就會直接退出,并報錯, 而對于所定義的命令的錯誤,或是編譯不成功,make根本不理。
8,make只管文件的依賴性,即,如果在我找了依賴關系之后,冒號后面的文件還是不在,那么對不起, 我就不工作啦。
3,項目清理
工程是需要被清理的
像clean這種,沒有被第一個目標文件直接或間接關聯,那么它后面所定義的命令將不會被自動執行, 不過,我們可以顯示要make執行。即命令——“make clean”,以此來清除所有的目標文件,以便重編譯。
但是一般我們這種clean的目標文件,我們將它設置為偽目標,用 .PHONY 修飾,偽目標的特性是,總是被執行的。
可以將我們的 mybin 目標文件聲明成偽目標,測試一下。
4,測試講解
以上都是面向于基層的原理,字有點多適合深度研究,現在我們通俗一點;
mybin:game.c 是依賴關系,mybin 是game.c 形成的可執行文件,但是具體要怎么實現呢,這就要 依賴方法了,gcc game.c -o mybin ,就是依賴方法;
而且 gcc game.c -o mybin 也可以寫成 gcc -o $@? $^ ;
$@ 表示 mybin ,$^ 表示 game.c
也是一樣的效果,而且更加方便,建議使用后者;
.PHONY 是講文件修飾成 偽文件,偽文件的特性是總是被執行;
最好放在下面給 clean ,這樣程序就是總是被執行清理了;
當我們總是執行 make ,后面的就失效了,因為 mybin 的修改時間比 game.c 的修改時間慢;
上面紅線畫的就是 修改時間,mybin 比 game.c 慢所以 make 不會被執行;
我們修改一下 game.c 文件看看;
剛修改完,game.c 的時間比 mybin 慢;
所以可以運行 make ,再次打開的時候 mybin 文件的修改時間就比 game.c 長了,make 也就執行不了了;
我們也可以用 touch 來刷新文件的修改時間;
如果將我們的 mybin 目標文件聲明成偽目標,測試一下。
這樣make 每次都會被執行了,但是不推薦這樣使用,因為這本身就是對的,沒有修改就不要執行嘛,沒有毛病,現在我們的文件小每次執行都沒有關系,如果我們文件非常大的時候,每次都執行的話就非常消耗時間了;
clean 是用來清理文件的,用的話是make clean;
直接一鍵清理文件;
哦對了,還有一個就是我們使用的 make,他為什么就執行 mybin,而不執行 clean 呢?
指令make 是從上往下執行的;
將他們換個順序;
那我們執行 make 的時候就是執行 clean 了,執行 make mybin 的時候就是形成可執行文件 mybin 了,這個是從上往下的,順序不影響;
三,Linux第一個小程序-進度條
開始整硬活了兄弟們;
先把剛開始需要的文件準備好;
game.h
#include<stdio.h>
#include<time.h>
#include<unistd.h>void game(double rate);
void download();
game.c
#include"game.h"
#define MAX 1024*1024*1024char* buff = "|/-\\";
int i = 0;
char arr[102] = { 0 };
void game(double rate)
{if (rate <= 1.0){arr[0] = '=';}printf("[%-100s][%.1lf%%][%c]\r", arr, rate, buff[i % 4]);fflush(stdout);arr[(int)rate] = '=';if (rate< 99.0){arr[(int)rate+1] = '>';}i++;
}void download()
{srand(time(NULL)^1023);int max = MAX;int cnt = 0;double rate = 0;while (rate<100.0){cnt+= rand() % (1024*1024);rate = ((cnt*1.0)/max)* 100;if (rate > 100){rate = 100;}game(rate);usleep(50000);}
}
test.c
#include"game.h"int main()
{download();return 0;
}
程序詳解
這個程序是做了一個內存進度條,讓 MAX 為需要下載的內存大小,然后 cnt 為已經下載的部分,rate 為已經下載的百分比,然后傳給 game 函數進行進度條的運行,game 函數,根據 rete 的大小進行百分比輸出,等于號也是,還有翻轉的數組來判斷程序有沒有卡頓,之后再等于號后面加上 > 進行輸出點綴,直到 100% ,退出程序;