閱讀GNU-Make相關的知識。

嘗試了解Python-Solvespace的Makefile運作方式。

Makefile簡介 :

閱讀資料來源:

  1. http://mropengate.blogspot.tw/2015/06/makefile-makefile.html

  2. http://jeff71321.pixnet.net/blog/post/92143030-makefile%E6%95%99%E5%AD%B8(%E4%B8%80)

GNU-Make在開發者工具包有著極其重要的地位,最大的好處就是「自動化編譯」。

相較於要用shell來執行編譯的Script,GNU-Make可以只針對部分內容作測試,相當有自由度。

make.exe依靠著Makefile的設定來將整個專案按照原作者的設定,編譯成可執行文件或是連結庫。

也因為如此,只要是願意加入專案協同的工程師,裝好原作者使用的工具,無論使用哪個編譯程式,就能利用一個make命令,從頭到尾將專案編譯好進行測試或除錯。


注意事項 :

GNU-Make在閱讀一份Makefile時有幾個重點。

首先若直接執行make指令,會尋找當前目錄中叫"Makefile"或"makefile"的文件。若Makefile並非這兩個名稱(亦能自訂附檔名),可以加上"-f"參數指定Makefile的名稱。

Makefile中包含了

1.顯式規則:說明如何生成一個或多個文件,有使用工具、依賴文件、使用參數等等。

2.隱晦規則:不太瞭解這個功能,大約是利用自動推導原則,可以比較簡略地寫定義,篩選檔案。

3.變量:自訂參數的功能,能自由更改位置或目標名稱、使用工具和參數等等。

4.文件指示:Makefile之間是可以互相溝通的,也可以透過情況作出判斷。

5.註解:Makefile的註解符號是"#",如果要使用井字符號,必須使用反斜線"#"。

特別注意,在Makefile中,命令項的起始一定要使用Tab縮排,不可使用空白字元。

一般撰寫程式的編譯器都能檢視空白字元的類型。

SciTE:View -> Whitespace

Netbeams:View -> Show Non-printable Characters

在此會發現Tab(→)和空白字元(.)的差異。

不過某些像是SciTE的編譯器,在按下Tab鍵時,會幫使用者轉換成四個空白字元,甚至會用空白字元補齊縮排,所以使用上需要注意。

Makefile中的目錄分隔號是斜線"/",換行閱讀符號是反斜線"\"。

GNU-Make在執行途中遇到錯誤就會停止並跳出,所以必須要整個Makefile和編譯過程都沒有干擾執行問題,才會編譯完畢。


主要規則 :

語法的結構就是目標文件(未生成)後方加上冒號和空格,接著同一行中必須接上會利用到的檔案名稱(不包含工具和include參數的項目)。

第二行是寫下如何產生目標文件的命令。

一個項目中有多個檔案時會用一個空白字元分隔。換行時如果想縮排以便閱讀,必須使用空白字元縮排,不然Tab起始的項目都會視為命令。

而如果命令不能執行時就會中斷操作。

Makefile中的參數定義和大部分的語言雷同。不過為了明顯標示,大部分使用者習慣大寫字母。

定義項目後,使用"$( )"符號括住來使用變數。變數可以是目錄位置、命令名稱、參數名稱,亦有如"$$(basename $$(notdir $$@))"內定的用法。


編譯結果 :

途中用Netbeams作輔助檢查檔案關聯性和編寫文件,並make專案。

不過用cmd下指令也是可行。只是直接打make會用到MinGW的make,必須先指定MSYS的make。

Python-Solvespace中的Makefile編寫有一些小缺漏,是Tab和空白字元的問題,後來改正就沒問題了。

不過後來在Netbeams編譯外層"Solvespace"時出現了一些問題:

檢查了一下,似乎中間的檔案"$(SRFOBJS)"找不到?而"$(SRFOBJS)"的檔案是從"srf\$(@B).cpp"和"$(HEADERS)"產生的。

其中"srf\$(@B).cpp"應該就是取下所有\srf資料夾的cpp檔案,配上標頭檔後生成obj檔。途中不知道什麼原因obj檔沒有產生,所以才會無法找到?

但是只編譯exposed資料夾的Makefile時又有這個問題:

上網檢查了一下這段的用途是編碼對應,可是語法照常來講應該沒錯才是。

而且後面對應的檔案導入時都出錯,所以就停止了。


Makefile和cmake的CMakelist.txt一樣都是工程師自己要創建的,所以又是一項工程,不過除了一些內定代號,其他都滿好理解的。

找了一下Python-Solvespace相關的網站,但是內容都好少。不過在Github的說明已經滿詳盡了,只是倉儲內的資料時間有點久遠,所以要花些時間偵錯。


Comments

comments powered by Disqus