我们通常只为每个自由软件的最新版本打包。但是有时候,比如对于版本不兼容的库,需要有同一个软件包的两个或更多版本。它们需要使用不同的Scheme变量名。我们为最新的版本使用软件包命名里规定的名字,旧的版本使用加上后缀的名字,后缀是-
和可以区分开版本号的版本号的最小前缀。
软件包定义里的名字对于同一个软件包的所有版本都是相同的,并且不含有版本号。
例如,GTK+的2.24.20和3.9.12两个版本可以这样打包:
(define-public gtk+ (package (name "gtk+") (version "3.9.12") ...)) (define-public gtk+-2 (package (name "gtk+") (version "2.24.20") ...))
如果我们还需要GTK+ 3.8.2,就这样打包
(define-public gtk+-3.8
(package
(name "gtk+")
(version "3.8.2")
...))
有时候,我们为软件包上游的版本控制系统(VCS)的快照而不是正式发布版打包。这是特殊情况,因为决定哪个是稳定版的权力应该属于上游开发者。然而,有时候这是必须的。那么,我们该如何决定写在version
里的版本号呢?
显然,我们需要让VCS快照的commit ID在版本号中体现出来,但是我们也需要确保版本号单调递增,以便guix package
--upgrade
决定哪个版本号更新。由于commit ID,尤其是Git的commit
ID,不是单调递增的,我们添加一个每次升级快照时都手动增长的revision数字。最后的版本号字符串看起来是这样:
2.0.11-3.cabba9e ^ ^ ^ | | `-- 上游的commit ID | | | `--- Guix软件包的revision | 最新的上游版本号
把版本号
里的commit
ID截短,比如只取7个数字,是一个好主意。它避免了美学上的烦恼(假设美学在这里很重要),以及操作系统限制引起的问题(比如Linux内核的127字节)。尽管如此,在origin
里最好使用完整的commit
ID,以避免混淆。通常一个软件包应该看起来是下面这样:
(define my-package
(let ((commit "c3f29bc928d5900971f65965feaae59e1272a3f7")
(revision "1")) ;Guix软件包的revision
(package
(version (git-version "0.9" revision commit))
(source (origin
(method git-fetch)
(uri (git-reference
(url "git://example.org/my-package.git")
(commit commit)))
(sha256 (base32 "1mbikn…"))
(file-name (git-file-name name version))))
;; …
)))
返回包的版本字符串,利用 git-fetch
。
(git-version "0.2.3" "0" "93818c936ee7e2f1ba1b315578bde363a7d43d05") ⇒ "0.2.3-0.93818c9"
返回包的版本字符串,利用 hg-fetch
,就像 git-version
那样。