Zxilly
Calm down
Zxilly's Blog

cjv:仓颉 SDK 版本管理器

参加仓颉内测的时候,我经常要在几个 SDK 版本之间来回切换。

仓颉当时更新很快,小版本之间也可能有不少破坏性变更。新版本发布以后旧的通常还不能直接删,手上的项目包括一些第三方依赖可能还依赖旧版,新功能要用新版试,出了兼容性问题又得切回原来的版本复现。电脑里需要配置好几套 SDK。

SDK 多了,切换就有点麻烦。PATHCANGJIE_HOME 要改,cjc、标准库和运行时库也得对上版本。只要有一处还指着旧目录,接下来看到的报错就未必是代码本身的问题。

因此我写了 cjv 来管这些 SDK。它把不同版本分开放,运行 cjccjpm 时再决定用哪一套。项目也可以在 cangjie-sdk.toml 里写明版本,换台电脑或者放进 CI,不用再重新配一遍。

安装当前 LTS 只需要:

cjv install lts
cjv default lts
cjc --version

前两行安装并选择 LTS。以后仍然运行普通的 cjc

切换工具链

cjv 初始化时会把一组代理放进 PATH。以后切换默认版本只改 cjv 的设置,shell 配置不用跟着重写:

cjv install sts
cjv default sts
cjc --version

临时试一下 nightly,也不用动默认版本:

cjc +nightly --version
cjpm +nightly build

+nightly 只对当前命令有效。

项目使用的版本可以写在仓库根目录的 cangjie-sdk.toml 里:

[toolchain]
channel = "lts-1.0.0"

cjv 会从当前目录向上寻找这个文件。项目中的 cjccjpm 都使用这里声明的版本,CI 脚本不用再单独写一份版本号。

哪些情况不需要 cjv

机器上长期只有一个固定版本时,手动配置环境更直接。没有切换版本或固定项目版本的需求,cjv 只会多加一层代理。

cjv 也不代替 cjpm。依赖解析、构建和包管理还是 cjpm 的工作;cjv 只管 SDK 从哪里来、放在哪里,以及本次命令使用哪一版。

项目要求的工具链尚未安装时,cjv 默认会自动下载。禁止联网的构建环境可以关掉这个行为:

cjv set auto-install false

关掉以后,缺少工具链或组件会直接报错。

安装

Linux 和 macOS:

curl -sSf https://cjv.zxilly.dev/install.sh | sh

Windows PowerShell:

irm https://cjv.zxilly.dev/install.ps1 | iex

脚本根据操作系统和 CPU 架构下载 cjv,校验后完成初始化。它写入的 PATH 一般要等到下一个终端会话才会生效。Linux 和 macOS 可以在当前终端加载:

source ~/.cjv/env

GitHub 访问不稳定时,Linux 和 macOS 可以改用 GitCode 镜像:

curl -sSf https://cjv.zxilly.dev/install.sh | sh -s -- --mirror

PowerShell 的写法是:

$env:CJV_MIRROR = "1"; irm https://cjv.zxilly.dev/install.ps1 | iex

不想执行安装脚本的话,可以从 Releases 下载预编译文件,把 cjv(Windows 上是 cjv.exe)放进 PATH。第一次运行 cjv install 时,它会补做初始化。

常用命令

安装和选择版本

ltsstsnightly 会解析到各自的当前版本。需要固定编译器时,直接安装带版本号的工具链:

cjv install lts-1.0.0
cjv default lts-1.0.0

查看本机状态:

cjv show
cjv show installed
cjv show active

show active 会显示当前工具链以及选择来源。发现版本与预期不同时,再用 cjv which cjc 查看实际执行的文件。

如果不喜欢把 +nightly 写在被代理的命令后面,也可以显式调用 cjv run

cjv run nightly cjc --version

两种写法的结果一样,都不会修改默认设置。

在项目中声明组件和目标

cangjie-sdk.toml 不只能写 SDK 版本。项目需要 stdx、离线文档或交叉编译目标时,可以一并声明:

[toolchain]
channel = "sts"
components = ["stdx", "docs"]
targets = ["ohos", "android"]

targets 中写 ohosandroid 这样的后缀,不写完整的平台名称。auto-install 开启时,cjv 会在第一次运行工具前补齐缺少的内容。

有时项目固定使用 LTS,但我想在本机拿 nightly 测一下。这种情况可以设置目录覆盖,不用修改已经提交的配置文件:

cjv override set nightly
cjv show active

用完删掉即可:

cjv override unset

运行编译产物

仓颉程序会动态链接 SDK 中的运行时库。直接执行编译产物时,系统可能找不到这些库。cjv exec 会先准备当前工具链的运行时环境,再启动程序:

cjv exec ./my_binary
cjv exec +nightly ./my_binary

它只影响启动的子进程。想让整个终端会话都使用当前工具链,可以加载 envsetup 的输出。

Bash 和 Zsh:

eval "$(cjv envsetup)"

PowerShell:

cjv envsetup | Invoke-Expression

代理如何选择工具链

初始化 cjv 后,PATH 中会多出一个固定目录,里面放着 cjccjpmcjfmtcjlint 等代理。代理先选出工具链,再启动对应 SDK 目录中的程序。

工具链的选择顺序是:

  1. 命令行中的 +toolchain
  2. CJV_TOOLCHAIN 环境变量
  3. 当前目录的本地覆盖
  4. 当前目录或父目录中的 cangjie-sdk.toml
  5. 默认工具链

越靠前的设置优先级越高。项目用 cangjie-sdk.toml 固定版本,本机测试可以加目录覆盖,单条命令还能再指定一次 +nightlycjv show active 会列出最终结果和它的来源。

工具链也可以指向一套已有的本地 SDK:

cjv toolchain link mysdk /path/to/local/sdk

cjv 保存的是目录引用。卸载 mysdk 不会删除原目录。由于自定义工具链没有对应的官方发布文件,缺少的组件也不能由 cjv 自动下载。

更新和卸载

检查并安装工具链更新:

cjv check
cjv update

更新 cjv 自身:

cjv self update

普通工具链用 cjv uninstall <toolchain> 删除。卸载 cjv 的命令是:

cjv self uninstall

这条命令会删除整个 cjv 主目录,已安装的工具链和设置也在里面。运行前最好先看一眼目录里有没有要保留的东西。

项目地址:https://github.com/Zxilly/cjv

中文用户手册:https://cjv.zxilly.dev/book/user-guide/zh-CN/

没有标签
首页      代码      cjv:仓颉 SDK 版本管理器

Zxilly

文章作者

发表回复

textsms
account_circle
email

Zxilly's Blog

cjv:仓颉 SDK 版本管理器
参加仓颉内测的时候,我经常要在几个 SDK 版本之间来回切换。 仓颉当时更新很快,小版本之间也可能有不少破坏性变更。新版本发布以后旧的通常还不能直接删,手上的项目包括一些第三方依赖…
扫描二维码继续阅读
2026-08-26