深入淺出 Julia 套件管理 (Package Management)
使用內建 Pkg 套件管理工具
Pkg.jl 是 Julia 內建的套件管理工具 (Package Manager),可以在兩者不同的模式下進行套件的管理:
- REPL Mode
- 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,然後再執行命令函式。
新增套件
新增套件時,會先執行幾個動作:
- Registry 更新。
- Repository 更新。
- 安裝該套件與相依 (dependency) 所需的套件。
- 更新環境設定檔。
- Build 套件與相依套件。
- 在第一次 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 的管理),我們再來談。
參考資料
- Pkg.jl 官方文件 https://julialang.github.io/Pkg.jl/v1/
- Pkg3 The new Julia package manager | Karpinski & Carlsson https://www.youtube.com/watch?v=HgFmiT5p0zU
- Julia 1.0 套件管理 (一): Environment https://medium.com/@dboyliao/julia-1-0-%E5%A5%97%E4%BB%B6%E7%AE%A1%E7%90%86-%E4%B8%80-environment-7f2659ca177
- Wikipedia “TOML” https://zh.wikipedia.org/wiki/TOML
- 其他來源 (忘了)