多版本管理

August 3, 2026 · View on GitHub

编写日期: 2026-05-17 | 更新: 2026-07-29 | 版本: 2026.7.29.0

多版本管理

xlings 支持同一工具的多个版本共存,并通过 shim 机制实现版本切换。不同 SubOS 环境可独立选择各自的活跃版本,物理存储通过引用计数共享。

基本操作

安装指定版本

xlings install gcc@14.2.0
xlings install gcc@16.1.0

多个版本并行安装,互不冲突。安装路径为:

~/.xlings/data/xpkgs/<namespace>-x-<package>/<version>/

例如 xim-x-gcc/16.1.0/local-x-mcpp/0.0.27/。命名空间是包所属的索引仓库 (官方索引为 xim),它同时出现在目录名里和命令行坐标里 —— 见下面的"坐标写法"。

切换活跃版本

xlings use gcc 14.2.0
xlings use gcc@14.2.0     # 等价写法

切换后,当前环境中 gcc 命令即指向 14.2.0 版本。

如果一个包属于一个"发布组"(例如 gcc 同时提供 gcc / g++ / cpp), use 会整组一起切换,不会只切一个而让其余留在旧版本。

新版本没有的程序会被点名。 组是按 release 定义的:如果旧 release 注册了 gcc-ar 而新 release 没有,它不会跟着切走,也不会消失 —— 它继续指向你刚离开 的那个 release。这种情况下 use 会逐个列出来:

[xlings] gcc -> 16.1.0
[warn] 1 program(s) are not part of gcc@16.1.0 and still resolve to the release you switched away from:
[warn]     gcc-ar (still 14.2.0)

如果不接受这种混合状态,用 --strict:有任何程序会被留下时直接拒绝切换, 不做任何改动。

省略版本号:确定就执行,有歧义就列出来

xlings use <name> 不带版本时不会弹出需要上下键选择的交互框,也不会 "打印一个列表然后假装切过了":

当前 subos 里已安装的版本数行为退出码
1直接切换到它0
>1不做任何改动,列出候选并给出确切命令0
0报错,并给出安装命令1
xlings use gcc            # 只装了一个版本 → 直接切;装了多个 → 列出候选
xlings use gcc --all      # 候选范围放宽到所有 subos

多个候选时返回 0,因为它不是一次失败:不给版本号本来就不是在表达切换, 而是在提问,而这条命令把问题完整回答了。想要切换就把版本号写出来 —— xlings use gcc 16.1.0 成功即 0、失败非零,没有第三种含义。

这条规则对脚本和 agent 是硬约定:"有没有人在键盘前"是探测不出来的 (很多 agent 会分配 pty),所以它不参与决定命令做什么,只决定怎么显示。

use 只在已安装的版本之间切换

xlings use <name> <version> 要求这个版本在当前 subos 里装过。换一个 全新的 subos,即使别的 subos 装过同一个版本,它也会拒绝并让你去 install

xlings subos new probe
XLINGS_ACTIVE_SUBOS=probe xlings use gcc 16.1.0
# [xlings:use] 'gcc' is not installed in this subos (probe)
#   nothing was changed
#   hint: install it here first with `xlings install gcc@16.1.0`

看着绕,但它挡掉的是一个更难查的结果:版本数据库不记录依赖关系,所以 "直接激活" 只能激活 gcc 自己,激活不了它依赖的 glibc —— 你会得到一个能跑、 -print-sysroot 也正确、唯独编译不了的工具链,而且全程没有任何提示。 install 会解析并安装依赖,所以安装归它管。

坐标写法:命名空间在最前面

带命名空间的包,完整坐标是 <namespace>:<package>@<version>

xlings install local:mcpp@0.0.27
xlings install fromsource:freetype@2.13.2

注意顺序。版本数据库内部把命名空间记在版本号那一侧(local:0.0.27), 但命令行接受的是命名空间在最前面的形式。写成 mcpp@local:0.0.27 会被解析成 一个叫 local:0.0.27 的版本号,任何包都没有这个版本,命令必然失败。

xlings use 的版本参数则用数据库里的写法:

xlings use freetype fromsource:2.13.2

查看已安装包

xlings list

列出所有已安装的包及其版本信息。

工作原理

Shim 机制

xlings 在 SubOS 的 bin/ 目录中放置与工具同名的硬链接,指向 xlings 二进制本身。当用户执行 gcc 时,xlings 通过 argv[0] 识别调用目标,查询当前 workspace 中的活跃版本配置,将调用转发到对应版本的 xpkg payload。

Version-View 与引用计数

多个 SubOS 环境共享同一份物理安装(位于 ~/.xlings/data/xpkgs/),每个环境仅记录自己的"版本视图"。引用计数确保仅当最后一个使用者卸载时才删除物理文件。

架构图

graph TD
    subgraph SubOS-A
        A1[".xlings.json<br/>gcc → 14.2.0"]
        A2["bin/gcc → xlings"]
    end
    subgraph SubOS-B
        B1[".xlings.json<br/>gcc → 16.1.0"]
        B2["bin/gcc → xlings"]
    end
    subgraph 物理存储
        P1["data/xpkgs/xim-x-gcc/14.2.0/"]
        P2["data/xpkgs/xim-x-gcc/16.1.0/"]
    end

    A2 -->|shim dispatch| P1
    B2 -->|shim dispatch| P2
    A1 -.->|版本视图| P1
    B1 -.->|版本视图| P2

与 SubOS 的交互

每个 SubOS 拥有独立的 workspace 配置文件(.xlings.json),记录该环境的活跃版本。这意味着:

  • SubOS-A 中执行 xlings use gcc@14.2.0 不影响 SubOS-B 的版本选择
  • 进入不同 SubOS 后,同一命令可能指向不同版本
  • 物理安装仅保留一份,节省磁盘空间

示例流程

# 创建两个独立环境
xlings subos new dev-legacy
xlings subos new dev-latest

# 在 dev-legacy 中使用旧版本
xlings subos use dev-legacy
xlings install gcc@14.2.0
xlings use gcc@14.2.0
gcc --version   # 14.2.0

# 在 dev-latest 中使用新版本
xlings subos use dev-latest
xlings install gcc@16.1.0
xlings use gcc@16.1.0
gcc --version   # 16.1.0

# 两个环境互不干扰,物理存储共享
xlings list

注意事项

  • 版本切换仅影响当前 SubOS 环境(或宿主环境)
  • 卸载某版本时,若其他环境仍在引用,物理文件不会被删除
  • 使用 xlings list 确认当前环境的活跃版本