壯族小伙看代碼喜歡運行起來看,什么源代碼都先想辦法跑起來再仔細研究。最近遇到困難:網上流出的天龍代碼是VS2010的工程,編譯沒問題但運行的時候缺少FoxScriptEngine.dll的動態庫,翻了一下工程發現只有FoxScript.h的頭文件,沒有對應的實現。lua腳本這塊的載入運行需要這個動態庫,沒有這個動態庫程序沒法運行。靜態的看代碼那個苦呀,於是在網上一通亂找,找到linux可運行的版本以及資源。接下來要做的就是把VS2010的工程換成Makefile。
平時都是手工寫Makefile,用的都是最簡單的功能,電腦上的《GNU make中文手冊》也沒看,渾渾噩噩,每次Makefile有問題都不知道怎么解決。無數次羡慕開源項目的編譯安裝方法:./configure make && make install。痛定思痛學習了一下如何使用GNU autotools工具。
本文主要參考《例解autoconf和automake生成Makefile文件》,使用autotool工具制作Makefile的基本流程如下圖:

圖 1-1
automake支持三種目錄層次[1]:flat、shallow和deep
(1) flat指的是所有文件都位於同一個目錄中。
(2) shallow指的是主要的源代碼都儲存在頂層目錄,其他各個部分則儲存在子目錄中。
(3) deep指的是所有源代碼都被儲存在子目錄中;頂層目錄主要包含配置信息。
一、簡單例子
下面寫一個helloworld來練練手:
1. helloworld.cpp
1: #include <stdio.h>
2: int main()
3: {
4: printf(“Hello World!\n”);
5: return 0;
6: }
2. 創建Makefile.am文件,寫入以下內容:
1: bin_PROGRAMS = hello
2: hello_SOURCES = helloworld.cpp
3.使用autoscan掃描目錄,將生成的configure.scan文件更名為configure.in或者configure.ac,主要內容可以簡略為:
1: AC_INIT(helloworld.cpp)
2: AM_INIT_AUTOMAKE(helloworld, 1.0)
3: AC_PROG_CXX
4: AC_OUTPUT(Makefile)
4. 執行aclocal命令,aclocal會根據configure.in的內容(主要是其中用到的m4宏)到指定的路徑下的m4宏定義文件中提取用到的宏定義,寫到aclocal.m4文件中,供automake使用。AC_PROG_CXX就定義在m4文件中。
5. 執行autoconf命令,生成configure腳本
6. 執行automake --add-missing --foreign,命令會根據Makefile.am及m4文件生成對應的Makefile.in。
7. 執行./configure,生成Makefile
8. make(make install安裝,make dist生成安裝包)
八個主要步驟清晰明確,寫Makefile變成一件愉快的事情。
二、創建天龍linux下的工程
天龍的目錄結構如下,Common目錄放置一些公用代碼和協議處理的cpp,Server目錄下五個工程對應五個可執行文件都是服務器端運行時需要啟動的。可以看到這樣的目錄結構適合使用automake的deep層次模式。
在linux下創建天龍代碼的工程時,一度想把Common目錄下所有cpp文件編成一個統一的靜態庫,做着做着發現這事不靠譜,五百多個cpp文件混在一堆,但功能並不是完全獨立的,一些文件需要用到Server目錄下的文件(這個Common目錄不是真正意義上的common)。
接下來只能從原有的VS2010工程文件入手為Server下的目錄每個工程做一個Makefile,需要用到Common目錄下文件時,用相對路徑指向Common即可。以BillingServer為例查看virtualstudio的工程文件Billing.vcproj
1: <Files>
2: <Filter
3: Name="Base"
4: >
5: <File
6: RelativePath="..\..\..\Common\ServerBase\Config.cpp"
7: >
8: </File>
9: <File
10: RelativePath="..\..\..\Common\ServerBase\Config.h"
11: >
12: </File>
13: <File
14: RelativePath="..\..\..\Common\ServerBase\File.cpp"
15: >
16: </File>
17: <File
18: RelativePath="..\..\..\Common\ServerBase\File.h"
19: >
20: </File>
21: <File
22: RelativePath="..\..\..\Common\ServerBase\Ini.cpp"
23: >
24: </File>
25:
26: ...............
27:
28: </Files>
.vcproj文件的可讀性還是很強的,可以很快提取出工程中所以依賴的文件(感謝萬能的vim)。在編寫Makefile.am文件的時候注意下面幾項:
1: bin_PROGRAMS = billing
2: INCLUDES = -Ihttp://www.cnblogs.com/../Common/ ........
3: billing_CPPFLAGS = -D__LINUX__ -D__linux
4: billing_LDADD = -lodbc
5: billing_LDFLAGS = -L/home/project/tlbb/unixODBC/lib
6:
7: billing_SOURCES = ./stdafx.cpp http://www.cnblogs.com/../Common/ServerBase/Config.cpp ...........
在billing_SOURCES項把所有依賴的cpp都添加好后,使用automake生成Makefile.in,然后./configure, make就可以編譯。(odbc的sqltypes.h文件由於typedef沖突,注釋掉好幾行才編譯通過的)
編譯完成后如果沒錯會在本地目錄生成可執行文件billing,運行之,發現晚上找到的資源里的ini配置文件好多項都已經變化了,只好挨個添加修改,最后總算運行起來。(數據庫的版本也對不上,現在只能跑起來玩玩,沒有數據)
References:
[1] http://www.ibm.com/developerworks/cn/linux/l-makefile/
聲明:本文所使用(涉及)的代碼均從互聯網上獲得,本人沒有傳播及利用其獲取任何商業利益。

