Windows下程式向Linux下移植實踐2-草原之狼-搜狐部落格

chief1985發表於2008-10-15
導讀:

3.1.Makefile的編寫

       Linux下一般都是使用make工具來管理和編譯一個大的開發工程的所有原始檔,make命令執行時,需要一個 Makefile 檔案,以告訴make命令需要怎麼樣的去編譯和連結程式makefile關係到了整個工程的編譯規則。一個工程中的原始檔不計其數,其按型別、功能、模組分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些檔案需要先編譯,哪些檔案需要後編譯,哪些檔案需要重新編譯,甚至於進行更復雜的功能操作,因為makefile就像一個Shell指令碼一樣,其中也可以執行作業系統的命令。在Windows的一些IDEVC中將自動幫你生成相應的makefile,所有這些都是透明的,但在Linux下你就不能不自己寫makefile了,會不會寫makefile,從一個側面說明了一個人是否具備完成大型工程的能力。

     make工具採用增量編譯的方式,每次只編譯被改動過確實需要編譯的原始檔,每次編譯時make工具將自動判斷那些原始檔需要重新編譯,當一個工程很大而又只改動了很少的幾個原始檔,這將節省很多時間。

具體makefile檔案的編寫規則可以檢視makeman info文件(Linux命令列方式下輸入:man make info make)makefile檔案的編寫規則很多,重要的是怎樣使用最簡單的方式寫出我們自己需要的makefile檔案。

    網上也有很多介紹資料,網上有一篇很好的介紹makefile檔案編寫的文章:

下文將著重介紹使用pwlib開發庫的工程的makefile的編寫,但對於其它工程只需將common.mak檔案中對pwlib庫進行編譯的指令碼去掉也可適用。

3.1.1使用pwlib開發庫的工程的makefile的編寫

PWLibPortable Windows Library的縮寫,翻譯為輕便的Windows類庫.PWLib採用C++編寫,設計初衷是為了能讓Openh323WindowsUnixX-Windows下執行, 不過隨著一步步的完善PWLib已經被跨平臺的程式所廣泛採用。

檢視Pwlib的主目錄下/samples/hello_world/目錄下例子程式的makefile檔案可以發現該Makefile檔案內容如下:

# Simple makefile for the hello world program

PROG    = hello

SOURCES = hello.cxx

ifndef PWLIBDIR

PWLIBDIR=$(HOME)/pwlib

endif

include $(PWLIBDIR)/make/ptlib.mak

# End of Makefile

實際上就是使用了Pwlib庫的ptlib.mak檔案,編譯時需要的標頭檔案,相應的編譯選項都在ptlib.mak檔案中設定好了。

我們只需在該makefile檔案所在目錄下,命令列輸入make all命令即可編譯出程式的Release版本和Debug版本,它們分別放在當前目錄的obj_linux_x86_robj_linux_x86_d子目錄下。

下面對該makefile中的內容進行解釋:

l         PROG變數為編譯出來的程式名稱。

l         SOURCES變數儲存的為本工程要進行編譯和連結的原始檔,當有多個原始檔時可以用空格隔開,雖然檔名可以帶上路徑,但路徑在SOURCES變數中不起作用,實際編譯時對於每個檔案它將截掉最後一個”/”字元前面的所有內容只保留檔名。

l         PWLIBDIRpwlib的安裝目錄,需要設定該環境變數(若要系統每次重啟都自動設定好該環境變數則將該環境變數的設定放入/etc/profile檔案中),若沒設定好則自動以使用者主目錄/pwlib”作為pwlib的安裝目錄。

3.1.2深入分析ptlib.mak檔案

分析ptlib.mak檔案,它的內容如下;

ifndef PWLIBDIR

PWLIBDIR=$(HOME)/pwlib

endif

 

include $(PWLIBDIR)/make/unix.mak

include $(PWLIBDIR)/make/common.mak

也就是ptlib.mak包含了另兩個檔案unix.makcommon.mak檔案,其中unix.mak為定義編譯選項變數的檔案,編譯規則放在common.mak檔案中。

通過對這兩個檔案的分析,歸納出一些我們寫makefile檔案要用到的一些變數,列出如下:

l         STDCCFLAGS:所有標頭檔案的include目錄編譯選項、預編譯巨集定義選項、警告選項、優化選項都放在該變數中,各編譯選項之間用空格分開。

l         LDFLAGS:共享庫、靜態庫搜尋目錄設定放入該變數中。

l         LDLIBS:連結時要用的庫的設定放入該變數中。

l         VPATH_CXX*.cxx原始檔的搜尋路徑放入該變數中,多個目錄以空格分開,編譯時將首先在makefile所在目錄查詢相應原始檔,沒找到則按照VPATH_CXX中的路徑設定進行查詢。

l         VPATH_C*.c原始檔的搜尋路徑放入該變數中,多個目錄以空格分開,檔案查詢順序和VPATH_CXX變數的類似。

3.1.3加入新的編譯規則

common.mak檔案中只對*.c*.cxx的原始檔定義了編譯規則,而一般windows下程式大多都使用了.cpp來作為C++原始檔的字尾。

怎樣加入對於.cpp字尾的原始檔的編譯規則呢,這需要修改pwlibcommon.mak檔案,具體步驟如下:

       1.加入對於.cpp檔案的搜尋目錄設定

vpath %.cxx $(VPATH_CXX)語句後面加入如下語句:

              vpath %.cpp $(VPATH_CXX)

       2.加入對於.cpp檔案的編譯規則

              $(OBJDIR)/%.o : %.cxx語句的前面加入如下語句:

$(OBJDIR)/%.o : %.cpp

       @if [ ! -d $(OBJDIR) ] ; then mkdir -p $(OBJDIR) ; fi

       $(CPLUS) $(STDCCFLAGS) $(OPTCCFLAGS) $(CFLAGS) $(STDCXXFLAGS) -x c++ -c $< -o $@

       3.加入對於.cpp檔案的.o檔案(目的碼檔案)的命名規則

       SRC_OBJS := $(SRC_OBJS:.cxx=.o)語句後面加入如下語句

SRC_OBJS := $(SRC_OBJS:.cpp=.o)

       4.加入對於.cpp檔案的.dep檔案(依賴檔案)的命名規則

       SRC_DEPS := $(SRC_DEPS:.cxx=.dep)語句後面加入如下語句

SRC_DEPS := $(SRC_DEPS:.cpp=.dep)

       5.加入對於.cpp檔案生成.dep檔案的生成規則,加入如下語句:

       $(DEPDIR)/%.dep : %.cxx語句前面加入如下語句

$(DEPDIR)/%.dep : %.cpp

       @if [ ! -d $(DEPDIR) ] ; then mkdir -p $(DEPDIR) ; fi

       @printf %s $(OBJDIR) > $@

       $(CPLUS) $(STDCCFLAGS:-g=) -M $< >> $@


本文轉自
http://larryjiazhiqiang.blog.sohu.com/67531576.html

相關文章