openSUSE:Build Service Concept Windows 支持

跳转到:导航搜索
此页面讨论了 openSUSE Build Service 的一个 DRAFT CONCEPT(草案概念):欢迎提出意见;讨论应在 Build Service 邮件列表或 mingw 专用列表上进行。

Windows 支持

如果 OpenSUSE Build Service 提供 Windows 支持,那么目标将是为 Windows 平台的终端用户提供易于安装的软件包的自由/开源软件。

通常,在 OBS 的语境下,目标是 Linux 软件的跨平台移植到 Windows,而不是为更广泛的 Windows 社区提供一个庞大的 Windows 专用构建农场 :-)

为 Windows 构建将带来一些重要的优势,例如

  • 更多的平台进行构建,从而提高自由软件项目的吸引力
  • 帮助在 Windows 平台上推广自由软件
  • 一个潜在的更大的社区,致力于通用自由软件和 openSUSE 项目基础设施。
  • OBS 构建大型复杂相互依赖的软件包和程序的能力
  • 一种依赖处理机制,可以在用户安装新软件包时暴露给终端用户。

待办事项:需要考虑操作系统、编译器等许可问题如何解决 Build Service。如果构建主机由社区提供,那么这可能不是问题。

对于工具链,至少有免费解决方案列在此页面上。尽管如此,即使它们可以免费下载,也必须仔细检查许可条款。


为 Windows 构建

为了将为 Windows 构建无缝集成到 Build Service 中,应考虑以下场景

1. 交叉编译

当前的 binutils 和 GCC 支持构建 PE 目标。

在 OBS 中,我们拥有 GTK+ 的完整构建,包括 GIMP、Evince、Evolution、KDE 应用程序如 Umbrello 和 KMyMoney 等等。生成的二进制文件在 Windows 上运行良好,但当前打包为 Linux RPM。

构建 ZIP/MSI/NSIS 软件包/安装程序是有限制的。非 RPM 可能不会传播到 /srv/obs/repos,具体取决于运行的 BuildService 软件版本。

2. 虚拟化构建

另一种生成本机 Windows 二进制文件的方法是在运行 Windows 主机的虚拟化环境中进行编译。在 Windows 虚拟化中,必须运行本机 Windows 编译器可执行文件、某种基础库以及控制构建并涵盖与 Build Service 通信的构建脚本。

Windows 的虚拟化似乎没有问题。使用 KVM 对我来说效果很好,并且据了解 Xen 也可以很好地工作(尽管我自己没有尝试过)。我理解这对于设置可靠的“干净”系统以构建每个新软件包至关重要。

3. 本地构建

此场景具有真实的非虚拟 Windows 盒子。构建是在 Windows 安装的沙盒中完成的。编译器和基础库安装在系统中。


构建描述

对于 Windows 的每个包,都需要一些元信息或构建描述。就像您拥有 debian.rules、debian.changelog 和 debian.control 一样,您可能拥有 windows.buildwindows.package

第一个文件,windows.build 将是某种文件,其中包含有关如何编译和打包程序的信息。可以使用 Windows 批处理文件语法进行这些步骤,或者可能更喜欢 Python 文件(然后可以将其跨平台地与 OS X 结合使用?)。此文件将包含的数据是

  • 如何解压缩源代码,
  • 如何启动构建,
  • 生成的“目标”文件列表,以及
  • 所需的版本及其版本号的软件包构建时依赖项列表。

与 RPM .spec 文件和 Debian 'control' 文件一样,这些内容将是(可能是?)外部于源代码。

第二个文件,windows.package 将是与实际安装和卸载生成的软件包相关的元信息。这些文件可以作为上述构建步骤的结果生成,也可以手动单独编写。包含的数据包括

  • 如何以静默/无人值守模式安装它,
  • 如何卸载它,以及
  • 如何在系统上检测它
  • 如何识别其版本号
  • 是否需要(事后检查)?
  • 软件包运行时依赖项及其所需的版本列表。
  • 可以从哪里下载软件包(如果未在标准“存储库”中可用)

我们应该能够为任何已发布的安装程序编写 .package 文件,这样我们就无需重新打包内容以适应 OBS 系统。如果有人为某个特定的 FOSS 程序编写了不错的安装程序代码,我们不应该重新打包该程序,而应该添加允许 OBS 了解如何在构建机器上安装/卸载该软件包的元数据。


软件包管理器

包管理器是 OBS 自动化构建系统的基本伴侣,因为需要一种快速有效地安装先决条件的方式,然后再进行主要构建。此外,如果设置了与包管理器通信的软件包,此包管理器还可以充当用户启动安装时的“顾问”。

与 Linux 相比,Windows 平台的差异在于,用户习惯于直接寻找“安装文件”,而不是首先使用包管理器。可以通过创建与包管理器“通信”后再进行操作的特殊安装程序来将这种心态与包管理器心态结合起来:首先请求安装所有必要的先决条件。

一个好的包管理器具有的优势是可以让开发人员摆脱低效的情况,即必须将所有先决条件与他们的安装程序包捆绑在一起,但必须为此建立一个合理的通用系统,并且该系统必须稳定(例如,在某些情况下,同一软件包的多个版本必须能够共存)。

在 Windows 的情况下,我们需要当前的机制继续按预期工作。这包括“添加/删除程序”工具,如果修改软件包使其在删除自身之前“与包管理器通信”,则可以使其正常工作——嵌入在卸载程序中的“pre-remove”和“post-remove”挂钩。使用 NSIS 等工具进行此类调用非常简单,但仍需要了解 MSI 的工作方式。

Windows 中还有用于“签名”软件包的机制。需要查看是否可以将这些机制采用到包管理器中,以确保即使用户首先需要安装额外的 CA 证书,也能保证软件包的真实性。

为了满足我们的需求,包管理器需要一个命令行界面或 API,供高级用户和构建管理器使用,以及一个可以被感知包管理器的安装程序访问的 API。

包管理器的预期命令

  • install package
  • install package-VERSION
  • remove package
  • register-dependencies package-VERSION deppackage1>=VERSION deppackage2==VERSION(允许软件包将其依赖项报告给包管理器)
  • depending-on package(已安装依赖包吗?),返回包和版本列表。
  • cacheclean(删除本地安装程序副本)
  • detect(确定系统上是否当前安装了软件包)
  • detect-all(搜索所有可识别的已安装软件包)

可以稍后添加自动升级/更新软件包作为功能,因为它不需要作为 OBS 集成的一部分。

虽然包管理器可以实现为Windows 服务,但这似乎没有必要。构建管理器以这种方式编写(以便进行外部控制)更重要;包管理器作为命令行程序就足够了。

检测

检测操作中需要执行的步骤

  • 使用每个已注册软件包的“如何在系统上检测它”脚本来确定软件包是否仍然安装
    • “如何在系统上检测它”脚本可能是一个简单的 Python 脚本,可以检查 Windows 注册表,或检查特定的已安装程序/DLL 等。或者,可以使其更简单。
    • 如果安装了以前的版本怎么办?继续从存储库中获取以前的 .package 文件?
  • 更新已消失软件包的注册表
  • 如果检测到,则返回 .package 文件中对应的值的版本号。

此操作用于检测已消失的软件包,因为某些卸载程序不会感知包管理器,因此不会在被删除时通知。

建议在早期设计阶段至少运行检测操作之前,应运行检测操作。出于这个原因,应使软件包检测最小化,例如,某个注册表项或文件是否当前存在。

检测所有

检测操作中需要执行的步骤(可选)

  • 从存储库下载所有 .package 文件
  • 使用每个文件的“如何在系统上检测它”脚本来确定软件包是否已安装
    • 如果已安装,则将 .package 详细信息记录在注册表中。

此操作用于检测已在包管理器控制之外安装的软件包。这是必要的,因为某些安装程序不会感知包管理器。

注册依赖项

注册依赖项操作中需要执行的步骤

  • 对于列表中的每个软件包
    • 检查软件包是否存在于存储库中
      • 如果不存在,则向用户发出警告。
      • 如果存在,则检查是否可以满足版本要求
    • 获取依赖版本的 .package 文件
    • 将 .package 详细信息记录在注册表中

需要此操作,因为我们希望感知包管理器的安装程序能够指定自己的依赖项。将建立本地依赖数据库,并且可能包括未在存储库中提供的软件包。

安装

安装操作中需要执行的步骤

  • 从存储库或嵌入在软件包中获取 .package 文件
  • 检查是否可以找到实际的软件包文件(在缓存中,或可下载:在存储库中,在网站上)
  • 检查软件包的依赖项(使用“check”操作),可以选择性地询问用户是否应安装它们……
  • 将软件包依赖项记录在包管理器(Windows 注册表?)中
  • 获取实际的软件包文件
  • 运行安装程序
    • 可选地,安装程序将回调到包管理器以注册其依赖项。它们必须同意上述内容。
  • 如果自动下载,则将安装程序移动到缓存。

此操作将从命令行调用,或通过暴露给构建管理器的 API 调用,或在安装其他软件包(满足依赖项)期间调用。

安装操作的便捷命令行用法依赖于存储库的概念。存储库需要包含

  • .package 文件/数据
  • 托管这些软件包的二进制安装程序文件的副本(不一定所有软件包)

依赖于

依赖操作中需要执行的步骤

  • 确定软件包是否已安装,确定版本号(使用“check”操作)
  • 使用本地记录的 .package 详细信息来确定是否安装了依赖软件包
    • 递归?
  • 可选地,使用存储库来检查是否安装了其他软件包“在包管理器之外”,但尚未检测到?
  • 返回累积的依赖软件包列表

此操作将暴露给感知包管理器的卸载程序,以便它们可以警告用户潜在的问题。

移除

移除操作中需要执行的步骤

  • 使用本地系统上的记录的 .package 详细信息来确定是否安装了依赖软件包。
  • 如果存在依赖项,则询问确认是否要删除它们
  • 按优先级顺序排列依赖项列表,然后反向遍历它(调用“remove”操作,不进行依赖项检查)
  • 运行 .package 详细信息中的“如何卸载它”脚本。

此操作将从命令行启动,但也将递归地在删除依赖项期间调用。

缓存清理

缓存清理操作中需要执行的步骤(可选)

  • 删除所有缓存安装程序文件

此操作将仅从命令行启动(最初)。


构建管理器

构建管理器将调用包管理器以满足构建时依赖项。它将以类似于当前 Linux 脚本的方式与 OBS 接口。

构建管理器将基于软件包管理器工作。使用 .build 文件,它将

  • 下载源代码(如果需要,这是否可以使用软件包管理器完成?)
  • 与软件包管理器通信以获取所有必要的先决条件。需要能够以非交互方式工作。
  • 解压源代码(使用 .build 文件中的指令)
  • 应用任何必要的补丁(这也许可以包含在上一步骤中)
  • 启动构建,并监视/侦听错误(使用 .build 文件中的指令)
  • 检查是否创建了所有预期的目标文件,并且
  • 如果请求,将目标文件发送到主服务器。

构建管理器将作为命令行程序实现。

为了与 OBS 集成,需要一个构建从机。像 BuildBot 中使用的方法会是一个好主意:一个在启动时启动的服务,并尝试与中央服务器建立连接。中央服务器将在设置从机时可配置。构建从机将等待来自构建主机的命令。

这种架构适用于“原生”构建节点以及虚拟化节点。构建从机甚至可能通过 Wine 在 Linux 系统上运行。

TODO 我们需要弄清楚这与当前 osc 命令行工具提供的功能有多少重叠。


初始 'seed' 包

虽然我们希望所有软件包都可以使用构建管理器构建,但必须有一些初始 'seed' 包。这些将通过简单地创建一个 .package 文件并将其添加到存储库中,作为 仅二进制 包创建。所有必要的元数据都将保存在二进制安装程序之外;这些二进制安装程序将不知道软件包管理器;此类软件包的成功安装将手动检测。

这些软件包的示例包括 MinGW 作为最低要求,以及可能还有其他软件包,例如 OpenGL 库等。

其中一些“仅二进制”软件包可以是“虚拟”软件包,用于检测 Windows 的组件,这些组件可能存在也可能不存在,例如 MSSQL、MS Visual Studio 等。在这种情况下,安装程序将被设置为始终失败(软件包管理器自身无法安装此类软件包),但已安装组件的检测仍然可以正常工作。

人们可以考虑软件包管理器本身是否会被视为一个软件包。删除软件包管理器应该从本地系统删除所有 .package 数据,因为这可以使用 detect-all 操作重新创建。可以给用户选择是否删除所有关联软件包。如果可能的话,与软件包管理器感知的安装程序中的钩子必须对软件包管理器不存在的情况是安全的(也许是“您想重新安装软件包管理器吗?”)


与 RPM 互操作?

OBS 当前正在使用交叉编译在 Linux 上为 MinGW 构建 RPM。是否有可能支持使用上述软件包管理器安装这些 RPM,也许具有减少的功能集?



开发计划

上述系统的开发可以分阶段进行。

  1. 为 MinGW 和相关工具构建初始 'seed' 包。
  2. 为这些 seed 包构建一个存储库
  3. 编写 'detect' 操作。
  4. 编写 'install' 操作,不带自动依赖项安装。
  5. 编写 'remove' 操作,不带自动依赖项删除。
  6. 添加对自动依赖项处理的支持。
  7. 添加对 'register-dependencies' 操作的支持。
  8. 添加对 'depended-upon' 操作的支持。
  9. 创建一个在安装期间与软件包管理器通信的“软件包管理器感知”软件包。
  10. 创建构建管理器。