登入  |  English
感謝您對「自由軟體鑄造場」的支持與愛護,十多年來「自由軟體鑄造場」受中央研究院支持,並在資訊科學研究所以及資訊科技創新研究中心執行,現已完成階段性的任務。 原網站預計持續維運至 2021年底,網站內容基本上不會再更動。本網站由 Denny Huang 備份封存。
也紀念我們永遠的朋友 李士傑先生(Shih-Chieh Ilya Li)。
源碼秘技 「純函數式」套件版本管理系統 Nix / NixOS

「純函數式」套件版本管理系統 Nix / NixOS

前言

Nix 的基礎概念如同 GoboLinux,每個套件都用獨立資料夾管理。

Nix 將每個套件視為一個函數的輸出值,其使用的函式庫則為該函數的傳入值,由於套件間不共用函式庫而避開了相依性地獄,因此開發團隊稱 Nix 是一個「純函數式」套件管理系統。

如果 Nix 單純是「又」一套套件管理系統,那我也不需要寫這篇了,幸好 Nix 引入了「版本控制」的概念讓我很放心的寫下去。

每當使用者安裝、移除套件或是修改設定檔時,Nix 會自動將當前使用環境設為一個新的版本,出問題時只要退回前一個版本即可解決問題。

NixOS 則是使用 Nix 做為套件管理工具的 GNU/Linux 發行版,從核心 (Kernel)、Nix 到套件,全部都可用 Nix 退回前一個版本。

官方網站除了提供原始碼,使用者也可以直接安裝二進位檔 (binary)。


簡單使用教學

以下皆以 Lubuntu 13.04 做為實驗環境。

Nix 的 nix-channel 相當於 source list 管理工具,nix-env 對應到 apt-get。

那麼如何操作 nix-channel 呢?

當使用者安裝一個軟體時,Nix 先根據 nix-channel 尋找是否有可安裝的二進位軟體包,有則直接下載,沒有則根據套件的安裝設定下載程式碼來編譯出套件並安裝。 nix-channel 最基本的 4 個參數分別為 --add、--remove、--list、--update,每個命令都用 sudo 執行。

--add 跟 --remove 用來新增與移除 channel。

例如:

sudo nix-channel --add https://nixos.org/releases/nixpkgs/channels/nixpkgs-unstable 即會自動將該 channel 加入 <b>~/.nix-channels中。

--list 會列出現有的 channel 及該 channel 的別名,使用者可以用別名的方式移除 channel。
--update 會從每個 channel 下載最新的二進位檔,每次新增 channel 後可先做 1 次。

有興趣的人可以到這邊尋找想要的 channel 及 nixpkgs channel(提供編譯好的二進位檔)。

有了 channel 後,要怎麼管理軟體包?

Nix 提供了 nix-env 這個指令,相當於 apt-get + git。

安裝、移除、更新的參數分別為 --install、--uninstall、--upgrade。
實際上,從 channel 下載的軟體包都放在 /nix/store/ 中,所謂的安裝只是將函式庫、執行檔連結到 <b>~/.nix-profile 中。
移除軟體包則是反過來將連結移除。

那麼先來試試看安裝 ghc 並且執行 ghci 看看:

  sudo nix-env --install ghc 或 sudo nix-env -i ghc
  ghci

咦?沒有 ghci?
因為 Nix 使用者環境沒加入設定檔中,所以搜尋不到。
根據官方文件,必需加入 sudo /etc/profile.d/nix.sh 或 sudo /nix/etc/profile.d/nix.sh 到 .bashrc。
而 nix.sh 等同在 .bashrc 中加入下列兩行:

  PATH=.nix-profile:"$PATH"
  export PATH

加入後只要 source .bashrc 就會能用 ghci 了。

剛剛只有講到 apt-get 吧?那 git 又是怎麼一回事?

nix-env 將不同版本稱為 generation。

最基本的是 --list-generations,會列出所有的 generation。
想返回之前的某個 generation,則使用 --switch-generation + 該 generation 的號碼。
例如:

  sudo nix-env --list-generations 

發現目前的 generation 是 6,如果想跳回 generation 4,則使用如下指令:

  sudo nix-env --switch-generation 4

想刪除 generation 5、6?

  sudo nix-env --delete-generations 5 6

前面有談到 --remove 只是移除掉連結,當使用者真的想移除掉軟體包時,必需使用 nix-collect-garbage,該指令不會產生新的 generation(無法返回前一個版本)。


總結

我們沒有談到使用 Nix 表達式(Nix expression Language,一個純函數、惰性的軟體包產生語言)建立 Nix 軟體包,也沒有談到如何使用 nix-store 分享自己的軟體包給其它人使用。
NixOS 目前的安裝方式跟 Arch 相似,官方 wiki 也有直接使用硬碟安裝 NixOS 的教學(Arch wiki 也有類似的教學資料),使用 Nix 直接打造一個發行版也是可行的。
我個人很期待 Nix 的未來發展,也希望大家會愛上這個工具。

作者簡介一卡,目前任職於百臂網路科技股份有限公司,是一名 Haskell 與 Functional Programming 的愛好者。





自由軟體鑄造場電子報 : 第 223 期 利用自由開源軟體元件開發雲端應用專案

分類: 源碼秘技