Homebrew 构建环境设计时将 可复制构建 作为目标,在可能的情况下实现。还为配方作者提供了一些便捷工具,以帮助实现确定性构建。
一些构建工具会嵌入或记录构建发生的时间。这会导致在对相同源代码重复构建时构建工件不同。为了避免此问题,Homebrew 构建环境将 SOURCE_DATE_EPOCH
环境变量 设置为使用该变量的工具的源代码的修改时间。
在必须手动设置构建时间的情况下,time
是一个 Ruby DateTime
对象,它包含与 SOURCE_DATE_EPOCH
环境变量相同的时间戳。然后可以使用 Ruby 在 DateTime
对象上提供的函数将此时间格式化为所需格式。
def install
system "make", "install",
"VERSION=#{version}",
"DATE=#{time.iso8601}",
"PREFIX=#{prefix}"
end
请参阅 kustomize
配方,了解使用 time.iso8601
的示例,或参阅 git-town
配方,了解使用 time.strftime
和自定义格式说明符的示例。
一些配方可能会在其构建过程中创建 gzip 压缩文件(例如,压缩手册页或其他数据文件)。构建机器可能会提供 gzip
实用程序的不同实现,并且默认情况下 gzip
会记录正在压缩的文件的修改时间,该时间通常根据构建时间而异。因此,依赖于构建机器的 gzip
实用程序通常会导致不可复制的输出成为构建的一部分。
为了避免此问题,Homebrew 提供了 Utils::Gzip.compress
帮助器函数,用于需要可复制 gzip
压缩的情况。此函数接受一个或多个要压缩的路径,并将压缩文件放在原始文件旁边,并带有 .gz
后缀,就像 gzip
实用程序所做的那样。它还返回一个 Pathname
对象数组,该数组可以被其他方法使用。
def install
system "make", "install"
man1.install Utils::Gzip.compress("mycommand.1")
end
def install
system "make", "install"
(pkgshare/"data").install Utils::Gzip.compress(*Dir["#{buildpath}/path/to/some/folder/contents/*"])
end
请参阅 par
配方,了解包含单个文件的示例,或参阅 pari-elldata
配方,了解包含多个文件的示例。
一些公式或构建工具会将特定于构建环境的路径记录在配置文件或二进制文件中。在构建可再发行版本时,Homebrew 会搜索构建的文件,并将路径替换为常见的 Homebrew 位置,例如 Homebrew 前缀和酒窖,并使用占位符 @@HOMEBREW_PREFIX@@
或 @@HOMEBREW_CELLAR@@
。当安装版本时,Homebrew 会将这些占位符扩展为最终用户机器上的相应路径。
这允许一些版本被可能在非默认前缀中安装了 Homebrew 的用户使用。它还导致在 Homebrew 的位置是唯一差异的平台之间产生完全相同的版本。
此搜索和替换过程会自动发生,并且不需要公式作者执行任何其他操作即可使用它。