SHBuild

  位于 Tools/SHBuild ,是可以用来递归遍历目录编译链接本机程序和调用其它相关功能的命令行工具。当前仅支持 MinGW32/MinGW64 环境。其它平台详见以下章节。

  直接(不带参数)运行 SHBuild 查询使用方法和选项等说明。

构建

  本节说明 SHBuild 的构建。关于使用 SHBuild 构建用户程序,参见前述概要和之后的章节。

  除非另行指定,其它章节也适用于本节内构建的非最终阶段 SHBuild 。本章仅补充仅适用于这些 SHBuild 的特点和功能。

  关于使用 bash 构建库、 SHBuild 、测试项目和基于 SHBuild 上的用户程序,参见关于 MinGW Sysroot 的说明

  当前只支持本机构建

  除了指定调用编译器等工具的名称外的其它情形对 SHBuild 是透明(transparent) 的,即 SHBuild 不使用目标平台的标识执行不同逻辑。这样,也可能不经修改调用命令的情况下成功交叉构建,但当前未测试。

引导(Bootstrapping)

  SHBuild 支持引导,即在受支持的构建环境中直接构建 SHBuild ,不依赖预先构建的 SHBuild 二进制映像。

  运行脚本 Tools/Scripts/SHBuild-build.sh 生成 SHBuild 可执行文件。

  脚本直接选取 YSLib 中的源文件作为依赖进行构建。因为直接调用编译器驱动链接,不支持显式指定并行编译,相对比较慢。编译的结果是静态链接的,二进制映像较大。

  这个过程只需要 C++ 工具链和 shell ,不需要直接调用 make ,但 GCC 使用 -flto 进行优化仍然需要 GNU make 。

  当前构建最后的链接器警告可以安全忽略。

  如能成功使用以下的多阶段构建方法(会按需调用引导脚本),一般不建议使用直接构建的版本。

自举(Self hosting)

  SHBuild 支持自举,即可使用构建的 SHBuild 继续构建自身。

除需 SHBuild 外,对外部环境的要求和引导一致。

  SHBuild 一直使用简单的源代码结构,设计初期即支持自举,现时仍不限制自举需要的版本。但由于仅测试相同版本的自举构建,因此一般建议使用相同版本。

  以下多阶段构建在引导的基础上自举构建 SHBuild 。

  此外,也可以直接使用 SHBuild-self-host.shSHBuild-self-host-DLL.sh 进行直接自举。这两个脚本主要用于内部测试。

多阶段构建

  使用工具脚本安装 Sysroot 时,按需构建 SHBuild 。当前这个过程分为两步:

  • 第一阶段(stage 1) :引导。
    • 调用脚本 Tools/Scripts/SHBuild-build.sh 构建 stage 1 SHBuild 。只依赖编译器进行编译链接。
    • 主要用于下一阶段使用。不保证具有所有 SHBuild 的功能特性。一般不建议直接使用。
  • 第二阶段(stage 2) :自举。
    • 在脚本 Tools/install-sysroot.sh 内直接调用成功引导的 SHBuild ,构建时链接到之前构建的 YFramework 和 YBase 动态库。
    • 自举结果为 stage 2 SHBuild ,这是当前最终生成的 SHBuild ,链接和运行依赖上述动态库。

  这些阶段需要的外部环境对应称为 stage 1 环境和 stage 2 环境。

  由于多平台构建的自然要求,这些环境需要相同(本机构建),或至少保持兼容性。当前工具脚本没有另行显示指定使用不同平台的接口,因此只支持本机构建。

运行

  SHBuild 通过参数执行命令,支持不同的运行模式:

  • 构建模式:调用递归扫描指定的目录以调用构建后端工具。
  • 命令模式:执行内建的功能。

  命令模式以 -xcmd, 起始的选项指定。其它情形的运行使用构建模式。

  命令行参数 -- 钱的参数中,以 -x 起始的特定选项(详见运行 SHBuild 的说明)被作为 SHBuild 选项。命令行参数 -- 后的参数不被识别为 SHBuild 选项,而被传递给后端或作为命令模式的参数。

构建模式

  构建模式递归扫描指定的源代码目录,以其中符合内建规则要求的文件作为输入,调用相应的后端命令行构建。构建包括对符合内建规则的输入的编译,以及对得到的目标文件进行链接。除 SHBuild 选项的命令行参数直接传除递给后端编译器。若需要构建复杂项目,可以使用其它的脚本支持。

  调用的构建后端工具的名称以及链接器命令行选项可使用环境变量指定。此外,若环境变量 SHBuild_CFLAGSSHBuild_CXXFLAGS 被定义为非空值,调用 C 和 C++ 编译器命令行时,变量的值会先于生成的命令选项以及上述命令行选项被传递。关于支持的环境变量,详见运行 SHBuild 的说明。

  调用的后端命令行的不同的命令行选项之间应确保以空白符间隔。环境变量确定的选项不被检查;由 SHBuild 生成的命令行选项之间以一个空格分隔。

内建规则

  遍历扫描目录时,不需要使用领域特定语言的外部脚本,SHBuild 识别名称符合特定模式串的文件。

  当前支持后缀名区分源文件。

  文件名符合以下通配符模式的文件视为 C 源文件:

  • *.c

  文件名符合以下通配符模式的文件视为 C++ 源文件:

  • *.cpp
  • *.cc
  • *.cxx

  对以上文件,对应的内建 C 和 C++ 编译器规则分别被调用。其它文件不被视为源文件。

  和 make 类似, SHBuild 的内建规则依赖文件修改时间(mtime) 判断一个目标是否最新。

  内建规则使用的编译器和环境变量参见直接运行 SHBuild 的使用说明。

命令模式

  参见运行 SHBuild 的说明。

构建应用程序

  使用 SHBuild 构建应用程序所需的环境和多阶段构建的最后一个阶段的相同。当前和自举时相同,即 stage 2 环境。

其它平台

  除构建 stage 1 SHBuild 外,当前未正式支持 Linux 。

  因为 SHBuild 本身和直接依赖的代码已经保证了可移植性,所以静态链接可以成功。得到的可执行文件除了没有扩展名,用法和前述 MinGW 下相同。

  使用进一步编译 YFramework 可能会出错,因为 YFramework 中宿主 GUI 支持未在 Linux 上实现。这不影响已经构建的 SHBuild 的可用性。

已知限制 若系统时间不正确,可能导致冗余的重复构建或无法构建。若文件时间戳无法被正确更新(如编译器或者文件系统实现问题导致无法在命令执行后正确地更新被修改的文件时间,或者不恰当的缓存配置导致修改时间没有立即更新),可能导致冗余的重复构建。

  当前不支持上述以外的其它平台。

NPL 支持

  SHBuild 运行 -xcmd,RunNPL-xcmd,RunNPLFile 命令支持解释 NPLA1 翻译单元。

  调用方式详见帮助文本。

  后者的翻译单元为文本文件。当前支持文件头可选的 UTF BOM 。**若找到 BOM ,直接跳过继续读取文件内容。在 SHBuild 中不假设文件编码,直接以窄字符流透明地处理。后续编码内容格式按 YFramework 提供的当前实现的方式支持。

  因此,一般应使用 UTF-8 + BOM ,或不带 BOM 的 UTF-8 作为编码。

应用

  当前 stage 1 SHBuild 构建 YSLib 库使用脚本已以此方式实现。 Shell 脚本调用 stage 1 SHBuild 解释这些脚本,其中进一步调用 stage 1 SHBuild 执行其它构建命令。