# 章 4. 安裝應用程式：套件與 Port

This translation may be out of date. To help with the translations please access the FreeBSD translations instance.

## 4.1. 概述

FreeBSD 內建豐富的系統工具集，此外 FreeBSD 提供了兩種安裝第三方軟體的套件管理技術︰由原始碼安裝的 FreeBSD Port 套件集，以及由預先編譯好的 Binary 安裝的 Binary 套件集。兩種方法都可使用本地的媒體或網路來安裝軟體。

讀完這章，您將了解：

- Binary 套件集與 Port 的差別。

- 如何找到已移植到 FreeBSD 的第三方軟體。

- 如何使用 pkg 管理 Binary 套件。

- 如何編譯來自 Port 套件集的第三方軟體原始碼。

- 如何找到應用程式已安裝的檔案來完成安裝後的設定。

- 若軟體安裝失敗要如何處理。

## 4.2. 安裝軟體的概要

通常要在 UNIX™ 系統上安裝第三方軟體時，有幾個步驟要作：

1. 找到並且下載軟體，該軟體有可能以原始碼或 Binary 格式發佈。

2. 自發佈的格式解壓縮軟體。 發佈的格式通常為 tarball 並以程式壓縮，如 compress(1), gzip(1), bzip2(1) 或 xz(1)。

3. 找到位於 INSTALL, README 或者 doc/ 子目錄底下的檔案閱讀如何安裝該軟體。

4. 若軟體是以原始碼的格式發佈則需要編譯該軟體。 這可能會需要修改 Makefile 或執行 `configure` Script。

5. 測試並安裝該軟體。

FreeBSD Port 是指設計用來自動化從原始碼編譯應用程式整個程序的一系列檔案，組成 Port 的檔案包含了自動下載、解壓縮、修補、編譯與安裝應用程式的必要資訊。

若軟體尚未被 FreeBSD 採用並測試，可能會需要經過一些修正才能正常安裝並執行。

雖然如此，目前已有超過 24,000 個第三方應用程式已經被移植到 FreeBSD。當可行時，這些應用程式也會做成預先編譯好的 套件 (Package) 供下載。

這些 Binary 套件可使用 FreeBSD 套件管理指令來管理。

不論是 Binary 套件或者 Port 都有相依性，若用 Binary 套件或 Port 來安裝應用程式，且該應用程式若有相依的程式庫尚未被安裝，則會自動先安裝該程式庫。

FreeBSD Binary 套件中含有一個應用程式中所有預先編譯好的指令、設定檔以及文件，Binary 套件可以使用 pkg(8) 指令來管理，如 `pkg install`。

雖然兩種技術非常相似，但 Binary 套件及 Port 有各自的優點。 要視您要安裝的應用程式需求來選擇。

Binary 套件優點

- 應用程式壓縮 Binary 套件的 tarball 會比壓縮原始碼的 tarball 還要小。

- 安裝 Binary 套件不需要編譯的時間，對於較慢的電腦要安裝大型的應用程式如 Mozilla, KDE 或 GNOME 這點顯的相當重要。

- Binary 套件不需要了解在 FreeBSD 上編譯軟體的流程。

Port 套件優點

- 由於 Binary 套件必須盡可能在大多數系統上執行，通常會採用較通用的編譯選項來編譯，由 Port 來編輯可更改編譯選項。

- 部份應用程式編譯期選項會與要安裝的功能有關，舉例來說 Apache 便有大量不同的內建選項可以設定。

  在某些情況，同樣的應用程式會存在多個不同的 Binary 套件，如 Ghostscript 有 ghostscript 及 ghostscript-nox11 兩種 Binary 套件，用來區別是否有安裝 Xorg。 若應用程式有一個以上的編譯期選項便無法用這個方式來區別 Binary 套件。

- 部份軟體的授權條款中禁止以 Binary 格式發佈。 這種軟體必須以原始碼發佈並由終端使用者編譯。

- 部份人並不相信 Binary 發佈版本，寧願閱讀原始碼來查看是否潛藏的問題。

- 原始碼可套用自訂的修補。

要持續追蹤 Port 的更新可以訂閱 FreeBSD Port 郵遞論壇 與 FreeBSD Port 問題郵遞論壇。

| 在安裝任何應用程式之前，請先查看 https://vuxml.freebsd.org/ 是否有與該應用程式相關的安全性問題或輸入 `pkg audit -F` 來檢查所有已安裝的應用程式是否有已知的漏洞。

本章接下來的部份將說明如何在 FreeBSD 使用 Binary 套件及 Port 套件安裝與管理第三方軟體。

## 4.3. 搜尋軟體

FreeBSD 上可安裝的軟體清單不斷在增加， 有幾種方式可以來找你想安裝的軟體：

- FreeBSD 網站有維護一份可搜尋的最新應用程式清單，在 https://www.FreeBSD.org/ports/。 可以依應用程式名稱或軟體分類來搜尋 Port。 *

  由 Dan Langille 維護的 FreshPorts.org，提供完整的搜尋工具並且可追蹤在 Port 套件集中的應用程式變更。註冊的使用者可以建立自訂的監視清單會自動寄發電子郵件通知 Port 的更新資訊。 *

  若找不到指定的應用程式，可以先到網站 SourceForge.net 或 GitHub.com 搜尋，後然再回到 FreeBSD 網站 檢查該應用程式是否已被移植。 *

  要搜尋 Binary 套件檔案庫中的應用程式可：

      # pkg search subversion
      git-subversion-1.9.2
      java-subversion-1.8.8_2
      p5-subversion-1.8.8_2
      py27-hgsubversion-1.6
      py27-subversion-1.8.8_2
      ruby-subversion-1.8.8_2
      subversion-1.8.8_2
      subversion-book-4515
      subversion-static-1.8.8_2
      subversion16-1.6.23_4
      subversion17-1.7.16_2

  套件名稱包含版本編號，且若 Port 使用 Python 為基礎，也會包含用來編譯該套件的 Python 版本。有些 Port 會有多個版本可使用，如 Subversion ，因編譯選項不同，有多個版本可用，這個例子中即指靜態連結版本的 Subversion。在指定要安裝的套件時，最好使用 Port 來源來指定該應用程式，Port 來源是指應用程式在 Port 樹中的路徑。再輸入一次 `pkg search` 並加上 `-o` 來列出每個套件來源：

      # pkg search -o subversion
      devel/git-subversion
      java/java-subversion
      devel/p5-subversion
      devel/py-hgsubversion
      devel/py-subversion
      devel/ruby-subversion
      devel/subversion16
      devel/subversion17
      devel/subversion
      devel/subversion-book
      devel/subversion-static

  `pkg search` 支援使用 Shell 萬手字元 (globs)、正規表示法、描述或檔案庫中的其他其他內容。在安裝 ports-mgmt/pkg 或 ports-mgmt/pkg-devel 之後，可參考 pkg-search(8) 以取得更多詳細資訊。

- 若 Port 套件集已安裝，有數個方法可以查詢 Port 樹中的本地版本。要找到 Port 所在的分類，可輸入 `whereis file`，其中 file 是要安裝的程式：

      # whereis lsof
      lsof: /usr/ports/sysutils/lsof

  或者，也可使用 echo(1)：

      # echo /usr/ports/*/*lsof*
      /usr/ports/sysutils/lsof

  請注意，這也會顯示已下載至 /usr/ports/distfiles 目錄中任何已符合條件的檔案。

- 另一個方法是使用 Port 套件集內建的搜尋機制來找軟體。要使用搜尋的功能需先 cd 到 /usr/ports 然後執行 `make search name=program-name`，其中 program-name 代表軟體的名稱。舉例搜尋 `lsof`：

      # cd /usr/ports
      # make search name=lsof
      Port:   lsof-4.88.d,8
      Path:   /usr/ports/sysutils/lsof
      Info:   Lists information about open files (similar to fstat(1))
      Maint:  ler@lerctr.org
      Index:  sysutils
      B-deps:
      R-deps:

  | 內建的搜尋機制會使用索引檔內的資訊。若出現訊息指出需要 INDEX 檔，可執行 `make fetchindex` 來下載最新的索引檔。當 INDEX 檔存在時，`make search` 方可執行請求的搜尋動作。

  "Path:" 此行代表 Port 的所在位置。

  若不要接受這麼多資訊，可使用 `quicksearch` 功能：

      # cd /usr/ports
      # make quicksearch name=lsof
      Port:   lsof-4.88.d,8
      Path:   /usr/ports/sysutils/lsof
      Info:   Lists information about open files (similar to fstat(1))

  若要進行更有深度的搜尋，使用 `make search key=string` 或 `make quicksearch key=string` 其中 string 是要搜尋的文字。該文字可以是一部份的註解、描述或相依套件，當不清楚程式的名稱時可以找到與特定主題相關的 Port。

  當使用 `search` 或 `quicksearch` 時，搜尋的字串不分大小寫。 搜尋 "LSOF" 會與搜尋 "lsof" 產生相同的結果。

## 4.4. 使用 pkg 管理 Binary 套件

pkg 是新一代套件管理工具用來取代舊版工具，提供許多功能讓處理 Binary 套件更快更簡單。

對於只想要使用在 FreeBSD 鏡像站上預先編譯 Binary 套件的站台，使用 pkg 管理套件便已足夠。

但是，對於那些想要從原始碼或使用自己的檔案庫編譯的站台，則會需要 Port 管理工具。

因為 pkg 僅能管理 Binary 套件，所以不能當做為替代 Port 管理工具，這些工具可用來安裝來自 Binary 與 Port 套件集的軟體，而 pkg 僅能安裝 Binary 套件。

### 4.4.1. 開始使用 pkg

FreeBSD 內建啟動 (Bootstrap) 工具可用來下載並安裝 pkg 及其操作手冊。這個工具是設計在 FreeBSD 版本 10.X 之後使用。

| 不是所有 FreeBSD 版本及架構支援此啟動程序，目前支援的清單列於 https://pkg.freebsd.org/，對不支援的版本，必須改透過 Port 套件集或者 Binary 套件來安裝 pkg。

要啟動 (Bootstrap) 系統請執行：

    # /usr/sbin/pkg

您必須有可用的網際網路連線供啟動程式使用方可成功。

否則，要安裝 Port 套件，則須執行：

    # cd /usr/ports/ports-mgmt/pkg
    # make
    # make install clean

當升級原使用舊版 pkg_* 工具的既有系統時，必須將資料庫轉換成新的格式，如此新的工具才會知道有那些已安裝過的套件。pkg 安裝完後，必須執行以下指令將套件資料庫從舊版格式轉換到新版格式：

    # pkg2ng

| 新安裝的版本因尚未安裝任何第三方軟體因此不須做這個步驟。

| 這個步驟無法還原。一旦套件資料庫轉為成 pkg 的格式，舊版 `pkg_*` 工具就不該再繼續使用。

| 套件資料庫轉換的過程可能會因內容轉換為新版本產生錯誤。通常，這些錯誤皆可安全忽略，即使如此，仍然有在執行 `pkg2ng` 後無法成功轉換的軟體清單，這些應用程式則必須手動重新安裝。

為了確保 FreeBSD Port 套件集會將新軟體的資訊註冊到 pkg 而非舊版套件資料庫，FreeBSD 版本 10.X 之前需要在 /etc/make.conf 加入此行：

    WITH_PKGNG=	yes

預設 pkg 會使用 FreeBSD 套件鏡像站 (Repository) 的 Binary 套件。若要取得有關編譯自訂套件檔案庫的資訊，請參考 使用 Poudriere 編譯套件。

其他 pkg 設定選項說明請參考 pkg.conf(5)。

pkg 的用法資訊可在 pkg(8) 操作手冊或不加任何參數執行 `pkg` 來取得。

每個 pkg 指令參數皆記庫在指令操件手冊。要閱讀 `pkg install` 的操作手冊，可執行以下指令：

    # pkg help install

    # man pkg-install

本章節剩餘的部份將會示範使用 pkg 執行常用的 Binary 套件管理工作。每個示範的指令皆會提供多個參數可使用，請參考指令的說明或操作手冊以取得詳細資訊或更多範例。

### 4.4.2. 取得有關已安裝套件的資訊

有關已安裝在系統的套件資訊可透過執行 `pkg info` 來檢視，若執行時未指定任何參數，將會列出所有已安裝或指定的套件版本。

例如，要查看已安裝的 pkg 版本可執行：

    # pkg info pkg
    pkg-1.1.4_1

### 4.4.3. 安裝與移除套件

要安裝 Binary 套件可使用以下指令，其中 packagename 為要安裝的套件名稱：

    # pkg install packagename

這個指令會使用檔案庫的資料來決定要安裝的軟體版本以及是否有任何未安裝的相依。例如，要安裝 curl：

    # pkg install curl
    Updating repository catalogue
    /usr/local/tmp/All/curl-7.31.0_1.txz          100% of 1181 kB 1380 kBps 00m01s

    /usr/local/tmp/All/ca_root_nss-3.15.1_1.txz   100% of  288 kB 1700 kBps 00m00s

    Updating repository catalogue
    The following 2 packages will be installed:

            Installing ca_root_nss: 3.15.1_1
            Installing curl: 7.31.0_1

    The installation will require 3 MB more space

    0 B to be downloaded

    Proceed with installing packages [y/N]: y
    Checking integrity... done
    [1/2] Installing ca_root_nss-3.15.1_1... done
    [2/2] Installing curl-7.31.0_1... done
    Cleaning up cache files...Done

新的套件以及任何做為相依安裝的額外套件可在已安裝的套件清單中看到：

    # pkg info
    ca_root_nss-3.15.1_1	The root certificate bundle from the Mozilla Project
    curl-7.31.0_1	Non-interactive tool to get files from FTP, GOPHER, HTTP(S) servers
    pkg-1.1.4_6	New generation package manager

不再需要的套件可以使用 `pkg delete` 來移除，例如：

    # pkg delete curl
    The following packages will be deleted:

    	curl-7.31.0_1

    The deletion will free 3 MB

    Proceed with deleting packages [y/N]: y
    [1/1] Deleting curl-7.31.0_1... done

### 4.4.4. 升級已安裝套件

執行以下指令，可將已安裝的套件升級到最新版本：

    # pkg upgrade

這個指令將會比對已安裝的版本與在檔案庫分類中的版本，並從檔案庫升級這些套件。

### 4.4.5. 稽查已安裝套件

在第三方的應用程式中偶爾可能會發現軟體漏洞，要找出這些程式，可使用 pkg 內建的稽查機制。要查詢已安裝在系統上的軟體是否有任何已知的漏洞可執行：

    # pkg audit -F

### 4.4.6. 自動移除未使用的套件

移除一個套件可能會留下不再需要使用的相依套件。不再需要的相依套件是當初隨著其套件所安裝的套件 (枝葉套件)，可以使用以下指令自動偵測並移除：

    # pkg autoremove
    Packages to be autoremoved:
    	ca_root_nss-3.15.1_1

    The autoremoval will free 723 kB

    Proceed with autoremoval of packages [y/N]: y
    Deinstalling ca_root_nss-3.15.1_1... done

因為相依所安裝的套件稱作 自動 (Automatic) 套件，而非自動套件即套件被安裝的原因不是因為其他套件所相依，可以使用以下方式查詢：

    # pkg prime-list
    nginx
    openvpn
    sudo

`pkg prime-list` 是一個別名指令，定義在 /usr/local/etc/pkg.conf，尚還有許多其他相關指令可以用來查詢系統的套件資料庫，例如，指令 `pkg prime-origins` 可用來取得上述清單的來源 Port 目錄：

    # pkg prime-origins
    www/nginx
    security/openvpn
    security/sudo

這份清單可以用來重新編譯所有安裝在系統中的套件，使用 ports-mgmt/poudriere 或 ports-mgmt/synth 這類的編譯工具。

要將一個安裝好的套件註記成為 "自動" 可以用：

    # pkg set -A 1 devel/cmake

當套件為末端套件 (Leaf Package) 且被註記為 "自動"，則會被 `pkg autoremove` 挑選出來。

要註記一個安裝好的套件為 "非自動" 可以用：

    # pkg set -A 0 devel/cmake

### 4.4.7. 還原套件資料庫

不如傳統的套件管理系統，pkg 有自己的套件資料庫備份機制，此功能預設是開啟的。

| 要停止週期的 Script 備份套件資料庫可在 periodic.conf(5) 設定 `daily_backup_pkgdb_enable="NO"`。

要還原先前套件資料庫的備份，可執行以下指令並將 /path/to/pkg.sql 替換為備份的位置：

    # pkg backup -r /path/to/pkg.sql

| 若要還原有週期 Script 所產生的備份必須在還原前先解壓縮。

要手動備份 pkg 資料庫，可執行以下指令，並替換 /path/to/pkg.sql 為適當的檔案名稱與位置：

    # pkg backup -d /path/to/pkg.sql

### 4.4.8. 移除過時的套件

預設 pkg 會儲存 Binary 套件在快取目錄定義在 pkg.conf(5) 中的 `PKG_CACHEDIR`，只會保留最後安裝的套件複本。較舊版的 pkg 會保留所有先前的套件，若要移除這些過時的 Binary 套件，可執行：

    # pkg clean

使用以下指令可清空全部的快取：

    # pkg clean -a

### 4.4.9. 修改套件 Metadata

在 FreeBSD Port 套件集中的軟體可能會經歷主要版號的修改，要解決這個問題可使用 pkg 內建的指令來更新套件來源。這非常有用，例如 lang/php5 重新命名為 lang/php53 因此 lang/php5 從此之後代表版本 `5.4`。

要更改上述例子中的套件來源，可執行：

    # pkg set -o lang/php5:lang/php53

再一個例子，要更新 lang/ruby18 為 lang/ruby19，可執行：

    # pkg set -o lang/ruby18:lang/ruby19

最後一個例子，要更改 libglut 共用程式庫的來源從 graphics/libglut 改成 graphics/freeglut 可執行：

    # pkg set -o graphics/libglut:graphics/freeglut

| 在更改套件來源之後，很重要的一件事是要重新安裝套件，來讓相依的套件也同時使用修改後的來源。要強制重新安裝相依套件，可執行：
    # pkg install -Rf graphics/freeglut

## 4.5. 使用 Port 套件集

Port 套件集是指一數個 Makefiles、修補及描述檔案，每一組這些檔案可用來編譯與安裝在 FreeBSD 上的一個應用程式，即稱為一個 Port。

預設，Port 套件集儲存在 /usr/ports 的子目錄下。

在應用程式可以使用 Port 編譯之前，必須先安裝 Port 套件集。若在安裝 FreeBSD 時沒有安裝，可以使用以下其中一種方式安裝：

Procedure: Portsnap 方法

FreeBSD 的基礎系統內含 Portsnap，這是一個可用來取得 Port 套件集簡單又快速的工具，較建議多數使用者使用這個方式。此工具會連線到 FreeBSD 的網站，驗証密鑰，然後下載 Port 套件集的新複本。該金鑰是要用來檢驗所有已下載檔案的完整性。

1. 要下載壓縮後的 Port 套件集快照 (Snapshot) 到 /var/db/portsnap：

       # portsnap fetch

2. 當第一次執行 Portsnap 時，要先解壓縮快照到 /usr/ports：

       # portsnap extract

3. 在完成上述第一次使用 Portsnap 的動作之後，往後可隨需要執行以下指令來更新 /usr/ports ：

       # portsnap fetch
       # portsnap update

   當使用 `fetch` 時也可同時執行 `extract` 或 `update` 如：

       # portsnap fetch update

Procedure: Subversion 方法

若要取得更多對 Port 樹的控制，或若有本地的變更需要維護，可以使用 Subversion 來取得 Port 套件集。請參考 Subversion Primer 來取得 Subversion 的詳細說明。

1. 必須安裝 Subversion 才可用來取出 (Check out) Port 樹。若已存在 Port 樹的複本，可使用此方式安裝 Subversion：

       # cd /usr/ports/devel/subversion
       # make install clean

   若尚無法使用 Port 樹，或已經使用 pkg 來管理套件，可使用套件來安裝 Subversion：

       # pkg install subversion

2. 取出 Port 樹的複本：

       # svn checkout https://svn.FreeBSD.org/ports/head /usr/ports

3. 若需要，在第一次 Subversion 取出後可使用以下指令更新 /usr/ports：

       # svn update /usr/ports

Port 套件集中含有代表不同軟體分類的目錄，每個分類底下的子目錄代表每個應用程式，每個內含數個用來告訴 FreeBSD 如何編譯與安裝該程式檔案的應用程式子目錄即稱作 Port Skeleton，每個 Port Skeleton 會含有以下檔案及目錄：

- Makefile：內含用來說明應用程式要如何編譯、要安裝該程式到那的敘述句。

- distinfo：內含編譯 Port 必須下載的檔案名稱以及校驗碼 (Checksum)。

- files/：此目錄含有編譯與安裝程式到 FreeBSD 時所需的修補檔。此目錄也可能含有其他用來編譯 Port 的檔案。

- pkg-descr：提供程式更詳細的說明。

- pkg-plist：Port 安裝的所有檔案清單，也同時會告訴 Port 系統解除安裝時要移除那一些檔案。

部份 Port 含有 pkg-message 或其他檔案用來處理特殊情況。要取得有關這些檔案的詳細資訊，以及 Port 的概要可參考 FreeBSD Porter’s Handbook。

Port 中並不含實際的原始碼，即為 distfile，在編譯 Port 解壓縮時會自動下載的原始碼到 /usr/ports/distfiles。

### 4.5.1. 安裝 Port

下面我們會介紹如何使用 Port 套件集來安裝、移除軟體的基本用法。 `make` 可用的目標及環境變數詳細說明可參閱 ports(7)。

| 在編譯任何 Port 套件前，請先確認已經如前章節所敘述之方法更新 Port 套件集。安裝任何第三方軟體皆可能會導致安全性漏洞，建議在安裝前先閱讀 https://vuxml.freebsd.org/ 了解 Port 已知的安全性問題。或者在每次安裝新 Port 前執行 `pkg audit -F`。此指令可以設定在每日系統安全性檢查時自動完成安全性稽查以及更新漏洞資料庫。要取得更多資訊，請參考 pkg-audit(8) 及 periodic(8)。

使用 Port 套件集會假設您擁有可正常連線的網路，同時也會需要超級使用者的權限。

要編譯並安裝 Port，需切換目錄到要安裝的 Port 底下，然後輸入 `make install`，訊息中會顯示安裝的進度：

    # cd /usr/ports/sysutils/lsof
    # make install
    >> lsof_4.88D.freebsd.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
    >> Attempting to fetch from ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/.
    ===>  Extracting for lsof-4.88
    ...
    [extraction output snipped]
    ...
    >> Checksum OK for lsof_4.88D.freebsd.tar.gz.
    ===>  Patching for lsof-4.88.d,8
    ===>  Applying FreeBSD patches for lsof-4.88.d,8
    ===>  Configuring for lsof-4.88.d,8
    ...
    [configure output snipped]
    ...
    ===>  Building for lsof-4.88.d,8
    ...
    [compilation output snipped]
    ...

    ===>  Installing for lsof-4.88.d,8
    ...
    [installation output snipped]
    ...
    ===>   Generating temporary packing list
    ===>   Compressing manual pages for lsof-4.88.d,8
    ===>   Registering installation for lsof-4.88.d,8
    ===>  SECURITY NOTE:
          This port has installed the following binaries which execute with
          increased privileges.
    /usr/local/sbin/lsof
    #

`lsof` 是需要進階權限才有辦法執行的程式，因此當該程式安裝完成時會顯示安全性警告。一旦安裝完成便會顯示指令提示。

有些 Shell 會將 `PATH` 環境變數中所列目錄中可用的指令做快取，來增加在執行指這些指令時的查詢速度。`tcsh` Shell 的使用者應輸入 `rehash` 來讓新安裝的指令不須指定完整路徑便可使用。若在 `sh` Shell 則使用 `hash -r`。請參考 Shell 的說明文件以取得更多資訊。

安裝過程中會建立工作用的子目錄用來儲存編譯時暫存的檔案。可移除此目錄來節省磁碟空間並漸少往後升級新版 Port 時造成問題：

    # make clean
    ===>  Cleaning for lsof-88.d,8
    #

| 若想要少做這個額外的步驟，可以編譯 Port 時使用 `make install clean`。

#### 4.5.1.1. 自訂 Port 安裝

部份 Port 提供編譯選項，可用來開啟或關閉應用程式中的元件、安全選項、或其他允許自訂的項目。這類的應用程式例子包括 www/firefox, security/gpgme 以及 mail/sylpheed-claws。若 Port 相依的其他 Port 有可設定的選項時，預設的模式會提示使用者選擇選單中的選項，這可能會讓安裝的過程暫停讓使用者操作數次。要避免這個情況，可一次設定所有選項，只要在 Port skeleton 中執行 `make config-recursive`，然後再執行 `make install [clean]` 編譯與安裝該 Port。

| 使用 `config-recursive` 時，會使用 `all-depends-list` Target 來收集所有要設定 Port 清單。建議執行 `make config-recursive` 直到所有相依的 Port 選項都已定義，直到 Port 的選項畫面不會再出現，來確定所有相依的選項都已經設定。

有許多方式可以重新進入 Port 的編譯選項清單，以便在編譯 Port 之後加入、移除或更改這些選項。方法之一是 `cd` 進入含有 Port 的目錄並輸入 `make config`。還有另一個方法是使用 `make showconfig`。最後一個方法是執行 `make rmconfig` 來移除所有曾選擇過的選項，讓您能夠重新設定。這些方法在 ports(7) 中都有詳細的說明。

Port 系統使用 fetch(1) 來下載檔案，它支援許多的環境變數可設定。若 FreeBSD 系統在防火牆或 FTP/HTTP 代理伺服器後面，可以設定 `FTP_PASSIVE_MODE`, `FTP_PROXY` 以及 `FTP_PASSWORD` 變數。請參考 fetch(3) 取得完整支援的變數清單。

對於那些無法一直連線到網際網路的使用者，可在 /usr/ports 下執行 `make fetch` 來下載所有的 distfiles，或是可在某個分類的目錄中，例如 /usr/ports/net，或指定的 Port Skeleton 中執行。要注意的是，若 Port 有任何的相依，在分類或 Port Skeleton 中執行此指令並 不會 下載相依在其他分類的 Port distfiles。可使用 `make fetch-recursive` 來下載所有相依 Port 的 distfiles。

在部份少數情況，例如當公司或組織有自己的本地 distfiles 檔案庫，可使用 `MASTER_SITES` 變數來覆蓋在 Makefile 中指定的下載位址。當要指定替代的位址時可：

    # cd /usr/ports/directory
    # make MASTER_SITE_OVERRIDE= \
    ftp://ftp.organization.org/pub/FreeBSD/ports/distfiles/ fetch

也可使用 `WRKDIRPREFIX` 及 `PREFIX` 變數來覆蓋預設的工作及目標目錄。例如：

    # make WRKDIRPREFIX=/usr/home/example/ports install

會編譯在 /usr/home/example/ports 的 Port 並安裝所有東西到 /usr/local 下。

    # make PREFIX=/usr/home/example/local install

會編譯在 /usr/ports Port 並安裝到 /usr/home/example/local。然後：

    # make WRKDIRPREFIX=../ports PREFIX=../local install

來同時設定工作及目標目錄。

這些變數也可做為環境變數設定，請參考您使用的 Shell 操作手冊來取得如何設定環境變數的說明。

### 4.5.2. 移除已安裝的 Port

安裝的 Port 可以使用 `pkg delete` 解除安裝。 使用這個指令的範例可以在 pkg-delete(8) 操作手冊找到。

或者，可在 Port 的目錄下執行 `make deinstall`：

    # cd /usr/ports/sysutils/lsof
    make deinstall
    ===>  Deinstalling for sysutils/lsof
    ===>   Deinstalling
    Deinstallation has been requested for the following 1 packages:

    	lsof-4.88.d,8

    The deinstallation will free 229 kB
    [1/1] Deleting lsof-4.88.d,8... done

建議閱讀 Port 解除安裝後的訊息，若有任何相依該 Port 的應用程式，這些資訊會被顯示出來，但解除安裝的程序仍會繼續。在這種情況下最好重新安裝應用程式來避免破壞相依性。

### 4.5.3. 升級 Port

隨著時間推移，Port 套件集中會有新版的軟體可用。本節將說明如何檢查是否有可以升級的軟體及如何升級。

要檢查已安裝 Port 是否有新版可用，請先確定已安裝最新版本的 Port 樹，使用 Procedure: Portsnap 方法 或 Procedure: Subversion 方法 中說明的指令來更新。在 FreeBSD 10 與更新的版本，或若套件系統已轉換為 pkg，可以使用下列指令列出已經安裝的 Port 中有那些已過時：

    # pkg version -l "<"

在 FreeBSD 9.X 與較舊的版本，可以使用下列指令列出已經安裝的 Port 中有那些已過時：

    # pkg_version -l "<"

| 在嘗試升級之前，請先從檔首閱讀 /usr/ports/UPDATING 來取得最近有那些 Port 已升級或系統已安裝。這個檔案中會說明各種問題及在升級 Port 時可能會需要使用者執行的額外步驟，例如檔案格式更改、設定檔位置更改、或任何與先前版本不相容的問題。留意那些與您要升級 Port 相關的指示，並依照這些指示執行升級。

#### 4.5.3.1. 升級與管理 Port 的工具

Port 套件集含有數個工具可以進行升級，每一種工具都有其優點及缺點。

以往大多 Port 安裝會使用 Portmaster 或 Portupgrade，現在有較新的 Synth 可使用。

| 那一種工具對特定系統是最佳的選擇取決於系統管理員。建議在使用任何這些工具之前先備份資料。

#### 4.5.3.2. 使用 Portmaster 升級 Port

ports-mgmt/portmaster 是可用來升級已安裝 Port 的小巧工具，它只使用了隨 FreeBSD 基礎系統安裝的工具，不需要相依其他 Port 或資料庫便可在 FreeBSD 使用，要使用 Port 安裝此工具可：

    # cd /usr/ports/ports-mgmt/portmaster
    # make install clean

Portmaster 將 Port 定義成四種類型：

- 根 Port：沒有相依且也不被任何其他 Port 相依。

- 主幹 Port：沒有相依，但被其他 Port 相依。

- 分支 Port：有相依，且其被其他 Port 相依。

- 枝 Port：有相依，但沒有被其他 Port 相依。

要列出這幾個分類並搜尋是否有新版：

    # portmaster -L
    ===>>> Root ports (No dependencies, not depended on)
    ===>>> ispell-3.2.06_18
    ===>>> screen-4.0.3
            ===>>> New version available: screen-4.0.3_1
    ===>>> tcpflow-0.21_1
    ===>>> 7 root ports
    ...
    ===>>> Branch ports (Have dependencies, are depended on)
    ===>>> apache22-2.2.3
            ===>>> New version available: apache22-2.2.8
    ...
    ===>>> Leaf ports (Have dependencies, not depended on)
    ===>>> automake-1.9.6_2
    ===>>> bash-3.1.17
            ===>>> New version available: bash-3.2.33
    ...
    ===>>> 32 leaf ports

    ===>>> 137 total installed ports
            ===>>> 83 have new versions available

此指令用來升級所有過時的 Port：

    # portmaster -a

| 預設 Portmaster 會在刪除已存在的 Port 前備份套件，若成功安裝新版 Portmaster 會刪除該備份。使用 `-b` 來讓 Portmaster 不會自動刪除備份。加入 `-i` 可啟動 Portmaster 的互動模式，會在升級每個 Port 前提示訊息。尚有許多可用的其他選項，請閱讀 portmaster(8) 的操作手冊來取得詳細的用法。

若升級的過程發生錯誤，可加入 `-f` 來升級並重新編譯所有 Port：

    # portmaster -af

Portmaster 也可用來安裝新的 Port 到系統，在編譯及安裝新 Port 前升級所有相依模組。要使用這個功能，要指定 Port 位於 Port 套件集中的位置：

    # portmaster shells/bash

更多有關 ports-mgmt/portmaster 的資訊可至其 pkg-descr 取得。

#### 4.5.3.3. 使用 Portupgrade 升級 Port

ports-mgmt/portupgrade 是另一個可以用來升級 Port 的工具，此工具會安裝一套可以用來管理 Port 的應用程式，它需要相依 Ruby。要安裝該 Port：

    # cd /usr/ports/ports-mgmt/portupgrade
    # make install clean

在執行升級之前使用此工具，建議使用 `pkgdb -F` 掃描已安裝的 Port 並修正該指令回報的所有資訊不一致的套件。

要升級所有安裝在系統上過時的 Port，可使用 `portupgrade -a`，或者加上 `-i` 會在每個套件升級時詢問確認：

    # portupgrade -ai

要升級指定的應用程式而非所有可用 Port 可使用 `portupgrade pkgname`，非常重要的是，要加上 `-R` 來先升級指定應用程式所有相依的 Port：

    # portupgrade -R firefox

若使用 `-P`，Portupgrade 會先在 `PKG_PATH` 清單中的本地目錄中搜尋可用的套件。若本地沒有可用的套件，則會從遠端下載。若套件無法在本地或遠端找到，Portupgrade 則會使用 Port 來安裝。要避免完全使用 Port 安裝，可使用 `-PP`，這個選項會告訴 Portupgrade 若沒有套件可用時放棄安裝：

    # portupgrade -PP gnome3

若只想要下載 Port distfiles 或套件，使用 `-P` 參數。若不要編譯或安裝任何東西，使用 `-F`。請參考 `portupgrade` 的操作手冊來取得所有可用選項的更多資訊。

更多有關 ports-mgmt/portupgrade 的資訊可至其 pkg-descr 取得。

### 4.5.4. Port 與磁碟空間

使用 Port 套件集會隨著時間消耗磁碟空間。在編譯與安裝 Port 完之後，在 Port Skeleton 中執行 `make clean` 可清除暫存的 work 目錄。若使用 Portmaster 來安裝 Port，則會自動移除該目錄，除非使用 `-K`。若有安裝 Portupgrade，此指令將會移除所有在 Port 套件集的本地複本中找到的 work 目錄：

    # portsclean -C

除此之外，許多過時的原始碼發行檔案會儲存在 /usr/ports/distfiles。使用 Portupgrade 刪除所有不再被任何 Port 所引用的 distfiles：

    # portsclean -D

Portupgrade 可以移除所有未被任何安裝在系統上的 Port 所引用的 distfiles：

    # portsclean -DD

若有安裝 Portmaster，則可使用：

    # portmaster --clean-distfiles

預設，若 distfile 應要被刪除，這個指令會以互動的方式向使用者確認。

除了以上指令外，ports-mgmt/pkg_cutleaves 可自動移除不再需要使用的 Port。

## 4.6. 使用 Poudriere 編譯套件

Poudriere 是一個使用 BSD 授權條款用來建立與測試 FreeBSD 套件的工具。它使用 FreeBSD Jail 來建置獨立的編譯環境，這些 Jail 可以用來編譯與目前所在系統不同 FreeBSD 版本的套件，也同樣可以在主機為 amd64 的系統上編譯供 i386 使用的套件。套件編譯完成後的目錄配置會與官方鏡像站完全相同。這些套件可由 pkg(8) 及其他套件管理工具使用。

Poudriere 可使用 ports-mgmt/poudriere 套件或 Port 安裝。安裝完成後會有一個範例的設定檔 /usr/local/etc/poudriere.conf.sample。複製此檔案到 /usr/local/etc/poudriere.conf，編輯複製的檔案來配合本地的設定。

雖然在系統上執行 poudriere 並不一定要使用 ZFS，但使用了是有幫助的。當使用了 ZFS，則必須在 /usr/local/etc/poudriere.conf 指定 `ZPOOL` 以及 `FREEBSD_HOST` 應設定到一個最近的鏡像站。定義 `CCACHE_DIR` 可開啟使用 devel/ccache 快取的功能來快取編譯結果並減少那些需時常編譯的程式碼的編譯次數。將 poudriere 資料集放到一個獨立的目錄並掛載到 /poudriere 可能會比較方便，其他設定項目採用預設值便足夠。

偵測到的處理器數量可用來定義要同時執行多少個編譯。並給予足夠的虛擬記憶體，不論是 RAM 或交換空間，若虛擬記憶體不足，編譯 Jail 的動作將會停止並被清除，會造成奇怪的錯誤訊息。

### 4.6.1. 初始化 Jail 與 Port 樹

在設定之後，初始化 poudriere 來安裝 Jail 及其所需的 FreeBSD 樹與 Port 樹。使用 `-j` 來指定 Jail 的名稱以及 `-v` 來指定 FreeBSD 的版本。在執行 FreeBSD/amd64 的系統上可使用 `-a` 來設定要使用的架構為 `i386` 或 `amd64`，預設會採用使用 `uname` 所顯示的架構。

    # poudriere jail -c -j 10amd64 -v 10.0-RELEASE
    ====>> Creating 10amd64 fs... done
    ====>> Fetching base.txz for FreeBSD 10.0-RELEASE amd64
    /poudriere/jails/10amd64/fromftp/base.txz      100% of   59 MB 1470 kBps 00m42s
    ====>> Extracting base.txz... done
    ====>> Fetching src.txz for FreeBSD 10.0-RELEASE amd64
    /poudriere/jails/10amd64/fromftp/src.txz       100% of  107 MB 1476 kBps 01m14s
    ====>> Extracting src.txz... done
    ====>> Fetching games.txz for FreeBSD 10.0-RELEASE amd64
    /poudriere/jails/10amd64/fromftp/games.txz     100% of  865 kB  734 kBps 00m01s
    ====>> Extracting games.txz... done
    ====>> Fetching lib32.txz for FreeBSD 10.0-RELEASE amd64
    /poudriere/jails/10amd64/fromftp/lib32.txz     100% of   14 MB 1316 kBps 00m12s
    ====>> Extracting lib32.txz... done
    ====>> Cleaning up... done
    ====>> Jail 10amd64 10.0-RELEASE amd64 is ready to be used

    # poudriere ports -c -p local
    ====>> Creating local fs... done
    ====>> Extracting portstree "local"...
    Looking up portsnap.FreeBSD.org mirrors... 7 mirrors found.
    Fetching public key from ec2-eu-west-1.portsnap.freebsd.org... done.
    Fetching snapshot tag from ec2-eu-west-1.portsnap.freebsd.org... done.
    Fetching snapshot metadata... done.
    Fetching snapshot generated at Tue Feb 11 01:07:15 CET 2014:
    94a3431f0ce567f6452ffde4fd3d7d3c6e1da143efec76100% of   69 MB 1246 kBps 00m57s
    Extracting snapshot... done.
    Verifying snapshot integrity... done.
    Fetching snapshot tag from ec2-eu-west-1.portsnap.freebsd.org... done.
    Fetching snapshot metadata... done.
    Updating from Tue Feb 11 01:07:15 CET 2014 to Tue Feb 11 16:05:20 CET 2014.
    Fetching 4 metadata patches... done.
    Applying metadata patches... done.
    Fetching 0 metadata files... done.
    Fetching 48 patches.
    (48/48) 100.00%  done.
    done.
    Applying patches...
    done.
    Fetching 1 new ports or files... done.
    /poudriere/ports/tester/CHANGES
    /poudriere/ports/tester/COPYRIGHT

    [...]

    Building new INDEX files... done.

在一台電腦，poudriere 可使用多組設定在多個 Jail 編譯來自不同 Port 樹的 Port。用來定義這些組合的自訂設定稱作 sets，可在安裝 ports-mgmt/poudriere 或 ports-mgmt/poudriere-devel 後參考 poudriere(8) 中的 CUSTOMIZATION 章節來取得詳細的資訊。

在此處示範的基本設定放了單一個 jail-, port- 以及 set- 特定的 make.conf 在 /usr/local/etc/poudriere.d。在此範例使用的檔案名稱由 Jail 名稱、Port 名稱以及 set 名稱所組成：10amd64-local-workstation-make.conf。系統 make.conf 與這個新的檔案在編譯時期會被合併為編譯 Jail 要使用的 make.conf。

要編譯的套件會輸入到 10amd64-local-workstation-pkglist：

    editors/emacs
    devel/git
    ports-mgmt/pkg
    ...

可使用以下方式設定選項及相依：

    # poudriere options -j 10amd64 -p local -z workstation -f 10amd64-local-workstation-pkglist

最後，編譯套件並建立套件檔案庫：

    # poudriere bulk -j 10amd64 -p local -z workstation -f 10amd64-local-workstation-pkglist

在執行時，按下 `Ctrl`+`t` 可以顯示目前編譯的狀態，Poudriere 也會編譯在 /poudriere/logs/bulk/jailname 中的檔案，可用在網頁伺服器來顯示編譯資訊。

完成之後，新套件現在可以從 poudriere 檔案庫來安裝。

要取得更多使用 poudriere 的資訊，請參考 poudriere(8) 及主網站 https://github.com/freebsd/poudriere/wiki。

### 4.6.2. 設定 pkg 客戶端使用 Poudriere 檔案庫

雖然可以同時使用自訂的檔案庫與官方檔案庫，但有時關閉官方檔案庫會有幫助。這可以透過建立一個設定檔覆蓋並關閉官方的設定檔來完成。建立 /usr/local/etc/pkg/repos/FreeBSD.conf 包含以下內容：

    FreeBSD: {
    	enabled: no
    }

通常最簡單要提供 poudriere 檔案庫給客戶端的方式是透過 HTTP。安裝一個網頁伺服器來提供套件目錄，通常會像：/usr/local/poudriere/data/packages/10amd64，其中 10amd64 是編譯的名稱。

若要連往套件檔案庫的 URL 是：`http://pkg.example.com/10amd64`，則在 /usr/local/etc/pkg/repos/custom.conf 的檔案庫設定檔為：

    custom: {
    	url: "http://pkg.example.com/10amd64",
    	enabled: yes,
    }

## 4.7. 安裝後的注意事項

不論軟體是從套件或 Port 安裝，大部份的第三方應用程式安裝完後需要做某種程度的設定，下列指令與位置可以用來協助找到應用程式安裝了什麼。

- 大部份應用程式安裝會在 /usr/local/etc 安裝至少一個預設的設定檔，若應用程式有大量設定檔的時則會建立一個子目錄來存放這些設定檔。範例的設定檔案名稱通常使用 .sample 結尾，設定檔應要仔細查看並可能要做一些編輯讓設定檔符合系統的需求，要編輯設定檔範本前需先複製該檔案並去除 .sample 副檔名。

- 應用程式提供的文件會安裝到 /usr/local/shared/doc，且許多應用程式也同時會安裝操作手冊，在繼續使用應用程式前應先查看這些文件。

- 部份應用程式會以服務的方式執行，在啟動應用程式前前需要加入設定到 /etc/rc.conf。這些應用程式通常會安裝啟動 Script 到 /usr/local/etc/rc.d，請參考 啟動服務 來取得更多資訊。

  | 依設計，應用程式不會在安裝時執行其啟動 Script，也不會在解除安裝或升級時執行其中止 Script，這留給各系統的管理者去做決定。

- csh(1) 的使用者應要執行 `rehash` 來更新已知 Binary 清單到 Shell 的 `PATH`。

- 使用 `pkg info` 來了解應用程式安裝了那些檔案、操作手冊以及 Binary。

## 4.8. 處理損壞的 Port

當發現某個 Port 無法順利編譯或安裝，可以嘗試以下幾種方法解決：

1. 搜尋 問題回報資料庫 看該 Port 有沒有待審核的修正，若有的話可以使用該修正來修正問題。

2. 尋求維護人員的協助，在 Port Skeleton 目錄中輸入 `make maintainer` 或閱讀 Port 的 Makefile 來取得維護人員的電子郵件位址。寄給維護人員的郵件內容請記得要包含 Port 的 Makefile 中的 `$FreeBSD:` 一整行及輸出的錯誤訊息。

   | 有一些 Port 並非由個人維護，而是由 郵遞論壇 維護，有許多，但並非全部，只要郵件地址長的像 freebsd-listname@FreeBSD.org 都是，寄信時記得代入實際的論壇名稱。 尤其是由 ports@FreeBSD.org 所維護的 Port 都不是由特定個人維護，而該 Port 的修正與支援都是來自訂閱該郵遞論壇的一般社群所提供，我們隨時歡迎志工參與!

   若寄信後沒有取得任何回應，可以依照 撰寫 FreeBSD 問題回報 的說明使用 Bugzilla 提出問題回報。

3. 自行修正看看！Porter’s Handbook 中含有 Port 基礎架構的詳細資訊，可提供資訊讓您可修正偶然損壞的 Port 或甚至您可以提交之自己的 Port！

4. 依照 使用 pkg 管理 Binary 套件 中的說明安裝 Binary 套件，替代使用 Port 安裝。

最後修改於: March 9, 2024 由 Danilo G. Baio

Prev
Home
Next