☰
OCaml 版本号、发布周期与发布流程全解析(ocaml/ocaml 仓库)
2026/10/8 1:57:27 网站建设 项目流程
  • 编程语言
  • 编译器
  • 语言运行时
  • 标准库

【免费下载链接】ocaml

The core OCaml system: compilers, runtime system, base libraries

项目地址:https://gitcode.com/gh_mirrors/oc/ocaml
点击查看免费下载

OCaml 的版本号遵循 Linux 风格的语义化方案,其含义直接关系到用户如何选择编译器、判断兼容性与规划升级时机。本文以 release-info/introduction.md 为骨架,结合仓库中的 release-info/calendar.md(预期发布日历)、release-info/howto.md(发布操作手册)、release-info/News(历版亮点)以及 build-aux/ocaml_version.m4、stdlib/sys.mli 等源码级证据,系统讲解 OCaml 版本字符串的解析方法、六个月一次的时间驱动发布节奏、minor 版本之间的分支冻结与预发布流程、4.14 LTS 例外策略,以及从打 tag 到 opam 同步的完整发布链路。读完你将能够一眼读懂任意 OCaml 版本号、判断某个版本属于哪个发布阶段,并理解仓库内各版本分支、Changes 与版本宏之间的对应关系。

OCaml 版本号的含义

OCaml 的版本字符串由三个数字组成,可选地跟一个预发布标签(prerelease tag)或开发标签(development tag),完整格式为:

%i.%i.%i[~alpha%i|~beta%i|~rc%i|+%s]

即主版本.次版本.修订号,后面可跟~alphaN、~betaN、~rcN(~前缀表示预发布)或+tag(+前缀表示开发/实验版本)。例如:

  • 4.14.1:正式发布版本;
  • 5.1.0~alpha2:5.1.0 的第二个 alpha 预发布版本;
  • 5.3.0+dev0-2023-12-22:带日期戳的开发版本。

这一格式也由标准库正式文档化:在 stdlib/sys.mli 中,Sys.ocaml_version的说明明确写出版本字符串形如"major.minor[.patchlevel][(+|~)additional-info]",其中major、minor、patchlevel均为整数,additional-info为任意字符串。实际编译出的编译器会在运行时把这一字符串暴露给程序,例如在顶层直接执行Sys.ocaml_version即可获取当前编译器版本。

三个数字分别代表什么

  • 主版本号(第一个数字):仅在语言层面加入重大新特性时递增。典型例子:OCaml 5 引入了共享内存并行(shared memory parallelism)与效应处理器(effect handlers);OCaml 4 引入了 GADT(广义抽象数据类型,Generalised Abstract Data Types)。从 release-info/News 可以印证,5.0.0(2022 年 12 月 15 日发布)"introduces a completely new runtime environment with support for shared memory parallelism and effect handlers",这正是主版本号跳升的驱动因素。
  • 次版本号(第二个数字):每发布一个新版本就递增一次。新次版本可能包含破坏性变更,但社区会尽可能保持向后兼容。例如 4.14.0 的 News 条目中明确列出了"为 OCaml 5 做准备而弃用的函数与模块(特别是 Stream 和 Genlex 模块)",说明这类破坏是在次版本中被逐步引入的。
  • 修订号(第三个数字):bugfix 号。升级到最新的修订版本永远是安全的——修订版本被设计为完全向后兼容,只包含重要或非常安全的 bug 修复。

预发布标签与开发标签

  • 预发布标签~alphaN、~betaN、~rcN:描述当前正在测试的编译器预发布版本,例如5.1.0~alpha2中的~alpha2。在仓库中,这些标签实际进入~前缀的版本宏。见下文"预发布版本"一节。
  • 开发标签+tag:表示开发或实验版本。编译器自身的开发版本使用形如+dev%i-%date的标签,例如5.3.0+dev0-2023-12-22。当前仓库的 VERSION 文件就写着5.6.0+dev1-2026-10-02,即 5.6 分支建立后的第一个开发版本。

版本号在仓库中的定义位置

自 OCaml 4.14 起,虽然 VERSION 文件仍然保留且内容正确,但版本的真实定义已迁移到 build-aux/ocaml_version.m4(其中的OCAML__VERSION*宏),VERSION 文件由tools/autogen自动重新生成。以当前仓库为例:

  • OCAML__VERSION_MAJOR=5,OCAML__VERSION_MINOR=6,OCAML__VERSION_PATCHLEVEL=0;
  • OCAML__VERSION_EXTRA=dev1-2026-10-02,OCAML__VERSION_EXTRA_PREFIX=+;
  • OCAML__VERSION宏最终拼出5.6.0+dev1-2026-10-02。

VERSION 文件头部注释还要求:更新版本时应先修改build-aux/ocaml_version.m4,再运行tools/autogen,并把两个文件一起提交。这一约束与 release-info/howto.md 中描述的发布操作步骤完全一致(见下文"发布流程")。

何时发布新版本:六个月一次的时间驱动节奏

自 OCaml 4.03 起,OCaml 采用基于时间的发布计划(time-based release schedule):每六个月发布一个新的次版本。

原文档写作时的规划是:

  • OCaml 5.3:约 2024 年 10 月;
  • OCaml 5.4:约 2025 年 4 月。

实际结果(以 release-info/News 与 release-info/calendar.md 为准)是:5.3.0 于 2025 年 1 月 8 日发布,5.4.0 于 2025 年 10 月 9 日发布,5.5.0 于 2026 年 6 月 19 日发布。可见"时间驱动"是节奏框架而非硬性承诺:文档明确说明时间只是近似值,遇到不可预见的问题时经常推迟发布,通常最多晚两个月。因此 release-info/calendar.md 开篇就幽默地声明:"这份预期日历与实际发布日历完全吻合的概率,低到可以视为意外事故。"

预发布日历中的"预期(早)"与"预期(晚)"两列正是这一弹性的体现,例如 5.6.0 的计划:

阶段预期(早)预期(晚)实际
特性冻结2026 年 9 月 15 日2026 年 10 月 1 日10 月 2 日
发布12 月 15 日次年 2 月 1 日待定

另外,bugfix 修订版本可以在任意时间发布,不受六个月周期的约束。

次版本之间发生了什么:分支、冻结与预发布

所有 PR 首先进入编译器的开发分支,名为trunk(这个名称来自 SVN 时代的标准叫法,比main更具描述性,一直沿用至今)。

特性冻结(Feature freeze)

在距离新版本发布三个月时——也就是两个发布之间时间窗的中点——维护者为下一个版本单独创建分支。设计意图(总会有例外)是:发布内容应对应于创建分支时trunk的状态,但还要再等三个月用于质量分析、收集反馈并整合 bugfix。

发布分支上不集成新特性,以避免最后一刻的改动引入计划外回归。只有 bugfix 和文档改进会进入发布分支,且通过从trunk的cherry-pick方式合入。维护团队没有资源同时维护超过一个开发分支、一个预发布分支和(例外的)一个 LTS 分支。

示例:5.1.0 于 2023 年 9 月发布,5.2 的特性冻结发生在 2023 年 12 月,5.2 计划于 2024 年 4 月前后发布(实际 5.2.0 于 2024 年 5 月 13 日发布)。

预发布版本:alpha → beta → rc

新版本分支创建、特性集稳定之后,就开始发布该分支的预发布版本。流程是:

  1. 分支创建后先发布alpha版本:5.2.0~alpha1、5.2.0~alpha2……;
  2. 核心开发工具(merlin、pppxlib、dune)移植到 alpha 版本可用后,切换到beta版本(如5.2.0~beta1);
  3. 正式发布前发布release candidate(如5.2.0~rc1),对"最终形态"的分支做最后检查。

设计意图是让 alpha、beta、rc 的稳定性保证逐级递增,可被越来越广泛的受众测试:

  • alpha 版本:
    • 内部 compiler-libs API 接近稳定,只接受 API 修复;
    • 不加入新特性,有问题的特性可能在此阶段被移除;
    • 非常欢迎 bug 修复;
    • 仍接受文档 PR;
    • 面向核心开发工具(merlin、ppxlib、dune),为整个 opam 生态解锁。
  • beta 版本:
    • compiler-libs API 稳定;
    • 特性集稳定;
    • 非常欢迎 bug 修复;
    • 仍接受文档 PR;
    • 面向早期采用者:opam 库作者此时应能测试自己的库。
  • rc 版本:
    • compiler-libs API 稳定、特性集稳定;
    • 只接受紧急 bug 修复;
    • 文档 PR 推迟到发布之后;
    • 面向广泛测试(在大规模私有代码库中发现部署/生产问题)。

从第一个 alpha 版本开始,会有一支小团队尝试用新版本构建并测试 opam 上的每一个包(大部分工作由 Kate Deplaix 完成)。这一实践在过去多次成功捕获 bug 与可用性回归,是预发布质量保障的关键一环。

release-info/calendar.md 中 5.5.0 的实际时间线是这条流程的完整实证:特性冻结 2026 年 1 月 22 日 → 首个 alpha 2 月 25 日 → 首个 beta 4 月 20 日 → 首个 rc 6 月 10 日 → 正式发布 6 月 19 日。从 alpha 到正式发布,前后跨度约四个月。

如何安装预发布版本

预发布版本的安装模板记录在 release-info/templates/beta.md 与 release-info/templates/rc.md 中:源码可从 caml.inria.fr 发行目录下载,也可直接用 opam 创建测试 switch:

opam update opam switch create ocaml-variants.$VERSION --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git

或选择特定变体(variant):

opam update opam switch create ocaml-variants.$VERSION+<VARIANT> --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git

其中<VARIANT>可替换为afl、flambda、fp、fp+flambda。beta 与 rc 的模板结构几乎相同——rc 模板只是在正文之后附加"插入相关 Changes 章节"的提示,因为它距离正式发布只有一步之遥。

Bugfix 版本

如果发现严重影响初始版本使用的问题,就会发布 bugfix 版本。此时通常会把发布后已合入trunk的安全 bugfix 反向移植(backport)到发布分支。大多数 bugfix 版本是M.m.1,发生在M.m.0发布后一两个月,用于修复预发布测试阶段未发现的重要问题。文档强烈鼓励用户尽快切换到最新 bugfix 版本,而维护团队也尽量保证这些版本零回归,让升级变得容易。

例外的 LTS 版本:OCaml 4.14

从 OCaml 4 切换到 OCaml 5 需要对运行时(runtime)做全面重写,这在以下方面对 OCaml 5 各版本的稳定性造成了负面影响:

  • 支持的架构;
  • 支持的操作系统;
  • 性能稳定性;
  • 运行时 bug 数量。

为了让稳定版本始终易得,维护团队例外地将 OCaml 4.14 维护为长期支持(Long Term Support)版本:在 OCaml 5 被认为足够成熟之前,会持续发布 4.14 的新 bugfix 版本。用户反馈哪些 OCaml 5 的修复也应合入 4.14 是受欢迎的。一旦 OCaml 5 稳定,这一延长支持就会停止——原文档预期至少支持到 OCaml 5.5 前后(约 2026 年 1 月)。从 release-info/calendar.md 可见,4.14.3 的发布流程(rc 预计 5 月 2 日~22 日,发布预计 5 月 9 日~6 月 1 日)当时仍在推进中,印证了这条 LTS 分支的活跃状态。

新版本如何发布:从打 tag 到 opam 同步

完整发布流程记录在 release-info/howto.md,其操作对象正是本仓库。文档将其分为"测试版本(Beta 或 Release Candidate)"与"生产版本(production release)"两类,两者在步骤上有差异。

0. 环境准备

发布前在/tmp/env-$USER.sh中配置发布环境变量:MAJOR/MINOR/BUGFIX定义版本号、PLUSEXT定义附加后缀(预发布标签)、HUMAN是发布公告署名、BRANCH与VERSION由它们拼接而成,TAGVERSION会把~替换为-(Git tag 中不允许~)。同时还要配置 Inria 档案服务器(ARCHIVE_HOST/ARCHIVE_PATH)与网页服务器(WEB_HOST/WEB_PATH)等访问信息。

1~4. 仓库状态检查、构建与测试

  • 检出发布分支并确认工作区干净、git pull最新;
  • 主版本发布时检查并更新 magic numbers(详见 utils/HACKING.adoc);
  • 依次执行make distclean、./configure --prefix=...、make -j5、make alldepend(确认依赖最新)、git diff(应无输出)、检查.depend无绝对路径、运行./tools/check-typo、make install以及./tools/check-symbol-names runtime/*.a(应无输出且返回 0);
  • 运行make tests跑完整测试套件(对应本仓库的 testsuite 目录)。

5. 构建、打 tag 并推送

发布的关键动作序列是:

  1. 先手动递增版本宏(例如4.07.0+dev8-2018-06-19→4.07.0+dev9-2018-06-26);
  2. 运行tools/autogen重新生成 configure 与 VERSION 等文件,提交"tag 前最后一笔提交";
  3. 把版本宏更新为目标版本(例如4.07.0+dev9-2018-06-26→4.07.0+rc2),同步更新 ocaml-variants.opam,再次tools/autogen;
  4. 生产版本需要连续运行两次make coreboot -j5,直到输出Fixpoint reached, bootstrap succeeded.(引导修复点达成);
  5. git tag -m "release $VERSION" $TAGVERSION打 tag;
  6. 发布后再把版本宏递增到下一个开发版本(生产版本为(N+1)+dev0,测试候选为N+dev(D+2)),提交并git push、git push --tags。

分支创建(branching)走的是"5-bis"备选流程:先在 trunk 上递增开发版本号、改名 Changes 头部,然后git branch $BRANCH创建分支、为新分支设定新的未来版本号(如4.07.0+dev1→4.08.0+dev0-2018-06-30)、更新 opam 开发包,最后推送并设置上游。创建后还需在 GitHub 上为分支配置保护规则、加入 Inria CI 列表、在 README.adoc 中更新分支徽章。

6. opam 包同步

生产版本需要在 opam-repository 中更新/创建:ocaml-base-compiler.$VERSION、ocaml-variants.$VERSION+options(所有发布都需要);ocaml-system、ocaml-src、ocaml-manual、虚拟包ocaml(必须指向下一个版本)等(生产发布需要)。注意更新 tarball 的 checksum 字段,并用opam-lint检查;PR 之前可以用本地仓库加 beta 仓库的方式预先验证 switch 能否构建。

7~13. 归档、上传与公告

  • 用git checkout-index导出 tag 对应的干净源码树,以owner/group = 0打包出.tar.gz与.tar.xz两个压缩归档;
  • 上传到 Inria 档案服务器,更新MD5SUM/SHA512SUM校验文件(注意保留旧校验文件作为回退备份);
  • 上传INSTALL.adoc、LICENSE、README.adoc、README.win32.adoc、Changes等说明文件;
  • 重新构建并上传参考手册(release candidate 若与上一版本手册完全相同可跳过),生产版本还要同步到公开网页并把manual-ocaml软链接指向新手册;
  • 生产版本与 ocaml.org 协作准备发布网页;最后在 caml-list、caml-announce、discuss.ocaml.org 上发布公告(公告模板见 release-info/templates 下的beta.md、rc.md、production.md);并向 compiler-explorer 等外部工具传播新编译器。

附录:Changes 文件的整理规范

release-info/howto.md 的附录对 Changes 文件给出了细致的整理规范:

  • 同步 trunk 与发布分支:发布分支的 Changes 条目必须精确包含在 trunk Changes 的对应版本章节中,用交互式 diff 工具(如 meld)比对同步;条目所在章节不一致时,应放到"最小的版本"章节(假设所有更大的版本都包含该变更)。
  • 每条目归入正确章节:新版本 Changes 的常用小节模板为:Language features、Runtime system、Code generation and optimizations、Standard library、Other libraries、Tools、Manual and documentation、Compiler user-interface and warnings、Internal/compiler-libs changes、Build system、Bug fixes。
  • 补充细节:尤其对语言变更给出具体语法示例(如#8820引号字符串扩展的例子),对破坏性变更明确说明破坏点与推荐迁移方式,便于用户判断、也便于日后 grep 追溯变更引入时机。
  • 排序:自 4.09 起按重要性而非数字/时间排序,"Language features"通常靠前,"Bug fixes"永远最后;过于琐碎的条目可移入 Bug fixes 章节;时不时把各版本亮点抽取同步到 release-info/News。

读者视角:如何利用这套规则做升级决策

结合以上机制,普通用户可以建立一条清晰的决策链:

  1. 读版本号:M.m.p~alpha/beta/rc表示预发布(稳定性递增、不推荐生产使用),M.m.p+tag表示开发版(可能随时变化),纯M.m.p才是正式版;无p或p缺失的字符串(如 3.08.0 之前的版本)不属于现代格式。
  2. 选版本:生产环境优先选当前次版本的最新修订号(如5.5.x中尽量取最高x),因为修订版本被保证完全向后兼容且只含安全修复;升级次版本前查阅对应版本的 Changes 与 release-info/News 了解破坏性变更。
  3. 尝鲜预发布:按 release-info/templates/beta.md 的 opam 命令用ocaml-variants.$VERSIONswitch 测试自己的库;库作者应至少从 beta 开始适配,以赶上正式发布。
  4. 追节奏:关注 release-info/calendar.md 的"预期(早)/预期(晚)/实际"三列——它如实反映了时间驱动计划"经常晚一两个月"的现实。
  5. 验证版本:在代码中可用Sys.ocaml_version(stdlib/sys.mli)读取编译器的完整版本字符串,配合Sys.development_version与Sys.ocaml_release_info(含major/minor/patchlevel及extra_prefix/extra_info字段)在运行时精确区分发布类型,这与build-aux/ocaml_version.m4中OCAML__RELEASE_EXTRA宏生成的 OCaml 值一一对应。

这套版本体系既是 OCaml 项目的发布纪律,也是用户与生态(dune、merlin、opam)协同演进的节奏表:alpha 解锁核心工具链、beta 带动库作者适配、rc 做最终部署验证,最后以完全向后兼容的修订版本收尾——理解它,就能在任何版本号出现时迅速定位它处在整个生态演进的哪个坐标点上。

  • 编程语言
  • 编译器
  • 语言运行时
  • 标准库

【免费下载链接】ocaml

The core OCaml system: compilers, runtime system, base libraries

项目地址:https://gitcode.com/gh_mirrors/oc/ocaml
点击查看免费下载

相关推荐

上一篇:终极轻量级内存优化工具:Mem Reduct深度解析与实战指南
下一篇:Bootstrap 3.0.3 前端框架快速入门:从快速开始到 Grunt 编译与插件源码解析(Parsley.js 仓库内嵌组件实战指南)

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询