7.1 verylup:工具鏈安裝與版本管理(2024-2026)#
為什麼需要工具鏈管理器#
問題:工具鏈版本與專案的糾纏#
考慮一個常見的硬體團隊困境:
- 專案 A 在 2024 年開始,鎖定 Veryl 0.13;
- 專案 B 在 2025 年開始,需要 0.17 的新語法;
- 兩個專案的工程師是同一批人,共用同一批機器與 CI。
如果 Veryl 只有「安裝一個版本」這一種模式,這個困境無解:升級工具鏈,專案 A 的建置可能因語言變更而破壞;不升級,專案 B 無法使用新特性。工程師會被迫用「多個安裝路徑 + 手動切 PATH」這種脆弱的方式管理版本——而 PATH 是全域狀態,切換會互相污染,CI 上的重現更是噩夢。
解法:Rust 的 rustup 模式#
這個問題在軟體世界已經有成熟的答案:Rust 的 rustup。它的核心思想是:
把「工具鏈版本」與「專案」解耦:機器上可以並存任意多個工具鏈版本,由每個專案(或每條命令)指定要用哪一個。
具體機制有三:
- 單一入口:
rustc/cargo是代理程式(shim),實際呼叫哪個版本由當前目錄的rust-toolchain.toml或命令列的+指定器決定; - 版本並存:所有工具鏈版本安裝在使用者目錄下,互不干擾;
- 宣告式鎖定:專案用檔案聲明自己的工具鏈需求,進入目錄即生效。
Veryl 在 2024 年 9 月發布的 verylup,就是把這個模式完整移植到硬體工具鏈的產物。這不是偶然的模仿——Veryl 本身就用 Rust 實作,其開發者每天都在 rustup 的體驗下工作,「工具鏈管理應該長什麼樣」對他們而言是一個已有答案的問題。
verylup 的定位與安裝#
定位#
verylup 的職責範圍非常克制:它只管理 Veryl 工具鏈本身(veryl 編譯器與 veryl-ls 語言伺服器)。專案的相依性管理(第三方套件)不歸它管——那是 Veryl.toml 與 Veryl.lock 的職責(7.3 節)。這個分工與 rustup(管工具鏈)/ cargo(管相依)的分工完全同構。
安裝方式#
方式一:Release binary(推薦)。 從 GitHub Releases 下載對應平台的預編譯二進位,放入 PATH:
# Linux x86_64 的例子
curl -LO https://github.com/veryl-lang/verylup/releases/latest/download/verylup-latest-linux-x86_64.tar.gz
tar xzf verylup-latest-linux-x86_64.tar.gz
mv verylup ~/.local/bin/
方式二:從原始碼安裝(需要 Rust 環境):
cargo install verylup
一次性初始化:verylup setup#
安裝 verylup 之後,必須執行一次性的初始化:
verylup setup
這個命令做兩件事:
- 下載最新的 Veryl 工具鏈;
- 建立
veryl與veryl-ls兩個 shim,放入 PATH。
之後你在命令列使用的 veryl,其實是 verylup 安裝的代理程式——它會根據「當前目錄的設定」與「命令列的 + 指定器」把請求轉發給正確的底層工具鏈。你從此不需要知道工具鏈實際安裝在哪裡。
日常使用#
更新與安裝特定版本#
verylup update # 更新 latest 工具鏈到最新版
verylup install 0.12.0 # 安裝指定版本
verylup show # 列出已安裝的工具鏈與預設版本
verylup show 的典型輸出概念上如下:
| 工具鏈 | 狀態 |
|---|---|
| latest | 預設 |
| 0.12.0 | 已安裝 |
| local | 已安裝(Veryl 開發用) |
版本指定器 +#
關鍵語法是 +:在任何 veryl 命令前指定工具鏈版本:
veryl +0.12.0 build # 用 0.12.0 建置
veryl +latest build # 用 latest 建置
veryl +0.13.1 check # 用 0.13.1 檢查
這個設計讓「同一台機器、同一個終端機」可以在不同專案間無縫切換:
cd ~/proj-a && veryl +0.12.0 build # 專案 A 鎖定舊版
cd ~/proj-b && veryl +latest build # 專案 B 追新版
配合 CI 時,+ 指定器讓「建置時使用的工具鏈版本」成為 CI 設定檔裡顯式的一行,而不是「這台 runner 碰巧裝的版本」——後者是硬體專案最常見的不可重現來源之一。
local 工具鏈:支援語言自身開發的體驗設計#
verylup 有一個特別的設計值得單獨說明:
verylup install local
這個命令把本機 Veryl 儲存庫建置出來的工具鏈裝進管理系統,命名為 local;若系統中已存在 local 工具鏈,它會成為預設。
這是為 Veryl 語言本身的開發者設計的:當你 clone 了 Veryl 編譯器的儲存庫、修改了編譯器程式碼之後,verylup install local 讓你用剛剛自己編譯出來的編譯器去編譯專案——包括用 Veryl 寫的語言測試與標準函式庫。整個迴路(改編譯器 → 立即在真實專案上測試)不需要任何手動的 PATH 操作或安裝步驟。
這個設計透露的哲學與 rustup 的 rustup toolchain link 一脈相承:工具鏈管理器不僅服務使用者,也服務工具鏈的開發者。一門年輕語言的演化速度取決於「改動 → 驗證」迴路的長度,verylup 把這個迴路壓到了最短。
離線安裝與 Shell 完成#
離線環境#
安全隔離的網路(國防、金融、車用晶片)是硬體開發的真實場景。verylup 支援離線安裝:在有網路的機器上下載工具鏈封存檔,再於目標機器上安裝(具體命令以官方文件為準,形式為下載對應版本的工具鏈封包後 verylup install 指向本地檔案)。
Shell 完成#
verylup completion zsh veryl > _veryl
支援 Bash、Elvish、Fish、PowerShell、Zsh 五種 shell。對命令列工具而言這是小事,但它反映了一貫的態度(對照 2.2 節的生產力支柱):工具的採用成本中,日常摩擦佔比極大;補全讓 veryl +<Tab> 列出已安裝版本,把「版本管理」變成可探索的互動而不是記憶負擔。
版本策略的哲學#
Veryl 的版本節奏#
Veryl 處於快速演化期:minor 版本每月發布(0.11、0.12、……一路到 0.22 以上),官方 README 明確聲明:
"This project is under the exploration phase of language design."
(本專案處於語言設計的探索階段。)
這句聲明是誠實的,也定義了使用者的責任邊界:Veryl 還沒有 1.0,語法可能在 minor 版本之間變動。因此版本管理的責任更多落在專案一側。
兩種專案策略#
| 專案類型 | 建議策略 | 理由 |
|---|---|---|
| 生產專案(要 tape-out 的設計) | 鎖定 +X.Y.Z,版本寫進 CI 與文件 | 任何語言變更都可能改變生成的 SV;可重現性高於一切 |
| 開發中專案(探索、學習、庫) | 追 +latest,在 CI 中用最新版測試 | 及早發現語言演化對自己的破壞,回饋上游 |
兩種策略可以並存:開發期追 latest,進入簽核階段的那一刻鎖定版本,之後只在有明確理由時升級,且升級本身要跑完整的回歸與等價性檢查(見 7.3 節的「語意等價保證」討論)。
版本治理是語言成熟度的一部分#
把視野拉高:版本治理本身就是語言成熟度的一部分。比較幾個生態系:
| 語言生態 | 版本治理機制 | 成熟度的訊號 |
|---|---|---|
| Rust | rustup + rust-toolchain.toml + edition 機制 | 大版本不相容變更被隔離在 edition 中 |
| Python | PEP 流程 + 虛擬環境 + pyproject.toml | 版本碎片化問題長期存在,治理工具是後補的 |
| SystemVerilog | 無工具鏈版本概念——IEEE 標準(2005/2009/2012/2017)+ 各家工具版本 | 「這份 RTL 用什麼工具、什麼版本編譯」沒有標準答案,靠 Makefile 與口口相傳 |
| Veryl | verylup + + 指定器(2024-) | 從第一天就把「工具鏈版本可指定、可並存、可鎖定」視為基礎設施 |
SystemVerilog 那一列值得停留一下。硬體產業四十年來沒有工具鏈版本管理器,這不是疏忽,而是產業結構的結果:工具是 EDA 商的產品(VCS、Questa、Vivado),版本跟著工具授權走而不是跟著專案走,「這個專案用 VCS 2023.06 編譯」寫在專案文件裡而不是任何機器可讀的設定裡。verylup 把這個資訊變成了專案可宣告、CI 可執行、審計可查證的一等公民——這是第 7 章整章的底層主題。
Docker 與跨環境可攜性#
官方 Docker image#
2025 年 10 月,Veryl 開始提供官方 Docker image,把「工具鏈 + verylup」打包成可宣告的環境。這解決的是 CI 與新成員上手時的「環境漂移」:與其靠文件說「先裝 verylup、再 setup、再裝 Verilator」,不如給一個鏡像。
2026 年間的兩個變更值得注意,因為它們展示了跨環境可攜性的實務努力:
- 2026-09:Linux 二進位從 musl 轉為 glibc。musl(Alpine 使用的 libc)的靜態連結二進位雖然「處處能跑」,但在動態連結的工具鏈(如需要 dlopen 的模擬器外掛)場景下相容性問題多。轉向 glibc 意味著優先保證主流 Linux 發行版的可靠性;
- 2026-10:移除 Alpine/Bullseye 變體的 Docker tag。維護過多的平台變體會稀釋測試資源——「每個變體都要有人驗證」——收斂變體是用可攜性的廣度換可靠性的深度。
這兩個決定的方向一致:可攜性的重點不是「能裝在任何地方」,而是「在任何裝了的地方都表現一致」。
Dockerfile 範例#
FROM ubuntu:24.04
# 安裝 verylup 與最新工具鏈
RUN apt-get update && apt-get install -y curl ca-certificates \
&& curl -LO https://github.com/veryl-lang/verylup/releases/latest/download/verylup-latest-linux-x86_64.tar.gz \
&& tar xzf verylup-latest-linux-x86_64.tar.gz \
&& mv verylup /usr/local/bin/ \
&& verylup setup
# 鎖定專案使用的工具鏈版本
RUN verylup install 0.13.0
WORKDIR /work
ENTRYPOINT ["veryl"]
CI 中的用法:
- run: docker run --rm -v $PWD:/work veryl-ci:latest +0.13.0 build
注意版本鎖定出現在兩層:鏡像建置時安裝了 0.13.0,執行時用 +0.13.0 指定。雙重鎖定的意義是:即使鏡像被重建,命令列的指定器也保證行為不變。
工具鏈演進時間線#
timeline
title Veryl 工具鏈與 verylup 的演進 2022-2026
2022 : Veryl 語言首次公開 : 單一安裝方式
2023 : 編譯器快速迭代 : 版本碎片化問題浮現
2024-09 : verylup 發布 : setup 機制 : + 版本指定器 : local 工具鏈
2025 : 每月 minor 發布節奏成形 : 0.11 到 0.20+
2025-07 : 套件註冊表上線 : 相依管理成熟
2025-10 : 官方 Docker image
2026-09 : Linux 二進位 musl 轉 glibc
2026-10 : 移除 Alpine/Bullseye 變體 : 平台策略收斂設計討論#
verylup 解決了什麼、沒解決什麼#
| 問題 | verylup 是否解決 | 由誰解決 |
|---|---|---|
| 多專案多版本並存 | 是 | verylup 的 shim + + |
| CI 中的版本確定性 | 是 | + 指定器寫進 CI 設定 |
| 專案相依套件的版本 | 否 | Veryl.toml / Veryl.lock(7.3 節) |
| 語言本身的語意變更風險 | 部分 | 鎖定版本 + 回歸測試(本節)+ 語意等價保證(7.3 節) |
| 下游工具(綜合器、模擬器)的版本 | 否 | 傳統 EDA 授權模式,語言層無法觸及 |
最後一列誠實地指出了邊界:verylup 管理 Veryl 工具鏈,但晶片設計的工具鏈不止 Veryl——綜合器、佈局布線、簽核工具依然是 EDA 商的版本世界。verylup 能保證的是「同樣的 Veryl 原始碼在同樣的工具鏈版本下生成同樣的 SV」;生成的 SV 進入下游工具後的可重現性,仍取決於下游工具的版本管理——那是硬體產業層級的問題,不是一門語言能獨力解決的。
從 verylup 看 Veryl 的整體策略#
verylup 的存在本身說明了一件重要的事:Veryl 團隊很早就意識到,語言的競爭不只是語法的競爭,是整條工具鏈體驗的競爭。SystemVerilog 的工程師要拼裝:編譯器(工具商的)、lint(另一家的)、格式化(要麼沒有、要麼是開源半成品)、版本管理(沒有)、文件產生(沒有)。Veryl 從第一天就把這些做成一體(2.2 節的生產力支柱),verylup 是這個一體化版圖的最後一塊基礎設施:讓「用哪個版本的這一體化工具鏈」本身也變成一等公民。
實作練習#
練習一:建立版本並存環境#
# 安裝與初始化
verylup setup
verylup show
# 安裝兩個版本並驗證
verylup install 0.12.0
veryl +0.12.0 --version
veryl +latest --version
觀察: 兩條 --version 的輸出不同,但執行的命令名稱相同——這就是 shim 機制的運作證據。
練習二:驗證版本鎖定的可重現性#
- 建立一個小專案,分別用
veryl +0.12.0 build與veryl +latest build建置; diff兩次生成的.sv檔案;- 若有差異,逐項判斷:這是格式差異(可接受)還是語意差異(需要鎖定版本並回報)?
思考: 這個實驗就是「生產專案鎖定版本」策略的實證基礎——你親眼確認了「不同工具鏈版本可能生成不同的 SV」是否在你使用的版本區間內成立。
本節小結#
- verylup 把 rustup 模式移植到硬體工具鏈:版本並存、shim 入口、
+指定器、專案級鎖定。 verylup setup是一次性的必要初始化;verylup update / install / show管理版本;veryl +X.Y.Z在命令層指定版本。local工具鏈支援語言自身開發的短迴路——工具鏈管理器同時服務使用者與開發者。- 版本策略:生產專案鎖定
+X.Y.Z,開發中專案追+latest;版本治理是語言成熟度的一部分,SystemVerilog 四十年來欠缺這一層。 - Docker image(2025-10)與 2026 年的平台收斂(musl 轉 glibc、移除 Alpine/Bullseye)體現「一致可攜」優先於「到處可裝」。
- 邊界:verylup 只管 Veryl 工具鏈;相依套件歸 7.3 節的
Veryl.lock,下游 EDA 工具的版本仍在傳統授權模式中。
下一節(7.2)進入每天使用的四個命令:build、fmt、check/lint、doc,以及它們在 CI 中的整合方式。
下一節:第 7.2 節「build、fmt、lint、doc 與 CI 整合」