2016年12月13日 星期二

Makefile教學

有於編譯opencv c++的檔案指令太長了記不起來=口=
只好來使用Makefile


1.什麼是Makefile?

很多Winodws的程序員都不知道這個東西,因為那些 Windows的IDE都為你做了這個工作,但我覺得要作一個好的和professional的程序員,makefile還是要懂。這就好像現在有這麼多的HTML的編輯器,但如果你想成為一個專業人士,你還是要了解HTML的標識的含義。特別在Unix下的軟體編譯,你就不能不自己寫makefile 了,會不會寫makefile,從一個側面說明了一個人是否具備完成大型專案的能力。

因為,makefile關係到了整個專案的編譯規則。一個專案中的原始碼檔案不計數,其按類型、功能、分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些檔案需要先編譯,哪些檔案需要後編譯,哪些檔案需要重新編譯,甚至於進行更複雜的功能操作,因為makefile就像一個Shell腳本一樣,其中也可以執行作業系統的命令。


2.關於程序的編譯和連結

於程序編譯的一些規範和方法,一般來說,無論是C、C++,首先要把原始碼檔案編譯成中間程式碼檔案,在Windows下也就是 .obj 檔案,UNIX下是 .o 檔案,即 Object File,這個動作叫做編譯(compile)。然後再把大量的Object File合成執行檔案,這個動作叫作連結(link)

編譯時,編譯器需要的是語法的正確,函數與變量的宣告的正確。對於後者,通常是你需要告訴編譯器頭檔案的所在位置(頭檔案中應該只是宣告,而定義應該放在C/C++檔案中),只要所有的語法正確,編譯器就可以編譯出中間目標檔案。一般來說,每個原始碼檔案都應該對應於一個中間目標檔案(O檔案或是OBJ檔案)。

連結時,主要是連結函數和全域變量,所以,我們可以使用這些中間目標檔案(O檔案或是OBJ檔案)來連結我們的應用程序。連結器並不管函數所在的原始碼檔案,只管函數的中間目標檔案(Object File),在大多數時候,由於原始碼檔案太多,編譯生成的中間目標檔案太多,而在連結時需要明顯地指出中間目標檔案名,這對於編譯很不方便,所以,我們要給中間目標檔案整理成套件,在Windows下這種套件叫「函式庫檔案」(Library File),也就是 .lib 檔案,在UNIX下,是Archive File,也就是 .a 檔案。

總結一下,原始碼檔案首先會生成中間目標檔案,再由中間目標檔案生成執行檔案。在編譯時,編譯器只檢測程序語法,和函數、變量是否被宣告。如果函數未被宣告,編譯器會給出一個警告,但可以生成Object File。而在連結程式時,連結器會在所有的Object File中找尋函數的實現,如果找不到,那到就會報連結錯誤碼(Linker Error),在VC下,這種錯誤一般是:Link 2001錯誤,意思說是說,連結器未能找到函數的實現。你需要指定函數的Object File.

3.Makefile 介紹

make命令執行時,需要一個 Makefile 檔案,以告訴make命令需要怎麼樣的去編譯和連結程式。

3.1Makefile的規則


在講述這個Makefile之前,還是讓我們先來粗略地看一看Makefile的規則。



    target ... : prerequisites ...

            command
            ...
            ...

    target也就是一個目標檔案,可以是Object File,也可以是執行檔案。還可以是一個標籤(Label),對於標籤這種特性,在後續的「偽目標」章節中會有敘述。

    prerequisites就是,要生成那個target所需要的檔案或是目標。

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

這是一個檔案的依賴關係,也就是說,target這一個或多個的目標檔案依賴於 prerequisites中的檔案,其生成規則定義在command中。說白一點就是說,prerequisites中如果有一個以上的檔案比 target檔案要新的話,command所定義的命令就會被執行。這就是Makefile的規則。也就是Makefile中最核心的內容。

來個簡單的範例吧

04_video_to_frame: 04_video_to_frame.cpp
g++ 04_video_to_frame.cpp -o 04_video_to_frame `pkg-config --cflags --libs opencv`


Makefile還很博大精深有興趣的大大可以去下面連結,寫的很好

Reference:

http://blog.xuite.net/jack_sb/2312/16268132-Makefile

沒有留言:

張貼留言