概述

  YSLib 项目提供一系列工具脚本。这些脚本主要集中位于 ToolsTools/Scripts 。其余特定局部用途的脚本可能位于其它目录,这些脚本可能依赖版本库内的工具脚本或 YSLib 安装时部署的工具脚本。

  关于脚本的解释环境和其它一般规则,参见关于脚本的开发说明。关于 shell 脚本,同时参见 shell 语言使用规约

  本文档附加约定,除非另行指定:

  • 公开的 shell 脚本和 NPLA1 脚本被 Tools/install-sysroot.sh 分别部署到安装路径下的 binshare/NPLA1 目录下。
  • 用于构建选项的环境配置外,提供的 shell 变量可能设置为只读。
  • 脚本引入不具有后缀 _ 的名称若不是被导出的变量,可在脚本之间使用,满足关于名称的约束,但不保证接口稳定性。

注释 维护者和开发者需要阅读开发说明,以保持脚本程序符合文档的描述。其中的一些信息(如关于环境变量等运行时环境的描述)也可能提供对脚本的非开发者用户有帮助的说明,作为运行环境中说明的补充。

Tools

  未归类的工具目录。这个目录的脚本是可用于整个项目或非特定子项目的工具脚本,如公用的构建脚本。

  工具脚本位于版本库目录 Tools 及其子目录 Scripts 下。

  工具主要用于开发,包括构建和版本库维护。

  一部分工具脚本也可被部署到 Sysroot 。在 stage 2 SHBuild 安装后运行的脚本可依赖安装的 Sysroot 实例的文件系统布局。支持维护版本库的开发脚本应保证在此之前(不依赖 Sysroot 的实例或仅依赖构建 stage 1 后可用的有限环境)可用。

环境配置

  一些环境变量可能被可选地在外部环境或在调用脚本的其它脚本中指定。若没有被指定为非空值,则可被特定上下文按需初始化。初始化后的值可能被断言非空,断言失败则非正常地退出脚本。

  这些变量可能指定外部环境的配置。

  在开发文档中的环境变量的基础上,以下各节补充指定适用于多个脚本的变量。在对应的脚本的文档中可能补充描述。

  一些环境变量具有特定的命名模式:

  • 开发文档中的环境变量具有相同前缀的外部扩展环境变量:
    • 具有前缀 SHBuild_ :可能适用于所有构建脚本流程。
      • 注释 具有前缀 SHBuild_S1_SHBuild_S2_ 的名称不指定环境变量,而是函数名称。
    • 具有前缀 YSLib_ :指定和 YSLib 库相关的环境和配置。
    • 注释 这些前缀的变量通常在开发文档中指定。仅在个别脚本中适用或不在 shell 脚本(而仅在 NPLA1 脚本)适用时,在本文档指定扩展。
  • 具有前缀 SS_公共构建配置变量
    • 注释 环境变量名称中的 SS 前缀表示 SHBuild Settings 。
  • 具有前缀 S1_ :在 stage 1 SHBuild 构建流程中作用的变量。
    • 注释 环境变量名称中的 S1 前缀表示 Stage 1 。
  • 具有前缀 CFLAGSCXXFLAGSLDFLAGS 等:指定构建工具使用的选项。

公共构建配置变量

  以下配置行为的环境变量可在多个构建脚本中被支持且具有一致的含义:

  • SS_DebugEnv 启用脚本执行时系统环境相关的调试输出。
  • SS_DirectExtract 启用直接解压缩。
  • SS_NoParallel 不使用并行命令调用。
  • SS_Offline 离线模式:不使用互联网。
  • SS_Verbose 启用详细消息输出。

  除非另行指定,这些变量的值当且仅当非空表示启用特性。

  具体作用在具体脚本的说明中详细描述。

Stage 1 共享变量

  以下变量影响 stage 1 的多个构建脚本的行为。

  • S1_BuildConf 内部配置名称。
    • 通常指定不同的值对应不共享的构建配置组合。
    • 注释 可影响默认构建目录。
  • S1_BuildDir Stage 1 SHBuild 构建和输出文件目录路径。
  • S1_CacheFile 缓存文件名。
  • S1_DistDir Stage 1 SHBuild 可执行程序目录路径。
  • S1_SHBuild Stage 1 SHBuild 可执行文件路径。
    • 注释 Win32 平台实际的可执行文件可隐含后缀 .exe

  具体作用可在具体脚本的说明中详细描述。

Tools/install-sysroot.sh

  Sysroot 安装脚本。用于直接构建和部署基础环境。

  构建时会调用 Tools/Scripts 目录下的脚本,按需构建 stage 1 SHBuild 后间接调用 SHBuild 构建 YBaseYFramework 的静态库和动态库,再构建依赖于动态库的 SHBuild

  构建使用变量 SHBuild_BuildDir 指定的路径作为中间输出目录。

注释 另见 Tools/Scripts/SHBuild-bootstrap.sh

  构建脚本同时可安装文件,完成 Sysroot 所需文件的部署。安装的起始目标位置由称为安装路径的目录路径指定,其字符串形式去除结尾分隔符的目录文件名为安装路径前缀。安装过程在必要时可创建 Sysroot 根目录、安装路径指定的目录及其子目录。安装路径的确定方式详见以下的使用方式。

  部署时使用 stage 1 SHBuild 更新文件和目录,在必要时创建符号链接或硬链接,若失败则改为普通复制。仅当被部署的文件为中间目标启用硬链接,以免后续操作意外覆盖源文件。注意在 Windows 上创建符号链接可能因为权限不足失败,取决于用户和组策略。建议使用系统管理权限运行以避免可能的权限问题。

基本使用

  脚本接受在 stage 2 使用的 SHBuild 命令行中的选项为命令行参数,如

Tools/install-sysroot.sh -xj,2

  使用 2 个并行线程构建。

  脚本也支持变量配置构建使用的路径,默认相当于使用如下 bash 命令配置变量:

: ${SHBuild_SysRoot:="$YSLib_BaseDir/sysroot"}
: ${SHBuild_BuildDir:="$YSLib_BaseDir/build/$(SHBuild_GetBuildName)"}

  其中:

  在 stage 1 SHBuild 构建调用 NPLA1 脚本 Tools/Scripts/SHBuild-YSLib*.txt ,调用方式和接受的配置(构建目标等)、具体默认设置和注意事项见对应 shell 脚本的文档相关章节。

Tools/Scripts

  这个目录的脚本可用于整个项目或项目核心部分的构建工具使用。

  当前有以下脚本忽略重复的 .source 命令:

  • SHBuild-common.sh

  以前缀 SHBuild_ 起始的名称保留使用。

  其中,前缀 SHBuild_Env_ 总是表示环境配置的只读变量名。这些变量若未被指定,可在第一次访问时(具体时机未指定)初始化为:

  • SHBuild_Env_Arch :参见函数 SHBuild_CheckUName
  • SHBuild_Env_OS :参见函数 SHBuild_CheckUName
  • SHBuild_Env_TempDir :缓存函数 SHBuild_GetTempDir 的输出。
  • SHBuild_Env_uname :缓存命令 uname 的输出。
  • SHBuild_Env_uname_m :缓存命令 uname -m 的输出。

Tools/Scripts/GenerateProjects.sh

  调用 ProjectGenerator 生成项目文件。

  当前支持生成所有 .cbp 文件。

  要求可使用 hggit 命令取版本库根目录,否则不保证输出到正确的路径。

变量 ProjectGenerator

  调用 RevisionPatcher 的命令。默认直接使用 type -P ProjectGenerator 的结果,一般要求可执行文件在环境变量 PATH 中。

Tools/Scripts/PatchRevision.sh

  开发过程中使用 RevisionPatcher 维护源文件中版本号的脚本。

  当前只支持 Mercurial 或 Git 版本库的已添加或修改的未提交文件。

  使用的版本控制系统会被检查。通过检查的条件、确定使用的版本控制的机制及支持的控制检查的环境变量同 Tools/Scripts/SHBuild-YSLib*.txt 公用的版本控制系统支持,参见以下相关章节的说明。

  若检查都失败,则脚本出错,不再继续运行。

  脚本利用 hggit 命令把未提交的这些修改导出为补丁备份到版本库根目录的 bak.patch ,然后使用这些内容调用 RevisionPatcher 取得文件和对应的新的版本号列表,最后使用 sed 查找对应文件并更新版本号。

  脚本依赖 sed 命令。使用的 sed 应支持 -b -i 选项。可使用 Linux 或 MSYS2 的发行版中的 sed 4.8 程序。

警告 某些 Win32 版本的 sed ,如 MSYS2 MinGW64 sed 4.4 可能损坏文本文件的行尾。有些替代版本可能解决这一问题

注释 当前不检查特定版本 sed 对选项的支持。

  若没有找到 \version r 模式的版本号前缀则忽略写入版本号。写入的版本号不影响换行符。

注释 这个脚本可用于自动化。例如,在 Mercurial 仓库的 hgrc[hooks] 节中添加 precommit.PatchRevision = bash Tools/Scripts/PatchRevision.sh 可在每次提交前调用这个脚本。在 YSLib 中,仅在主分支版本中启用。

变量 PatchBegin

  匹配版本号的起始行,应为一个表示行数的正整数。默认值为 "1"

变量 PatchEnd

  匹配版本号的结束行,应为一个表示行数的正整数。默认值为 "20"

变量 RevisionPatcher

  调用 RevisionPatcher 的命令。默认值为 type -P RevisionPatcher 的结果。

注释 可执行文件可以在环境变量 PATH 中。

变量 PatchHg

  指定使用 Mercurial 。参见以上确定使用 Mercurial 或 Git 的说明。

变量 PatchGit

  指定使用 Git 。参见以上确定使用 Mercurial 或 Git 的说明。

Tools/Scripts/SHBuild-bootstrap.sh

  编译 stage 1 SHBuild 时被包含的脚本。

  脚本执行构建配置的环境初始化。其中指定静态链接需要依赖的 YSLib 源文件以及头文件路径等的必要变量。

  脚本按需设置变量 S1_BuildConf 的值,以确保部分变量之后在包含 Tools/Scripts/SHBuild-YSLib.sh 时能被按需初始化。默认值为 stage1

  • 注释 有的脚本如 Tools/install-sysroot.sh 在此之前应已初始化部分变量。其它脚本可能依赖这里的初始化。

Tools/Scripts/SHBuild-build.sh

  编译 stage 1 SHBuild 的脚本。

  以下公共构建配置变量影响脚本的特定行为:

  • SS_NoParallel 的作用当前包括:
    • 不检查并行命令的可用性。
    • 不使用并行命令构建。
  • SS_Verbose 的作用当前包括:
    • 调用命令前回显。

  使用变量 SHBuild_Output 指定输出路径。默认值为 SHBuild ,即在当前工作目录下生成名为 SHBuild 的可执行文件(视宿主平台不同可能带后缀如 Win32 带 .exe )。

  调用函数 SHBuild_CheckPCH 检查预编译头:若变量 SHBuild_NoPCH 非空则跳过预编译头,否则使用预编译头包含标准库头。预编译的头文件目标由 YBase 下的 stdinc.h ,之后构建时包含预编译头路径为 $SHBuild_PCH_stdinc_h 。后者的默认路径为当前工作目录下的 stdinc.h

  因为升级或更换编译器和/或选项,可导致预编译头文件( .gch 文件)不和生成的环境匹配而不被识别。

注意 预编译头文件不保证对不同的操作系统版本兼容,参见先决条件中 PC(Win32) 平台关于操作系统版本的说明。

  不被识别的预编译头文件通常:

  • 可引起编译器警告,并忽略预编译头文件。
    • 若仅需避免产生警告,确保编译器命令行使用恰当选项,如添加 -Wno-invalid-pch
  • 可能引起无法构建的错误。

  一般仍然需要避免使用不匹配的预编译头文件。若无法保证预编译头文件和使用的工具链和选项匹配:

  • 可设置变量 SHBuild_NoPCH 的值非空以跳过预编译头文件的使用。
  • 可以手动删除生成的预编译头文件。在没有设置变量 SHBuild_NoPCH 的情形下构建通常会默认自动生成。
    • 注释 具体的支持和生成预编译头文件的位置参见具体构建目标的说明,如 Sysroot

已知缺陷 构建时不自动更新预编译头。

  除非环境变量 SS_NoParallel 的值非空,构建前可选地检查可用的并行命令。支持如下:

  • 支持 GNU parallel 命令 parallel
  • 不支持 moreutils parallelparallel 命令的可用性会忽略。
  • 不对并行数指定选项。
    • 原理 默认应已能充分使用宿主环境的计算资源。

Tools/Scripts/SHBuild-BuildApp.sh

  应用程序构建脚本。这个脚本被保留,不再具有实际功能。

  这个脚本是公开的工具,被安装脚本部署。

Tools/Scripts/SHBuild-BuildPkg.sh

  包构建脚本。当前只支持构建应用程序,具体步骤和使用的参数参见 Tools/Script/SHBuild-BuildApp.txt

  这个脚本是公开的工具,被安装脚本部署。

Tools/Scripts/SHBuild-common.sh

  被应用程序构建脚本包含的脚本,提供公共基础功能。

  这个脚本是公开的工具,被安装脚本部署。

注意 这个脚本包含 INC_SHBuild_common 守卫变量检查,默认重复包含只被执行一次。

函数 SHBuild_Popd

  同 bash 内建 popd 但不回显标准输出。

函数 SHBuild_Pushd

  同 bash 内建 pushd 但不回显标准输出。

函数 SHBuild_Put

  使用 printf 输出非格式字符串。

  使用 $* 形式传递字符串,此时 IFS 是默认值。

函数 SHBuild_Puts

  使用 printf 输出非格式的换行的字符串。

  使用 $* 形式传递字符串,此时 IFS 是默认值。

  换行符由变量 SHBuild_EOL 指定。若值为空,则首先初始化为全局只读变量。当前默认值通过检查 $COMSPEC 是否定义,以确保 Windows 环境(包括 MSYS )使用 CR+LF ,其它情况使用 LF 。

  这个函数在可用时可用于代替 echo ,以取得对环境更好的适应性。

注意 具体的检查逻辑实现可能在以后改变。

函数 SHBuild_Puts_Err

  同函数 SHBuild_Puts,但重定向标准输出到标准错误。

函数 SHBuild_Puts_Exit

  第一参数指定错误码,以之后的参数调用函数 SHBuild_Puts_Exit,然后以错误码退出。

函数 SHBuild_Puts_Verbose

  当变量 SS_Verbose 的值非空时,调用函数 SHBuild_Puts

函数 SHBuild_AssertNonempty

  断言第一参数为名称的变量非空,否则显示出错并退出。

  使用 eval 实现。

函数 SHBuild_CheckedCall

  检查第一参数为名称的命令存在,否则显示出错并退出。

  使用 hash 实现以优化性能。

函数 SHBuild_CheckedCallSilent

  同 SHBuild_CheckedCall ,但不显示错误外的标准输出。

函数 SHBuild_InitReadonly

  断言第一参数为名称的变量非空,若空则使用 eval 对后续求值并初始化第一参数指定的只读变量。

  初始化时在当前 shell 中求值初值。

  若发生初始化且变量 SS_Verbose 的值非空,则在标准输出中显示。

已知限制 当前实现使用临时文件 /tmp/InitReadonly 暂存作为初值的调用结果。需确保这个临时文件所在的目录和这个文件可写。

原理

  保证当前 shell 中求值允许初值中调用可能修改当前 shell 环境的 shell 函数。这使一个 SHBuild_InitReadonly 调用中,间接的嵌套调用可使用先前已通过同一个调用者初始化的变量。

函数 SHBuild_2m

  接受 1 个表示路径的参数,调用 cygpath 转换路径到 Windows 混合风格路径。

  当 cygpath 不存在时返回原路径。

函数 SHBuild_2u

  接受 1 个表示路径的参数。

  调用 cygpath 转换 Windows 路径到 UNIX 路径。

  当 cygpath 不存在时返回原路径。

函数 SHBuild_EchoEscape

  当标准输出使用终端时调用 echo -ne 输出参数指定的 ANSI 转义序列。

已知缺陷 不检查 $TERM 支持。

函数 SHBuild_EchoString

  接受 2 个参数,输出转义序列指定格式的内容,包含以下步骤:

  • 使用 SHBuild_EchoEscape 输出第二参数指定的转义序列。
  • 使用 SHBuild_Put 输出第一参数的内容。
  • 使用 SHBuild_EchoEscape 输出复位格式的转义序列。

函数 SHBuild_EchoVar

  接受 2 个参数 xy ,以特定颜色显示为 x = "$y" 的形式,其中 $yy 的值。

  第二参数一般是字符串。

函数 SHBuild_EchoVar_N

  接受 1 个参数 x ,调用 SHBuild_EchoVar 显示为 x = $x 的形式。

  右侧求值时会替换参数中的 ._

  参数一般是字符串。

函数 SHBuild_EchoVarA

  接受 2 个参数 xy ,以特定颜色显示为 x = ($y) 的形式,其中 $yy 的值。

  第二参数一般是数组。

函数 SHBuild_EchoVarA_N

  接受 1 个参数 x ,调用 SHBuild_EchoVarA 显示为 x = $x 的形式。

  右侧求值时会替换参数中的 ._

  参数一般是数组。

函数 SHBuild_CheckUName

  调用 SHBuild_CheckedCall 按需初始化只读变量 SHBuild_Env_OSSHBuild_Env_Arch 的值。

  变量 SHBuild_Env_OS 的值通过分类系统的值(一般即 SHBuild_Env_uname 的值)标识操作系统:

  • OS_X :输入匹配 *Darwin* ,用于标识 OS X 系统。
  • Win32 :输入匹配 *MINGW**MSYS* ,用于标识 Windows 系统。
  • Linux :输入匹配 *Linux* ,用于标识 Linux 系统。
  • unknown :不支持的系统。

  变量 SHBuild_Env_Arch 的值通过分类输入的处理器体系结构的值(一般即 SHBuild_Env_uname_m 的值)标识体系结构:

  • x86_64 :输入匹配 x86_64i*86-64
  • i*86 :输入匹配 i*86 ,使用原值。
  • aarch64 :输入是 aarch64
  • unknown :不支持的体系结构。

  若同时指定环境变量 SHBuild_Env_ArchSHBuild_Env_OS ,不进行自动环境检测,不依赖 uname

函数 SHBuild_GetTempDir

  取临时目录的路径。

  依次检查以下环境变量的值,若非空则作为结果:

  • TMPDIR
  • TEMP
  • TMP

  若这些环境变量都没有非空值,则使用经过 SHBuild_2m 转换的 /tmp(被 POSIX.1 要求支持)作为结果。

注意 以上过程在所有平台上都一致。这是自适应环境的基本接口,因此不对环境变量的值的合法性进行判断。若结果不表示一个可访问的目录,在访问以此构造的文件路径时可能引发错误。应用程序一般需自行检查或保证使用的环境中这些路径可访问。

说明 以上检查中,支持的环境变量符合惯例(en-US) 。检查环境变量的顺序(偶然地)和一些类似功能的实现(如 MySQL 在 Windows 上)一致,和其它一些特定平台的 API(如 Win32 API )及另一些不作为公开行为的实现(如 libiberty 的 choose_tmpdir )可能不一致。被支持的环境变量可用性举例:

已知限制 不检查路径是否表示实际可写的目录。另见文件访问约定。

  当前脚本实现假定临时目录可写,不满足条件时,文件操作可能失败。脚本使用的临时文件前也不保证检查文件可写。若此文件不可写(例如,在之前被 root 等高权限用户创建),则依赖文件可写的操作可能失败。对构建脚本,这可能导致依赖临时文件进行检查判断失效,而使错误的选项被使用。

  一般地,脚本可使用特定的例程(如 Shell 脚本可选地使用在许多环境中可用的 mktemp 命令)随机化文件名减少冲突。若需要更可靠地避免上述问题,可在运行脚本前清理临时目录,或预先设置 SHBuild_GetTempDir 访问的环境变量指定确保可写的空目录,同时避免并发调用脚本导致不安全并发访问此目录中的临时文件。脚本不使用其它方法确定直接使用的临时目录,但脚本间接调用的外部工具仍可能导致不安全的访问,而无法保证可靠。

函数 SHBuild_Platform_Detect

  通过参数指定的操作系统和体系结构名,结合环境变量,确定平台名称,检查非空并返回。

  第一和第二参数分别指定操作系统名和体系结构名,接受的取值参见函数 SHBuild_CheckUName

  当前 Win32 系统外的结果和 SHBuild_CheckUName 初始化 SHBuild_Env_OS 的结果一致。处理如下:

  • 若操作系统名为 Win32
    • 若环境变量 MSYSTEM 设置为 MSYS2 支持的环境,结果对应如下:
      • MINGW64MinGW64
      • MINGW32MinGW32
      • CLANG64MinGW_Clang64
      • CLANG32MinGW_UCRT64
      • CLANGARM64MinGW_ClangARM64
      • UCRT64MinGW_UCRT64
    • 否则,若体系结构为 x86_64 ,则结果为 MinGW64
    • 否则,结果为 MinGW32
  • 否则,结果为操作系统名。

函数 SHBuild_PrepareBuild

  准备构建环境。按以下方式初始化变量使之具有非空值:

  • 调用函数 SHBuild_GetTempDir 初始化 SHBuild_Env_TempDir
  • 调用函数 SHBuild_CheckUName 初始化 SHBuild_Env_OSSHBuild_Env_Arch
  • 初始化 SHBuild_Host_OSSHBuild_Env_OS 的值。
  • 当变量 SHBuild_Host_OS 的值是 Win32 时,且环境变量 MSYSTEM 的值是 MSYS2 支持的环境支持的值,初始化 SHBuild_Host_Arch 对应的目标体系结构;否则,初始化 SHBuild_Host_ArchSHBuild_Env_Arch 的值。

函数 SHBuild_GetBuildName

  取用于进一步初始化构建路径的构建名称。

  首先调用函数 SHBuild_PrepareBuild 按需初始化变量 SHBuild_Env_ArchSHBuild_Env_OS 为非空值。

  结果为以变量 SHBuild_Env_OSSHBuild_Env_Arch 的值作为参数调用函数 SHBuild_Platform_Detect 的结果。

函数 SHBuild_BuildGCH

  构建 GNU 预编译头文件,依次执行:

  • 以第二参数指定的路径附加 .gch 后缀确定输出路径。
  • 检查输出路径是否已存在文件,若存在则视为目标已被构建,输出消息并跳过以下步骤。
  • 确保输出路径所在的目录被创建。
  • 输出开始构建的消息。
  • 硬链接第一参数指定输入的头文件路径到第二参数指定的安装路径。
  • 按第一参数指定的输入路径和输出路径调用第三个参数指定构建命令。
  • 输出构建完成的消息。

已知限制 构建命令仅支持 GNU 兼容工具链。

函数 SHBuild_CheckPCH

  检查和按需构建 GNU 预编译头文件并设置变量,依次执行:

  • 检查变量 SHBuild_NoPCH 的值,若为空值,则:
    • 以第一参数、第二参数和 $CXX -xc++-header $CXXFLAGS 调用 SHBuild_BuildGCH 生成 GNU 风格预编译头文件。
    • 设置内部变量 SHBuild_IncPCH 为合适的命令行选项的数组(以 "-include" 和头文件名作为其元素)用于包含生成的预编译头文件。
  • 否则:
    • 输出跳过消息。
    • 设置 SHBuild_IncPCH 的值为空数组。

已知限制 构建命令仅支持 GNU 兼容工具链。

函数 SHBuild_2w

  接受 1 个表示路径的参数,调用 cygpath 转换 UNIX 路径到 Windows 路径。

  当 cygpath 不存在时返回原路径。

函数 SHBuild_Install

  接受 2 个表示路径的参数,安装前者指定的文件到后者。

  首先调用 rsync ,若失败调用 cp

注意 防火墙可能导致 rsync 超时失败。

函数 SHBuild_InstallDir

  接受 2 个表示路径的参数,安装前者指定的目录到后者。

  首先调用 rsync ,若失败调用 cp

注意 防火墙可能导致 rsync 超时失败。

函数 SHBuild_Install_Exe

  接受 2 个表示路径的参数,安装前者指定的可执行文件到后者。

  首先调用 SHBuild_Install ,然后在目标上设置可执行权限。

  接受 2 个表示路径的参数,安装前者指定的文件到后者为硬链接。

  首先删除目标,其次调用 Windows 命令解释器的 mklink ,若失败调用 ln

  接受 2 个表示路径的参数,安装前者指定的可执行文件到后者为硬链接。

  首先调用 SHBuild_Install_HardLink ,然后在目标上设置可执行权限。

注意 mklink 需要 Windows Vista 后的命令解释器(cmd) 的支持。硬链接需要文件系统(如 NTFS )支持。

  接受 2 个表示路径的参数,安装前者指定的文件到后者为符号链接。

  首先删除目标,其次调用 Windows 命令解释器的 mklink ,若失败调用 ln

注意 mklink 需要 Windows Vista 后的命令解释器(cmd) 的支持。符号链接需要文件系统(如 NTFS )支持。权限不足可能导致 mklink 创建符号链接失败,可在组策略改变相关默认行为。在一些版本的系统上,可能需要进一步的配置以通过链接执行文件。

函数 SHBuild_LoadCache

  加载环境缓存。

  函数接收 2 个参数,分别是缓存文件路径和被缓存的变量名的正则表达式模式的数组。

  加载缓存通过解析文件内容验证后包含实现。

  文件的内容应为可执行的 shell 赋值代码。当前检查支持的格式如下:

  • 每行一个条目,忽略首尾空白符。
  • 若条目的形式是 if ... then; ASSIGNMENT; fi ,简化为 ASSIGNMENT 进行下一步检查,忽略其余部分。
  • 进一步地,若条目的形式是 declare -X VAR=... ,其中 X 是匹配正则表达式模式 (-|[Aagirx]+) 的属性之一,简化为 VAR 进行下一步检查,忽略其余部分。
    • 注释 作为全局变量,declare 条目一般应具有 -g 属性,否则声明为局部变量,实际没有加载配置。
  • 进一步地,VAR 应为合法的标识符,匹配正则表达式模式 [A-Za-z_][A-Za-z_0-9]*

  若任意检查失败,则缓存格式无效,内容不会被加载;否则,包含缓存文件,以执行其中的赋值代码。

  函数的返回值如下:

  • 0 :成功。
  • 1 :内容无效。
  • 2 :指定的缓存文件无法读取。

函数 SHBuild_SaveCache

  保存环境缓存。

  函数接受的参数及其含义和函数 SHBuild_LoadCache 一致。

  首先打开文件,然后解析 declare -p 结果,把其中变量名匹配第二参数中任意的正则表达式且内容满足函数 SHBuild_LoadCache 格式要求的行写入指定的缓存文件。

  写入前,替换内容中的 declare --declare -declare -g 以确保声明全局变量。

注释 不要求支持 declare -p 结果中的所有变量属性。不支持的属性被忽略。

  函数的返回值如下:

  • 0 :成功。
  • 2 :指定的缓存文件无法写入。

函数 SHBuild_GetSystemPrefix

  转换参数指定的平台名称字符串为系统前缀字符串。

  系统前缀用于在文件系统中安装部署。

  通常系统前缀因为之前仍有非空的其它前缀(如 SHBuild_SysRoot 指定的值)而不是绝对路径的前缀。因此,系统前缀以 / 起始而不需要考虑所在的环境是否符合 FHS 的问题。

  当前支持的结果包括:

  • 参数为 MinGW64 时,结果为 /mingw64
  • 参数为 MinGW32 时,结果为 /mingw32
  • 否则,结果为 /usr

  本函数的结果符合 Sysroot 中关于 Sysroot 的目录布局的约定。

注释 参数典型地来自调用函数 SHBuild_Platform_Detect 的结果。

函数 SHBuild_S1_InitConf

  初始化 stage 1 Sysroot 构建配置,依次执行:

  • 断言变量 SHBuild_ToolDir 非空。
  • 按需初始化变量 YSLib_BaseDir ,默认值为 "$SHBuild_ToolDir/../.."
    • 注释 Stage 1 环境下总是可通过脚本所在目录推断 YSLib 源代码和存储库中的其它源文件的位置。
  • 尝试以切换当前目录的方式访问 $YSLib_BaseDir
  • 按需初始化变量 SHBuild_BuildDir ,默认值为 YSLib 版本库根目录下的 build/$(SHBuild_GetBuildName)
  • 确保变量 SHBuild_BuildDir 指定的目录被创建,并尝试以切换当前目录的方式访问。
  • 变量 S1_BuildDir 的值为空,断言变量 S1_BuildConf 的值非空。
    • 注释 这排除以下的初始化默认值使用非预期路径。
  • 按需初始化变量 S1_BuildDir ,默认值为 "$SHBuild_BuildDir/.$S1_BuildConf"
  • 按需初始化变量 S1_DistDir ,默认值为 "$S1_BuildDir/.stage1"
  • 按需初始化变量 S1_SHBuild ,默认值为 "$S1_DistDir/SHBuild"
  • 确保变量 S1_BuildDir 指定的目录被创建,并尝试以切换当前目录的方式访问。
  • 确保变量 S1_DistDir 指定的目录被创建,并尝试以切换当前目录的方式访问。

  以上变量初始化后只读。

函数 SHBuild_S2_Prepare

  准备 stage 2 Sysroot 环境,依次执行:

  • 确保变量 SHBuild_SysRoot 的初始化。
    • 使用第一参数作为这个变量的默认值。若变量这个未被设置,则以默认值赋值。
  • 断言这个变量的值非空,以其值作为创建目录,若指定的目录已存在则忽略。
  • 初始化变量 SHBuild_SystemPrefix
  • 初始化变量 SR_Prefix 的值为 "$SHBuild_SysRoot$SHBuild_SystemPrefix"

函数 SHBuild_S2_Prepare_Build

  准备 stage 2 Sysroot 构建环境,依次执行

  • 以第一参数调用 SHBuild_S2_Prepare
  • 导出变量 SHBuild 的值为 "$SR_Prefix/bin/SHBuild"

Tools/Scripts/SHBuild-common-options.sh

  被应用程序构建脚本包含的基础功能,提供默认的编译器和链接器命令行选项。

  若某个变量提供默认值且执行脚本时没有非空值,则设置为脚本提供的默认值。

  这个脚本是公开的工具,被安装脚本部署。

  包含 Tools/Scripts/SHBuild-common-toolchain.sh 确定工具链。

注意 G++ 和 Clang++ 不完全兼容。以下部分变量通过 Tools/Scripts/SHBuild-common-toolchain.sh 中的例程判断 G++ 和 Clang ,并自动使用不同的选项默认值。因此直接通过名称和符号链接等方式伪装会失效而可能导致错误。

  以下所有变量仅在外部环境设置为空或未设置时提供默认值,按顺序被指定。可在外部设置为非空值以避免被本脚本中的值覆盖。以下仅列出部分相对不容易变动的默认值,其它默认值参见脚本源代码。若不需要默认值,可以提前设置非空值或在 . 指令后直接设置其它(可能为空的)值。

变量 SHBuild_Debug

  默认值为空。

  非空时,指定变量的值:

CXXFLAGS_OPT_DBG='-O0 -g -D_GLIBCXX_DEBUG_PEDANTIC'
LDFLAGS_OPT_DBG=' '

变量 C_CXXFLAGS_GC

  C/C++ 编译器生成二进制节 GC 选项。

  默认值为 -fdata-sections -ffunction-sections

  设置后会被检查是否支持,参见下文。

变量 LDFLAGS_GC

  链接器生成二进制节 GC 选项。

  默认值为 -Wl,--gc-sections

  设置后会和 C_CXXFLAGS_GC 通过 $CXX 作为编译器编译链接简单程序测试是否支持。若不支持,此变量和 C_CXXFLAGS_GC 都会被置空。

已知限制 Windows 上的工具链可能缺乏 /dev/null 的必要支持,因此此项检查使用的输出路径指定为 /tmp/null

变量 C_CXXFLAGS_PIC

  C 和 C++ 编译器共用的 PIC ( Position Independent Code ,位置无关代码)生成选项。

  默认值在 Win32 上为空,其它平台上为 -fPIC -fno-semantic-interposition

  用于保证生成的对象文件可被用于生成动态库。

变量 LDFLAGS_STRIP

  链接器剥离符号选项。

  默认值为 -s

变量 C_CXXFLAGS_EXT

  指定 C/C++ 语言扩展的选项。

  默认值和平台相关:若为 Win32 环境则为空,否则为 -D_POSIX_C_SOURCE=200809L

注释 若实现环境没有提供适当的宏定义,YFramework 中使用 POSIX 平台文件系统 API 的实现要求不被满足而可能构建失败。

变量 C_CXXFLAGS_ARCH

  C 和 C++ 编译器共用的体系结构相关选项。

  默认值为空。

  不限制具体形式,使用 G++ 时可以是 -march=native

变量 C_CXXFLAGS_COMMON

  C 和 C++ 编译器共用的公共选项。

  默认值为 -pipe $C_CXXFLAGS_GC $C_CXXFLAGS_ARCH -pedantic-errors $C_CXXFLAGS_EXT

变量 C_CXXFLAGS_OPT_LV

  C 和 C++ 编译器优化等级选项。

  默认值为 -O3

函数 SHBuild_Get_C_CXXFLAGS_WARNING

  取 C 和 C++ 编译器共用的警告命令行选项的默认值。

  结果包括以下列表中的内容:

  • -Wall
  • -Wcast-align
  • -Wdeprecated
  • -Wdeprecated-declarations
  • -Wdouble-promotion
  • -Wextra
  • -Wfloat-equal
  • -Wformat=2
  • -Winvalid-pch
  • -Wlogical-op
  • -Wmissing-declarations
  • -Wmissing-include-dirs
  • -Wmultichar
  • -Wno-format-nonliteral
  • -Wredundant-decls
  • -Wshadow
  • -Wsign-conversion
  • -Wstringop-overflow=0
  • -Wsuggest-attribute=const
  • -Wsuggest-attribute=noreturn
  • -Wsuggest-attribute=pure
  • -Wtrampolines

  通过检查 C++ 编译器和版本已知不支持的选项会被替换为其它功能近似的选项或被排除。

注释 当前仅检查 C++ 编译器,假定 C 编译器和 C++ 编译器版本对应一致(即 G++ 蕴含 GCC ,Clang++ 蕴含 Clang )。

变量 C_CXXFLAGS_WARNING

  C 和 C++ 编译器共用的警告命令行选项。

  默认值是调用函数 SHBuild_Get_C_CXXFLAGS_WARNING 得到的值。

变量 C_CXXFLAGS_IMPL_WARNING

  和特定实现相关的 C 和 C++ 编译器共用的警告命令行选项。

  默认值为空值。

变量 CXXFLAGS_IMPL_WARNING

  和特定实现相关的 C++ 编译器警告命令行选项。

  默认值为空值。

变量 CXXFLAGS_IMPL_COMMON

  和特定实现相关的 C++ 编译器一般命令行选项。

  默认值包括若干特定实现的选项。

线程命令行选项

  线程命令行选项是一组未指定名称的内部命令行选项,包含编译器选项和链接器选项的默认值。其中,编译器选项被变量 CFLAGS变量 CXXFLAGS 的默认值使用,链接器选项被变量 LDFLAGS 的默认值使用。

  默认值按以下方式检查和指定线程参数:

  • 通过 -dumpspecs 的内容检查是否匹配 mthreads: 。若成功,编译器和链接器选项添加 -mthreads
  • 否则,测试带有 -mthread 选项的构建。若(直接调用编译器驱动)构建通过,则链接器选项添加 -mthreads ,并检查编译。
    • 若编译不通过,则编译器选项添加 -D_MT ,否则添加 -mthreads
  • 否则,若通过 -dumpspecs 的内容检查匹配 no-pthread: 且带有 -pthread 时无法构建,则保持编译器和链接器选项不变。
  • 否则,编译器和链接器选项添加 -pthread

注意 不论 C 或 C++ ,当前实现在调用编译器测试构建时总是使用函数 SHBuild_CXX_TestSimple

变量 CXXFLAGS_IMPL_OPT

  和特定工具相关的 C++ 编译器优化命令行选项。

  默认值包括若干特定实现的选项。

变量 CFLAGS_STD

  指定 C 标准的编译器命令行选项。

  默认值为 -std=c11

变量 CFLAGS_WARNING

  C 编译器警告命令行选项。

  默认值包含以下列表中的内容:

  • 变量 C_CXXFLAGS_WARNING 的内容
  • 变量 C_CXXFLAGS_IMPL_WARNING 的内容

变量 CXXFLAGS_STD

  指定 C++ 标准的编译器命令行选项。

  默认值为 -std=c++11

函数 SHBuild_Get_CXXFLAGS_WARNING

  取 C++ 编译器的警告命令行选项的默认值。

  结果包括以下列表中的内容:

  • 变量 C_CXXFLAGS_WARNING 的内容
  • 变量 C_CXXFLAGS_IMPL_WARNING 的内容
  • -Wconditionally-supported
  • -Wctor-dtor-privacy
  • -Wdeprecated(仅当旧版本 GCC 中这个选项支持 C++ 但不支持 C 时)
  • -Wno-deprecated-register
  • -Wno-mismatched-tags
  • -Wno-missing-braces(仅当 Clang++ < 6.0 ,作为这个问题的变通)
  • -Wnon-virtual-dtor
  • -Woverloaded-virtual
  • -Wsign-promo
  • -Wshorten-64-to-32
  • -Wstrict_null_sentinal
  • -Wsuggest-final-methods
  • -Wsuggest-final-types
  • -Wweak-vtables
  • -Wzero-as-null-pointer-constant
  • 变量 CXXFLAGS_IMPL_WARNING 的内容

  除以上变量中的内容外,通过检查 C++ 编译器和版本已知不支持的选项会被替换为其它功能近似的选项或被排除。

变量 CXXFLAGS_WARNING

  C++ 编译器警告命令行选项。

  默认值是调用函数 SHBuild_Get_CXXFLAGS_WARNING 得到的值。

变量 CXXFLAGS_OPT_DBG

  C++ 编译器优化和调试相关的命令行选项。在未设置非空的 SHbuild_Debug 时。

  默认值包含以下列表中的内容:

  • 变量 C_CXXFLAGS_OPT_LV 的内容
  • 变量 CXXFLAGS_OPT_UseAssert 没有被设置非空值时包含 -NDEBUG
  • 变量 CXXFLAGS_IMPL_OPT 的内容
  • -fomit-frame-pointer

变量 CFLAGS

  C 编译器使用的命令行选项。

  默认值为 $CFLAGS_STD $C_CXXFLAGS_PIC $C_CXXFLAGS_COMMON $CFLAGS_WARNING $C_CXXFLAGS_IMPL_THRD_ $C_CXXFLAGS_COMMON_IMPL_ $CXXFLAGS_OPT_DBG 。其中,C_CXXFLAGS_COMMON_IMPL_编译器线程命令行选项,而 C_CXXFLAGS_COMMON_IMPL_ 是根据支持的编译器在内部定义的非公开变量。

注意 当前和 C++ 编译器选项共用 CXXFLAGS_OPT_DBG

变量 CXXFLAGS

  C++ 编译器使用的命令行选项。

  默认值为 $CXXFLAGS_STD $C_CXXFLAGS_PIC $C_CXXFLAGS_COMMON $CXXFLAGS_WARNING $C_CXXFLAGS_IMPL_THRD_ $CXXFLAGS_IMPL_COMMON $CXXFLAGS_OPT_DBG 。其中,C_CXXFLAGS_COMMON_IMPL_编译器线程命令行选项,而 CXXFLAGS_IMPL_COMMON 的默认值包含变量 C_CXXFLAGS_COMMON_IMPL_ 的内容。

变量 LDFLAGS_OPT_DBG

  链接器优化和调试相关的命令行选项。在未设置非空的 SHbuild_Debug 时。

  默认值为 $LDFLAGS_STRIP $LDFLAGS_IMPL_OPT $LDFLAGS_GC

变量 LDFLAGS

  链接器使用的命令行选项。

  默认值依次包含以下内容:

  默认使用 -Wl, 传递链接器特定的命令行。

Tools/Scripts/SHBuild-common-toolchain.sh

  被应用程序构建脚本包含的基础功能,提供默认的编译器和链接器等工具的名称。

  支持 GCC/G++ 和 Clang/Clang++ 。

  支持 ar 及与其兼容的工具 gcc-ar/llvm-ar 的自动检测。对 Clang++ 和 G++ ,分别使用 llvm-argcc-ar

  以下可在环境外部配置,在值确定后被导出:

  • CC
    • 若操作系统为 Win32MSYSTEM 指定为默认使用 llvm 工具链(即 Clang )的环境,默认值为 clang ,否则为 gcc
  • CXX
    • 若操作系统为 Win32MSYSTEM 指定为默认使用 llvm 工具链(即 Clang++ )的环境,默认值为 clang++ ,否则为 g++
  • AR
    • 默认值为变量 CXX 指定的 C++ 编译器确定的自动检测结果;若非 Clang++ 和 G++ ,则使用 ar
  • ARFLAGS
    • 默认值为 rcs
  • LD
    • 默认值为变量 CXX 的值。

  关于 MSYSTEM 指定的环境和使用的工具链的对应关系,参见 MSYS2 支持的环境;关于支持的 MSYSTEM 的值和 MSYS2 环境,另见函数 SHBuild_Platform_Detect

  以下只读变量在初始化配置时被按需初始化并断言非空:

  • SHBuild_CC_Name :C 编译器名称。
    • 在调用函数 SHBuild_CC_GetVersion 时被首先初始化。
    • 初值是 $CC 作为参数调用函数 SHBuild_CheckCC 的结果。
  • SHBuild_CC_Version :C 编译器版本号。
    • 当前未使用。
    • 初值是调用函数 SHBuild_CC_GetVersion 的结果。
  • SHBuild_CXX_Name :C++ 编译器名称。
  • SHBuild_CXX_Version :C++ 编译器版本号。
    • 在脚本 Tools/Scripts/SHBuild-common-toolchain.sh 确定 C++ 版本号前初始化。
    • 初值是调用函数 SHBuild_CXX_GetVersion 的结果。

  上述按需初始化使用函数 SHBuild_InitReadonly

注释 可通过外部执行环境指定这些变量具有非空值而跳过初始化。

  这个脚本是公开的工具,被安装脚本部署。

函数 SHBuild_CheckCompiler

  尝试以参数指定的编译参数和输入调用参数指定的编译器,并按检查结果选择和输出参数的值。

  检查编译器时,首先排除参数指定的编译器不可执行的情形,然后通过尝试编译以参数指定的源程序进行。

  前四参数分别指定编译器的路径、尝试编译的源程序、检查成功时输出的结果和检查失败时输出的结果,之后的参数指定编译选项和源文件。选项和源文件参数中,应在语言选项(如 -xc++ )后出现一次表示输入源程序的 -

注释 这允许自由安排参数中 - 的顺序。一般地,- 应出现在 -xc++ 等参数之后,而出现在链接的库选项之前(如有)。若指定链接的其它库选项在 - 之前,其中的符号在使用 GNU ld 等对出现顺序敏感的链接器时,无法在源程序中引用而链接失败。

  检查前断言前两个参数非空。指定编译选项的参数为空时,第三和第四参数可能不提供或为空。

  源程序和换行符通过管道输入编译器。

注释 对 ISO C 以及 ISO C++11 前的版本,翻译单元不以空行结尾引起未定义行为。此处指定源程序的参数可以不以换行结尾也可安全处理。

  结果是以下之一:

  • 空值(第一参数指定不可执行的路径)。
  • 第三参数(检查成功时的结果)。
  • 第四参数(检查失败时的结果)。

注意 当前不检查失败原因。编译命令调用依赖可写的临时目录。参见函数 SHBuild_GetTempDir 的已知限制。

函数 SHBuild_CheckCC

  尝试调用参数指定的编译器以检查 C 编译器风格。

  第一参数指定编译器可执行文件路径。

  结果是以下之一:

  • 空值(不支持的编译器)。
  • Clang
  • GCC

函数 SHBuild_CheckCXX

  尝试调用参数指定的编译器以检查 C++ 编译器名称。

  第一参数指定编译器可执行文件路径。

  结果是以下之一:

  • 空值(不支持的编译器)。
  • Clang++
  • G++

函数 SHBuild_CC_Test

  测试 "$CC" 指定的编译器 C 编译器命令行是否可成功调用。

  第一参数指定源程序,之后的参数指定编译选项。编译选项前隐含 -pipe -xc

  以 SHBuild_CheckCompiler 实现编译器调用。

函数 SHBuild_CC_TestSimple

  测试 "$CC" 指定的编译器 C 编译器命令行编译最小程序是否可成功调用。

  参数指定编译选项。

  以 SHBuild_CC_Test 实现编译器调用。

  使用的最小程序是 int main(void){return 0;}

函数 SHBuild_CXX_Test

  测试 "$CXX" 指定的编译器 C++ 编译器命令行是否可成功调用。

  第一参数指定源程序,之后的参数指定编译选项。编译选项前隐含 -pipe -xc++

  以 SHBuild_CheckCompiler 实现编译器调用。

函数 SHBuild_CXX_TestSimple

  测试 "$CXX" 指定的编译器 C++ 编译器命令行编译最小程序是否可成功调用。

  参数指定编译选项。

  以 SHBuild_CXX_Test 实现编译器调用。

  使用的最小程序是 int main(){}

函数 SHBuild_CC_GetVersion

  尝试调用 "$CC" 指定的编译器以管道输入的程序取 C 编译器版本号。

  结果是以下之一:

  • 成功时:GCC 或 Clang 版本号的 X.Y.Z 转换为 X * 10000 + Y * 100 + Z 的数值的字符串。
  • 失败时:空。

已知缺陷 不支持无法取得 __GNUC_PATCHLEVEL__ 的旧版本 GCC 。 已知缺陷 不支持 Apple Clang 。

函数 SHBuild_CXX_GetVersion

  尝试调用 "$CXX" 指定的编译器以管道输入的程序取 C++ 编译器版本号。

  结果是以下之一:

  • 成功时:G++ 或 Clang++ 版本号的 X.Y.Z 转换为 X * 10000 + Y * 100 + Z 的数值的字符串。
  • 失败时:空。

已知缺陷 不支持无法取得 __GNUC_PATCHLEVEL__ 的旧版本 GCC 。 已知缺陷 不支持 Apple Clang 。

Tools/Scripts/SHBuild-self-host.sh

  SHBuild 自举测试用脚本。

  使用 SHBuild 编译并静态链接构建 SHBuild 。和 stage 1 SHBuild 类似,直接使用 YSLib 源文件。

Tools/Scripts/SHBuild-self-host-DLL.sh

  SHBuild 自举测试用脚本。

  使用 SHBuild 编译并动态链接构建 SHBuild 。依赖 /usr/lib 中存在的 YFramework 和 YBase 动态库文件。

Tools/Scripts/SHBuild-YSLib.sh

  作为 stage 1 SHBuild 公共配置脚本被不同的 stage 1 构建脚本包含。

  包含脚本依次执行:

注意 这个脚本包含 INC_SHBuild_YSLib 守卫变量检查,默认重复包含只被执行一次。

变量 SHBuild_PCH_stdinc_h

  预编译头文件名称,默认值为 "$S1_BuildDir/stdinc.h"

函数 SHBuild_S1_InitializePCH

  初始化 stage 1 使用的预编译头文件:即调用:

SHBuild_CheckPCH "$INCLUDE_PCH" "$SHBuild_PCH_stdinc_h"

Tools/Scripts/SHBuild-YSLib*.txt

  构建 YSLib 用的 NPLA1 脚本,包含以下文件:

  调用方式详见 stage 1 SHBuild 中关于 NPL 支持的说明

  可通过外部环境变量配置脚本行为。

版本控制系统支持

  脚本以相同的方式检查和识别版本控制系统。

  以下环境变量提示使用 Mercurial 或 Git :

  命令可用需要满足以下条件:

  • 被检查的命令应在 $PATH 中。
    • 若在 Windows 中使用 shell ,可能需要提前设置环境以确保继承环境变量。
    • 注意 MSYS2 提供的 mercurial 包的可执行文件是脚本而不是可执行文件,不被 NPLA1 脚本调用的 Windows 命令行支持。
    • 注释 不使用 HG 环境变量,因为可能设置为不被支持的 hg 程序路径。事实上,MSYS2 的包 mercurial 安装到 /etc/profile.d/mercurial.sh 设置 HG 为脚本,覆盖从其它位置继承的 hg.exe
  • 且当前工作目录求在对应的版本库中,同时确定仓库的顶层目录路径。
    • 对 Git ,要求存在工作区。

Tools/Scripts/SHBuild-YSLib-common.txt

  Tools/Scripts/SHBuild-YSLib-common.txt 包含一些公共的库,包括支持类似 Tools/Scripts/SHBuild-common-options.shTools/Scripts/SHBuild-common-toolchain.sh 的选项以环境变量的方式配置,但 C 编译器相关的选项除外(不使用而被忽略)。

  除关于 shell 脚本NPLA1 脚本之间的一般差异外,与 Tools/Scripts/SHBuild-common-options.shTools/Scripts/SHBuild-common-toolchain.sh 的不同为:

  • 通过调用函数进入构建环境变量检测并在之后进入回调函数中构建。
    • 按需初始化变量。构建环境变量检测可能延迟访问以避免不必要初始化的值。配置时为确定变量的默认值的检查的调用顺序可能不同。
    • 使用 debug 模式时,CXXFLAGS_OPT_DBG 设置为 -O0 -g -D_GLIBCXX_DEBUG_PEDANTIC ,不再被环境变量覆盖。
    • 生成变量默认值的选项之间的空白符可能不同(通常可确保为一个空格)。
    • 附加支持构建应用的配置,在导出的变量的默认值中添加扩展的选项(参见以下相关说明)替换 shell 脚本中指定的默认值(可影响其它默认值)。
    • 附加检查 sanitizer 。参见以下相关章节的说明。
  • 支持更多变量和默认值。
    • 除非另行指定,这些变量在构建环境变量检测中使用。参见以下各节。
    • 在构建动态库或应用程序时,使用空 C_CXXFLAGS_GC 值。
      • 原理 这些选项影响编译时代码生成,不总是优化的。对静态库,因为始终无法预测可能需要排除的定义,启用这些选项是合理的。否则,通常从源代码直接确保排除冗余定义更有效。
      • 注释 LDFLAGS_GC 的值仍被保持。对使用空的 C_CXXFLAGS_GC 值构建的目标文件这没有预期的作用,但对其它情形(典型地,静态库)仍然有效。
  • 提供部分和 shell 脚本不同的函数,详见版本库中的 doc/NPL.txt

  这个脚本被 Tools/Scripts/SHBuild-YSLib-build.txt 加载,并被 Tools/install-sysroot.sh 间接调用。

  以下公共构建配置变量影响脚本的特定行为:

  • SS_DebugEnv 的作用当前包括:
    • 对环境变量修改时输出修改的变量名和对应的值。
  • SS_Verbose 的作用当前包括:
    • LDFLAGS 变量中附加 -mwindows 时提示。
    • 在安装文件时输出安装类型、目标和源。

  脚本支持外部调用这个脚本的命令行设置变量的默认值,以覆盖直接指定构建环境变量检测确定的选项,如:

CXX=clang++ CXXFLAGS='-std=c++11 -O2' Tools/install-sysroot.sh

警告 使用预编译头选项和缺陷同 Tools/Scripts/SHBuild-build.sh 。其中的特性未指定使用 shell 实现,和后者可能存在 shell 环境中可见的差异。

  这个脚本是公开的工具,被安装脚本部署。

变量 LDFLAGS_DYN_BASE

  指定动态库基础链接选项。

  默认值和平台相关:若为 Win32 环境则使用 -shared -Wl,--dll ,否则为 -shared

变量 LDFLAGS_DYN_EXTRA

  指定动态库附加链接选项。

  默认值等价于 -Wl,--no-undefined,--dynamic-list-data,--dynamic-list-cpp-new,--dynamic-list-cpp-typeinfo

变量 LDFLAGS_DYN

  指定动态库链接选项。

  默认值为 $LDFLAGS_DYN_BASE $LDFLAGS_DYN_EXTRA

变量 LIBS_RPATH

  用于指定在运行时 ELF 映像需要的动态库的路径的链接器选项。

  在 Win32 默认不设置,其它平台默认值为 -Wl,-rpath,'\$ORIGIN:\$ORIGIN/../lib'

变量 LIBPFX

  库前缀。

  在 Win32 默认不设置,其它平台默认值为 lib

变量 DSOSFX

  动态库文件名后缀。

  在 Win32 默认值为 .dll ,其它平台默认值为 .so

变量 EXESFX

  可执行文件名后缀。

  在 Win32 默认值为 .exe ,其它平台默认不设置。

Sanitizer 检查支持

  构建环境变量检测支持 sanitizer :若在变量 CFLAGSCXXFLAGSLDFLAGSSHBuild_CXXFLAGS 中包含启用被支持的 sanitizer 的选项 (以 -fsanitizer=address 起始),配置最终在 CFLAGSCXXFLAGSLDFLAGS 最后添加自动调整的选项。

  构建配置支持 ASan、TSan、MSan、UBSan 和 LSan 。Sanitizer 自身支持的系统和编译器详见 sanitizer 的文档。

  ASan 使用的选项要求和建议参见 FAQ

注意 GCC 不支持 MSan 。MSan 要求标准库使用带 MSan 的选项构建,否则会有假阳性结果

注意 具体调整的选项参见脚本具体实现,不保持构建版本之间稳定。* 注意 构建脚本不保证构建的二进制程序的具体可用性。构建的程序可能因为程序及 sanitizer 实现的缺陷运行时出错,可能另需具体排查原因修复。

扩展选项的默认值

  变量 LDFLAGS 的默认值依次包含:

  • 和 shell 脚本中相同的默认值。
  • 生成可执行程序时且要求按需调整链接器参数时,附加的值:
    • 当需要生成 Win32 子系统程序时,附加 -mwindows
  • 构建动态可执行程序时,变量 LIBS_RPATH 的内容。
  • 构建动态库或应用时,变量 LDFLAGS_DYN 的内容。

SHBuild 附加构建选项环境变量

  若回调函数中调用 SHBuild 构建,可在此之前设置扩展环境变量并调用函数 SHBuild_Extend_CallVariables 以更新被 SHBuild 使用的环境变量 LDFLAGSLIBS 的值。这些影响 SHBuild 工具调用构建工具的命令行的 SHBuild 附加构建选项环境变量,包括:

  • SHBuild_CFLAGS
  • SHBuild_CXXFLAGS
  • SHBuild_LDFLAGS
  • SHBuild_LIBS

  除非另行指定,SHBuild 附加构建选项环境变量的默认值为空,不被脚本设置。

其它函数和可在外部设置的其它变量

  详见版本库中的 doc/NPL.txt

  其它变量不被构建环境变量检测访问,而通过函数调用生效,如 SHBuild_Extend_CallVariables

Tools/Scripts/SHBuild-YSLib-build.txt

  这个脚本当前包括和安装相关的流程,实现 Tools/install-sysroot.shstage 1 SHBuild 构建后的主要逻辑

  脚本支持在构建前自动从网络安装外部依赖项二进制归档文件以准备从源代码构建安装 YFramework 库。这仅在环境变量 YSLib_DistDir 被设置非空值时启用。这需要一些外部工具命令的支持:

  脚本使用 Tools/Scripts/SHBuild-YSLib-common.txt 中提供的一些函数。

  脚本支持以下外部扩展环境变量指定构建和部署目标:

  • SHBuild_UseDebug 非空时启用构建和安装 debug 配置的库。
  • SHBuild_UseRelease 非空时启用构建和安装 release 配置的库。
  • SHBuild_NoStatic 非空时跳过静态库构建。
  • SHBuild_NoDynamic 非空时跳过动态库构建。
  • SHBuild_No3rd 非空时跳过第三方库安装。
    • 外部依赖项中的库,只安装启用的配置决定的必要的外部依赖。启用的配置由 SHBuild_UseDebugSHBuild_UseRelease 指定。
  • SHBuild_NoDev 非空时跳过可选的开发工具构建和安装。
  • SHBuild_Rebuild_S1 非空时跳过文件存在性检查,总是重新构建 stage 1 SHBuild 。
  • SHBuild_NoDev 非空时跳过 stage 2 SHBuild 后的开发工具构建和安装。
  • YSLib_DistDir 非空时应指定包含一个绝对路径作为储存 YSLib 归档的目录。

  以下公共构建配置变量影响脚本的特定行为:

  • 所有调用 Tools/Scripts/SHBuild-YSLib-common.txt 而生效的公共构建配置变量在此作用相同。
  • SS_DirectExtract 的作用包括:
    • 安装下载的归档时,直接用工具命令行覆盖对应位置的文件,而不先解压缩释放到临时目录后再更新。
  • SS_Offline 的作用包括:
    • 不检查下载工具命令的可用性。
    • 不使用网络下载资源。

  以下构建时的中间变量可被外部配置,当外部没有配置或为空值时使用默认值:

  • SHBuild_SystemPrefix :系统前缀,在 Sysroot 根路径下决定安装路径。
    • 默认值由脚本 Tools/Scripts/SHBuild-YSLib-common.txt 中的函数的调用确定:同 SHBuild_GetSystemPrefix (SHBuild_Platform_Detect SHBuild_Host_OS SHBuild_Host_Arch) 的结果。
    • 脚本 Tools/Scripts/SHBuild-common.sh 中提供 shell 脚本的等价调用:$(SHBuild_GetSystemPrefix (SHBuild_Platform_Detect "$SHBuild_Host_OS" "$SHBuild_Host_Arch"))
  • SHBuild_YF_Libs_freetype :freetype 库链接参数。
    • 默认值为 -lfreetypepkg-config --libs freetype2 的输出结果。
      • 其中存在 Sysroot libfreetype.a 时默认值为前者。
  • SHBuild_YF_Libs_FreeImage :FreeImage 库链接参数。
    • 默认值为 -lFreeImaged-lFreeImage ,对应 debug 和非 debug 配置。

  这个脚本也可能使用其它变量用于传递参数给被调用的命令,包括一些 SHBuild 预期的变量;后者作为公开接口,但其具体含义和使用不保证在不同版本间稳定

  在自举构建 stage 2 SHBuild 前构建安装 YFramework 库时,接受以下环境变量:

  • INCLUDES_freetype 指定覆盖包含路径的编译器命令行选项。
    • 默认值以 -I 起始,使用版本库目录下的 3rdparty/freetype/include 目录带有适当引号的完整路径。
  • 环境变量 SHBuild_VCS_hgSHBuild_VCS_git 指定构建时的版本控制系统,作用参见以下说明。

  在 stage 2 环境中构建其它目标时接受以下外部环境变量(部分被 SHBuild 直接以环境变量的方式接受):

  • INCLUDES :包含路径,和非 SHBuild 中的 Makefile 惯用法含义类似。
  • LDFLAGS :链接命令行选项。
  • LIBS :作为命令行选项的链接时使用的库路径。
  • LIBS_RPATH :非 Windows 平台使用的 rpath 路径。
  • SHBuild 附加构建选项环境变量:参见 Tools/Scripts/SHBuild-YSLib-common.txt 。其中变量 SHBuild_CXXFLAGS 同时作用在预编译头构建。

版本字符串

  在 stage 1 构建 YFramework 前,通过选择的版本控制系统指定确定版本字符串,可在被构建的 YFramework 库中引用。

  确定版本字符串时,检查对应的命令,具体方式详见关于版本控制系统支持的描述。若检查都失败,则版本字符串为空串。否则,使用第一个检查成功的命令生成对应的版本字符串。

已知限制 若使用 git 生成版本字符串,当前同时依赖 sed 命令。

  若版本字符串非空,则通过宏定义的方式参与之后的构建。当前影响以下源文件所在的翻译单元:

  • YFramework/source/YSLib/Core/YCoreUtilities.cpp

  在构建前,若被影响的上述翻译单元已被构建,在生成目录中对应的(以 .d 为扩展名的)依赖文件被修改,以添加对版本控制系统中的特定文件的依赖。这能使最新的版本控制系统的修改影响生成的目标代码,而无需手动修改这些翻译单元的源文件。

已知限制 当前自动更新依赖的实现同时依赖 sed -i 命令。

Tools/Scripts/SHBuild-BuildApp.txt

  NPLA1 应用程序构建脚本。可利用此工具脚本调用 SHBuild 构建特定配置(configuration) 下使用 YSLib 库和基础环境开发的应用程序。

  这个脚本是公开的工具,被安装脚本部署。

基本原理

  配置是特定用途的一组程序输出的集合。常见软件配置可以区分目标平台,是否为调试配置等。

  脚本通过设置特定的环境变量并调用 SHBuild 递归扫描指定目录完成构建。其中调用命令由环境变量 SHBuild 指定。若变量 SHBuild 为空,则假定使用脚本程序在 Sysroot 中,由 Sysroot 的布局确定的 SHBuild 的位置作为变量 SHBuild 的默认值。

  脚本支持区分 debug 和非 debug 配置以及静态和 DLL 配置。详见以下说明。

  debug 配置总称 debug 模式。非 debug 配置总称 release 模式。

调用方式

  无参数调用时,显示帮助文本。以第一参数指定配置名称,执行脚本直接一次性配置后构建。之后可选的其它参数被脚本传递给 SHBuild ,详见以下的操作说明。

使用须知

  脚本依赖 Sysroot 。

  这个脚本被 Tools/Scripts/SHBuild-BuildPkg.sh 调用。

  当前只支持构建,不支持部署。

  构建时调用的工具链命令行及配置详见 Tools/Scripts/SHBuild-YSLib-common.txt 的说明。

  需要先确保源代码可访问。注意源代码目录会被递归扫描,建议在目录中只包含所有需要构建的源文件或被包含的文件。

操作说明

  一般步骤:

  • 新建一个 GNU bash 脚本(以下称为用户构建脚本 ),调用此脚本(若无法在 PATH 找到,需要使用完整路径)。
  • 以源代码所在目录的路径作为参数,执行通过此脚本包含的 SHBuild_BuildApp 函数,等待构建完成。
  • 直接包含后的脚本仍可使用无参数调用用户构建脚本查看选项和说明。

  简化操作:也可以不创建用户构建脚本,直接在命令行中执行,例子见入门

  若有必要,在调用本脚本之前设置 SHBuild_BuildDir 变量为指定输出文件所在的目录的完整路径,如:

export SHBuild_BuildDir=$(dirname "$0"`/../build)

  上述命令行指定相对于用户构建脚本上一层目录的 build 子目录下作为基准输出路径。若不显式设置此变量,工具脚本会指定其默认值为用户构建脚本所在的目录。

  调用本脚本。脚本会自动加入必要的参数调用 SHBuild ,传递的参数依次具体如下:

  • 中间变量 SHBOPT 的值,包括根据配置决定的目录设置选项、-xid,include -xmode,2 以及用户在脚本命令行指定的剩余选项 SHBOPT_BASE
  • 传递给本脚本的配置名称以外的可选参数。
  • SHBuild_BuildApp 的值,用于编译器的库配置(包含路径以及使用 DLL 需要的宏定义 -DYF_DLL -DYB_DLL ),由脚本根据静态或动态库配置自动确定,无需重复输入类似选项。

特别注意 脚本执行以输出基准路径作为当前工作目录,需要以此为基准指定源文件路径( SHBuild 使用的 SRCPATH 参数)。

  通过脚本命令行间接传递给 SHBuild 的参数 SHBOPT_BASE 以及函数 SHBuild_BuildApp 的参数都可以进一步对构建过程进行调整,如 -xj,2 指定 2 个并行线程构建。

注意 以 SHBuild 作为 NPLA1 脚本解释器时,传递的参数可能会被 SHBuild 截获,而不被继续传递给 脚本中调用的 SHBuild 。为避免这种情形,在 -xcmd,RunNPLFile 和本的脚本文件名选项后,可加上 -- 分隔其余命令行参数。

配置设置

  传递给 SHBuild 指定使用 .配置名称 相对路径(无需另外指定 -xd, 参数)。如 -cdebug 指定输出路径为 .debug 。省略此项默认配置名为 shbuild

  脚本根据以下规则自动检测配置:

  • 若配置名称以 debug 起始,或环境变量的 SHBuild_Debug 值非空,则视为使用 debug 配置。
  • 若配置名称以 static 结束,活环境变量 SHBuild_Static 的值非空,则视为使用 static 配置。

环境变量

  环境变量 SHBuild_DebugSHBuild_Static 可按上述自动检测配置过程指定配置类型。

  默认情况下,release 配置会在链接器命令行加入 -mwindows和 debug 配置编译的程序行为不保证相同。设置非空变量 SHBuild_NoAdjustSubsystem 禁用此行为。

  脚本使用包含 YSLib 库的编译器命令行。脚本已经导出了用于链接器的包含使用 YSLib 库命令行参数的变量 LDFLAGSLIBS 。若有必要,可设置 SHBuild 附加构建选项环境变量(参见 Tools/Scripts/SHBuild-YSLib-common.txt )。