之前做了一次在Android上的移植,後來多次被人問到移植的相關問題。正好做完那個項目很久了也沒有認真的把編譯的知識進行單純的整理。有很多問題沒有總結在此,是因為我沒遇到。有些知識還是需要用到的時候再學也為時未晚的。好了不羅嗦了,開始對編譯的過程進行簡單的總結吧。
linux應用程式編譯時間,需要交叉編譯GCC,它依賴於所運行系統的核心、glibc庫等。針對ARM處理器平台建立交叉編譯環境,通常是要在pc上建立目標代碼為ARM的編譯交叉連(toolchains),它可以編譯和處理Linux核心及應用程式。需要下面幾個工具鏈的源碼。
-binutils,一組編譯開發工具,包括連接器彙編器以及其他用於目標檔案和檔案的工具。它包括:
-----addr2line把程式地址轉換為檔案名稱和行號。在命令中給它一個地址和一個可執行檔名,它就使用這個可執行檔的調試資訊之處在給出的地址上是那一個檔案及行號。
------ar建立、修改、提取歸檔檔案。歸檔檔案是包含多個檔案內容的一個大檔案,其結構保證了可以恢複原始檔案內容。
------as 主要用來編譯GNU C編譯器(gcc)輸出的彙編檔案,產生目標檔案由連接器ld串連。
------c++filt ,連接器使用它來過濾c++和java符號,防止重載函數衝突。
------gprof顯示程式調用段的各種資料。
------nm列出目標檔案中的符號。
------objcopy把目標檔案中的內容複寫到另一種類型的目標檔案中。
-----objdump顯示一個或更多目標檔案的資訊。使用選項來控制其顯示的資訊。它所顯示的資訊很有用,可用它觀察到程式中全域變數和函數編譯所處的資料區段和地址。
-----ranlib產生歸檔檔案索引,並將其儲存到這個歸檔檔案中。在索引列出了歸檔檔案個成員所定義的可重分配的目標檔案。
----readelf顯示elf格式包括可執行檔的資訊。
----size列出目標檔案每一段的大小以及總體的大小。
-----strings列印某個檔案的可列印字串。這些字串最少4個字元長也可以使用選項-n設定字串的最小長度。預設情況下,它只列印目標檔案初始化和可載入段中的可列印字元;對於其他類型的檔案,它只列印整個檔案的可列印字元,這個程式對於瞭解非文字檔的內容很有協助。
----strip丟棄目標檔案中的全部或者特定符號。通常,串連完成的elf格式的檔案是沒有經過strip的,他/它包括符號表等多餘資訊,可使用這個工具讓elf檔案更精簡。通常他會在應用程式的最後發布時使用。
--gcc是linux中最重要的軟體開發工具。它是gnu c和c++的編譯器。利用gcc編譯器可同時編譯並連結c和c++來源程式。
--glibc,提供系統調用和基本函數的c庫(標準c庫)如open\mallloc、printf等。所有linux上的c程式編譯時間都需要與glibc庫連結。如果是動態串連的程式,在運行時也要用到它。另外面對一些簡單的應用,也可以使用更為精簡的C庫,如uClibc。
--glibc-linuxthreads,POSIX(Portable Operating System Interface,可移植作業系統介面)線程庫。
--linux核心源碼。
當然,你如果時間充足的情況下,完全可以試圖自己去做一個交叉編譯環境,但是本人曾試著努力過。但是花了近兩個月的時間,最終因為課程的原因還是使用了現成的交叉編譯鏈。
首先需要明確在Android中存在兩種交叉編譯鏈,一個是arm-eabi-gcc;另一個是arm-none-linux-gnueabi-gcc。通常後面的支援的庫函數相對多一點。但是Android本身使用的是前者。