原始碼編譯安裝的原理

probe發表於2020-09-17

Linux上幾乎所有的軟體都經過了 ,因此幾乎所有的軟體都會提供原始碼。 
而一個軟體要在Linux上執行,必須是二進位制檔案,因此當我們拿到軟體原始碼後,需要將它編譯成二進位制檔案才能在Linux上執行。


軟體編譯過程

將原始碼編譯成可供Linux執行的二進位制檔案一共需要兩步: 
1. 使用gcc編譯器將原始碼編譯成目標檔案 
2. 再次使用gcc編譯器將目標檔案連結成二進位制檔案

這過程看似簡單,實則不然。一個軟體的原始碼往往被封裝在多個原始檔中,此外這些檔案有錯綜複雜的依賴關係,編譯需要嚴格按照指定的順序進行,這無疑增加了編譯的難度。好在make命令可以幫助我們簡化編譯過程。

整個編譯過程被濃縮在Makefile檔案中( 告訴make命令需要怎麼去編譯和連結程式),當執行make命令時,make會去當前目錄中尋找Makefile檔案,並根據該檔案中的要求完成整個編譯過程。

而Makefile檔案由configure命令產生。當執行configure命令時,configure會根據當前系統環境動態生成一個適合本系統的Makefile檔案,供make命令使用。


Linux原始碼安裝步驟

  1. 獲取原始碼 
    將軟體的原始碼下載至/usr/local/,並解壓。
  2. 檢視INSTALL與README檔案 
    解壓後檢視INSTALL與README檔案,這兩個檔案中詳細介紹了本軟體的安裝方法和注意事項
  3. 建立Makefile檔案 
    執行configure命令,生成Makefile檔案
  4. 編譯 
    執行make clean;make命令將原始碼編譯成二進位制檔案。 
    PS:make clean命令用來清除上一次編譯生成的目標檔案。這個步驟可有可無,但為了確保編譯的成功,還是加上為好。為了防止由於軟體中含有殘留的目標檔案導致編譯失敗,也許之前有人安裝過呢,在重新安裝之前還是清理一下比較好。
  5. 安裝 
    執行make install命令將上一步編譯好的二進位制檔案安裝到指定的目錄中去。


安裝演示

1.進入/usr/local/,並建立memcached目錄:

cd /usr/local/   mkdir memcached

2.下載memcached的原始碼

wget 

3.解壓原始碼

tar -zxvf memcached-1.4.29.tar.gz

4.執行configure,生成Makefile檔案

./configure --prefix=/usr/local/memcached/

此時當前目錄下將會生成一個Makefile檔案。

  • 注意:--prefix引數指定軟體安裝目錄。當執行make install命令時,會將軟體安裝在此路徑中。

5.執行make,從Makefile中讀取指令,編譯原始碼

make clean; make

此時make會讀取Makefile檔案,將原始碼編譯成二進位制檔案,並存放在當前目錄下。

6.執行make install,將軟體安裝至指定目錄

make install

此時二進位制檔案會被安裝到先前 configure prefix 引數設定的路徑中去。 
安裝完成!


cmake命令

cmake就是一個與make同級別的編譯工具,只不過它依靠的不是Makefile作為編譯規則,而是根據CMakeLists.txt來編譯的。
CMake是一個比make更高階的編譯配置工具,它可以根據不同平臺、不同的編譯器,透過編寫CMakeLists.txt,可以控制生成的Makefile,從而控制編譯過程。
CMake自動生成的Makefile不僅可以透過make命令構建專案生成目標檔案,還支援安裝(make install)、測試安裝的程式是否能正確執行(make test,或者ctest)、生成當前平臺的安裝包(make package)、生成原始碼包(make package_source)、產生Dashboard顯示資料並上傳等高階功能,只要在CMakeLists.txt中簡單配置,就可以完成很多複雜的功能,包括寫測試用例。
如果有巢狀目錄,子目錄下可以有自己的CMakeLists.txt

原始碼編譯安裝的原理a) 編寫 CmakeLists.txt

b) 執行命令"cmake PATH"或者"ccmake PATH"生成 Makefile ( PATH 是 CMakeLists.txt 所在的目錄 )

[root@localhost mariadb-10.0.34]# cmake . -LH # "."表示編譯當前目錄,列印引數選項

列子:
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql/ -DMYSQL_DATADIR=/usr/local/mysql/data/ -DEFAULT_CHARSET=utf8 -DMYSQL_TCP_PORT=3306 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DWITH_DEBUG=0 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DMYSQL_USER=mysql

上述引數:
-DCMAKE_INSTALL_PREFIX= /usr/local/mysql 準備安裝到哪裡
-DEFAULT_CHARSET=utf8 預設的字符集
-DMYSQL_TCP_PORT=3306 資料庫的監聽埠
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock 本機連回資料庫的unix socket
-DWITH_DEBUG=0 關閉debug模式
-DWITH_INNOBASE_STORAGE_ENGINE=1 開啟innodb引擎


1. 什麼是“Linux函式庫”?

執行在Linux上的軟體時常會呼叫Linux核心的某些功能或其他軟體的某些功能,那麼這些被軟體呼叫的功能稱為Linux的函式庫。軟體自身的函式庫存放在軟體安裝目錄下的lib中,而Linux的函式庫存放在/usr/lib和/usr/include中,linux核心的函式庫存放在/lib/modules中。

2. Linux函式庫的分類

Linux函式庫分為靜態函式庫 和 動態函式庫。 
1. 靜態函式庫 
- 副檔名:xxx.a 
- 在編譯時會被整合到軟體的二進位制檔案中去。因此擁有靜態函式庫的軟體較為龐大。而且當系統的函式庫更新時,引用該函式庫的所有軟體都需要重新編譯才能正常使用。這是非常麻煩的!但擁有靜態函式庫的軟體可以獨立執行。 
2. 動態函式庫 
- 副檔名:xxx.so 
- 在編譯時僅僅將函式庫的路徑整合到軟體的二進位制檔案中去。由於軟體中包含的是函式庫的路徑,因此該軟體無法獨立執行,且函式庫的路徑不能發生變化,一旦變化,該軟體將無法找到函式庫,從而無法執行!這是動態函式庫的最大缺點。但當動態函式庫更新時,軟體無需重新編譯,因此更新較為方便,這是動態函式庫的最大優點。

目前大部分軟體均使用動態函式庫,就是因為動態函式庫在更新時體現出的優勢。

3. 提升函式庫讀取效率

軟體在執行某些功能時需要呼叫函式庫中的函式,而函式庫又是以檔案的形式存放在外設上。那麼如果將函式庫存放在記憶體中,那麼將會大大提升讀取速度。在Linux中,可以使用ldconfig命令將指定的函式庫載入進記憶體。具體步驟如下: 
1. 在/etc/ld.so.conf中設定需要載入進記憶體的函式庫 
2. 使用ldconfig命令使配置生效

4. 檢視軟體的動態函式庫

使用ldd命令即可檢視指定軟體所使用的全部動態函式庫。

[root@iZ231tx6fm4Z tomcat]# ldd /usr/bin/passwd
        linux-vdso.so.1 (0x00007fff3adff000)
        libuser.so.1 => /usr/lib64/libuser.so.1 (0x00007f6428bd5000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f642899d000)
        libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f6428751000)
        libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f642854e000)
        libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f6428249000)
        libpopt.so.0 => /lib64/libpopt.so.0 (0x00007f6428040000)
        libpam_misc.so.0 => /lib64/libpam_misc.so.0 (0x00007f6427e3c000)
        libaudit.so.1 => /lib64/libaudit.so.1 (0x00007f6427c20000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f6427a01000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f642765b000)
        libpam.so.0 => /lib64/libpam.so.0 (0x00007f642744d000)
        libgthread-2.0.so.0 => /lib64/libgthread-2.0.so.0 (0x00007f6427249000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f642702e000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6426e11000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f6426c0d000)        /lib64/ld-linux-x86-64.so.2 (0x00007f6428dee000)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69980869/viewspace-2722100/,如需轉載,請註明出處,否則將追究法律責任。

相關文章