深入淺出 Julia 套件管理 (Package Management)

James Huang
10 min readApr 14, 2019

--

使用內建 Pkg 套件管理工具

Pkg REPL Mode

Pkg.jl 是 Julia 內建的套件管理工具 (Package Manager),可以在兩者不同的模式下進行套件的管理:

  1. REPL Mode
  2. Functional API Mode (本文將以 Jupyter Notebook 做為範例環境)

在本文中,將會介紹幾個比較常用的 Pkg 指令深入介紹如何透過環境 (environment) 來了解 Julia 的套件管理、並說明如何建構不同的專案 (project) 環境

開始使用

REPL 模式

輸入 ']' 即可進入套件管理命令提示。

julia> ]

這時候可以看到命令提示字元已經變更為套件管理命令提示。輸入 status 或是 st 指令列出目前 project 資訊,例如已安裝的套件及版本。

(v1.1) pkg> status
# 或是
(v1.1) pkg> st

要退出的話,按 BackSpace 鍵或是 Ctrl+C 都可以退出套件管理命令提示。

Functional API 模式

使用 Functional API 模式時,要先使用 using Pkg,然後再執行命令函式。

新增套件

新增套件時,會先執行幾個動作:

  1. Registry 更新。
  2. Repository 更新。
  3. 安裝該套件與相依 (dependency) 所需的套件。
  4. 更新環境設定檔。
  5. Build 套件與相依套件。
  6. 在第一次 using 套件時,會進行 precompile 的動作。

下列範例以安裝 PyCall 套件為例。

REPL 模式

(v1.1) pkg> add PyCall

Functional API 模式

下面的範例是安裝完 PyCall 套件後,呼叫 Python math 並進行計算。

Julia 很多套件都需要呼叫 Python 套件,如果本機已經有 Python 環境,而希望直接使用已安裝的版本,在新增套件前須指定 ENV 變數 (如下範例)。

若未指定的話,當有需要 Python 套件時,Julia 會用內含的 Miniconda 進行 Python 套件的安裝。

julia> ENV["PYTHON"]="<Python安裝路徑>\\python.exe"

安裝特定版本的套件

有時候因開發需求,需要使用某個套件的特定版本,這時候在 add 時就需要指定版本編號。

REPL 模式

(v1.1) pkg> add PyCall@1.91.0

Functional API 模式

以下面例子來講,安裝指定的版本,將原前版本降級。

另外,也可以從遠端或是本地端的 gitrepo 安裝。

Pkg.add(PackageSpec(url="https://github.com/JuliaLang/Example.jl", rev="master")) # From url Pkg.add(PackageSpec(url="/remote/mycompany/juliapackages/OurPackage"))` # From path (has to be a gitrepo)# Source: Pkg.jl 官方文件

已安裝的套件檔案

路徑結構

以 Windows 為例,Julia 主要的環境目錄在 c:\使用者\<登入帳號>\.julia 路徑下。目錄結構如下圖。

  • compiled: precompile 的檔案存放路徑。如果有安裝多版本 Julia,會依不同版本環境儲存。
  • conda: 安裝 mini conda 的路徑,包含 conda package manager 等。
  • environments: 存放環境設定檔 Project.toml 和 Manifest.toml。
  • logs: manifest 的存取紀錄,和 REPL 指令的歷史紀錄。
  • packages: 安裝套件及 Build 的檔案路徑。
  • prefs: 套件的偏好設定,例如:我們安裝 IJulia 到既有的 Jupyter 時,指定既有 Jupyter 的路徑及執行檔的設定值就會存放在此路徑下。
  • registries: repo 設定檔。

Project.toml 與 Manifest.toml 設定檔

「TOML」這個名字是「Tom’s Obvious, Minimal Language(湯姆的淺顯的、極簡的語言)」的縮寫,Julia 環境使用 TOML 做為設定檔的格式。

Project.toml 記錄透過 Pkg 安裝的套件。

[deps]
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"

Manifest.toml 記錄已安裝的套件及相依套件的資訊。以 IJulia 為例,我們可以看到有許多相依的套件。另外也包含了版本編號等資訊。

[[IJulia]]
deps = ["Base64", "Conda", "Dates", "InteractiveUtils", "JSON", "Markdown", "MbedTLS", "Pkg", "Printf", "REPL", "Random", "SoftGlobalScope", "Test", "UUIDs", "ZMQ"]
git-tree-sha1 = "8eb8459d806de665f1347b25e9ad9428c2609f0f"
uuid = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
version = "1.18.1"
[[PyCall]]
deps = ["Conda", "Dates", "Libdl", "LinearAlgebra", "MacroTools", "Serialization", "Statistics", "Test", "VersionParsing"]
git-tree-sha1 = "29febb62247356e13ef87bf253d1cda10de74bfc"
uuid = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
version = "1.91.0"
...

Project.toml 與 Manifest.toml 兩個設定檔是建構環境重要的檔案,不建議手動修改,以免造成資訊不完整。

套件的安裝路徑 packages

安裝的套件及其相依的套件會安裝 packages 路徑下。特別要提的是,一旦安裝過後,不需要的套件檔案,包含曾安裝過套件不同的版本,均會存放不會清除,如下圖所示,本機曾安裝過不同版本的 PyCall,均會保存。

同一個套件、在同一個環境,僅會有一個版本可以使用,不會有多版本並存的情況。

清除必須要透過 gc 指令,用法會在刪除套件指令時示範。

更新套件

REPL 模式

update 指令若不帶參數的話,會更新所有套件。若只要更新單一套件的話,指定套件名稱即可。

(v1.1) pkg> update

(v1.1) pkg> update PyCall

Functional API 模式

強制不更新套件版本

如果在環境中有特定的套件要維持不更新版本的話,可以透過 pin 指令來達到目的。

舉例來說,我們把 PyCall 版本降級,而且要強制維持 1.91.0 版本 (目前最新版本為 1.91.2)。

(v1.1) pkg> pin PyCall

以下面 Functional API 模式為例,我們可以看到被 pin 的套件版本標記了 ⚲ 符號,而且就算執行 update,也不會被更新為新版。

解除 pinned 套件

要解除版本鎖定,使用 free 指令,⚲ 標記被移除時表示該版本已經解除鎖定。

(v1.1) pkg> free PyCall

刪除套件

刪除套件可以透過 rm 指令達成。

(v1.1) pkg> rm PyCall

或是透過 Functional API 模式

using Pkg
Pkg.rm("PyCall")

刪除未使用的套件實體檔案

在上文中有提到,執行 rm 指令後套件的實體檔案並不會從磁碟中移除,若確定這些檔案已經不需要的話,可以執行 gc 指令移除實體檔案,被刪除的套件的相依套件也會被移除,如下面範例所示。

不移除實體檔案的好處是,如果下次再重新安裝該套件的相同版本時,不需要再經過下載的動作,所以重新安裝的速度會非常快。

建立獨立環境

在 Julia 裡面,建立獨立的環境 (environment) 與系統環境區隔,稱為專案 (project),其概念可類比為 Python 的 virtual environment,也是用來開發套件時所必需要做的。

在獨立環境下安裝的套件,實體檔案仍然會安裝到系統環境下 (以 Windows 為例:c:\使用者\<登入帳號>\.julia)。

從遠端安裝

下面程式碼示範的是:

  • 從遠端下載 Project.toml 檔
  • 啟動專案
  • 下載安裝所設定的套件
  • precompile 專案中的套件,在未來使用時就不需要再經過 precompile,節省使用時間。

範例是下載安裝 Packt 出版的 Julia Programming Projects 書中第二章所需要的套件。

還有另一個可以應用的場景,當要移轉專案時,也可以透過上面介紹的方式,在另外一台電腦上方便地重建環境。

結語

Julia 內建的 Pkg 套件管理功能功能完整,在使用上難度也不高。不管是透過 REPL 模式或是 Functional API 模式,除了語法上有些不同之外,均能達到相同的目標。

本文介紹了常用的指令,可以用來管理套件與建構環境。Pkg 還有其他的指令,也許未來在有用到的時候,或是討論進階主題時 (例如 registry 的管理),我們再來談。

參考資料

--

--