Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

简介

cjv(Cangjie Version Manager)是仓颉编程语言 SDK 的工具链管理器。它在一台机器上管理多个仓颉 SDK 安装,处理版本切换,并对 cjccjpm 等 SDK 工具提供透明的代理执行。

cjv 解决什么问题

直接安装仓颉 SDK 时,系统里往往只能保留一个版本,切换版本意味着重新下载、解包、改 PATH。当你手头有多个项目、各自需要不同的 SDK 时,这会很麻烦。

cjv 把 LTS、STS、nightly 和具体版本的 SDK 并排安装在同一个主目录下,互不干扰。你可以为整机设置一个默认工具链,也可以为单个目录或单条命令指定工具链;cjv 会按环境变量、目录覆盖、工具链文件、默认值的优先级,解析出每次该用哪个 SDK。

直接运行 cjccjpm 等命令时,cjv 会把调用代理到解析出的工具链,并注入运行时和组件所需的环境变量(如 CANGJIE_STDX_PATH_DYNAMIC)。你不需要手动改 PATH 或导出变量。

在此之上,cjv 还支持交叉编译目标 SDK、stdx 等扩展组件、离线文档,以及配置运行时环境以直接运行编译产物。

适合谁用

cjv 面向需要在 LTS、STS、nightly 之间来回切换的仓颉开发者,以及在同一台机器上维护多个项目、各项目锁定不同 SDK 版本的人。如果你做交叉编译(如鸿蒙 OHOS、Android),需要在宿主 SDK 之外管理目标 SDK,cjv 也能帮上忙。团队可以通过工具链文件让版本切换可复现、可随项目走。

上手路径

  • 安装 cjv:获取并安装 cjv 本体。
  • 快速上手:安装第一个工具链、设默认、运行命令。
  • 核心概念:了解工具链、通道、组件、代理与覆盖等术语,理解 cjv 的工作方式。

cjv 以 Apache-2.0 协议开源,源码见 https://github.com/Zxilly/cjv

安装 cjv

本章介绍如何安装 cjv 自身。cjv 是一个单文件可执行程序,安装它不需要预先准备任何仓颉 SDK。工具链由 cjv 在安装后按需下载(见快速上手)。

共有三种安装方式:

如果网络环境无法访问 GitHub,可使用文中各方式的镜像源变体,从 GitCode 下载。

一键安装脚本

脚本会探测当前平台、下载匹配的二进制、校验 SHA-256,然后运行 cjv init 完成初始化(包括把 cjv 的 bin 目录加入 PATH)。

Linux / macOS

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

脚本探测不到终端时(例如纯管道执行)会以非交互方式静默安装。若检测到控制终端,cjv init 会进入交互式向导,询问安装目录、是否修改 PATH 等。把额外参数转发给 cjv init 即可跳过交互,例如用 -y 接受默认选项:

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

-s -- 之后的所有参数(除 --mirror 外)都会原样传给 cjv init,因此 --no-modify-path--default-toolchain noneinit 的选项均可在此使用。

Windows(PowerShell)

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

install.ps1 接受 -Yes(跳过确认)、-DefaultToolchain <name>(默认安装的工具链,none 表示不装)、-NoModifyPath(不修改 PATH)等参数。通过管道执行时需用脚本块形式传参:

& ([scriptblock]::Create((irm https://cjv.zxilly.dev/install.ps1))) -Yes

Windows ARM64 没有原生构建,脚本会自动改装 amd64 版本,在系统的 x64 模拟层下运行。

镜像源(GitCode)

GitHub 访问不畅时,使用镜像源从 GitCode 下载 cjv-mirror 归档:

# Linux / macOS:加 --mirror 标志
curl -sSf https://cjv.zxilly.dev/install.sh | sh -s -- --mirror
# Windows:设置 CJV_MIRROR 环境变量
$env:CJV_MIRROR = "1"; irm https://cjv.zxilly.dev/install.ps1 | iex

镜像与默认源装出的是同一个 cjv,区别仅在于下载来源以及后续 cjv self update 的更新源。镜像变体可与上面的其它参数自由组合,例如 curl -sSf https://cjv.zxilly.dev/install.sh | sh -s -- --mirror -y

下载预编译二进制

前往 Releases 页面,下载与平台匹配的归档并解压,把得到的 cjv(Windows 上为 cjv.exe)放入 PATH 中的任意目录。

归档命名规则为 cjv_<goos>_<goarch>,扩展名在 Windows 上是 .zip,其余平台是 .tar.gz

平台归档文件
Linux x86_64cjv_linux_amd64.tar.gz
Linux ARM64cjv_linux_arm64.tar.gz
macOS Apple Siliconcjv_darwin_arm64.tar.gz
macOS Intelcjv_darwin_amd64.tar.gz
Windows x86_64cjv_windows_amd64.zip

镜像源用户可从 GitCode Releases 下载对应的 cjv-mirror_<goos>_<goarch> 归档。

手动安装的二进制不会自动初始化。首次安装工具链时,cjv 会补上 PATH 配置,详见下文首次安装时的 PATH 配置

从源码编译

需要本机已安装 Go(版本要求见仓库 go.mod):

go install github.com/Zxilly/cjv/cmd/cjv@latest

二进制会被装到 $(go env GOBIN)(默认 $(go env GOPATH)/bin),请确保该目录在 PATH 中。国内网络可加上代理:

GOPROXY=https://goproxy.cn,direct go install github.com/Zxilly/cjv/cmd/cjv@latest

与手动下载二进制一样,源码安装不会自动初始化,PATH 会在首次安装工具链时配置。

首次安装时的 PATH 配置

cjv 在自己的 bin 目录(默认 ~/.cjv/bin)下放置二进制以及指向各工具链的代理符号链接(见代理)。要让 cjccjpm 等命令在终端中直接可用,这个目录必须在 PATH 中。

通过安装脚本安装时,cjv init 会立即完成 PATH 配置。通过 go install 或手动下载二进制安装时,cjv 在你首次安装工具链(如 cjv install lts)时才把 bin 目录加入 PATH

具体写入方式因平台而异。Windows 上写入用户级注册表 PATH;Linux 和 macOS 上把 PATH 追加到 shell 配置文件(如 ~/.profile~/.bashrc~/.zshenv 以及 fish 的 config)。无论哪种方式,配置都要在新开的终端里才生效;当前会话需重启或手动 source 才能识别新 PATH

跳过自动配置

把环境变量 CJV_NO_PATH_SETUP 设为 1,即可跳过这一步的 PATH 修改,适用于 CI 等不希望改动用户环境的场景:

CJV_NO_PATH_SETUP=1 cjv install lts

使用安装脚本时,Linux / macOS 传 --no-modify-path,Windows 用 -NoModifyPath。此时需手动把 bin 目录加入 PATHcjv init 也会打印出可供 sourceenv 脚本路径(Linux / macOS 为 ~/.cjv/env,Windows 为 ~/.cjv/env.ps1~/.cjv/env.bat)。

CJV_NO_PATH_SETUP 等环境变量的完整说明见环境变量

验证安装

cjv --version

能打印出版本号就说明安装成功。接下来可以安装第一个工具链,继续阅读快速上手

cjv 自身的更新用 cjv self update,卸载用 cjv self uninstall(会一并移除所有已安装的工具链)。详见命令参考

快速上手

本章带你跑通从安装工具链到运行仓颉工具的完整流程,并介绍日常会用到的常用命令。读完即可上手,更深入的概念见 核心概念,每条命令的完整选项见 命令参考

本章假设你已经装好了 cjv 本身。如果还没有,先看 安装 cjv

五分钟跑通

下面四步演示了最典型的用法:安装一个 LTS 工具链、把它设为默认、检查状态,再用它运行命令。

# 1. 安装最新的 LTS 工具链
cjv install lts

# 2. 设为默认工具链
cjv default lts

# 3. 查看活跃和已安装的工具链
cjv show

# 4. 用指定工具链运行命令
cjv run lts cjc --version

cjv install lts 下载并安装 LTS 通道的最新工具链。lts 是一个通道名,cjv 会把它解析成具体版本。除了 lts,你还可以安装 stsnightly 或某个确切的版本号。各通道的含义见 通道

cjv default ltslts 记为默认工具链。设好默认后,未在项目里另行声明工具链时,cjv 都会使用它。

cjv show 列出当前活跃的工具链和所有已安装的工具链,便于确认安装结果。只想看其中一项时,可用 cjv show activecjv show installed

cjv run lts cjc --version 显式用 lts 工具链执行 cjc --versioncjv run <工具链> <命令> [参数...] 临时切到指定工具链运行某条命令,不改变默认设置,便于在多个工具链之间临时对比。

直接使用 cjccjpm(代理执行)

装好工具链并配置好 PATH 后,你不需要每条命令都加 cjv run 前缀,直接调用 SDK 工具即可:

cjc --version
cjpm build

cjv 会解析当前应使用的工具链,把命令转发给对应的 SDK,并配置必要的运行环境。常用的 cjccjpmcjfmtcjlintcjdbcjcovcjprof 等工具都支持这种用法。

代理使用的工具链解析规则与 cjv run 一致,但不需要你指定工具链。它会按优先级自动判断:环境变量、目录覆盖、项目中的 cangjie-sdk.toml,最后回退到默认工具链。完整的解析顺序见 代理目标与覆盖

如果解析到的工具链尚未安装,且你启用了 auto_install 设置,cjv 会在代理前自动把它装上,无需手动 cjv install。开启方式:

cjv set auto-install true

该设置的细节见 配置

提示:仓颉编译出的二进制文件在运行时还需要正确的库搜索路径。运行自己编译出的程序见 运行时环境 中的 cjv execcjv envsetup

项目级工具链

把工具链声明写进项目,团队成员进入该目录后就会自动用上同一个工具链,无需各自手动切换。在项目根目录放一个 cangjie-sdk.toml

[toolchain]
channel = "lts"

之后在该目录(或其子目录)里,无论是 cjv run、代理执行的 cjc/cjpm,还是 cjv show active,都会优先使用这里声明的工具链。该文件的完整字段(channelcomponentstargets)见 工具链文件

如果只想给某个目录临时绑定一个工具链而不提交文件,可以用目录覆盖:

cjv override set nightly

详见 目标与覆盖

常用命令一览

下面是日常最常用的命令。每条命令的完整参数和子命令见 命令参考

命令说明
cjv install <工具链>安装工具链(如 ltsstsnightly 或具体版本)
cjv uninstall <工具链>卸载工具链
cjv update [工具链]更新已安装的工具链
cjv default [工具链]设置或显示默认工具链
cjv show显示活跃和已安装的工具链
cjv run <工具链> <命令> [参数...]用指定工具链运行命令
cjv exec [+工具链] <命令> [参数...]在仓颉运行时环境中执行命令
cjv which <命令>显示活跃工具链中某个 SDK 工具的路径
cjv check检查可用更新(不安装)
cjv override set <工具链>为当前目录设置工具链覆盖
cjv component add <名称>...为工具链安装组件(如 stdx
cjv self update更新 cjv 自身到最新版本

下一步

核心概念

cjv 用几个相互配合的概念来管理仓颉 SDK。一个工具链是某个版本的仓颉 SDK 安装。你通常通过通道(如 ltsstsnightly)指定要安装哪个工具链,而不必记住具体版本号。每个工具链还可以挂上若干组件(如 stdxdocs),它们是随 SDK 一同发布的扩展资源。

当你直接调用 cjccjpm 等 SDK 工具时,代理会把调用转发到当前活跃的工具链。哪个工具链活跃由若干来源按优先级共同决定。目录级的覆盖为某个项目目录固定一个工具链。目标则是宿主工具链的附加交叉编译 SDK,用于为其他平台构建产物。

以下子章节逐一介绍这些概念:

  • 工具链:仓颉 SDK 的安装单位,以及活跃工具链的解析方式。
  • 通道lts / sts / nightly 等可滚动更新的别名。
  • 组件stdxdocsstdx-docs 等随工具链管理的扩展资源。
  • 代理:对 SDK 工具调用的透明转发与按需安装。
  • 目标与覆盖:交叉编译目标 SDK 与目录级工具链覆盖。

工具链

工具链(toolchain)是 cjv 管理的基本单位,也就是一份完整、可独立运行的仓颉 SDK 安装。一个工具链至少包含编译器 cjc、包管理器 cjpm 以及配套的运行时库。在它之上还可以挂载 组件(如 stdxdocs)和 交叉编译目标

cjv 可以同时安装多个工具链,并在它们之间切换。每个工具链都有一个唯一的名称,你在几乎所有命令里都用这个名称来指代它:

cjv install lts          # 安装名为 lts 的工具链
cjv default sts          # 把默认工具链设为 sts
cjv run nightly cjc -V   # 用 nightly 工具链运行 cjc
cjv uninstall lts        # 卸载 lts

所有已安装的工具链都位于 <CJV_HOME>/toolchains/<名称>/ 下,CJV_HOME 默认是 ~/.cjv

工具链名称的形式

工具链名称可以是以下几种形式之一。前几种由 cjv 直接识别,从官方源下载;最后一种 custom 由你显式创建。

形式示例说明
通道名ltsstsnightly解析为该 通道 当前的最新版本
通道名 + 版本lts-1.0.5sts-1.1.0-beta.23该通道下的一个具体版本
裸版本号1.0.5不带通道前缀的版本号,跨所有通道查找
custom(自定义)my-sdklocal-buildcjv toolchain link 创建,见下文

通道名

ltsstsnightly 是三个通道。单独使用通道名时,cjv 把它解析为该通道当前的最新版本。通道名不区分大小写,LTSLtslts 等价。

cjv install lts      # 安装最新 LTS
cjv install nightly  # 安装最新 nightly

各通道的语义、更新节奏与下载来源详见 通道

通道名 + 版本

在通道名后加 - 和版本号,即可锁定该通道下的一个具体版本。版本号可以带预发布后缀:

cjv install lts-1.0.5
cjv install sts-1.1.0-beta.23
cjv install nightly-1.1.0-alpha.20260306010001

这样安装的工具链名称就是你输入的完整字符串,例如 lts-1.0.5,后续命令也用它来指代:

cjv default lts-1.0.5
cjv uninstall sts-1.1.0-beta.23

裸版本号

如果只给出版本号(以数字开头,不带通道前缀),cjv 会在所有通道中查找匹配该版本的已安装工具链:

cjv run 1.0.5 cjc --version

用它来引用某个已安装的版本,不必记住它属于哪个通道。

custom:自定义工具链

凡是不匹配上述任何形式的名称(既不是通道名、不是 通道-版本、也不以数字开头),都被视为 custom(自定义)工具链。这类工具链不来自官方源,而是由你通过 cjv toolchain link 显式创建:

cjv toolchain link my-sdk /path/to/local/sdk

自定义工具链有两种来源,区别在于数据归谁所有,详见下文 自定义工具链 一节。

命名规则

无论哪种形式,工具链名称都必须满足以下约束,否则命令会报错:

  • 不能为空;
  • 不能包含路径分隔符 /\
  • 不能是 ...
  • 不能以 + 前缀开头,+cjv execcjv envsetup 等命令里的工具链选择语法,直接写名称即可;
  • 末尾多余的 /\ 会被自动去掉。

此外,在 cjv toolchain link 中,自定义工具链的名称不能与保留的通道名冲突:ltsstsnightly 已被官方通道占用,不能用作链接名。

自定义工具链

自定义工具链让你把官方源之外的 SDK 纳入 cjv 管理,例如本地编译的 SDK、内部分发的构建,或某个临时下载的归档。它有两种创建方式,区别在于这份数据是否由 cjv 拥有。

来源一:链接本地目录(cjv 不拥有数据)

第一种方式是引用一个已存在的本地 SDK 目录,不复制其中的文件:

cjv toolchain link my-sdk /path/to/local/sdk

被链接的目录必须是一个真正的仓颉 SDK。cjv 会校验其中存在 bin/cjc,否则拒绝链接。

因为只是一个链接,原始数据仍归你所有。你在源目录里做的任何改动都会立刻通过 cjv 生效;cjv toolchain uninstall my-sdk(以及 cjv uninstall my-sdk)只删除这个链接,不会动你的原始目录。这种方式适合调试自编译的 SDK,或在多个工具之间共享同一份安装。

来源二:从归档安装(cjv 拥有数据)

cjv toolchain link 的第二个参数是本地 .zip / .tar.gz 归档或一个 HTTP(S) URL 时,cjv 会把它安装到 <CJV_HOME>/toolchains/<名称>/。本地源归档不会被移动或删除:

# 本地归档(源文件保留)
cjv toolchain link my-sdk ./cangjie-sdk.tar.gz

# URL
cjv toolchain link my-sdk https://example.com/cangjie-sdk.tar.gz

与本地链接相反,这种工具链的数据由 cjv 管理:cjv toolchain uninstall my-sdk 会真正删除这份目录及其组件。

物化安装支持几个额外参数,它们仅对归档来源(本地文件或 URL)有效,搭配本地目录使用会被拒绝:

  • --sha256 <hash>:校验归档的 SHA-256;
  • --force:覆盖同名的已安装工具链;
  • --no-stdx:跳过自动探测并安装随包的 stdx。

完整的归档格式约定、布局要求、校验行为与示例,见 从 URL 或本地归档安装工具链

为自定义工具链挂载 stdx

通过链接本地目录创建的自定义工具链没有对应的官方 release 资产,因此 cjv component add stdx 对它无效。需要时改用 cjv component link stdx 把一个本地 stdx 目录挂上去:

cjv component link stdx /path/to/local/stdx --toolchain my-sdk

详见 组件

查看与管理工具链

列出所有已安装的工具链,自定义工具链也会出现在列表中:

cjv toolchain list
# 等价于
cjv show installed

查看当前活跃的工具链以及整体状态:

cjv show
cjv show active

设置默认工具链、为目录设置覆盖,以及通过环境变量或 cangjie-sdk.toml 选择工具链等机制,决定了在某个上下文里哪个工具链处于活跃状态。这部分的优先级规则详见 目标与覆盖工具链文件

通道

通道(channel)是 cjv 对仓颉 SDK 发布流的命名。每个通道代表一条持续更新的发布线。安装一个通道时,cjv 会从版本清单解析该通道当前的最新版本并安装它。

通道含义元数据来源
lts长期支持版版本清单(manifest)
sts短期支持版版本清单(manifest)
nightly每日构建(预览版)版本清单(manifest)

通道名大小写不敏感,LTSLtslts 等价。

选哪个通道

lts 版本相对稳定、维护周期长,适合生产构建以及对兼容性敏感的项目。sts 更新更快,适合希望较早使用新特性的项目。nightly 包含最新但尚未稳定的改动,适合尝鲜、复现 upstream 行为或为 SDK 本体提 bug。

cjv install lts
cjv install sts
cjv install nightly

通道与版本名

把通道名交给 cjv install 会安装该通道的最新版本,并以 <通道>-<版本> 的名称落盘。也可以固定具体版本:

cjv install lts-1.0.5
cjv install sts-1.1.0-beta.23
cjv install nightly-1.1.0-alpha.20260306010001

# 裸版本号在 LTS / STS 中查找所属通道
cjv install 1.0.5

nightly 的具体版本使用带通道前缀的名称。完整命名规则见工具链

Manifest 分发模型

正式通道与 nightly 使用独立的静态清单:versions.json 记录 LTS/STS,nightly.json 记录 nightly。两份文件都包含可用版本、平台 SDK URL、组件 URL 与校验和。cjv 按请求通道加载对应文件,因此普通 LTS/STS 操作无需下载 nightly 历史。

默认清单由 cangjie-version-manifest 维护。正式版本通过 PR 更新 versions.json,nightly 定时任务采集 GitCode Cangjie/nightly_build Release 并直接更新 nightly.json

manifest_url 指向正式通道文件,nightly 文件从同目录的 nightly.json 派生。配置 dist_serverCJV_DIST_SERVER 时,两份文件位于分发根下。来源优先级和部署契约见配置内部分发源

通道与组件

manifest 记录 stdx、docs、stdx-docs 的实际下载 URL。默认清单采集的上游来源如下:

组件LTS / STS 来源nightly 来源
stdxcangjie_stdx 发布nightly_build 发布
docscangjie-docs-bundle 发布nightly_build 发布
stdx-docscangjie_stdx 发布nightly_build 发布

三个通道的组件都使用 manifest 中声明的 URL,并可携带 SHA-256。组件机制见组件

cjv install nightly -c stdx,docs

在工具链文件中指定通道

项目可以在 cangjie-sdk.toml 中声明通道,让协作者使用相同的工具链选择:

[toolchain]
channel = "lts"

channel 可以是通道名,也可以是带版本的工具链名。完整字段语义见工具链文件

检查更新

cjv check 查询 manifest,并比较已安装通道与各通道的最新版本:

cjv check

组件

组件(component)是与仓颉 SDK 一同发布、但与 SDK 本体分开管理的扩展资源。装好一个工具链之后,可以按需为它挂上组件,也可以单独卸载,不影响 SDK 本身。

cjv 当前支持三类组件:

组件内容安装位置(相对 CJV_HOME
stdx仓颉扩展库(Cangjie 扩展库的动态/静态库文件)stdx/<tc>/{dynamic,static}
docs仓颉主体离线文档(dev-guide、libs/std、tools)docs/<tc>/main/
stdx-docs仓颉扩展库的离线文档docs/<tc>/stdx/

其中 <tc> 是工具链名(如 lts-1.0.5)。组件按工具链拆分存放,每个工具链各有一份独立的组件。卸载工具链时,对应的 stdx/<tc>/docs/<tc>/ 会一并清理。

未配置统一企业分发源时,组件的默认下载来源取决于通道

配置 dist_server 后,LTS/STS 组件由 versions.json 描述,nightly 组件由 nightly.json 描述;相对 URL 以分发根解析,绝对 URL 原样使用,组件条目还可提供 SHA-256。见内部分发源

自动注入的环境变量

stdx 是唯一向运行时环境贡献变量的组件。某工具链装好 stdx 后,cjv 会在代理执行以及 cjv exec / cjv envsetup 中自动注入两个环境变量,无需手动设置:

环境变量指向
CANGJIE_STDX_PATH_DYNAMIC<CJV_HOME>/stdx/<tc>/dynamic
CANGJIE_STDX_PATH_STATIC<CJV_HOME>/stdx/<tc>/static

这两个变量只在对应工具链确实装有 stdx 时才会出现。docsstdx-docs 是纯文档数据,不贡献任何运行时环境变量。运行时环境的完整说明见运行时环境

安装与卸载组件

最直接的方式是在安装工具链时用 -c / --component 一并装上组件:

# 安装 nightly 工具链,并顺带装上 stdx 和 docs
cjv install nightly -c stdx,docs

组件名支持逗号分隔,也支持重复传入(如 -c stdx -c docs)。

工具链装好之后也可以单独管理组件。cjv component 的子命令默认作用于当前活跃工具链,用 --toolchain <tc> 可指定其他工具链:

# 为 lts 工具链添加 stdx
cjv component add stdx --toolchain lts

# 一次添加多个
cjv component add stdx docs

# 卸载组件(remove 亦可写作 rm / uninstall / delete)
cjv component remove stdx-docs

cjv component add 在组件已安装时会跳过。如需强制重新下载安装,加 --force

查看组件

cjv component list 列出组件在当前工具链下的安装与可用情况:

# 列出某工具链的所有组件及其状态
cjv component list --toolchain nightly

# 只看已安装的组件
cjv component list --installed

「可用」与否取决于通道。三类组件在 LTS、STS、nightly 上都受支持,但 custom 工具链没有对应的 release 资产,通过 cjv component add 安装会失败(见下一节)。

链接本地 stdx

对于通过 cjv toolchain link 链接的 custom 工具链,cjv component add stdx 无法工作,因为 custom 工具链没有可供下载的 release 资产。这时改用 cjv component link stdx <path>,把一个本地的 stdx 目录挂到工具链上:

# 先链接一个本地编译/获取的 SDK
cjv toolchain link mysdk /path/to/local/sdk

# 再把本地 stdx 链接到这个工具链
cjv component link stdx /path/to/local/stdx --toolchain mysdk

标准通道(如 lts)也可以用 link 替代下载,适合离线环境或调试自编译的 stdx。此时工具链上可能已存在一份下载安装的 stdx,需要加 --force 覆盖:

cjv component link stdx /path/to/local/stdx --toolchain lts --force

<path> 必须包含 dynamic/static/ 两个子目录。链接后,CANGJIE_STDX_PATH_DYNAMICCANGJIE_STDX_PATH_STATIC 仍会正常配置;移除组件或卸载工具链不会删除原始目录。

link 目前仅对 stdx 有效;docsstdx-docs 不支持链接,只能下载安装。

在工具链文件中声明组件

工具链文件 cangjie-sdk.tomlcomponents 字段同样会被识别。开启 auto_install 后,代理执行会按需补齐当前项目缺失的组件:

[toolchain]
channel = "nightly"
components = ["stdx", "docs"]

团队成员进入项目目录运行 cjccjpm 时,cjv 就会在代理前自动装好声明的组件。

打开离线文档

装好 docsstdx-docs 后,cjv doc 会在浏览器中打开当前工具链的本地 HTML 文档:

# 打开文档首页
cjv doc

# 跳转到指定主题
cjv doc stdx        # 扩展库文档(来自 stdx-docs)
cjv doc std         # 标准库
cjv doc dev-guide   # 开发指南(亦可用 book)
cjv doc tools       # 工具文档

常用参数:

  • --toolchain <tc>:打开指定工具链的文档(默认当前活跃工具链)。
  • --path:只打印解析出的文件路径,不启动浏览器,便于在脚本中使用或确认文档位置。
# 只打印路径,不打开浏览器
cjv doc --path

# 查看 nightly 工具链的工具文档路径
cjv doc tools --toolchain nightly --path

不带主题时 cjv doc 打开文档入口(优先 docs 的主页,其次 stdx-docs)。如果对应工具链尚未安装 docs / stdx-docs,命令会提示先用 cjv component add 安装相应组件。

代理

你很少会直接键入 cjv run 来跑仓颉的 SDK 工具。大多数时候你会像使用一个普通安装的 SDK 那样直接运行 cjccjpmcjfmt,由 cjv 在背后把这次调用转发到正确的工具链。这种机制称为代理执行(proxy)。

代理是 cjv 实现多工具链无缝切换的基础。你切换默认工具链、设置目录覆盖,或在项目里放一个 工具链文件,下一次运行 cjc 就会自动落到对应的工具链上,无需改 PATH,也无需重新激活。

支持的工具

<CJV_HOME>/bin/ 加入 PATH 后,可以直接调用以下 SDK 工具:

  • cjccjc-frontend:编译器
  • cjpm:包管理器
  • cjfmt:格式化工具
  • cjlint:静态检查
  • cjdb:调试器
  • cjcov:覆盖率工具
  • cjprof:性能分析工具
  • cjtrace-recoverchir-dishle
  • LSPServerLSPMacroServer:语言服务

首次安装默认会配置 PATH;若使用 CJV_NO_PATH_SETUP=1 跳过了这一步,需要手动加入该目录。

工具链选择

直接调用 SDK 工具时,cjv 按以下顺序选择工具链:

  1. +toolchain 选择器(见下文)
  2. CJV_TOOLCHAIN 环境变量
  3. 目录覆盖(cjv override set)
  4. 当前目录或父目录中的 cangjie-sdk.toml
  5. 默认工具链(cjv default)

cjv 会配置所选工具链的运行环境,并原样传递命令参数、标准输入输出和退出码。完整优先级规则见目标与覆盖,环境配置见运行时环境

下面两条命令是等价的:

# 直接调用(经代理)
cjc --version

# 显式指定工具链运行
cjv run lts cjc --version   # 假设当前解析到的活跃工具链是 lts

要查看某个工具最终会落到哪个二进制,用 cjv which

cjv which cjc
# 打印活跃工具链中 cjc 的真实路径

+toolchain 选择器

代理模式支持在参数最前面用 + 临时指定工具链,优先级高于其余所有解析方式,只对这一次调用生效:

# 用 nightly 工具链编译,无论当前默认/覆盖/工具链文件是什么
cjc +nightly main.cj

# 用 sts 跑一次构建
cjpm +sts build

+ 后面的工具链名不能为空,否则报错。该语法与 cjv execcjv envsetup 中的 +toolchain 一致。

auto_install:自动补齐缺失项

代理执行时,解析到的工具链(或其声明的目标、组件)可能尚未安装。此时的行为由 auto_install 设置决定。

auto_install = true 是默认值。cjv 在转发调用之前先把缺失的部分装好,然后照常执行。克隆一个带 cangjie-sdk.toml 的项目后,直接运行 cjpm build 就会触发首次安装,无需手动 cjv install

auto_install = false 时,遇到未安装的工具链、目标或组件,cjv 直接报错退出,不做任何下载。

自动安装会按需覆盖三类缺失项:

  1. 活跃工具链本体未安装时自动安装。
  2. 工具链文件中 targets 声明的交叉编译目标 SDK 缺失时自动补齐(见 交叉编译)。
  3. 工具链文件中 components 声明的组件(如 stdxdocs)缺失时自动安装(见 组件)。

例如,某项目的工具链文件如下:

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

在开启 auto_install 的机器上首次运行任意被代理的工具:

cjpm build

cjv 会依次确认 nightly 工具链、ohos 目标 SDK、stdxdocs 组件是否就绪,补齐所有缺失项后再执行 cjpm build。自动安装的进度信息打印到标准错误,不会污染工具自身的标准输出。

切换 auto_install

# 关闭与开启(写入 settings.toml)
cjv set auto-install false
cjv set auto-install true

该设置保存在 ~/.cjv/settings.tomlauto_install 字段,默认值为 true,详见配置

不会被自动安装的情形

通过 cjv toolchain link 链接的 custom 工具链没有对应的可下载发布资产,cjv 不会、也无法对其执行自动安装;若解析到一个未链接的 custom 名字,直接报错。

cjv exec 的交叉编译目标 SDK 必须先通过 cjv install <toolchain> --target <suffix> 安装。代理路径只补齐工具链文件中声明的 targets,不会凭空为一次性命令安装目标 SDK。

自动安装中任何一步下载或安装失败时,cjv 不会继续转发调用,而是以工具链或组件未安装错误退出,并在标准错误上给出失败原因。

目标与覆盖

每次执行被代理的 SDK 工具(如 cjccjpm)时,cjv 都要回答两个问题:用哪个工具链,以及这个工具链上要带哪些交叉编译目标。前者由一套带优先级的解析链决定,后者由「目标」(targets)这一附加安装维度决定。

工具链解析优先级

cjv 按以下优先级从高到低解析当前活跃的工具链,取第一个命中的来源:

  1. CJV_TOOLCHAIN 环境变量
  2. 目录覆盖(通过 cjv override set 设置)
  3. 工具链文件(当前目录或某级父目录中的 cangjie-sdk.toml)
  4. 默认工具链(通过 cjv default 设置)

代理执行、cjv execcjv envsetup 以及大多数接受 [toolchain] 参数的命令都使用同一套解析链。在任意目录下会用到哪个工具链,答案都是一致且可预测的。

1. CJV_TOOLCHAIN 环境变量

设置 CJV_TOOLCHAIN 会无条件覆盖其余所有来源,适合 CI、容器或临时验证场景:

CJV_TOOLCHAIN=nightly cjc --version

它优先级最高,目录覆盖、工具链文件、默认工具链都会被忽略。详见 环境变量

2. 目录覆盖

目录覆盖把某个具体目录(及其子目录)绑定到一个工具链,信息存放在全局 settings.toml 中,而不是项目里。它适合你不想或不能在项目里放 cangjie-sdk.toml 的情况,例如对方仓库不属于你,或你只想本地临时切换。

3. 工具链文件 cangjie-sdk.toml

cjv 从当前目录向上递归查找 cangjie-sdk.toml,用找到的第一个文件作为项目的工具链声明。这是随仓库提交、对协作者生效的项目级工具链锚点。完整字段说明见 工具链文件

4. 默认工具链

当以上三者都没有命中时,回退到通过 cjv default 设置的全局默认工具链:

cjv default lts

若连默认工具链都未设置,cjv 会报错提示尚未配置任何工具链。

覆盖与工具链文件如何在目录树上交错

第 2 级和第 3 级并不是先扫完所有覆盖再扫所有工具链文件,而是沿目录树逐级向上,在每一级同时检查目录覆盖和 cangjie-sdk.toml

  • 在同一级目录上,目录覆盖优先于该级的 cangjie-sdk.toml
  • 更靠近当前目录的工具链文件,优先于更靠上的目录覆盖。

也就是说,优先级既看来源类型也看距离。若在 ~/work 上设置了目录覆盖,而 ~/work/proj 里有 cangjie-sdk.toml,那么在 ~/work/proj 下工作时,更近的工具链文件胜出;只有当某一级既无更近的文件也命中了覆盖时,覆盖才生效。这样项目自带的声明就不会被祖先目录上一个宽泛的覆盖意外盖掉。

提示:cangjie-sdk.toml 存在但 channel 为空时,cjv 不会静默回退,而是直接报错,提醒你补全声明。只有文件根本不存在时才会继续向上查找。

管理目录覆盖

设置覆盖

# 为当前目录设置覆盖
cjv override set nightly

# 为指定目录设置(无需先 cd 进去)
cjv override set lts --path /path/to/project

cjv override set 会校验工具链名并记录目录的绝对路径。同一目录的等价路径不会产生重复条目。

移除覆盖

# 移除当前目录的覆盖
cjv override unset

# 移除指定目录的覆盖
cjv override unset --path /path/to/project

# 清理所有指向「已不存在目录」的覆盖
cjv override unset --nonexistent

--nonexistent 适合定期清理。项目目录被删除后,其覆盖条目会残留在 settings.toml 里,这条命令会把所有目标目录已不存在的覆盖一次性删掉。

列出覆盖

cjv override list

输出按目录路径排序,每行形如 目录 → 工具链。没有任何覆盖时会给出相应提示。

交叉编译目标(targets)

「目标」是与工具链解析正交的另一个维度。它回答的不是用哪个工具链,而是这个工具链要额外带哪些交叉编译 SDK。

目标 SDK 是宿主工具链之上的附加安装项,不会改变当前活跃的工具链。代理执行 cjccjpm 时,仍然使用宿主 SDK。安装一个目标只是把对应的交叉编译 SDK 备好,供你在需要时为该目标产出二进制。

只填后缀

无论在命令行还是在 cangjie-sdk.toml 中,targets 都只填目标后缀,例如 ohosandroidohos-arm32,不要写完整平台 key(如 linux-x64-ohos)。cjv 会把后缀拼接到当前宿主元组上,自动得到完整目标。后缀必须匹配 ^[a-z0-9]+(?:-[a-z0-9]+)*$,且不能本身就是一个完整平台元组。

在安装时附加目标

# 安装宿主 STS SDK,并额外装上当前宿主对应的 OHOS 交叉 SDK
cjv install sts -t ohos

# target 支持重复或逗号分隔
cjv install sts -t ohos -t android
cjv install sts --target ohos,android

在项目里声明目标

项目可在 cangjie-sdk.toml 中声明附加 targets。开启 auto_install 时,代理执行会自动补齐缺失的目标 SDK:

[toolchain]
channel = "sts"
targets = ["ohos", "android", "ohos-arm32"]

重复的后缀会自动去重。targets 与工具链解析无关,它只在你选定的工具链上叠加交叉编译能力。关于如何驱动交叉编译构建、以及目标 SDK 的运行时环境,见 交叉编译

工具链文件

cangjie-sdk.toml 是放在项目里的工具链声明文件。有了它,一个项目就固定使用某个工具链,并可一并声明该项目需要的交叉编译目标和组件。任何人在这个目录(或其子目录)下运行 cjccjpm 等命令,cjv 都会自动切换到声明的工具链,不必手动 cjv default 或设置环境变量。

它在工具链解析链中的位置参见目标与覆盖。环境变量 CJV_TOOLCHAIN 与目录覆盖的优先级更高,默认工具链的优先级更低。

[toolchain]
channel = "lts"                  # 必填
components = ["stdx", "docs"]    # 可选
targets = ["ohos", "android"]    # 可选

文件位置与查找

cjv 从当前工作目录开始,沿目录树逐级向上查找名为 cangjie-sdk.toml 的文件,使用遇到的第一个文件并就此停止,不会合并多个层级的文件。因此子目录里的工具链文件会覆盖父目录里的。

举例,目录结构如下:

~/work/
  cangjie-sdk.toml        # channel = "lts"
  project/
    cangjie-sdk.toml      # channel = "sts"
    src/

~/work/project/src/ 下运行命令,cjv 向上找到的第一个文件是 ~/work/project/cangjie-sdk.toml,于是使用 sts~/work/ 里那个 lts 文件被遮蔽。查找会一直向上走到文件系统根目录为止。

同一层级的优先级:如果某一层级同时存在目录覆盖(cjv override set)和 cangjie-sdk.toml,该层级的目录覆盖优先。但更靠近当前目录的工具链文件,仍然胜过更上层的目录覆盖。

字段参考

所有字段都位于 [toolchain] 表下。表名必须正好是 toolchain

channel

项目
类型string
是否必填
默认值

工具链名称,也就是平时传给 cjv install 的那个标识符。它可以是通道名(ltsstsnightly),也可以是带版本的精确名称(如 lts-1.0.5nightly-1.1.0-alpha.20260306010001)。通道与版本的写法详见通道工具链

[toolchain]
channel = "lts"
[toolchain]
channel = "lts-1.0.5"

channel 不能为空。一个被找到但 channel 为空的工具链文件(空文件、channel = ""、或只写了无法识别的键)会被视为配置不完整并直接报错,cjv 不会跳过它去继续解析下一级。详见下文空文件与空 channel

components

项目
类型string[]
是否必填
默认值[](空)

声明该项目需要随工具链一起就绪的组件,例如扩展库 stdx、离线文档 docsstdx-docs

[toolchain]
channel = "lts"
components = ["stdx", "docs"]

满足自动安装条件(见下文auto_install 的关系)时,cjv 会在代理执行前自动补齐这里列出但尚未安装的组件。条件不满足时,缺失的组件会让命令以“组件未安装”错误终止,提示你手动运行 cjv component add

组件名会经过校验,未知组件名会报错。可用组件清单见组件

targets

项目
类型string[]
是否必填
默认值[](空)

声明该项目需要的交叉编译目标,每一项只写目标后缀,例如 ohosandroidohos-arm32

[toolchain]
channel = "sts"
targets = ["ohos", "android", "ohos-arm32"]

需要遵守以下规则:

  • 只写后缀,不要写完整平台 key。ohos 正确,linux-x64-ohos 这种完整 SDK 目标元组会被拒绝并报错。
  • 大小写与下划线会被规范化:OHOSohos_arm32 会被分别归一为 ohosohos-arm32
  • 单个字符串里支持逗号分隔,等价于写成多项:targets = ["ohos,android"]targets = ["ohos", "android"] 等价。
  • 不允许空目标:targets = ["ohos", ""]targets = [","] 会报错。
  • 重复项会自动去重。

components 一样,满足自动安装条件时,cjv 会在代理执行前自动安装这里声明但缺失的目标 SDK,否则会以“工具链未安装”错误提示你手动运行 cjv install <toolchain> --target <suffix>

目标 SDK 是宿主工具链的附加安装项,不改变当前活跃工具链,cjccjpm 仍用宿主 SDK 运行。完整说明见交叉编译

未识别的键

无法识别的键不会让解析失败,只会以 warn 级别日志提示(可通过 CJV_LOG 控制日志级别,见环境变量),其余可识别字段照常生效。常见诱因是拼写错误:

[toolchian]        # 表名拼错,应为 [toolchain]
channal = "lts"    # 键名拼错,应为 channel

上例中没有任何可识别的字段被读到,于是 channel 实际为空,这又会触发空 channel 报错。当工具链文件看起来配置了却不生效时,先检查是否有这类 warn 日志。

注意:键名拼写错误只警告不报错,但 TOML 语法错误会报错。例如缺少右括号的 [toolchain 会让整次解析失败并终止命令。

空文件与空 channel

只要 cangjie-sdk.toml 被找到,cjv 就认定你打算在此声明工具链。如果该文件存在、但解析后 channel 为空,cjv 会报错而不是悄悄回退。以下几种情况都属于空 channel

  • 完全空的文件;
  • 写了 channel = ""
  • 只写了无法识别的键(如上一节的拼写错误),导致没有有效的 channel

这几种情况都会得到类似下面的错误,并指出具体文件路径:

…/cangjie-sdk.toml: toolchain.channel is empty; please specify a channel (e.g. lts, sts, nightly)

如果想让某个目录回退到上一级或默认工具链,请删除该文件,而不是把它清空。

auto_install 的关系

channel 决定用哪个工具链,targetscomponents 决定附带就绪哪些目标和组件。后两者是否会被自动补齐,取决于用户设置中的 auto_install

  • auto_install 开启(默认,对应 cjv set auto-install true)时,代理执行(直接调用 cjccjpm 等)会在运行前自动安装工具链文件里声明、但本机尚缺的目标 SDK 与组件。
  • auto_install 关闭(cjv set auto-install false)时,cjv 不会自动安装,缺失的目标或组件会让命令以相应的“未安装”错误终止,并提示你手动安装。

auto_install 的含义与设置方法见代理配置

targetscomponents 只在工具链由 cangjie-sdk.toml 解析得到时才生效。如果当前活跃工具链来自更高优先级的来源,例如 CJV_TOOLCHAIN 环境变量,或 cjv run/cjv exec+toolchain 显式指定,那么工具链文件里的 targetscomponents 不会被应用(此时连这个文件都未必会被读取)。它们是项目工具链声明的一部分,随 channel 一同来自同一个文件。

完整示例

一个为 OpenHarmony 交叉编译、需要扩展库和离线文档的项目:

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

配合开启自动安装,团队成员首次在该目录运行 cjpm build 时,cjv 会自动安装 sts 工具链、ohos 目标 SDK,以及 stdxdocs 组件,无需任何额外步骤:

cjv set auto-install true
cd my-ohos-project
cjpm build        # 缺失的工具链 / 目标 / 组件会被自动补齐

相关章节

从 URL 或本地归档安装工具链

cjv toolchain link <name> <path><path> 有三种形态:本地目录、本地归档文件(.zip / .tar.gz),或一个 http(s):// URL。传入目录时,cjv 只创建一个指向它的链接;传入归档时——无论是本地文件还是 URL——cjv 会解包它,并把它落地成一个由 cjv 拥有的真实工具链。

两种行为:引用与物化

传入本地目录时使用引用模式;传入本地归档或 HTTP(S) URL 时使用物化模式。

维度引用模式(本地目录)物化模式(本地归档 / URL)
<path> 形态本地目录,如 /path/to/sdk本地归档 sdk.zip,或 https://...
toolchains/<name> 内容引用原目录由 cjv 管理的安装目录
数据归属cjv 不拥有,只是引用cjv 拥有
随包 stdx不涉及可选,自动安装(见下文)
卸载行为只删链接,原目录保留删除整个目录(含 stdx)
是否改默认工具链

本地归档会就地读取,不会被移动或删除。引用本地目录的说明见工具链组件

# 物化:从 URL 下载、解包,落地为 cjv 拥有的真实目录
cjv toolchain link mysdk https://example.com/cangjie-linux-x64-1.0.0.zip

# 物化:从本地归档解包,落地为 cjv 拥有的真实目录(源文件保留)
cjv toolchain link mysdk ./cangjie-linux-x64-1.0.0.zip

# 引用(对照):只创建一个指向本地目录的链接
cjv toolchain link mysdk /path/to/local/sdk

名称必须是自定义名

<name> 必须是自定义名,不能与保留的通道名 ltsstsnightly 冲突,也不能包含路径分隔符、+ 前缀,或为空、... 等非法名称:

# 报错:lts 是保留通道名
cjv toolchain link lts https://example.com/sdk.zip

标志

物化模式支持三个标志,本地归档与 URL 同样适用:

标志作用
--sha256 <hex>校验归档的 SHA-256。缺省时只校验归档格式是否合法
--forcetoolchains/<name> 已存在时覆盖重装
--no-stdx即便归档内含 stdx,也不安装随包 stdx

这三个标志只在物化模式(本地归档或 URL)下有效。如果你在传入本地目录时带上其中任意一个,cjv 会直接报错,提示该标志不适用于链接本地目录,而不是默默忽略。

# 校验归档的 SHA-256(本地归档同样适用)
cjv toolchain link mysdk ./cangjie-linux-x64-1.0.0.zip \
  --sha256 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

# 覆盖已存在的同名工具链
cjv toolchain link mysdk https://example.com/cangjie-linux-x64-1.1.0.zip --force

# 只装 SDK,跳过随包 stdx
cjv toolchain link mysdk ./cangjie-linux-x64-1.0.0.zip --no-stdx

未提供 --sha256 时,URL 依赖 TLS,本地归档则视为可信文件。需要校验内容完整性时,请始终提供 SHA-256。

期望的归档格式

物化模式支持 cangjie-build CI 产物和裸 SDK 归档。

CI 构建产物(嵌套布局)

从 GitHub Actions 下载的构建产物 cangjie-<target>-<version> 是一个外层 ZIP,可包含以下归档:

<外层 .zip>
├── cangjie-sdk-<sdk_name>-<version>.<tar.gz|zip>            (内层 SDK,必需)
└── cangjie-stdx-<sdk_name>-<version>.<stdxver>.<tar.gz|zip> (内层 stdx,可选)
  • 外层归档为 .zip
  • 内层归档在 Linux 上通常为 .tar.gz,在 Windows 上通常为 .zip
  • 内层 SDK 解开后是单一顶层目录 cangjie/,内含 bin/lib/tools/runtime/ 等。
  • 内层 stdx 解开后是单一顶层目录 <platform>_cjnative/(如 linux_x86_64_cjnativewindows_x86_64_cjnative),内含 dynamic/static/

裸 SDK 归档

归档也可以直接包含一个 SDK 顶层目录。该目录必须包含完整 SDK 布局;这种格式不包含随包 stdx。

随包 stdx 自动安装

当归档内含 cangjie-stdx-* 且未指定 --no-stdx 时,cjv 会同时安装 stdx 组件。

# 归档含 stdx → SDK 与 stdx 一并装好
cjv toolchain link mysdk ./cangjie-linux-x64-1.0.0.zip

# 验证 stdx 已就位
cjv component list --toolchain mysdk

stdx 的管理方式见组件

仅支持当前系统

物化安装只支持与当前操作系统匹配的 SDK。尝试安装其他系统的 SDK 会报错。

# 在 Linux 上尝试安装 Windows SDK → 落地前报错,toolchains/<name> 不会被创建
cjv toolchain link winsdk https://example.com/cangjie-windows-x64-1.0.0.zip

如果你需要为另一个平台准备 SDK,请在那个平台上执行安装,或使用交叉编译的目标 SDK 机制。

卸载:cjv 拥有,真删除

物化安装的工具链由 cjv 拥有,卸载时会真正删除落地的目录,包括随包安装的 stdx:

cjv toolchain uninstall mysdk

这会删除 toolchains/mysdk/stdx/mysdk/ 以及 docs/mysdk/(若存在)。引用模式的卸载只删除链接条目,原始目录不受影响。

更多相关内容:工具链解析优先级见 工具链,组件与 stdx 见 组件,运行时环境注入见 运行时环境,完整命令签名见 命令参考

交叉编译

仓颉支持交叉编译:在宿主机器上为另一个平台(如 OpenHarmony、Android)生成可执行文件。除了宿主工具链外,这还需要对应平台的 target SDK(交叉编译 SDK)。

本章介绍如何安装、声明和使用 target SDK。targets 与目录覆盖在工具链解析中的位置,参见目标与覆盖

target SDK 是附加安装项

target SDK 不是一条独立的工具链,而是挂在某条宿主工具链上的附加安装项。安装 target SDK 不会改变当前活跃工具链,也不会改变 cjv default。直接调用 cjccjpm 等工具时(代理模式),用的仍然是宿主 SDK,target SDK 只在你显式请求交叉编译环境时才会被使用。

target SDK 的版本锁定到宿主工具链已解析出的版本。如果该版本没有对应的 target 资产,安装会失败,而不会装上一个版本错配的 SDK。cjv install sts -t ohos 给你的是 STS 宿主 SDK,加上与之配套的 OHOS 交叉 SDK,宿主开发体验完全不变。

安装 target SDK

cjv install-t / --target 标志在安装宿主工具链时附带交叉编译目标:

# 安装宿主 STS SDK,并额外安装当前宿主对应的 OHOS 交叉 SDK
cjv install sts -t ohos

一次安装多个目标有两种等价写法,可以混用:

# 重复标志
cjv install sts -t ohos -t android

# 逗号分隔
cjv install sts --target ohos,android

# 两者混用也可以
cjv install sts -t ohos,android -t ohos-arm32

--target 只接受目标后缀,例如 ohosandroidohos-arm32,不要填写完整的平台 key(如 linux-x64-ohos)。平台前缀由 cjv 根据宿主自动补全。

target SDK 可以和组件在同一条命令里一起安装:

# 宿主 STS + OHOS 交叉 SDK + stdx 组件
cjv install sts -t ohos -c stdx

target SDK 是附加的:你随时可以对一条已安装的工具链再跑一次 cjv install <tc> -t <新后缀> 来补装新的目标,已装好的部分不受影响。

在工具链文件中声明 targets

项目可以把交叉编译目标写进 cangjie-sdk.toml[toolchain] 表,让协作者无需记忆安装命令。targets 与命令行同样只填后缀:

[toolchain]
channel = "sts"
targets = ["ohos", "android", "ohos-arm32"]

targets 是附加语义:它在宿主工具链之上声明需要哪些 target SDK,不会改变 channel 解析出的活跃工具链。

当设置中启用了 auto_install 时,代理执行会在调用 SDK 工具前自动补齐缺失的 target SDK;未启用时,你需要手动用上文的 cjv install … -t … 安装。targets 字段的完整语义见工具链文件目标与覆盖

独立 SDK 模型与 cjv envsetup --target

每个 target SDK 都是自包含的:它有自己的 CANGJIE_HOME、自己的 bin 目录和运行时库路径。要进入某个 target SDK 的交叉编译环境,给 cjv envsetup--target=SUFFIX

# 输出 OHOS 交叉编译环境(独立 SDK 模型)
eval "$(cjv envsetup --target=ohos)"

# 其他 shell
cjv envsetup --target=ohos | source             # Fish
cjv envsetup --target=ohos | Invoke-Expression   # PowerShell

不带 --target 时输出宿主工具链环境;带上 --target 后,CANGJIE_HOMEPATH 与库搜索路径指向对应的 target SDK。

--target 同样遵循与代理模式一致的工具链解析优先级,并支持 +toolchain 语法指定宿主工具链:

# 为 +nightly 宿主工具链输出 OHOS 交叉环境
eval "$(cjv envsetup +nightly --target=ohos)"

注意:cjv envsetup --target 不会自动安装 target SDK。对应 target 必须已经通过 cjv install <toolchain> --target <suffix> 安装,否则命令会报错。

配置好环境后,就可以直接调用交叉编译工具链了:

eval "$(cjv envsetup --target=ohos)"
cjc --version          # 此处的 cjc 来自 OHOS target SDK
cjpm build             # 产物面向 OHOS 平台

环境变量注入、不同 shell 的写法,以及一次性执行(cjv exec)与配置当前会话(cjv envsetup)之间的取舍,详见运行时环境

卸载

target SDK 随宿主工具链一同清理。卸载宿主工具链时,挂在它上面的 target SDK 会一并移除:

cjv toolchain uninstall sts

运行时环境

仓颉编译出来的二进制文件并不是完全自包含的。它们动态链接到 SDK 自带的运行时库(例如 libcangjie-runtime),还可能依赖 SDK 提供的其它共享库。直接运行这些产物时,操作系统需要在库搜索路径里找到这些 .so/.dylib/.dll,否则会因为找不到动态库而启动失败。

cjv 的代理在调用 cjccjpm 等 SDK 工具时会自动注入这些路径,但你自己编译出来的产物并不经过代理,你是直接 ./my_binary 运行它的。这时需要先把运行时环境准备好。cjv 提供两种方式。cjv exec 在正确的运行时环境里执行一条命令,运行结束即恢复,不会污染当前 shell。cjv envsetup 把环境变量配置脚本输出到 shell,持久配置当前会话,之后可以直接运行编译产物。

两者都使用与代理模式一致的工具链解析优先级,并支持 +toolchain 语法显式指定工具链。

运行时环境包含什么

无论用哪种方式,cjv 注入的内容都来自当前工具链对应的 SDK 目录。CANGJIE_HOME 指向该 SDK 的根目录。SDK 的 bintools/bin 等目录被前置到 PATH。运行时库目录被前置到平台对应的库搜索变量:Linux 上是 LD_LIBRARY_PATH,macOS 上是 DYLD_LIBRARY_PATH,Windows 上则通过 PATH(Windows 没有独立的库搜索变量)。如果当前工具链装了 stdx 组件,还会注入 CANGJIE_STDX_PATH_DYNAMICCANGJIE_STDX_PATH_STATIC

cjv exec:一次性执行

cjv exec 在准备好的运行时环境里运行指定命令,运行结束即恢复,不会改动你当前的 shell:

cjv exec ./my_binary arg1 arg2

子进程的退出码会被原样透传,因此 cjv exec 可以用在脚本和 CI 流水线里。标准输入、输出、错误流也会原样转发。

指定工具链

在命令前加 +toolchain 即可临时切换到指定工具链,而不改变默认或当前激活的工具链:

# 用 nightly 工具链的运行时环境执行
cjv exec +nightly ./my_binary

不带 +toolchain 时,cjv exec 按标准解析优先级选择工具链(CJV_TOOLCHAIN → 目录覆盖 → cangjie-sdk.toml → 默认工具链)。

运行以 + 开头的命令

+toolchain 选择器只会消费第一个参数。如果你要执行的命令本身就以 + 开头,用 -- 终止符把它和选择器隔开:

# 此处 +foo 是要执行的命令名,不是工具链
cjv exec -- +foo arg1

cjv envsetup:配置当前 shell

cjv envsetup 不直接执行命令,而是把配置运行时环境所需的 shell 命令打印到标准输出。你需要把它的输出喂给当前 shell 求值,让环境变量在当前会话中生效。配置一次之后,本会话内就可以反复直接运行编译产物,无需每次都套一层 cjv exec

不同 shell 的求值方式不同:

# Bash / Zsh
eval "$(cjv envsetup)"
# Fish
cjv envsetup | source
# PowerShell
cjv envsetup | Invoke-Expression

cjv envsetup 同样支持 +toolchain

eval "$(cjv envsetup +nightly)"

Shell 自动检测与 --shell

cjv envsetup 通过检查父进程来自动判断当前 shell 类型,并据此选择正确的输出语法。它识别 bashzshsh 等 POSIX shell,以及 fishpowershell/pwshcmd

如果自动检测失败(例如在某些嵌套或非交互环境中),cjv 会回退到 POSIX 语法并在标准错误打印一条提示。此时,或当你想为另一个 shell 生成脚本时,用 --shell 显式指定,取值为 bashfishpowershellcmd

cjv envsetup --shell=fish | source
cjv envsetup --shell=powershell | Invoke-Expression

交叉编译:--target

cjv envsetup--target=SUFFIX 用于输出已安装目标 SDK 的运行时环境,而不是宿主 SDK 的。当交叉编译产物需要运行(例如在目标设备或模拟器上)时,这很有用。

cjv 对目标 SDK 采用独立 SDK 模型:CANGJIE_HOME 指向目标 SDK 目录,PATH 与库搜索路径也全部取自该目录,与宿主 SDK 互不干扰。

# 输出已安装 ohos 目标 SDK 的运行时环境
eval "$(cjv envsetup --target=ohos)"

目标 SDK 必须先随宿主工具链一并安装,--target 才能找到它:

cjv install sts --target ohos

目标后缀(如 ohosandroid)的含义详见交叉编译目标与覆盖

相关章节

  • 代理:代理模式如何为 SDK 工具自动注入运行时环境。
  • 组件stdx 组件及其注入的 CANGJIE_STDX_PATH_* 变量。
  • 环境变量:cjv 涉及的全部环境变量。
  • 交叉编译:安装与使用交叉编译目标 SDK。

环境变量

cjv 的部分行为可以通过环境变量调整。环境变量适合临时覆盖、在 CI 中注入凭据,以及在不写入 settings.toml 的情况下改变默认行为。

下表列出面向用户的常用变量。除非另有说明,所有变量都在命令运行时读取,因此可以逐次调用临时设置:

CJV_LOG=debug cjv install lts

常用变量

变量默认值说明
CJV_HOME~/.cjv覆盖 cjv 的主目录(数据根目录)。必须是绝对路径,否则 cjv 会报错退出。该变量优先级高于 settings.toml 中持久化的 home 设置。
CJV_TOOLCHAIN强制指定活跃工具链,覆盖所有其他解析方式(目录覆盖、工具链文件、默认工具链)。
CJV_LOGwarn日志级别,可选 debuginfowarnerror。无法识别的值按 warn 处理。日志输出到标准错误(stderr)。
CJV_MAX_RETRIES3单次下载失败后的最大重试次数。取值需为非负整数,非法值将被忽略并回退到默认值。
CJV_DOWNLOAD_TIMEOUT180HTTP 下载的超时时间(秒)。取值需为正整数,非法值将被忽略并回退到默认值。
CJV_DIST_SERVER覆盖工具链分发根。LTS/STS 使用 <root>/versions.json,nightly 使用 <root>/nightly.json
CJV_NO_PATH_SETUP设为 1 跳过首次安装时的 PATH 自动配置(适用于 CI 环境和集成测试)。其他值(包括未设置)不生效。
CANGJIE_STDX_PATH_DYNAMIC由 cjv 注入指向 <CJV_HOME>/stdx/<tc>/dynamic,仅当对应工具链安装了 stdx 组件时注入。通常无需手动设置。
CANGJIE_STDX_PATH_STATIC由 cjv 注入指向 <CJV_HOME>/stdx/<tc>/static,仅当对应工具链安装了 stdx 组件时注入。通常无需手动设置。

详细说明

CJV_HOME

CJV_HOME 决定 cjv 存放工具链、组件、文档、下载缓存与设置文件的根目录,默认是用户主目录下的 ~/.cjv

它必须是绝对路径。相对路径会随当前工作目录变化而指向不同位置,导致从不同目录调用 cjv 时看到不同的安装集合,因此 cjv 会拒绝相对路径并报错退出。

主目录的解析顺序为(从高到低):

  1. CJV_HOME 环境变量
  2. settings.toml 中持久化的 home(通过 cjv set home <path> 写入)
  3. 默认值 ~/.cjv

如需将主目录持久化而非每次设置环境变量,参见配置cjv show home 会打印当前生效的主目录及其来源。

CJV_TOOLCHAIN

CJV_TOOLCHAIN 位于工具链解析优先级的最顶端,会覆盖目录覆盖、工具链文件(cangjie-sdk.toml)和默认工具链。常用于临时切换工具链运行单条命令:

CJV_TOOLCHAIN=nightly cjc --version

完整的解析顺序详见目标与覆盖

CJV_LOG

将日志级别调到 debug 可以观察下载、解析与代理执行的细节,便于排查问题:

CJV_LOG=debug cjv install lts

CJV_MAX_RETRIESCJV_DOWNLOAD_TIMEOUT

这两个变量用于在网络不稳定或镜像较慢时调整下载行为:

# 提高重试次数并延长超时(适用于慢速网络)
CJV_MAX_RETRIES=5 CJV_DOWNLOAD_TIMEOUT=600 cjv install sts

CJV_MAX_RETRIES 指失败后的重试次数,CJV_DOWNLOAD_TIMEOUT 以秒为单位。两者的非法值都会被忽略并回退到默认值。

CJV_DIST_SERVER

CJV_DIST_SERVER 临时覆盖 settings.toml 或系统后备配置中的 dist_server。它适合在 CI 中切换正式源与预发布源:

CJV_DIST_SERVER=https://artifacts.corp.example/cjv/dist cjv install nightly

设置后,LTS/STS 与对应组件由 <root>/versions.json 描述,nightly 与对应组件由 <root>/nightly.json 描述。cjv 按操作所需通道加载文件;相对制品 URL 以该根为基准,绝对 URL 按 manifest 原样使用。完整布局见内部分发源

CJV_NO_PATH_SETUP

首次安装工具链时,cjv 会把自身的 bin 目录加入 PATH,使代理命令(如 cjccjpm)立即可用。在 CI 环境或集成测试中,自动修改 PATH 往往不必要,可将该变量设为 1 跳过:

CJV_NO_PATH_SETUP=1 cjv install lts

只有值恰好为 1 时才会跳过,其他值不生效。

CANGJIE_STDX_PATH_DYNAMICCANGJIE_STDX_PATH_STATIC

这两个变量由 cjv 在代理执行和运行时环境配置(cjv exec / cjv envsetup)中自动注入,分别指向 stdx 组件解压后的 dynamicstatic 目录。仅当当前工具链安装了 stdx 组件时才会注入。

一般情况下无需手动设置它们,cjv 会确保仓颉编译器和构建工具能正确找到扩展库。关于 stdx 组件的安装与目录布局,参见组件;关于运行时环境的配置方式,参见运行时环境

网络代理(https_proxy / http_proxy / no_proxy

cjv 的下载会自动遵循标准代理环境变量,在企业受限网络里无需任何 cjv 配置。设置方式、支持的代理方案(http / https / socks5)与注意事项详见网络代理

高级变量

以下变量面向特殊场景,普通用户通常无需设置。

变量说明
CJV_LANG覆盖界面语言(如 zhenja)。未设置时跟随系统区域设置。
CJV_ALLOW_INSECURE_MANIFEST设为 1 时,允许从非回环(loopback)主机通过明文 HTTP 拉取工具链清单。默认要求 HTTPS,因为清单同时携带下载 URL 与其校验和。仅在信任的内部镜像场景使用,详见内部分发源
CJV_FALLBACK_SETTINGS指定系统级后备设置文件路径;平台默认路径和企业分发示例见部署受管客户端

网络代理

企业网络常常不允许直接访问外网,而要求通过代理服务器。cjv 会读取标准的代理环境变量,因此在这类网络里无需任何 cjv 配置——设好环境变量即可让 cjv 的所有下载(工具链、组件、清单、自更新)走代理。

设置代理

cjv 的下载都走 HTTPS,因此设置 https_proxy 通常就够了。不同系统与 shell 的命令略有差异:

  • Linux / macOS(bash / zsh):

    export https_proxy=http://proxy.example.com:8080
    
  • Windows 命令提示符(cmd):

    set https_proxy=http://proxy.example.com:8080
    
  • Windows PowerShell:

    $env:https_proxy="http://proxy.example.com:8080"
    

代理 URL 支持 http://https://socks5:// 三种方案。用 SOCKS5 代理时,把上面的值换成 socks5://proxy.example.com:1080 即可。

排除内网地址

no_proxy 用来列出经过代理的主机,常用于让内部镜像或本地服务直连:

export no_proxy=localhost,127.0.0.1,mirror.corp.internal

例如用 --mirror 或自建镜像源安装工具链时,可以把镜像主机加入 no_proxy,让它绕过代理直连。

识别的变量

cjv 识别下列变量(大小写均可),与多数命令行工具一致:

变量作用
https_proxy / HTTPS_PROXYHTTPS 请求使用的代理。cjv 的下载都是 HTTPS,这是最关键的一个
http_proxy / HTTP_PROXYHTTP 请求使用的代理
no_proxy / NO_PROXY不经过代理的主机列表(逗号分隔)

注意:cjv 识别 ALL_PROXY / all_proxy。如果你只设了 ALL_PROXY,请改设 https_proxy

代理变量在 cjv 启动时从环境读取,因此请在运行 cjv 之前于当前 shell 里设好(上面那种逐次 https_proxy=… cjv … 的前缀写法也可以)。

相关:cjv 自身读取的 CJV_* 变量见环境变量。需要统一镜像 SDK、nightly 与组件时,见企业部署

配置

cjv 把持久化设置保存在 ~/.cjv/settings.toml 这个 TOML 文件里。日常使用中你不需要手动编辑它,用 cjv set 子命令修改即可,它们会校验取值、写回文件,并打印确认信息。

本章介绍 cjv set 的全部子命令、settings.toml 中对应的字段,以及 ~/.cjv/ 目录的整体布局。运行时通过环境变量做的临时覆盖(如 CJV_HOMECJV_DIST_SERVER)见 环境变量

settings.toml

设置文件始终位于 <用户主目录>/.cjv/settings.toml,不会随 CJV_HOME 改变。

一个典型的 settings.toml 大致长这样:

version = 1
default_toolchain = "lts"
auto_self_update = "check"
auto_install = true
manifest_url = "https://raw.githubusercontent.com/Zxilly/cangjie-version-manifest/master/versions.json"

[overrides]
"/home/me/project-a" = "sts"

字段速览:

字段类型对应命令说明
versionint(自动维护)设置文件格式版本,由 cjv 自动写入和迁移
default_toolchainstringcjv default <toolchain>默认工具链,见 工具链
manifest_urlstring手动编辑 / 系统后备配置LTS/STS 清单地址;nightly 从同目录的 nightly.json 按需读取
dist_serverstring手动编辑 / 系统后备配置工具链分发根;包含 versions.jsonnightly.json,见内部分发源
auto_self_updatestringcjv set auto-self-updatecjv update 时的自更新行为:enable / disable / check
auto_installboolcjv set auto-install代理模式下是否自动安装缺失的工具链
homestringcjv set home持久化的 CJV_HOME 数据目录路径
default_hoststringcjv set default-host默认主机平台标识(goos-goarch 形式)
overridestablecjv override目录到工具链的覆盖映射,见 目标与覆盖

文件中无法识别的键(例如拼写错误)会以 warn 级别日志提示,但不会阻止 cjv 启动。把 version 设成超过当前二进制支持的值则会报错。

manifest_urldist_server 通过用户设置文件或系统后备配置提供。来源优先级为 CJV_DIST_SERVERdist_servermanifest_url。根地址对应 <root>/versions.json<root>/nightly.json;直接配置 manifest_url 时,nightly 文件位于其同一目录。完整契约见内部分发源

cjv set

cjv set 修改 settings.toml 中的单项设置。只有当新值与当前值不同时才会写盘,并打印 设置 '<key>' 已更新为 '<value>'

cjv set auto-self-update

控制 cjv update 在更新工具链之后是否顺带自更新 cjv 本体。

# 自动下载并安装 cjv 的新版本
cjv set auto-self-update enable

# 完全关闭自更新(连提示都不打印)
cjv set auto-self-update disable

# 默认:仅在有新版本时提示,不自动安装
cjv set auto-self-update check

enable 会在 cjv update 完成后自动升级 cjv;disable 会跳过自更新;check(默认)只打印当前 cjv 版本,不自动升级。

无论此设置如何,你都可以随时用 cjv self update 手动升级 cjv。

cjv set auto-install

控制代理模式下,当解析出的工具链尚未安装时是否自动安装它。默认开启(true)。

# 默认:直接调用 cjc / cjpm 时,缺失的工具链会被自动安装
cjv set auto-install true

# 关闭:缺失工具链时报错,而不是自动安装
cjv set auto-install false

开启时,直接运行 cjccjpm 等 SDK 工具,如果当前解析到的工具链没装,cjv 会先把它装上再代理执行。cangjie-sdk.toml 中声明的 组件目标 同样适用:开启 auto-install 后,代理执行会按需补齐缺失的组件和目标 SDK。

cjv set home

CJV_HOME 数据目录路径持久化到 settings.toml。传入的相对路径会被转成绝对路径后存储。

# 把数据目录持久化到指定位置
cjv set home /opt/cjv-data

# 传空字符串可清除该覆盖,恢复到默认 ~/.cjv
cjv set home ""

CJV_HOME 环境变量始终优先于此设置。即使在 settings.toml 里持久化了 home,只要 shell 中设置了 CJV_HOME 环境变量,后者仍然生效。settings.toml 文件本身不受影响,永远留在 ~/.cjv/

cjv set default-host

设置默认的主机平台标识(goos-goarch 形式,如 linux-amd64)。一般无需手动设置,cjv 会自动探测当前主机平台;仅在自动探测不符合预期、需要显式指定时才用到。

cjv set default-host linux-amd64

取值必须是 cjv 能识别的合法平台标识,否则命令会报错。

~/.cjv 目录结构

cjv 的全部数据都放在 CJV_HOME(默认 ~/.cjv)下,各子目录职责相互解耦:

~/.cjv/
  bin/            # cjv 与 SDK 工具命令入口
  toolchains/     # 已安装的 SDK 工具链(仅 SDK 本体)
  stdx/           # stdx component(按工具链拆分,路径通过 CANGJIE_STDX_PATH_* 暴露)
    <tc>/
      dynamic/
      static/
  docs/           # 离线文档(与工具链解耦,docs 与 stdx-docs 各自独占子目录)
    <tc>/
      main/                    # docs component(dev-guide / libs/std / tools 入口)
      stdx/                    # stdx-docs component(libs_stdx 入口)
  downloads/      # 下载暂存区(安装成功后即清空,仅用于中断恢复)
  settings.toml   # 用户设置

bin/ 存放 cjv 与 cjccjpm 等 SDK 工具的命令入口。把这个目录加入 PATH 后即可直接调用这些命令,详见代理

toolchains/<tc>/ 是每个已安装工具链的 SDK 本体。

stdx/<tc>/ 按工具链拆分存放 stdx 组件,分为 dynamic/static/。代理或运行时环境中会自动注入 CANGJIE_STDX_PATH_DYNAMICCANGJIE_STDX_PATH_STATIC 指向这两个目录,详见 组件

docs/<tc>/ 是离线文档,与工具链目录解耦。main/docs 组件(dev-guide、libs/std、tools),stdx/stdx-docs 组件。用 cjv doc 在浏览器中打开。

downloads/ 是下载暂存区,安装成功后即清空,只在安装中断时保留以便恢复。settings.toml 是本章描述的用户设置文件。

cjv toolchain uninstall <tc> 会连带清理 stdx/<tc>/docs/<tc>/,不会留下孤立的组件数据。

如果设置或持久化了自定义 CJV_HOME,上述 bin/toolchains/stdx/docs/downloads/ 都会落在新路径下;唯独 settings.toml 始终留在用户主目录的 ~/.cjv/(见上文 settings.toml)。

企业部署概览

企业网络可以让 cjv 通过统一代理访问上游,也可以把工具链和组件发布到内部 HTTPS 制品库。网络请求集中在安装、更新、远程查询和自动补齐阶段;已安装工具链的日常命令在本地执行。

选择部署模式

网络条件推荐模式支持范围
允许经企业代理访问公网设置标准代理环境变量全部通道和自更新,受上游可用性约束
终端只能访问内部制品库配置统一 dist_serverLTS、STS、nightly、SDK 与组件均可完整内网化
完全离线或气隙环境本地归档或目录链接已安装或本地提供的工具链可用
要求强制统一源和版本内部分发源 + 网络 ACL + 企业软件分发系统后备配置提供默认值,网络 ACL 实施访问策略

mirror 构建变体提供 GitCode 默认端点,适合 GitHub 访问不稳定的网络。企业内部镜像使用 dist_server

工具链分发与 cjv 更新是两条链路

cjv 将两类制品分开处理:

  • 工具链分发源:SDK、stdx、docs、stdx-docs,以及 LTS、STS、nightly 的版本元数据。企业部署通过 dist_serverCJV_DIST_SERVER 统一控制。
  • cjv 本体:安装脚本首次下载 cjv 时可使用 CJV_UPDATE_ROOT。企业软件分发系统负责已安装 cjv 的升级,客户端配置 auto_self_update = "disable"

配置 dist_server 后,cjv 从 <dist_server>/versions.json 按需读取 LTS/STS,从 <dist_server>/nightly.json 按需读取 nightly。两份文件分别携带对应通道的 SDK 与组件。

网络访问范围

操作默认来源企业替代方式
安装 cjv 本体GitHub 或 GitCode Release内部托管发布归档与 checksums.txt,安装脚本设置 CJV_UPDATE_ROOT
安装、查询或更新工具链默认 manifest配置 dist_server
下载 SDK 和组件manifest 中声明的 URL在对应的 versions.jsonnightly.json 中声明批准的 URL
cjv self update官方版使用 GitHub,mirror 版使用 GitCode关闭自更新,由企业软件分发系统升级 cjv

cjpm 项目依赖仓库和凭据遵循项目自身配置;企业还需配置对应的依赖仓库镜像。cjv 的企业分发源覆盖 SDK 与组件。

接下来依次完成:

  1. 建设内部分发源
  2. 部署受管客户端
  3. 配置代理或完全离线终端
  4. 制定发布、升级与验收流程

内部分发源

dist_server 是工具链制品根地址。假设配置为:

dist_server = "https://artifacts.corp.example/cjv/dist"

cjv 按通道读取两个独立文件:

https://artifacts.corp.example/cjv/dist/versions.json  # LTS / STS
https://artifacts.corp.example/cjv/dist/nightly.json   # nightly

LTS/STS 操作只读取 versions.json;nightly 操作只读取 nightly.jsoncjv checkcjv update 根据已安装通道加载所需文件。相对 SDK 与组件 URL 以分发根为基准解析,绝对 URL 完全按 manifest 中的值使用。

推荐布局

企业制品库
└── cjv/
    ├── dist/                         # dist_server 指向这里
    │   ├── versions.json             # LTS / STS 及其组件
    │   ├── nightly.json              # nightly 及其组件
    │   ├── sdk/
    │   ├── components/
    │   └── nightly/
    └── releases/                     # cjv 本体归档和 checksums.txt

分发端点通过 HTTPS GET 向受管终端提供机器可读的只读访问。网络白名单、设备身份或企业反向代理可以实施访问控制。

versions.json 契约

versions.json 的顶层是 channels,包含 ltssts

{
  "channels": {
    "lts": {
      "latest": "1.0.5",
      "versions": {
        "1.0.5": {
          "linux-x64": {
            "name": "cangjie-sdk-linux-x64-1.0.5.tar.gz",
            "url": "sdk/cangjie-sdk-linux-x64-1.0.5.tar.gz",
            "sha256": "<64 位十六进制 SHA-256>"
          }
        }
      }
    },
    "sts": {
      "latest": "1.1.0",
      "versions": {
        "1.1.0": {
          "linux-x64": {
            "name": "cangjie-sdk-linux-x64-1.1.0.tar.gz",
            "url": "sdk/cangjie-sdk-linux-x64-1.1.0.tar.gz",
            "sha256": "<64 位十六进制 SHA-256>"
          }
        }
      }
    }
  }
}

nightly.json 契约

nightly.json 直接表示一个通道,包含 latestversions 和可选 components

{
  "latest": "1.2.0-alpha.20260822010101",
  "versions": {
    "1.2.0-alpha.20260822010101": {
      "linux-x64": {
        "name": "cangjie-sdk-linux-x64-1.2.0-alpha.20260822010101.tar.gz",
        "url": "nightly/20260822/cangjie-sdk-linux-x64-1.2.0-alpha.20260822010101.tar.gz",
        "sha256": "<64 位十六进制 SHA-256>"
      }
    }
  },
  "components": {
    "1.2.0-alpha.20260822010101": {
      "docs": {
        "name": "cangjie-docs-html-1.2.0-alpha.20260822010101.tar.gz",
        "url": "nightly/20260822/cangjie-docs-html-1.2.0-alpha.20260822010101.tar.gz",
        "sha256": "<64 位十六进制 SHA-256>"
      }
    }
  }
}

每个 SDK 条目包含 nameurlsha256。nightly 的 sha256 可以暂为空,此时 cjv 读取 <url>.sha256;企业镜像宜直接填入校验和。组件条目支持可选 sha256。版本键决定工具链名称,URL 精确定位下载资产。

cjv install nightly 安装 nightly.jsonlatest;带版本的 nightly 安装、checkupdatelist-remote 和组件安装都读取同一文件。项目固定确切 nightly 版本可获得可复现构建。

发布顺序

  1. 镜像并校验批准版本的 SDK 与组件归档。
  2. 计算 SDK SHA-256;组件也建议计算并写入 manifest。
  3. 先发布所有归档,并用普通终端账户验证 HTTPS GET。
  4. 分别生成 versions.jsonnightly.json
  5. 原子替换对应文件;制品齐全后推进该文件中的 latest
  6. 保留项目工具链文件引用的全部精确版本。

来源优先级为 CJV_DIST_SERVER、设置文件中的 dist_servermanifest_url。CI 可用环境变量临时选择测试源。

部署受管客户端

推荐把“安装 cjv”“下发系统配置”和“安装默认工具链”拆成可分别检查退出码的步骤。

1. 安装 cjv 本体

可以直接通过企业软件分发系统下发并校验 cjv 归档,也可以在内部托管安装脚本。Windows PowerShell 示例:

$env:CJV_UPDATE_ROOT = "https://artifacts.corp.example/cjv/releases/latest/download"
& ([scriptblock]::Create((irm https://artifacts.corp.example/cjv/install.ps1))) `
  -Yes -DefaultToolchain none -NoModifyPath

CJV_UPDATE_ROOT 的作用域是安装脚本此次下载。工具链分发由 dist_server 控制,已安装二进制的升级由企业软件分发流程控制。-NoModifyPath 让企业通过 GPO、终端管理工具或构建镜像统一设置 PATH;允许 cjv 修改用户环境时可省略该参数。

自动化部署建议使用 -DefaultToolchain none,再单独执行 cjv install,以便分别检查 cjv 与 SDK 的安装结果。

2. 下发系统后备配置

cjv 会从下列系统级路径读取后备设置:

  • Windows:C:\ProgramData\cjv\settings.toml
  • Linux / macOS:/etc/cjv/settings.toml

也可以用 CJV_FALLBACK_SETTINGS 指定其他路径。受管终端示例:

version = 1
dist_server = "https://artifacts.corp.example/cjv/dist"
default_toolchain = "lts-1.0.5"
auto_self_update = "disable"
auto_install = false

请把示例版本替换为企业批准的确切版本。受限网络建议设置 auto_install = false:项目请求尚未部署的工具链或组件时,cjc / cjpm 会立即返回缺失错误。

配置优先级为 CJV_DIST_SERVER、用户 ~/.cjv/settings.toml、系统后备文件和内置默认值。防火墙、DNS 与代理白名单实施网络访问策略。

建议为每个用户分配独立的 CJV_HOME

3. 安装并固定批准版本

确认系统配置已经就位,再安装确切版本:

cjv install lts-1.0.5 -c stdx
cjv default lts-1.0.5
cjv which cjc
cjc --version

项目提交 cangjie-sdk.toml 后,各开发机使用同一批准版本:

[toolchain]
channel = "lts-1.0.5"
components = ["stdx"]

nightly 项目固定 manifest 中保留的确切版本即可获得可复现配置:

[toolchain]
channel = "nightly-1.2.0-alpha.20260822010101"

工具链文件的完整语义见工具链文件

代理与完全离线环境

仅使用企业代理

代理模式通过 HTTPS_PROXY / https_proxy 访问上游,并用 NO_PROXY / no_proxy 直连内部服务:

$env:HTTPS_PROXY = "http://proxy.corp.example:8080"
$env:NO_PROXY = "localhost,127.0.0.1,artifacts.corp.example"
cjv install lts-1.0.5

cjv 支持 HTTP_PROXYHTTPS_PROXYNO_PROXY 这一组标准变量。TLS 解密代理使用企业 CA 时,先把 CA 安装进操作系统信任库。完整变量说明见网络代理

慢速链路可以调整下载重试和整个请求的超时:

$env:CJV_MAX_RETRIES = "5"
$env:CJV_DOWNLOAD_TIMEOUT = "600"

同时使用内部分发源时,把 dist_server 主机加入 NO_PROXY,让内部制品流量直接到达制品库。

完全离线部署

本地 SDK 归档或解压目录可以直接安装:

# 从本地归档物化安装;推荐始终提供批准的 SHA-256
cjv toolchain link corp-sdk ./cangjie-sdk.zip --sha256 <approved-sha256>

# 或引用已经解压的 SDK 目录
cjv toolchain link corp-sdk /opt/corp/cangjie-sdk

# stdx 可以从本地目录链接
cjv component link stdx /opt/corp/cangjie-stdx --toolchain corp-sdk
cjv default corp-sdk

本地归档或目录会创建 custom 工具链,项目中的 cangjie-sdk.toml 使用相同的自定义名称。stdx 支持本地链接;docsstdx-docs 通过内部分发源预装。更多归档格式说明见从 URL 或本地归档安装工具链

远程查询和更新使用可达的内部 HTTPS manifest;气隙环境固定本地 custom 工具链并执行本地构建流程。

发布、升级与验收

cjv 本体升级

工具链由 dist_server 分发,cjv 本体由企业软件分发系统升级。建议流程如下:

  1. 在受控环境获取 cjv 发布归档和同一发布的 checksums.txt
  2. 校验后发布到企业制品库或软件分发系统。
  3. 在客户端设置 auto_self_update = "disable"
  4. 通过 GPO、终端管理平台、系统包或基础镜像统一升级 cjv。

CJV_UPDATE_ROOT 为安装脚本选择首次下载地址;后续版本由上述企业升级流程发布。

Nightly 发布策略

nightly 由独立的 nightly.json 发布,发布策略应比 LTS/STS 更严格:

  • 先镜像同一版本的全部批准平台、目标 SDK 和组件,再推进 channels.nightly.latest
  • latest 精确选择一个版本;缺少目标或组件时返回对应错误。
  • 保留所有被 cangjie-sdk.toml 固定的 nightly 版本及其组件。
  • 让每个 SDK 条目的 URL 精确指向对应的上游或内部制品。
  • nightly.json 使用原子发布,让客户端始终读取完整版本。

上线验收清单

  • 从普通用户会话分别执行 LTS 与 nightly 远程列表,确认请求按通道命中 versions.jsonnightly.json
  • 在仅配置 dist_server 的终端安装批准的 nightly,确认安装成功。
  • 安装批准版本及所需组件后,执行 cjv which cjccjc --version
  • 检查 manifest 中 host SDK、交叉编译目标、stdx、docs 和 stdx-docs 的 URL,确认都符合企业批准的访问范围。
  • 临时从 nightly.json 删除某个版本或组件,确认命令返回明确的缺失错误,并核对分发端访问日志。
  • 断开网络后再次编译,确认已安装工具链完成本地构建。
  • 确认 auto_install = falseauto_self_update = "disable",并由企业流程负责升级。
  • 验证企业 CA、代理变量和 NO_PROXY 在实际终端与 CI 服务账户下均生效。
  • 用网络 ACL 将终端访问范围限制为企业批准的下载地址。

系统后备配置用于提供一致默认值;真正的强制策略由网络 ACL、终端权限和软件分发流程共同完成。

命令参考

本章逐条列出 cjv 的命令,给出用法、参数、标志与可复制的示例。每个命令的简短说明也会出现在 cjv <command> --help 中。

全局约定

几乎所有命令都接受全局标志 --json,它把结果以稳定的 JSON 结构输出到标准输出,便于脚本消费。cjv runcjv execcjv init 不支持 JSON 输出,传入 --json 会报错。

未显式指定工具链的命令会按统一优先级解析活跃工具链:CJV_TOOLCHAIN 环境变量、目录覆盖、cangjie-sdk.toml 工具链文件、默认工具链,按此顺序取第一个生效的。详见 目标与覆盖

标准通道名为 ltsstsnightly,也可写成具体版本(如 lts-1.0.0)。通过 cjv toolchain link 链接的自定义工具链使用任意自定义名,但不得与保留通道名冲突。cjv execcjv envsetup 还支持以 +name 前缀临时指定工具链,覆盖默认解析。

被代理或被执行的子命令以其原始退出码退出,这适用于 cjv runcjv exec


安装与卸载

cjv install

安装仓颉 SDK 工具链,可附带交叉编译目标与组件。

cjv install <toolchain> [-t target]... [-c component]... [--force]

参数:

  • <toolchain>(必填):要安装的工具链,如 ltsstsnightly 或具体版本。它不能用于安装自定义工具链,那种情况请用 cjv toolchain link

标志:

标志说明
-t, --target <suffix>需要附加安装的交叉编译目标后缀(可重复或逗号分隔),如 ohosandroidohos-arm32
-c, --component <name>需要附加安装的组件(可重复或逗号分隔),如 stdxdocsstdx-docs
--force强制重新下载并重装,即使已安装

示例:

# 安装最新 LTS 工具链
cjv install lts

# 安装具体版本
cjv install lts-1.0.0

# 安装宿主 STS SDK,并额外安装两个交叉编译目标
cjv install sts -t ohos -t android
cjv install sts --target ohos,android

# 安装时顺带装上组件
cjv install nightly -c stdx,docs

# 强制重装
cjv install lts --force

target 只填目标后缀,不要写完整平台 key(如 linux-x64-ohos)。交叉编译目标是宿主工具链的附加安装项,不改变活跃工具链。详见 交叉编译组件

cjv uninstall

卸载工具链,并一并清理其 stdx 与离线文档。

cjv uninstall <toolchain> [-y]

参数:

  • <toolchain>(必填):要卸载的工具链名称。

标志:

标志说明
-y, --yes跳过确认提示

卸载会在交互式终端弹出确认;非交互式终端、--json 模式或加 -y 时直接执行。如果被卸载的工具链是默认工具链,cjv 会把默认指向另一个已安装的宿主工具链,指向它的目录覆盖也会被清除。卸载会连带删除 <CJV_HOME>/stdx/<tc>/<CJV_HOME>/docs/<tc>/

cjv uninstall sts
cjv uninstall lts-1.0.0 -y

cjv toolchain uninstall <name> 与本命令等价,行为一致。

cjv update

将指定工具链或所有已安装工具链更新到对应通道的最新版本。

cjv update [toolchain] [--no-self-update]

参数:

  • [toolchain](可选):只更新指定工具链。省略时更新所有已安装工具链。

标志:

标志说明
--no-self-update跳过 cjv 自更新检查

传入通道名(如 lts)时,更新该通道当前已安装版本到最新版本。传入具体版本时,等同于安装该版本,已安装则跳过。自定义(链接)工具链无法更新,会被跳过或报错。更新到新版本后,原指向旧版本的默认工具链与目录覆盖会自动改指向新版本,旧目录被删除。更新结束后会根据 auto-self-update 设置决定是否自更新 cjv 本身,可用 --no-self-update 关闭。

# 更新所有工具链
cjv update

# 只更新 LTS
cjv update lts

# 更新但不触发 cjv 自更新
cjv update --no-self-update

cjv check

检查已安装工具链是否有可用更新,但不执行安装。

cjv check

逐个列出已安装工具链:有更新显示 当前 → 最新,已是最新显示 ,并在末尾显示 cjv 自身版本。--json 模式输出结构化结果,含 update_availablelatest 等字段。

cjv check
cjv check --json

查看与运行

cjv show

显示活跃工具链、默认主机平台与已安装工具链列表。

cjv show
cjv show active
cjv show installed
cjv show home

子命令:

子命令说明
cjv show显示活跃工具链 + 默认主机 + 已安装列表(含各工具链已装组件)
cjv show active仅显示当前活跃工具链及其来源
cjv show installed仅列出已安装工具链
cjv show home显示 CJV_HOME 路径及其来源
cjv show
cjv show active
cjv show home

cjv run

使用指定工具链运行命令,不影响当前 shell。

cjv run [--install] <toolchain> <command> [args...]

参数:

  • <toolchain>(必填):用于运行命令的工具链。
  • <command>(必填):要运行的命令;可以是工具链自带工具(如 cjccjpm),也可以是该工具链环境下 PATH 中的任意命令。
  • [args...]:传给命令的参数。

标志:

标志说明
--install当目标工具链未安装时,先自动安装再运行

命令在该工具链的运行时环境中执行,cjv 会注入正确的 PATH 与库路径,并应用已安装组件的环境(如 CANGJIE_STDX_PATH_*)。该命令不支持 --json

# 用 sts 工具链查看 cjc 版本
cjv run sts cjc --version

# 工具链未装则先装再运行
cjv run --install nightly cjpm build

cjv exec

在仓颉运行时环境中执行任意命令,便于直接运行编译产物。

cjv exec [+toolchain] <command> [args...]

参数:

  • [+toolchain](可选):以 +name 前缀临时指定工具链;省略时按标准优先级解析活跃工具链。
  • <command>(必填):要执行的命令。
  • [args...]:传给命令的参数。

仓颉编译出的二进制动态链接运行时库,需要正确的库搜索路径。cjv exec 在注入了运行时库路径的环境中执行命令,但不影响当前 shell。该命令不支持 --json

# 在活跃工具链的运行时环境中运行编译产物
cjv exec ./my_binary arg1 arg2

# 指定工具链
cjv exec +nightly ./my_binary

# "--" 之后的内容原样传递,可运行以 "+" 开头的命令名
cjv exec -- +weird-command

详见 运行时环境

cjv envsetup

输出用于配置仓颉运行时环境的 shell 命令,供当前 shell 会话 eval

cjv envsetup [+toolchain] [--target=SUFFIX] [--shell=TYPE]

参数与标志:

参数 / 标志说明
[+toolchain]+name 临时指定工具链
--shell=TYPE手动指定 shell 类型:bashfishpowershellcmd;省略时自动检测
--target=SUFFIX输出已安装目标 SDK 的运行时环境(独立 SDK 模型),如 --target=ohos

envsetup 与代理模式使用相同的工具链解析优先级。--target 对应的目标 SDK 需先通过 cjv install <toolchain> --target <suffix> 安装。--json 模式输出结构化的环境描述(变量、PATH 前后置、库路径键),不打印 shell 脚本。

# Bash / Zsh
eval "$(cjv envsetup)"

# Fish
cjv envsetup | source

# PowerShell
cjv envsetup | Invoke-Expression

# 指定工具链并强制 bash 格式
cjv envsetup +nightly --shell=bash

# 输出已安装 ohos 目标 SDK 的环境
cjv envsetup --target=ohos

cjv which

显示活跃工具链中某个 SDK 工具的路径;不带参数时打印工具链根目录。

cjv which [command]

参数:

  • [command](可选):要查询的工具名,如 cjccjpm。省略时打印活跃工具链根目录。
# 打印活跃工具链根目录
cjv which

# 打印 cjc 的绝对路径
cjv which cjc

cjv whichcjv run 使用一致的工具解析逻辑:除固定代理工具外,也能解析 bin/tools/bin/ 下的二进制。

cjv doc

在浏览器中打开当前工具链的离线文档。

cjv doc [topic] [--path] [--toolchain <tc>]

参数:

  • [topic](可选):要跳转的子页主题,如 stdxstddev-guidebooktools。省略时打开根 index.html

标志:

标志说明
--path只打印文档路径或 URL,不打开浏览器
--toolchain <tc>指定要打开文档的工具链(默认为当前活跃工具链)

若目标工具链尚未安装 docs / stdx-docs,会提示先用 cjv component add 安装。--json 模式同样只返回路径,不启动浏览器。命令别名:cjv docs

cjv doc
cjv doc std
cjv doc --path
cjv doc stdx --toolchain nightly

工具链管理

cjv toolchain list

列出已安装的工具链(等价于 cjv show installed)。

cjv toolchain list

将自定义工具链链接到本地目录(引用),或从本地归档 / URL 解包并安装为 cjv 拥有的工具链(物化)。

cjv toolchain link <name> <path|url> [--sha256 <hash>] [--force] [--no-stdx]

参数:

  • <name>(必填):自定义工具链名。必须是自定义名,不能与保留通道名 ltsstsnightly 冲突,也不能含路径分隔符、+ 前缀或为非法名。
  • <path|url>(必填):本地目录、本地归档文件(.zip / .tar.gz),或 HTTP(S) URL。目录使用引用模式,归档和 URL 使用物化模式。

两种行为:

维度引用模式(本地目录)物化模式(本地归档 / URL)
<path> 形态本地目录本地归档 sdk.zip,或 https://...
toolchains/<name> 内容引用原目录由 cjv 管理的安装目录
数据归属cjv 不拥有,只引用cjv 拥有
卸载行为只删链接,原目录保留删除整个目录(含 stdx)

标志(仅物化模式,本地归档与 URL 同样适用):

标志说明
--sha256 <hash>用该 SHA-256 校验归档
--force覆盖同名的已存在工具链
--no-stdx跳过安装随包的 stdx 组件

这三个标志只对物化模式有效,与本地目录一起使用会报错,而不是静默忽略。引用模式要求目录是一个真实的仓颉 SDK(须存在 bin/cjc)。

# 引用模式:只创建链接,原目录保留
cjv toolchain link mysdk /path/to/local/sdk

# 物化模式(本地归档):解包落地为 cjv 拥有的真实目录,源文件保留
cjv toolchain link mysdk ./cangjie-linux-x64-1.0.0.zip

# 物化模式(URL):下载、解包,落地为 cjv 拥有的真实目录
cjv toolchain link mysdk https://example.com/cangjie-linux-x64-1.0.0.zip

# 物化模式 + 校验 + 覆盖同名 + 跳过随包 stdx
cjv toolchain link mysdk https://example.com/sdk.zip \
  --sha256 <hash> --force --no-stdx

物化模式的归档格式、随包 stdx 和平台限制见从 URL 或本地归档安装工具链。链接本地 stdx 见组件

cjv toolchain uninstall

卸载工具链(等价于 cjv uninstall)。

cjv toolchain uninstall <name> [-y]
标志说明
-y, --yes跳过确认提示

组件管理

cjv component 的子命令统一支持持久标志 --toolchain <tc> 指定目标工具链;省略时使用当前活跃工具链。

cjv component add

为工具链安装一个或多个组件(如 stdxdocsstdx-docs)。

cjv component add <name>... [--toolchain <tc>] [--force]
标志说明
--toolchain <tc>目标工具链(默认为当前活跃工具链)
--force强制重新下载并重装,即使已安装

<name> 可重复或逗号分隔。通过 cjv toolchain link 链接的自定义工具链没有对应的 release 资产,component add 对其不可用,请改用 cjv component link

cjv component add stdx --toolchain lts
cjv component add stdx,docs
cjv component add stdx --force

将本地组件目录链接到工具链,而非通过下载安装。当前用于 stdx

cjv component link <name> <path> [--toolchain <tc>] [--force]
标志说明
--toolchain <tc>目标工具链(默认为当前活跃工具链)
--force替换已存在的组件安装(无论它是 link 还是下载得到的)

<path> 必须包含 dynamic/static/ 两个子目录。链接后相关环境变量仍会正常配置;移除组件或卸载工具链不会删除原始目录。

# 自定义工具链没有 release 资产,用 link 挂上本地 stdx
cjv toolchain link mysdk /path/to/local/sdk
cjv component link stdx /path/to/local/stdx --toolchain mysdk

# 标准通道也可用 link 替代下载(离线 / 调试自编译 stdx)
cjv component link stdx /path/to/local/stdx --toolchain lts --force

cjv component remove

从工具链卸载一个或多个组件。

cjv component remove <name>... [--toolchain <tc>]

<name> 可重复或逗号分隔。别名:uninstallrmdeletedel

cjv component remove stdx-docs
cjv component remove stdx,docs --toolchain nightly

cjv component list

列出组件的已安装与可安装情况。

cjv component list [--toolchain <tc>] [--installed] [-q]
标志说明
--toolchain <tc>目标工具链(默认为当前活跃工具链)
--installed仅列出已安装的组件
-q, --quiet以单列形式输出(只打印名字,便于脚本)
cjv component list
cjv component list --toolchain nightly
cjv component list --installed -q

详见 组件


默认工具链与覆盖

cjv default

设置或显示默认工具链。

cjv default [toolchain]

参数:

  • [toolchain](可选):要设为默认的工具链。省略时显示当前默认。传入 none 清除默认设置。

交叉编译目标变体(如 lts-1.0.0-ohos)不能设为活跃或默认工具链,请用宿主工具链并通过 targets 配置。若设为一个尚未安装的工具链,会给出 warn 但不阻止。

# 显示当前默认
cjv default

# 设为 lts
cjv default lts

# 清除默认
cjv default none

cjv override set

为某个目录设置工具链覆盖。进入该目录(或其子目录)时,cjv 优先使用该工具链。

cjv override set <toolchain> [--path <dir>]
标志说明
--path <dir>为指定目录设置覆盖,而非当前目录
cjv override set nightly
cjv override set lts --path /path/to/project

cjv override unset

移除目录的工具链覆盖。

cjv override unset [--path <dir>] [--nonexistent]
标志说明
--path <dir>移除指定目录的覆盖,而非当前目录
--nonexistent移除所有指向已不存在目录的覆盖
cjv override unset
cjv override unset --path /path/to/project
cjv override unset --nonexistent

cjv override list

列出所有目录覆盖。

cjv override list

工具链解析优先级与覆盖语义详见 目标与覆盖


配置

cjv set

修改 cjv 设置(存储在 <CJV_HOME>/settings.toml)。

cjv set auto-self-update <enable|disable|check>
cjv set auto-install <true|false>
cjv set default-host <goos-goarch>
cjv set home <path>

子命令:

子命令取值说明
auto-self-updateenable / disable / check设置自动自更新行为;check 只检查不更新
auto-installtrue / false代理模式下,解析到的工具链未安装时是否自动安装
default-host<goos-goarch>设置默认主机平台标识(如 linux-amd64),用于解析下载平台
home<path>持久化 CJV_HOME 到 settings.toml;传空字符串清除该覆盖;CJV_HOME 环境变量仍优先生效
cjv set auto-self-update check
cjv set auto-install true
cjv set default-host linux-amd64
cjv set home /opt/cjv

详见 配置环境变量


自管理

cjv self update

将 cjv 自身更新到最新版本。

cjv self update
cjv self update

cjv self uninstall

卸载 cjv 自身以及所有已安装的工具链(删除整个 <CJV_HOME>/ 并清理 PATH 配置)。

cjv self uninstall [-y]
标志说明
-y, --yes跳过确认提示

交互式终端会弹出确认。--json 模式下必须配合 -y 才能执行。

cjv self uninstall
cjv self uninstall -y

安装引导

cjv init

交互式引导首次安装:配置数据目录、PATH,并可选安装默认工具链与组件。通常由安装脚本调用,也可手动运行。

cjv init [-y] [--default-toolchain <name>] [-c component]... [--no-modify-path]
标志说明
-y, --yes跳过交互菜单,按默认选项非交互安装
--default-toolchain <name>要安装的默认工具链(默认 lts;用 none 跳过安装工具链)
-c, --component <name>随默认工具链安装的组件(可重复或逗号分隔)
--no-modify-path不修改 PATH

标准输入不是终端时(如 curl ... | sh 引导),自动回退为非交互安装。该命令不支持 --json

cjv init
cjv init -y --default-toolchain lts -c stdx,docs
cjv init -y --default-toolchain none --no-modify-path

安装方式详见 安装 cjv

常见问题

本章汇总使用 cjv 时最常遇到的问题。命令的完整说明见命令参考,背景概念见核心概念

nightly 的版本和下载地址从哪里来?

默认 manifest_url 指向 cangjie-version-manifest 生成的 versions.json;同目录的 nightly.json 由定时任务采集 GitCode nightly_build 发布生成。nightly 安装、更新、检查和远程列表按需读取后者。

nightly SDK 条目带有 SHA-256 时,cjv 直接校验;条目暂未记录校验和时,cjv 会读取资产旁的 <url>.sha256 sidecar。上游尚未发布 sidecar 时,cjv 显示完整性提示并依赖 HTTPS 传输保护。企业部署可以在内部 manifest 中为每个批准制品填入 SHA-256。详见内部分发源

在 macOS 上为什么没有自动识别我的 CPU 架构?

浏览器无法跨浏览器可靠地读取 Mac 的 CPU 架构(Apple Silicon 还是 Intel)。Safari 与 Firefox 完全不暴露架构信息,Safari 甚至在 Apple Silicon 上仍把平台标识冻结为 MacIntel。因此 cjv 的网页安装向导在无法确定架构时不会猜测,而是采用两种回退策略。

命令安装给出的 install.sh 一行命令不写死架构,由脚本在你的机器上自行探测后下载匹配的二进制。手动下载则在下载页同时给出 Apple Silicon(arm64)与 Intel(x86_64)两个选项,由你按自己的机器选择。

如果你不确定本机架构,在终端运行 uname -m:输出 arm64 选 Apple Silicon,输出 x86_64 选 Intel。安装 cjv 自身之后,工具链的下载会由 cjv 根据本机真实架构自动解析,不再有这个问题。

在离线或受限网络环境下怎么用 cjv?

cjv 的多数操作都需要从上游下载资产,但有几种方式可以适配离线、内网或镜像环境。

完整的制品库布局、系统后备配置、批量安装步骤和验收清单见企业部署。本节只列出离线使用的快捷方式。

cjv 的 mirror 构建变体提供 GitCode 默认 manifest 与自更新后端,适合 GitHub 访问不稳定的环境;企业内部镜像使用 dist_server

完整企业镜像应设置 dist_server,在根目录同时发布 versions.jsonnightly.json。也可以把 manifest_url 直接设为内部 versions.json 的完整 URL,cjv 会从同目录定位 nightly 文件。详见配置

如果你已经拿到解压好的 SDK 目录,用 cjv toolchain link 直接挂载,不会触发下载:

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

离线环境下无法 cjv component add stdx(需要下载 release 资产),改用 cjv component link 把本地 stdx 目录挂上去。标准通道也可用 --force 以本地目录替代下载:

cjv component link stdx /path/to/local/stdx --toolchain mysdk
cjv component link stdx /path/to/local/stdx --toolchain lts --force

<path> 必须是包含 dynamic/static/ 两个子目录的目录。详见组件

也可以把 SDK 归档放到内网可访问的地址,再用 URL 安装,见从 URL 安装工具链

此外,CJV_MAX_RETRIESCJV_DOWNLOAD_TIMEOUT 可调节下载的重试次数与超时,应对慢速链路。完整列表见环境变量

为什么 custom 工具链不能用 cjv component add stdx

通过 cjv toolchain link 创建的 custom 工具链没有对应的官方 release 资产,cjv 不知道该从哪里下载 stdx,因此 cjv component add stdx 对它无效。请改用下列两种方式之一:

# 方式一:链接一个本地的 stdx 目录
cjv component link stdx /path/to/local/stdx --toolchain mysdk

# 方式二:从一个 SDK 归档安装时,归档内若自带 cangjie-stdx-* 内层包,
# cjv 会把它作为 stdx 组件一并安装(见“从 URL 安装工具链”)

cjv component remove stdxcjv toolchain uninstall 不会删除链接来源目录。标准通道(lts / sts / nightly)也可以用 cjv component link stdx ... --force 以本地目录替代下载,适合离线或调试自编译 stdx 的场景。详见组件

卸载一个工具链会清理哪些目录?

执行 cjv uninstall <tc>(等价于 cjv toolchain uninstall <tc>)时,与该工具链相关的三处目录都会被一并删除:

目录内容
<CJV_HOME>/toolchains/<tc>SDK 本体
<CJV_HOME>/stdx/<tc>stdx 组件
<CJV_HOME>/docs/<tc>docs 与 stdx-docs 离线文档

stdx 与 docs 与工具链解耦、各自独立存放,但卸载时会被当作该工具链的附属物一起清掉,以免下次重装时残留过期的扩展资源。如果 stdx/<tc> 是通过 cjv component link 链接的本地目录,删除的只是符号链接,你的原始数据不受影响。

卸载同时还会清理 settings.toml 中指向该工具链的引用:如果它是默认工具链,默认设置会被清空;指向它的目录覆盖(override)也会被移除。

提示:cjv self uninstall 会删除整个 ~/.cjv 目录,连同 cjv 自身、所有工具链、组件、文档和设置一起卸载。

从 URL 安装的工具链能跨操作系统吗?

不能。cjv toolchain link 的物化安装(本地归档或 URL)只支持与当前操作系统匹配的 SDK;若 SDK 面向的系统与本机不符,cjv 会在安装前拒绝:

无法在 windows 上安装 linux SDK;此安装仅支持与当前系统匹配的 SDK

cjv 安装后要立刻校验 SDK 可用(运行其中的工具),异系统的二进制无法在本机执行。需要给其他系统准备 SDK 时,请到对应系统上安装。

这条限制只针对操作系统,不针对交叉编译目标。在同一台机器上为其他平台编译产物是支持的,那通过附加的目标 SDK 实现,见交叉编译

直接运行 cjccjpm 时 cjv 是怎么介入的?

cjv 在自己的 bin/ 目录里为每个 SDK 工具创建了代理符号链接。直接调用这些工具时,cjv 会按既定优先级解析出活跃工具链,再把调用透明地转发给对应 SDK。解析优先级从高到低为:

  1. CJV_TOOLCHAIN 环境变量
  2. 目录覆盖(cjv override set
  3. 工具链文件 cangjie-sdk.toml(当前或父目录)
  4. 默认工具链(cjv default

如果设置里开启了 auto-install 而解析到的工具链尚未安装,cjv 会在转发前自动把它装好。详见代理工具链文件

编译出的二进制运行时报找不到运行时库怎么办?

仓颉编译产物动态链接运行时库(如 libcangjie-runtime),需要正确的库搜索路径。用 cjv exec 在正确环境中一次性运行,或用 cjv envsetup 配置当前 shell 会话:

# 一次性执行,不影响当前 shell
cjv exec ./my_binary arg1 arg2

# 或为当前 shell 注入运行时环境(Bash/Zsh)
eval "$(cjv envsetup)"

详见运行时环境

我把 channel 拼成了 channal,为什么没报错只是个警告?

cangjie-sdk.toml 里未识别的键(如把表名写成 [toolchian]、把字段写成 channal)会以 warn 级别日志提示,但不会中断解析。cjv 会忽略它们并回退到下一级解析方式。如果发现工具链选择不符合预期,请先把日志级别调到 warn(默认)或 debug 检查这类提示:

CJV_LOG=debug cjv show active

工具链文件的字段语义见工具链文件,环境变量见环境变量