2012年5月6日 星期日

使用 MacPorts 安裝 Unix 程式及 Python 模組

1. 什麼是 MacPorts

MacPorts 是一套 Unix 套件管理介面,可以方便我們安裝、更新、移除、管理 Unix 程式。

熟悉 Linux 的人,可以把 MacPorts 想像 Linux 上面的 APT 系統。比如我們可以用 MacPorts 來安裝 PHP+MySQL 或其他 Linux 上好用的程式。


MacPorts 的故事

Mac OS X 的前一代並不是 Mac OS 9,而是賈柏斯在 1985 年被董事會趕出蘋果公司後,在 80 年代自己創立的 NeXTStep 作業系統。

NeXTStep 底層便是 BSD 的 Unix 系統,所以當賈柏斯回鍋蘋果後,就決定用 FreeBSD 作為 OS X 底層的 Unix 核心。MacPorts 其實就是把 FreeBSD 標準的 ports 套件系統,再移植修改到 OS X 上。FreeBSD 的創辦人後來也被挖角到蘋果,他個人便支持 MacPorts 計畫。 

再加上編譯 Android 步驟也是以 MacPorts 為範例,因此雖然 OS X 上還有其他類似的套件管理系統 (如 HomeBrew),但我最推薦 MacPorts。

2. 安裝 MacPorts 系統

2.1 安裝基本 MacPorts 

請至 MacPorts 網站上下載安裝檔,再按照一般的 Mac 安裝方式。

2.2 目錄結構 

安裝完成後,系統會增加一個 /opt/local 目錄,未來 MacPorts 安裝的程式都會放在這裡。

這是一個很好的設計,因為每一版的 Mac OS X 已經內建很多基本的 Unix 指令,這些指令通常是放在 /bin 或 /usr/bin 目錄下,比如 ls 是 Mac OS 內建指令

$ which ls
/bin/ls

因此 Mac OS X 內建的 Unix 程式不會跟 MacPorts 的 Unix 程式打架。以後升級新版 Mac OS 時,也可順利升級,不會發生衝突。

2.3 設定環境變數 

由於 MacPorts 的安裝目錄跟 Mac OS 不同,所以我們需要修改環境變數,請編輯 ~/.profile 檔案,加上兩行

export PATH=/opt/local/bin:/opt/local/sbin:$PATH
export MANPATH=/opt/local/share/man:$MANPATH

MacPorts 的安裝程式通常會自動幫你加上第一行。但你還得加上第二行才能使用 man 指令查看說明文檔。

3. 基本使用方式

安裝好 MacPorts 後,所有 MacPorts 的操作都可在終端機命令列下使用 port 程式。

3.1 更新 Port Tree

MacPorts 的設計會把它目前管理的所有套件 (目前超過一萬個) 的基本資訊放在 /opt/local 下,稱作 Port Tree,接下來所有操作都會根據 Port Tree 內的資料去做。

比如過了一個月後,很多套件都已經更新了,這時候我們會希望用 port selfupdate 指令更新 Port Tree。

$ sudo port selfupdate
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.0.4 installed,
MacPorts base version 2.0.4 downloaded.
--->  Updating the ports tree
--->  MacPorts base is already the latest version

(注意 port 指令前面要打 sudo,代表這類指令會修改系統,需要 root 管理員權限)

3.2 安裝套件

使用 port search 指令可以尋找可安裝的套件,如
$ port search wget

接下來用 port install 安裝程式,如
sudo port install wget

3.3 管理已安裝套件

我們可以列出已安裝的程式
$ port list installed

(這邊列出來的程式會比我們安裝的還多,這是因為要安裝一個套件往往需要安裝其他套件,MacPorts 會自動幫忙安裝)

也可以列出已安裝,但網路上有更新版的程式
$ port list outdated

我們可以用一行指令升級這些程式
sudo port upgrade outdated

3.4 有圖型介面的程式

一般情況我們用 MacPorts 上安裝的都是 Unix 的命令列程式,但有少數程式是有視窗圖型介面的 (比如 Emacs),這個時候新裝的程式的啟動圖示會放在「應用程式」->「MacPorts」資料夾下。

可以再把這些程式從 Finder 拖拉到 Dock 上了。

以 Emacs 為例,雖然可以在網路上找到 Mac OS 的個別安裝檔,但這類常見 Unix 程式改用 MacPorts 安裝管理會比自行安裝好,一來版本常常會比較新,二來未來要升級也很方便。

4. 切換 Mac 內建的 Unix 程式 - 以 Python 為例

有些情況下 Mac 已經內建了一個功能,但我們希望用 MacPorts 安裝別的版本。

以 Python 為例,Mac OS X Lion 已經內建 Python 2.7 版,但我們卻可能希望改用 MacPorts 自己的 Python 版本,有幾個原因
  1. MacPorts 內的版本很齊全,比如有 Python 2.5, 2.6, 2.7, 3.1, 3.2, 3.3 可以選
  2. MacPorts 除了 Python 主程式,還幫忙移植了大量常用的 Python 模組。
    我目前用 port search py27 可以查到四百多個 Python 模組。
前面提到 MacPorts 的設計跟 Mac OS X 的主程式切割得很乾淨,所有檔案都放在 /opt/local 目錄下,所以假如想要安裝 MacPorts 的 Python 模組,得切換到 MacPorts 自己的一整套 Python 系統,而跳過 Mac OS 內建的那一套 Python 系統。

舉例,首先我們安裝 MacPorts 的 Python 2.7 套件
$ sudo port install python27

接下來 MacPorts 為了系統穩定性,並不會馬上取代原本 Mac OS 內建的 Python
$ which python
/usr/bin/python

我們可以使用 port select 指令切換 Python 系統,比如

$  sudo port select python 
Available versions for python:
none
python25-apple
python26-apple
python27
python27-apple (active)

這代表目前使用的是 Mac OS 內建的 Python 2.7,我們可以切換掉 MacPorts 內建的 Python 2.7
$  sudo port select python python27

這時候 Python 系統已經被切到 MacPorts 下的 Python 2.7 了



$ which python

/opt/local/bin/python


$ ls -l /opt/local/bin/python

lrwxr-xr-x  1 root  admin  24  5  6 20:50 /opt/local/bin/python -> /opt/local/bin/python2.7

這時候我們就可以利用 MacPorts 安裝各種 Python 2.7 的模組了,比如
$ sudo port install py27-lxml


這時 Python 檔案 (*.py) 開頭就不應該寫死路徑了,比如原本大家常常會寫
#!/usr/bin/python

應該要改成
#!/usr/bin/env python

結語

MacPorts 是 Mac OS 相比 Windows 的一大優勢。雖然 Windows 上也能裝 Cygwin 系統,但功能完整度就差很多了...

若能善用 MacPorts,可以發現 Mac OS 除了優秀的使用者介面外,在執行為 Linux/Unix 設計的專業程式,並不會比 Ubuntu/Redhat 這類原生的 Linux 套件遜色。這也是很多工程或科學工作人員愛用 Mac 的原因之一。

關於怎樣把 MacPorts 升級到 OS X Mountain Lion,請參考另一篇文章「升級 MacPorts 到 Mountain Lion

4 則留言:

  1. 安裝 Xcode 4.3 以後,Xcode 安裝路徑會從 /Developer 換到 /Applications 目錄下,只要確認 MacPorts 是最新版 (使用 port selfupdate 指令),port 指令會警告 Xcode 路徑改變,會提示你如何替換 Xcode 路徑 (他會告知如何執行 xcode-select 的指令)。

    回覆刪除
  2. 另外最近 port upgrade outdated 會把 GNU Emacs 更新到 24 版,問題比較多。

    可以先查看目前 emacs-app 的所有版本
    $ port list installed | grep emacs

    然後再 activate 舊版的 Emacs (假設舊的版本是 23.4_1)
    $ sudo port activate emacs-app @23.4_1
    ---> Computing dependencies for emacs-app
    ---> Activating emacs-app @23.4_1

    回覆刪除
  3. 如果希望 port upgrade outdated 不要升級到 Emacs,可以執行

    $ port list outdated | sed 's/^\([^ ]*\).*$/\1/g' | grep -v emacs | xargs sudo port upgrade

    這一行指令的功能就是在 port upgrade 時跳掉 emacs

    回覆刪除
  4. MacPorts 上現在最新版的 emacs 24 問題比較少,可以使用了。Options 選單 -> Show/Hide -> Tool-bar 可以把新增的 toolbar 隱藏起來。

    回覆刪除