當前位置:
首頁 > 最新 > 詳解如何用源代碼安裝軟體,以及如何卸載它

詳解如何用源代碼安裝軟體,以及如何卸載它

對於絕大多數的 Linux 用戶來說,第一次從源代碼中編譯和安裝一個軟體看上去像是一個入門儀式:它讓很多人感到恐懼;但是,如果你能克服困難,你將可能進入一個全新的世界,並且,如果你做到了,那麼你將成為社區中享有特權的一部分人。

-- Sylvain Leroux

本文導航

A. 在 Linux 中從源代碼開始安裝軟體

04%

第 1 步:從 GitHub 上獲取源代碼

07%

第 2 步:理解程序的構建系統

22%

第 3 步:文件系統層次化標準(FHS)

30%

B. 如果在源代碼安裝的過程中出現錯誤怎麼辦?

44%

從 Debian 9.0 中 「Stretch」 開始

46%

在 CentOS 7.0 上

56%

C. 從源代碼中對要安裝的軟體做一些改變

64%

D. 讓 shell 找到我們定製構建的軟體

74%

從 /usr/local/bin 中添加一個鏈接

80%

修改 PATH

84%

E. 怎麼去卸載剛才從源代碼中安裝的軟體

89%

等等? 依賴地獄在哪裡?

93%

編譯自  https://itsfoss.com/install-software-from-source-code/

作者  Sylvain Leroux

譯者  qhwdw

簡介:這篇文章詳細介紹了在 Linux 中怎麼用源代碼安裝程序,以及怎麼去卸載用源代碼安裝的程序。

Linux 發行版的一個最大的優點就是它的包管理器和相關的軟體庫。通過它們提供的資源和工具,你才能夠以完全自動化的方式在你的計算機上下載和安裝軟體。

但是,儘管付出了很多的努力,包維護者仍然沒法照顧好每種情況,也不可能將所有的可用軟體都打包進去。因此,仍然存在需要你自已去編譯和安裝一個新軟體的情形。對於我來說,到目前為止,最主要的原因是,我編譯一些軟體是我需要去運行一個特定的版本。或者是我想去修改源代碼或使用一些想要的編譯選項。

如果你也屬於後一種情況,那你已經知道你應該怎麼做了。但是,對於絕大多數的 Linux 用戶來說,第一次從源代碼中編譯和安裝一個軟體看上去像是一個入門儀式:它讓很多人感到恐懼;但是,如果你能克服困難,你將可能進入一個全新的世界,並且,如果你做到了,那麼你將成為社區中享有特權的一部分人。

建議閱讀:怎樣在 Ubuntu 中安裝和刪除軟體(完全指南)

[1]

A. 在 Linux 中從源代碼開始安裝軟體

這正是我們要做的。因為這篇文章的需要,我要在我的系統上安裝NodeJS

[2]

8.1.1。它是個完全真實的版本。這個版本在 Debian 倉庫中沒有:

  • 第 1 步:從 GitHub 上獲取源代碼

    像大多數開源項目一樣,NodeJS 的源代碼可以在 GitHub:https://github.com/nodejs/node上找到。

    所以,我們直接開始吧。

    The NodeJS official GitHub repository

    如果你不熟悉GitHub

    [4]

    ,git

    [5]

    或者提到的其它版本管理系統

    [6]

    包含了這個軟體的源代碼,以及多年來對該軟體的所有修改的歷史。甚至可以回溯到該軟體的最早版本。對於開發者來說,保留它的歷史版本有很多好處。如今對我來說,其中一個好處是可以得到任何一個給定時間點的項目源代碼。更準確地說,我可以得到我所要的 8.1.1 發布時的源代碼。即便從那之後他們有了很多的修改。

    Choose the v8.1.1 tag in the NodeJS GitHub repository

    在 GitHub 上,你可以使用 「branch」 (分支)按鈕導航到這個軟體的不同版本。「分支」 和 「標籤」 是 Git 中一些相關的概念

    [7]

    。總的來說,開發者創建 「分支」 和 「標籤」 來在項目歷史中對重要事件保持跟蹤,比如當他們啟用一個新特性或者發布一個新版本時。在這裡先不詳細介紹了,你現在只需要知道我在找被標記為 「v8.1.1」 的版本。

    The NodeJS GitHub repository as it was at the time the v8.1.1 tag was created

    在選擇了 「v8.1.1」 標籤後,頁面被刷新,最顯著的變化是標籤現在作為 URL 的一部分出現。另外,你可能會注意到文件改變日期也有所不同。你現在看到的源代碼樹是創建了 v8.1.1 標籤時的代碼。在某種意義上,你也可以認為像 git 這樣的版本管理工具是一個時光穿梭機,允許你在項目歷史中來回穿梭。

    NodeJS GitHub repository download as a ZIP button

    此時,我們可以下載 NodeJS 8.1.1 的源代碼。你不要忘記去點那個建議的大的藍色按鈕來下載一個項目的 ZIP 壓縮包。對於我來說,為講解的目的,我從命令行中下載並解壓這個 ZIP 壓縮包。但是,如果你更喜歡使用一個GUI

    [8]

    工具,不用擔心,你可以取代下面的命令方式:

  • 下載一個 ZIP 包就可以,但是如果你希望「像個專家一樣」,我建議你直接使用 工具去下載源代碼。它一點也不複雜 — 並且如果你是第一次使用該工具,它將是一個很好的開端,你以後將經常用到它:

  • 順便說一下,如果你有任何問題,這篇文章的第一部分只是做一個總體介紹而已。後面,為了幫你排除常見問題,我們將基於 Debian 和基於 RedHat 的發行版更詳細地解釋。

    不管怎樣,在你使用 或者作為一個 ZIP 壓縮包下載了源代碼後,在當前目錄下就有了同樣的源代碼文件:

  • 第 2 步:理解程序的構建系統

    構建系統就是我們通常所說的「編譯源代碼」,其實,編譯只是從源代碼中生成一個可使用的軟體的其中一個階段。構建系統是一套工具,用於自動處置不同的任務,以便可以僅通過幾個命令就能構建整個軟體。

    雖然概念很簡單,實際上編譯做了很多事情。因為不同的項目或者編程語言也許有不同的要求,或者因為編程者的好惡,或者因為支持的平台、或者因為歷史的原因,等等等等 … 選擇或創建另外一個構建系統的原因幾乎數不清。這方面有許多種不同的解決方案。

    NodeJS 使用一種GNU 風格的構建系統

    [9]

    。這在開源社區中這是一個很流行的選擇。由此開始,你將進入一段精彩的旅程。

    寫出和調優一個構建系統是一個非常複雜的任務。但是,作為 「終端用戶」 來說,GNU 風格的構建系統使用兩個工具讓他們免於此難: 和 。

    文件是個項目專用的腳本,它將檢查目標系統的配置和可用功能,以確保該項目可以被構建,並最終吻合當前平台的特性。

    一個典型的 任務的重要部分是去構建 。這個文件包含了有效構建項目所需的指令。

    另一方面,工具

    [10]

    ,這是一個可用於任何類 Unix 系統的 POSIX 工具。它將讀取項目專用的 然後執行所需的操作去構建和安裝你的程序。

    但是,在 Linux 的世界中,你仍然有一些定製你自己專用的構建的理由。

  • 命令將展示你可用的所有配置選項。再強調一下,這是非常的項目專用。說實話,有時候,在你完全理解每個配置選項的作用之前,你需要深入到項目中去好好研究。

    不過,這裡至少有一個標準的 GNU 自動化工具選項是你該知道的,它就是眾所周知的 選項。它與文件系統的層次結構有關,它是你軟體要安裝的位置。

    第 3 步:文件系統層次化標準(FHS)

    大部分典型的 Linux 發行版的文件系統層次結構都遵從文件系統層次化標準(FHS)

    [11]

    這個標準說明了你的系統中各種目錄的用途,比如,、、 等等。

    當使用 GNU 自動化工具和大多數其它的構建系統時,它會把新軟體默認安裝在你的系統的 目錄中。這是依據 FHS 中「 層級是為系統管理員本地安裝軟體時使用的,它在系統軟體更新覆蓋時是安全的。它也可以用於存放在一組主機中共享,但又沒有放到 /usr 中的程序和數據」,因此,它是一個非常好的選擇。

    層級以某種方式複製了根目錄,你可以在 這裡找到可執行程序,在 中找到庫,在 中找到架構無關的文件,等等。

    使用 樹作為你定製安裝的軟體位置的唯一問題是,你的軟體的文件將在這裡混雜在一起。尤其是你安裝了多個軟體之後,將很難去準確地跟蹤 和 中的哪個文件到底屬於哪個軟體。它雖然不會導致系統的問題。畢竟, 也是一樣混亂的。但是,有一天你想去卸載一個手工安裝的軟體時它會將成為一個問題。

    要解決這個問題,我通常喜歡安裝定製的軟體到 子目錄下。再次引用 FHS:

    「 是為安裝附加的應用程序軟體包而保留的。

    包安裝在 下的軟體包必須將它的靜態文件放在單獨的 或者 目錄中,此處 是所說的那個軟體名的名字,而 處是提供者的 LANANA 註冊名字。」(LCTT 譯註:LANANA 是指The Linux Assigned Names And Numbers Authority

    [12]

    。 )

    因此,我們將在 下創建一個子目錄,用於我們定製的 NodeJS 安裝。並且,如果有一天我想去卸載它,我只是很簡單地去刪除那個目錄:

  • 在你運行完成 命令之後,如果有任何的除了 「ok」 以外的信息,將意味著在構建過程中有錯誤。當我們使用一個 選項去運行並行構建時,在構建系統的大量輸出過程中,檢索錯誤信息並不是件很容易的事。

    在這種情況下,只能是重新開始 ,並且不要使用 選項。這樣錯誤將會出現在輸出信息的最後面:

  • 最終,編譯結束後,你可以運行這個命令去安裝你的軟體:

  • 然後測試它:

  • B. 如果在源代碼安裝的過程中出現錯誤怎麼辦?

    我上面介紹的大多是你能在文檔完備的項目的「構建指令」頁面上看到。但是,本文的目標是讓你從源代碼開始去編譯你的第一個軟體,它可能要花一些時間去研究一些常見的問題。因此,我將再次重新開始一遍整個過程,但是,這次是在一個最新的、最小化安裝的 Debian 9.0 和 CentOS 7.0 系統上。因此,你可能看到我遇到的錯誤以及我怎麼去解決它。

    從 Debian 9.0 中 「Stretch」 開始

  • 這個問題非常容易去診斷和解決。去安裝這個 包即可:

  • 現在沒有問題了。

  • 很顯然,編譯一個項目,你需要一個編譯器。NodeJS 是使用C++ 語言

    [13]

    寫的,我們需要一個 C++編譯器

    [14]

    。在這裡我將安裝 ,它就是為這個目的寫的 GNU C++ 編譯器:

  • 還差一個其它工具。同樣的癥狀。同樣的解決方案:

  • 成功!

    請注意:我將一次又一次地安裝各種工具去展示怎麼去診斷編譯問題,以及展示怎麼去解決這些問題。但是,如果你搜索關於這個主題的更多文檔,或者讀其它的教程,你將發現,很多發行版有一個 「meta-packages」,它包羅了安裝一些或者全部的用於編譯軟體的常用工具。在基於 Debian 的系統上,你或許遇到過build-essentials

    [15]

    包,它就是這種用作。在基於 Red Hat 的發行版中,它將是「Development Tools」組。

    在 CentOS 7.0 上

  • 命令沒有找到?可以用 包管理器去安裝它:

  • 你知道的:NodeJS 是使用 C++ 語言寫的,但是,我的系統缺少合適的編譯器。Yum 可以幫到你。因為,我不是一個合格的 CentOS 用戶,我實際上是在互聯網上搜索到包含 g++ 編譯器的包的確切名字的。這個頁面指導了我:https://superuser.com/questions/590808/yum-install-gcc-g-doesnt-work-anymore-in-centos-6-4。

  • 再次成功!

    C. 從源代碼中對要安裝的軟體做一些改變

    從源代碼中安裝一個軟體,可能是因為你的分發倉庫中沒有一個可用的特定版本。或者因為你想去修改那個程序。也可能是修復一個 bug 或者增加一個特性。畢竟,開源軟體這些都可以做到。因此,我將抓住這個機會,讓你親自體驗怎麼去編譯你自己的軟體。

    在這裡,我將在 NodeJS 源代碼上做一個微小改變。然後,我們將看到我們的改變將被納入到軟體的編譯版本中:

    用你喜歡的文本編輯器

    [17]

    (如,vim、nano、gedit、 … )打開文件 。然後,嘗試找到如下的代碼片段:

  • 它在文件的 3830 行

    [18]

    附近。然後,修改包含 的行,將它替換成如下內容:

  • 然後,返回到你的終端。在繼續之前,為了對強大的 Git 支持有更多的了解,你可以去檢查一下,你修改是文件是否正確:

  • 在你前面改變的那行之前,你將看到一個 「-」 (減號標誌)。而在改變之後的行前面有一個 「+」 (加號標誌)。

    現在可以去重新編譯並重新安裝你的軟體了:

  • 這個時候,可能失敗的唯一原因就是你改變代碼時的輸入錯誤。如果就是這種情況,在文本編輯器中重新打開 文件並修復錯誤。

    一旦你完成了新修改版本的 NodeJS 的編譯和安裝,就可以去檢查你的修改是否包含到軟體中:

  • 恭喜你!你對開源程序做出了你的第一個改變!

    D. 讓 shell 找到我們定製構建的軟體

    到目前為止,你可能注意到,我通常啟動我新編譯的 NodeJS 軟體是通過指定到該二進位文件的絕對路徑。

  • 這是可以正常工作的。但是,這樣太麻煩。實際上有兩種辦法可以去解決這個問題。但是,去理解它們,你必須首先明白,你的 shell 定位可執行文件是通過在環境變數

    [19]

    中指定的目錄裡面查找的。

  • 在這個 Debian 系統上,如果你不指定一個精確的目錄做為命令名字的一部分,shell 將首先在 中查找可執行程序;如果沒有找到,然後進入 中查找;如果沒有找到,然後進入 查找;如果沒有找到,然後進入 查找;如果沒有找到,然後進入 查找;如果沒有找到,那麼,shell 將報告一個錯誤,「command not found」。

    由此,我們可以知道有兩種方法去確保命令可以被 shell 訪問到:將它(該二進位程序)增加到已經配置好的 目錄中,或者將包含可執行程序的目錄添加到 中。

    從 /usr/local/bin 中添加一個鏈接

    只是從 中拷貝NodeJS 二進位可執行文件到 是一個錯誤的做法。因為,如果這麼做,該可執行程序將無法定位到在 中的需要的其它組件。(軟體以它自己的位置去定位它所需要的資源文件是常見的做法)

    因此,傳統的做法是去使用一個符號鏈接:

  • 這一個簡單而有效的解決辦法,尤其是,如果一個軟體包是由好幾個眾所周知的可執行程序組成的,因為,你將為每個用戶調用的命令創建一個符號鏈接。例如,如果你熟悉 NodeJS,你知道應用的 組件,也應該從 做個符號鏈接。我把這個留給你做練習。

    修改 PATH

    首先,如果你嘗試過前面的解決方案,請先移除前面創建的節點符號鏈接,去從一個乾淨的狀態開始:

  • 現在,這裡有一個改變你的 的魔法命令:

  • 簡單說就是,我用環境變數 之前的內容前綴了一個 替換了其原先的內容。因此,你可以想像一下,shell 將先進入到 目錄中查找可執行程序。我們也可以使用 命令去確認一下:

  • 鑒於 「符號鏈接」 解決方案是永久的,只要創建到 的符號鏈接就行了,而對 的改變僅影響到當前的 shell。你可以自己做一些研究,如何做到對 的永久改變。給你一個提示,可以將它寫到你的 「profile」 中。如果你找到這個解決方案,不要猶豫,通過下面的評論區共享給其它的讀者!

    E. 怎麼去卸載剛才從源代碼中安裝的軟體

    因為我們定製編譯的 NodeJS 軟體全部在 目錄中,卸載它不需要做太多的工作,僅使用 命令去刪除那個目錄即可:

  • 注意: 和 是 「非常危險的雞尾酒」!一定要在按下回車鍵之前多檢查幾次你的命令。你不會得到任何的確認信息,並且如果你刪除了錯誤的目錄它是不可恢復的 …

    然後,如果你修改了你的 ,你可以去恢復這些改變。它一點也不複雜。

    如果你從 創建了一個符號鏈接,你應該去刪除它們:

  • 等等? 依賴地獄在哪裡?

    作為最終的討論,如果你讀過有關的編譯定製軟體的文檔,你可能聽到關於依賴地獄dependency hell

    [20]

    的說法。那是在你能夠成功編譯一個軟體之前,對那種煩人情況的一個別名,你必須首先編譯一個前提條件所需要的庫,它又可能要求其它的庫,而這些庫有可能與你的系統上已經安裝的其它軟體不兼容。

    發行版的軟體包維護者的部分工作,就是實際去地解決那些依賴地獄,確保你的系統上的各種軟體都使用了兼容的庫,並且按正確的順序去安裝。

    在這篇文章中,我特意選擇了 NodeJS 去安裝,是因為它幾乎沒有依賴。我說 「幾乎」 是因為,實際上,它有依賴。但是,這些源代碼的依賴已經預置到項目的源倉庫中(在 子目錄下),因此,在你動手編譯之前,你不用手動去下載和安裝它們。


    喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

    本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


    請您繼續閱讀更多來自 Linux中國 的精彩文章:

    2018 年開源技術 10 大發展趨勢
    使用 parallel 利用起你的所有 CPU 資源
    FreeCAD:Linux 下的 3D 建模和設計軟體
    Linux 長期支持版關於未來的聲明
    Shell 中的命令替換及參數擴展

    TAG:Linux中國 |