先决条件

  本文档列出受支持的构建配置的关联的先决条件,以及这些环境下的已知问题和相关应对。

注释 构建配置和平台的相关定义详见术语。对问题的描述可能仅适用于个别的配置和源代码版本。仅需要配置构建环境的用户可以跳过关于非目标平台和不相关的问题的内容。

  特定历史版本依赖的详细环境和平台库版本参见开发文档 doc/Dependencies.txt 。以下仅为当前最新主分支版本中用于构建 YSLib 自身及基于 YSLib 开发应用的环境配置说明。

  关于本项目对平台的定义和项目保持的环境约束,包括开发需要的以下基础环境外的其它第三方依赖,在了解下文内容后,参见开发说明

注意 获取到源代码并不保证能够直接构建 YSLib(特别是对于直接从版本库获取的途径)。如需自行构建,应注意开发说明中有关外部依赖项的部分获取必要的其它文件。

  关于运行环境,另见运行时平台环境的说明

  详细提交测试的环境参见开发文档 doc/Test.txt

  若不使用特定的特性或构建平台,构建环境的部分要求是可选的。

  以下各节的环境配置以“宿主平台/目标平台(目标平台名)”为标题指定,其中目标平台名是正式的配置名称(也在其它项目文档中作为配置名称使用),若和平台一致则被省略;其它平台的标识当前仅为明确开发流程,在用户文档中使用。对宿主平台和目标平台两者一致的情形,只标识一个平台。关于“平台”的一般含义,参见术语

公共构建环境

  构建环境提供工具链(语言实现)和构建需要的工具。某些工具被不同的构建环境共享(但可能仍需针对不同构建平台使用不同二进制程序)。

  Windows 平台上的 MSYS2 基础环境符合以下公共构建环境的所有要求。当前发布和一般提交(包括本机平台和交叉构建)时仅测试 MSYS2 。

命令行环境

  除非另行指定,构建环境的命令兼容 POSIX shell 。当前非 POSIX shell 的命令行构建环境仅在 Sysroot stage 2 环境 被支持。

工具链

  使用 make 的平台需要 POSIX shell 支持。

  除非另行指定,make 使用 GNU make ,版本 3.78 以上(建议使用 4.0 以上版本,虽然 YSLib makefile 不使用不兼容的特性);不使用 mingw32-make

  注意 make 可能被构建工具使用,详见以下链接时优化的说明。

  POSIX shell 实现可使用和工具脚本兼容的脚本解释环境 ,一般即 bash (建议版本 4.0 或以上)。

  除非另行指定,直接支持的 C++ 实现为 GNU C++ 4.9 或以上版本。

自动环境检测

  在命令行环境中使用脚本构建时,脚本可能自动检测构建环境而需要附加的工具。这些工具可能在具体的构建环境(如以下各节)中可能已被提供或可选安装,参阅各个构建环境附带的文档。

  • grep :用于判断线程支持的命令行选项。
  • uname :用于查询平台配置。

  使用特定的选项跳过自动检测构建时,可不依赖某些工具。详见具体脚本的说明。

控制台和终端

  除了自动检测环境( Win32 或非 Win32 下使用 ANSI 转义序列)开启的彩色(前景色)文本,构建环境没有使用依赖特定终端的字符界面。因此可以使用不同的控制台或终端模拟器。

注意 在 Windows 平台上若使用 ConEmu 出现 0xC0000005 错误,尝试升级到最新版本后勾选 Inject ConEmuHk 选项 ,或直接使用 cmd 代替。

线程执行环境

  除非另行指定,线程执行环境使用 ISO C++ 的定义,参见 ISO C++ [intro.multithread]

  库或接口的集合对多线程环境的依赖性满足以下要求:

  • 明确不依赖多线程执行环境时,保证在指定平台上可用的的公开 API 可构建并满足接口约定的语义,可在单线程执行环境中运行。
  • 明确严格不依赖多线程执行环境时,在不依赖多线程执行环境的要求上,还应保证语义一致。
  • 否则,不保证接口提供的功能可用。

  YSLib 整体不依赖多线程执行环境。特定的依赖多线程执行的情形包括以下话题:

  • 使用 ISO C++ 线程环境(首先要求实现满足整体要求):
    • 运行时环境需要部署的线程支持库,参见以下章节对各个平台的说明。
    • 特定的依赖线程环境语义的接口,参见具体组件的开发文档(如 doc/YSLib.txt )及源代码中的 API 注释或以此构建 API 文档
  • 特定的平台实现使用非 ISO C++ 线程模型或实现(不保证平台中立):
    • 不会作为对所有平台必要的公开接口。
    • YCLib 提供 POSIX API 封装。
    • 其它实现细节参见开发文档 doc/YCLib.txt 等。

链接时优化(LTO)

  YSLib 默认在 release 构建配置下通过向编译器和链接器传递命令行参数 -flto 等启用 LTO 。若工具链不支持 LTO ,可能需要自行修改脚本去除相关选项——这不被正式支持。

  MSYS2 的 MinGW 目标的 binutils-git 包的 gnu-ar 较早启用了 LTO 插件,可以直接使用。现在 MSYS2 的 MinGW 目标的 binutils 包也应支持。其它工具链需自行验证。

注意 GCC 4.9 起使用 LTO 默认不启用 -ffat-lto-objects 选项,因此需要链接器具有 LTO 插件支持,否则在启用 -flto 选项时会出现无法解析符号的链接错误。因为本项目当前只支持 GCC 5.0 以上的版本,使用 GCC 时这总是应当被注意。

注意 GCC 的 LTO wrapper 默认使用 make ,若没有 make 也没有通过指定 MAKE 环境变量替代,构建时使用 -flto 会失败。

PC/DS(DS)

  支持的构建环境:

  • DS 交叉编译环境,包括
    • 使用 make 的公共构建环境
    • ARM 目标平台 C/C++ 交叉编译环境
    • 生成 .nds 文件的 ndstool 工具
    • 环境变量 DEVKITARM 指定工具路径(见以下说明)

  支持的运行环境:

  • Nintendo/iQue DS[Lite/i/LL]
    • 仅测试了 iQue DS Lite
  • DeSmuME 0.9.9 (注意新版本因为自动 DLDI 存在缺陷,暂时不支持运行自制程序。)

  环境变量 DEVKITARM 指定一个 POSIX 路径,其中的 bin 子目录下包括工具。示例( POSIX shell 使用 Windows 路径):

export DEVKITARM=/C/devkitPro/devkitARM

  建议使用发布时最新版本的 devkitPro

  devkitPro 在 Windows 下提供 MSYS ,在 devkitPro 安装目录下 msys/bin 包含 bash 等程序。可把此路径添加到环境变量 PATH 。也可使用 MSYS2 替代。

  发布和一般提交时仅测试 devkitPro 最新版本,目标平台三元组 arm-none-eabi。

PC(Win32)

  Windows 平台使用 Microsoft VC++ 构建。因为一些已知的问题,暂不正式支持。参见以下 MinGW32 平台的构建条件以获取 Windows 可执行文件。

  但以下的部分信息和 MinGW 通用。

Windows 子系统

  Windows NT 内核以上支持不同的称为子系统(subsystem) 的用户模式运行时环境 ,主要包括 Win32 子系统、OS/2 子系统和 POSIX 子系统。

  因为标准库实现以及 YFramework 的部分组件依赖 Win32 API ,YSLib 在 Windows 上的实现依赖 Win32 子系统。

  Microsoft Visual C++ 提供 /SUBSYSTEM 链接器选项来指定不同的子系统。在此 CONSOLE 指定控制台程序,而 WINDOWS 指定非控制台的通常使用 GUI 的程序,它们都使用 Win32 子系统实现。

  控制台程序和 GUI 程序的入口不同,也有一些行为上的不同。例如,启动控制台程序默认会显示命令行窗口;GUI 程序忽略命令行的交互式输入。

操作系统版本

  Windows 操作系统版本一般对(非交叉编译的)构建没有直接影响,但有以下例外:

  GCC 的预编译头文件不保证对系统兼容:升级系统后可能出现错误,例如升级 Windows 10 1803 以后的系统,使用旧的预编译头文件(而不更改编译器二进制文件),可能出现以下内部错误:

internal error in mingw32_gt_pch_use_address, at config/i386/host-mingw32.c:184: MapViewOfFileEx: 试图访问无效的地址。

  此时删除所有预编译头文件,或不使用预编译头文件重新构建即可。类似的问题在其它的项目中也是已知的问题,使用类似的方式解决。

  另外,部分 Windows 版本可能存在不明原因的内核缺陷导致类似的问题。不仅限于构建,这些问题可能对运行也有影响。

  硬件故障(如有缺陷的物理内存)也可能导致类似的故障,但这和使用的操作系统版本无关。

预编译头文件

  部分构建使用可选的预编译头文件。

PC(MinGW32)

  MinGW32 包含 32 位和 64 位宿主和目标平台。关于 MinGW 或 MinGW32 的称谓,参见这里的说明。

  支持的构建环境:

  • 目标 32 位(i686) MinGW GCC 工具链。
    • 支持不同的 MinGW 运行时
    • 要求标准库多线程支持,否则只支持构建 YBase ,不支持构建 YFramework 。
      • 当前 GCC 官方的 libstdc++ 只提供 POSIX 线程模型的支持,不支持 Win32 线程模型。
      • 可考虑使用 mcfgthread
    • 仅测试 Windows 上的本机构建(构建平台三元组同目标平台三元组)。
      • 一般提交时仅测试 MinGW-W64 的发行版。

  非正式支持的构建环境:

  • 目标 64 位(x86_64) MinGW GCC 本机工具链(宿主和目标平台三元组 x86_64-w64-mingw32 或 x86_64-pc-mingw32 )。
  • 以上工具链中使用 LLVM 和 Clang++ 代替 GCC 。
    • 仅测试 MSYS2 的 MSYSTEMMINGW32MINGW64 替换 GCC 。
    • 虽然可支持,没有测试 MSYSTEMCLANG32CLANG64 的工具链。
    • 当前 32 位平台暂不支持 LLD( MSYS2 包 mingw32/mingw-w64-i686-lld )。
  • 虽然可支持,没有测试 MSYSTEMUCRT64 的工具链。
  • 暂不在配置脚本以外支持和测试 MSYSTEMCLANGARM64 的工具链(宿主平台三元组 aarch64-w64-mingw32 )。

  对 i686 平台,存储库中 YFramework/MinGW32/lib-i686 目录用于保存外部依赖项 FreeType2 和修改版 FreeImage 的二进制文件。

  对 x86_64 平台,需要自行编译依赖项。若构建环境存在可二进制兼容的 FreeType2 ,只需要编译修改版本的 FreeImage 。

  支持的运行环境:

  • Microsoft Windows XP 或以上版本的操作系统。
    • 对于 64 位目标工具链构建的程序,需要 64 位操作系统。
    • 当前默认发行的二进制文件使用 MSYS2 环境(详见以下小节)构建,要求 Microsoft Windows 7 64 位或以上版本的操作系统。
  • 构建环境匹配的附加运行库,默认支持的工具链要求包括以下动态库文件:
    • libwinpthread-1.dll
    • libgcc_s_dw2-1.dll
    • libstdc++-6.dll
    • libquadmath-0.dll(自 build 932 起)

  注意以上运行库未在发布版本中打包。此处依赖的详细说明参见开发文档 doc/Dependencies.txt @1.5.2 。

  若缺少 DLL ,也可在 MinGW32 GCC 发行版中的 bin 目录下找到。

特别注意 应使用对应的正确的线程模型(使用 POSIX 或 MCF 而不是 Win32 ,后者没有实现标准库的线程支持)以及异常模型( i686 为 Dwarf2 和 SjLj 之一,特定构建版本相关)。运行时 DLL 不匹配会导致错误。

MSYS2

  建议使用 MSYS2 环境。

  MSYS2 以从 Arch Linux 移植的 pacman 作为包管理器,可以直接通过命令行安装和移除不同的包,包括开发工具。

  以下环境也可用于开发其它 MSYS2 或 MinGW32 应用(忽略标注为 YSLib 的步骤即可)。

体系结构和命令行调用

  一个 MSYS2 环境同时支持 MSYS2 和 i686(x86) 和 x86_64(x64) 的 MinGW32 三个目标平台。其中 MSYS2 目标类似 Cygwin ,运行时依赖特定的 POSIX 兼容层 DLL (这里一般是 msys-2.0.dll ),性能往往较依赖 MSVCRT (默认版本现在 Windows 系统中应都已存在部署)的 MinGW32 目标低。所以不需要严格的 POSIX 兼容的应用尽量使用 MinGW 而不是 MSYS2 目标。

  MSYS2 自身也存在不同的体系结构而成为目标平台。和 MinGW32 不同,每个基础环境是 i686 和 x86_64 之一。在 x64 Windows 上,可以通过部署多个基础环境,合理设置环境变量 PATH 来切换使用 i686 或 x86_64 (而 32 位 Windows 只支持 i686 )路径;但一般情形下只需要使用其中之一。这个决定一般会作用到所有 MSYS2 程序,如 bash

  不论是 i686 还是 x86_64 的 MSYS2 基础环境,都可以选择安装 i686 或 x86_64 的 MinGW32 目标的包,但因为使用不同的 MSYS2 程序,两者并非可完全替换。

注意 因为基础环境中 uname 是位于 /usr/bin 的 MSYS2 程序,基础环境的体系结构会影响 uname 的结果而导致目标体系结构的自动判断结果不同,当前可能会影响后续需要的命令,详见 MinGW Sysroot 开发指令

注意 MSYS2 程序和不同体系结构的(本机或其它 MSYS2 )程序混用可能出现问题。参见下文关于 MSYS2 程序运行问题的说明。

  一个 MSYS2 环境中可能同时存在不同目标的程序,通过合理控制环境变量 PATH 的顺序或在调用时加前缀(prefix) 控制。例如 /usr/bin/gcc.exe/mingw32/bin/gcc.exe 可能同时存在,分别是 MSYS2 和 i686 MinGW32 的 GCC ,可通过以下方式确定调用 MinGW32 GCC :

  • PATH 中使 /mingw32/bin 尽量靠前来指定 gcc 调用 MinGW32 而不是 MSYS2 GCC
  • 若存在 i686-w64-mingw32-gcc 等明确目标平台的版本,一般可以直接在命令行中代替 gcc
  • 明确路径前缀,即使用 /mingw32/bin/gcc 代替 gcc

  某些工具可能在附加路径前缀 /mingw32 指定此类程序的安装位置。但当前 YSLib 不提供工具控制这些部署方式,默认只使用第一种方式:手动配置 PATH

  MSYS2 MinGW 工具链使用 POSIX 线程模型。

  MSYS2 MinGW i686 工具链使用 Dwarf2 异常模型。

  当前 YSLib 不支持 MSYS 目标。

主要配置步骤

  (某些步骤和原理也可参考官方 Wiki 。)

  • 进入官方发布站点/北京理工大学镜像/清华大学 TUNA 镜像/中国科学技术大学开源软件镜像的其中一个子目录下载 MSYS2 基础环境:
    • 目录 i686x86_64 针对 MSYS2 而非 MinGW32 目标。
    • 一般尽量选择较新的 x86_64 版本。
    • 如果有能解压缩 .xz 的软件,可以直接下载压缩包,否则选择 .exe 文件;对应版本内容一致。
  • 安装 MSYS2 基础环境到自定义的目录如 C:\msys2 (以下称为MSYS2 根目录)。
    • 注意 Win32 下 PATH_MAX260 ,此处最好避免过长的路径以使一些软件具有更好的兼容性。
    • 对压缩包直接利用现有工具解压;对可执行文件直接执行安装。
    • 之后,必须执行 MSYS2 根目录下的 msys2_shell.bat 确保完成安装。
  • 设置环境变量:
    • 可总是使用 MSYS2 根目录下自带的批处理文件打开 终端(默认是 mintty ),会自动在终端环境的 PATH 变量前加入对应所需的路径,不需要另行设置。
      • 对较新的版本(安装了 filesystem-2016.05-2 或更新版本的包)的 MSYS2 基础环境安装,分别运行启动脚本 msys2_shell.cmd -msysmsys2_shell.cmd -mingw32mingw64_shell.cmd -mingw64 进入对应的 MSYS2 、MinGW32 和 MinGW64 的 shell 。
      • 对未更新 filesystem-2016.05-2 或更新版本的包的 MSYS2 旧版本基础环境安装,分别运行启动脚本 msys2_shell.cmdmingw32_shell.batmingw64_shell.bat 进入对应的 MSYS2 、MinGW32 和 MinGW64 的 shell 。
    • 也可直接一次性设置 Windows 系统环境变量,这样可以对其它命令行环境(如 cmd )生效。
      • 注意 环境变量的值需要符合 Windows 的路径格式,每个路径之间以分号分隔。
      • 需要设置 bash 所在的 MSYS 工具的目录(即 MSYS2 根目录下的 /usr/bin )以及 MinGW 目标编译器和其它工具所在的目录(对 32 位的目标为 MSYS2 根目录下的 /mingw32/bin )。
      • 注意 因为 MSYS 和 MinGW 是不同的目标,使用不同的 GCC (可能被同时安装),需要保证 MinGW 编译器被优先搜索,所以 MinGW 目录一般应在 MSYS 目录之前。
    • 一些构建环境可能会依赖环境变量 MSYSTEM 的值,MSYS2 根目录批处理文件进入的不同环境对此有不同的设置。YSLib 中的构建脚本可使用此变量判断平台。MSYS2 中对应的启动脚本会自动完成这些设置。
  • 确保能搜索到正确的 MinGW 编译器。
    • 可以进入 Shell 执行命令 type -P gcc ,确定输出的结果为 MinGW 编译器(默认为 /mingw32/bin/gcc.exe/mingw64/bin/gcc.exe 之一)而不是 MSYS 编译器(默认为 /usr/bin/gcc.exe
    • 若已确保 MSYS 根目录下 /usr/bin 目录在环境变量 PATH 中,直接进入 cmd 或 Shell 直接执行 which gcc ,方法和效果与上述方法相同
    • 可以直接在命令行执行 gcc -v 查看输出,确认 Target: 带有后缀 -w64-mingw32
  • 建议手动执行 pacman -Syu 自行升级,或 pacman -S 安装所需的包的最新版本
  • 若用于构建 YSLib ,建议获取源代码后,进入 bash (此处也可以使用其它 Shell )后运行 POSIX Shell 脚本 Tools/msys2-pacman-update.sh 以确保 YSLib 构建需要的依赖项被安装
    • 脚本不会重复安装已经安装的包

  上述脚本调用 MSYS2 的包管理器 pacman 分批下载安装或更新所需工具:首先安装必要的工具,其次安装可选(但推荐)的工具。具体内容详见脚本代码。若安装工具时需要确认,按 Y 并回车。

配置安装源

  官方镜像配置参见 pacman-mirrors

  若 pacman 下载过慢,可用文本编辑器打开 MSYS 根目录下的 /etc/pacman.d 中的配置文件,编辑对应的镜像地址。如对于 32 位的 MinGW 包,在 mirrorlist.mingw32 的其它非注释行之前插入:

## 清华大学 TUNA 镜像( 2016-09-23 已变更,注意大小写)
Server = http://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/i686
## 中国科学技术大学开源软件镜像(之前曾停止更新,最后更新 2015-06-18 ;2015-11-01 已恢复)
Server = http://mirrors.ustc.edu.cn/msys2/mingw/i686
## 北京理工大学镜像(最后更新早于 2017-02-09)
Server = http://mirror.bit.edu.cn/msys2/REPOS/MINGW/i686

  因为包 mingw-w64-x86_64-freetype 的 FreeType2 可二进制兼容,x86_64 平台只需要编译修改版本的 FreeImage 。

MSYS2 程序运行问题

  MSYS2 类似 Cygwin ,依赖 fork 调用创建新进程。这可能会出错。

  在执行以下步骤(参考这里)后,重新运行程序:

  • 关闭窗口或用任务管理器终止 sh.exebash.exe 等进程并尽量确保没有基于 MSYS2 环境的其它程序正在被运行
  • 执行 MSYS 根目录下的 autorebase.bat

  也可以参考 Cygwin 的解决方法

  混用 x86/x64 程序(不管是 Win32 还是 MSYS 程序)导致的类似问题可能经以上步骤仍然无法修复,这可由 MSYS2 在特定操作系统上的一个缺陷引起。变通做法是只使用固定目标的程序,例如只使用 i686 MSYS 基础系统执行 i686 MinGW32 GCC 。注意 i686 MinGW32 GCC 是 x86 的 Win32 程序。尽管它不是 MSYS2 程序,但可在 LTO 时调用 MSYS2 程序 make ,这时候可能出错。

  如果确定只使用少数程序,在命令行指定替换。例如 x86_64 的 MSYS2 bash 环境中使用 i686 MinGW32 GCC ,指定 LTO 调用的 make

export MAKE=/path-to-another-msys2-root/mingw32/make

  或直接替换所有 make

export make=/path-to-another-msys2-root/mingw32/make

注意 %SystemRoot%\System32\cmd.exe 在 x64 Windows 下是 x64 程序,对应的 x86 版本是 %SystemRoot%\SysWOW64\cmd.exe

GCC with the MCF thread model

  也可使用 MCF 线程模型构建的 GCC ,基于 MinGW-W64 和 mcfgthread ,使用 MCF 线程模型。

  这个发行版没有 make

  需自行编译依赖项。

  未在提交中测试。

MinGW-Builds

  也可使用 MinGW-W64 发行版,如 mingw-builds ,并自行获得和配置脚本 Tools/msys2-pacman-update.sh 中被安装的工具。

  需使用基于 POSIX 线程模型的版本,否则只可用 YBase 。

  需自行编译依赖项。

  当前未测试。

Nuwen.net

  对 x86_64 平台可使用 newen.net 提供的 MinGW 发行版,包含比较多的第三方库。

  仍需自行编译依赖项以支持 YFramework (当前不支持)。

  因为 15.2 之前的版本仅支持 Win32 线程模型,不支持 std::thread 等标准库线程 API ,不支持生成 YFramework ,只支持生成 YBase 。

  当前未测试。

Windows 子系统

  基本内容参见以上 PC(Win32) 平台关于 Windows 子系统的介绍。

  在 MinGW 工具链的命令行中,选项 -mconsole-mwindows 对应 Microsoft VC++ 工具链的子系统选项。若没有指定,一般默认为前者。通常 -mwindows 隐式使用一些附加的库,如 -lgdi32 -lcomdlg32 。和 VC++ 不同,当前使用的 MinGW 实现一般可以支持统一使用 main 作为入口,不需要特别修改。

  对 gccg++ ,使用 -dumpspecs 查看内建支持的 specs 。Clang/Clang++ 不适用 specs ,需要查看文档和源代码。

PC/Android

  支持的构建环境:

  • Android 开发环境(仅测试 Windows x64 宿主环境),包括:
    • 使用 make 的公共构建环境。
    • JDK(仅测试 Oracle JDK 1.8 ;注意 Android 仅支持部分 Java 8 特性)。
    • Android SDK 。
    • Android SDK Build-tools 。
    • Android NDK (仅使用独立工具链)。
    • 用于打包 APK 的私钥(用 Tools/create-android-debug-keystore.sh 可生成默认私钥)。

  支持的运行环境:

  • Android 模拟器,运行操作系统 Android 5 (对应 API level 21 ),或更高版本(未测试,可能有兼容性问题)。
  • 物理设备,操作系统要求同上(未正式测试,可能有兼容性问题)。

PC/Linux

  当前仅用于可移植性测试。要点:

  • 当前仅测试 x86-64 (提供 FreeImage 二进制文件)
  • 可用被支持版本的 G++ 或 Clang++
  • 因为不提供 freetype2 的二进制库,需要保证 freetype2 库文件可用,可以通过 pkg-source 找到或位于 /usr/lib 路径中
  • 使用 XCB 作为系统库,但功能不全

  Windows 10 可使用 WSL(Windows Subsystem for Linux)

  注意 Windows 10 秋季创意者更新(版本 1709 )的 WSL 存在已知可导致并行构建失败的缺陷 ,以及可能有的其它问题 ,本项目不针对这些问题单独提供变通。

其它构建环境

  集成开发环境是可选的,参见构建

  关于文档构建需要的依赖,参见构建文档

  关于执行工具脚本需要的环境,参见脚本