English Version

简体中文版

Contents(zh-CN)/主题目录

Copyright of this wiki

© 2013-2020 FrankHB and wiki editors.

Except where otherwise specified explicitly, materials in this repository are licensed under following terms:

http://creativecommons.org/licenses/by-sa/4.0/

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

About

The YSLib Project is a project of platform-neutral framework consists of several multi-licensed open source libraries. It is aiming to develop native applications in a naturally cross-platform manner.

See LICENSE.TXT in the source directory for licensing affairs.

The main part (except libraries not being maintained in this project) of the libraries is coded in C++, which is strictly conforming to ISO/IEC 14882. (For features being used, see here. For some issues concerned with this project, see here.)

The project is currently in Alpha state(zh-CN) with following interface compatibility strategies:

  • ABI compatibility for any revision depending on specific platform, toolchain or build configuration is never guaranteed.
  • ABI compatibility may not be retained between releases with same platform, toolchain and build configuration.
  • API of libraries may be modified locally and there is no guarantee for compatibility between releases.
  • UI of tools (see contents(zh-CN) for the list) may be modified progressively across builds; unless specified elsewhere, added features are kept being backward compatible within at least one next releases.

See here(zh-CN) for basic steps to use YSLib in development.

See here(zh-CN) for releases and plans.

Currently supported platforms

  • (Nintendo/iQue) DS (arm-none-eabi)
  • MinGW32 (i686-w64-mingw32, compatible with i686-pc-mingw32)

Pending supported platform

  • Android (arm-linux-androideabi)
  • MinGW64 (x86_64-w64-mingw32)
  • Linux32 (i686-linux-gnu)
  • Linux64 (x86_64-linux-gnu)

Documentation

Documentation in the YSLib project

Documentation in the YSLib project consist of several parts:

  • The development documentation which is intended for the project maintainers, see development(zh-CN).
    • The document in /doc/vsd can be viewed by Microsoft Office Visio or Microsoft Visual Studio 2013.
  • Souce code documentation, which can be generated using Doxygen, see building documentation(zh-CN).
    • Currently the Doxygen commands in the source code are mainly coded in simplified Chinese. It is planned to utilize Doxygen's ~[LanguageId] command to generate multilingual documents in future. All other comments, however, should be in English by default.
  • Other non-generated documents are text files in the repository, like Readme.zh-CN.txt.

About this wiki

This wiki is a project related to the YSLib project. They are currently the only two members in the same project group, each has separated repository. Common documentation for the project group, general user documentation and list of significant features for the YSLib project are dominated by this wiki. Documentation in the YSLib project is mainly for maintainers of the project. They are bidirectionally referenced, namely the content of this wiki may be refenenced in the YSLib project and vice versa.

Unless otherwise specified, the content of this wiki is fit for the current last master branch revision (i.e. the revision tip of master branch in the repository).

See here for rules to edit this wiki.

It is intended to reference every pages of this wiki in this page.

Contributions

Contributions to the projects are welcomed. Provided materials thereby shall be adjusted by contributors (and the project maintainer) to conform the license of the corresponding projects if necessary.

Rules in this wiki are treated as consensus. Rules in project documentation have effect on maintainers but not other contributors. However, the contents in the projects shall always be conforming to the project rules.

To feedback or report issues, use Bitbucket issue tracker, or contact the project maintainer as noted below.

Rules for project contents

The following philosophy are generally accommodated throughout the projects.

  • Do not reinvent the wheel. Projects here only accepts modular components which would be better elsewhere. Here "better" is defined as "superior than current solution in at least one aspect for consensually known need".

    • See the notes in features(zh-CN) for the list of invented wheels and the rationale.
  • Decline premature optimization. However, what is "premature" is determined by the need, which would be probably variable.

Contacts

概要

  YSLib 项目是一个提供多个开源库组成的平台中立框架的项目,主要致力于以自然的方式开发跨平台本机应用。

  使用的许可证见源代码目录中的 LICENSE.TXT 。

  主要部分(非此项目维护的库除外)使用 C++ 编码,严格符合 ISO/IEC 14882 。(使用的 ISO 特性参见这里(en-US) 。和本项目相关的被报告的问题见这里(en-US) 。)

  项目当前为 Alpha 状态,具有以下接口兼容性策略:

  • 任意版本不保证依赖特定平台、工具链或构建配置的 ABI 兼容性。
  • 同一平台、工具链和构建配置的发布版本之间的 ABI 可能不兼容。
  • 库的 API 设计在局部调整而不保证在发布版本之间兼容。
  • 工具(列表参见目录)的 UI 可能会在构建中渐进修改;除非另行指定,添加的特性在之后的至少一个发布版本中保持向后兼容

  关于使用 YSLib 开发的基本步骤,参见入门

  目前已发布版本、进展和计划看这里

当前支持平台

待定支持平台

  • Android (arm-linux-androideabi)
  • MinGW64 (x86_64-w64-mingw32)
  • Linux32 (i686-linux-gnu)
  • Linux64 (x86_64-linux-gnu)

文档

YSLib 项目中的文档

  YSLib 项目中的文档主要包括以下几个部分:

  • 主要供项目维护者参考的开发文档,详见开发说明
    • 目录 /doc/vsd 下的文档可使用 Microsoft Office Visio 或 Microsoft Visual Studio 2013 查看。
  • 源代码文档,可使用 Doxygen 生成,参见构建文档
    • 当前源代码中的 Doxygen 命令主要编码为简体中文。未来计划使用 Doxygen 的 ~[LanguageId] 命令生成多种语言的文档。其它注释主要使用英文。
  • 其它非生成的文本文件,如 Readme.zh-CN.txt

关于本 wiki

  本 wiki 是和 YSLib 项目关联的项目。本 wiki 和 YSLib 项目组成了同一个项目组当前仅有的两个成员,每个项目都有单独的版本库。项目组的公共文档、 YSLib 的一般用户文档和重要特性列表主要由本 wiki 提供。 YSLib 项目中的文档主要面向项目的维护者。两者的文档构成双向引用,即 YSLib 项目可能引用本 wiki 的内容,反之亦然。

  除非另行指定,本 wiki 的内容适合当前最新的主分支版本(即版本库 master 分支标识为 tip 的版本)。

  编辑本 wiki 的规则参见这里(en-US)

  本页面有意引用所有本 wiki 的所有页面。

贡献

  对项目的贡献受到欢迎。由此提供的材料应在必要时由贡献者(及项目维护者)调整,以符合相应项目的许可证。

  **这个 wiki 规则被视为共识。**在项目文档内部的规则对维护者而不是其他贡献者有效。但是,项目中的内容应符合项目规则。

  要反馈或报告问题,使用 Bitbucket 问题跟踪系统,或按如下方式联系项目维护者。

项目内容规则

  下列指导原则一般地适用于所有项目。

  • **不重复发明轮子。**这里的项目只接受比别处更好的模块化组件。此处“更好”定义为“在至少一个方面比现有解决方案更有效地满足一致同意的已知需求”。
    • 参见特性注记的轮子列表和原理。
  • **拒绝不成熟的优化。**然而,何谓“不成熟”由需求决定,这很可能变化。

联系方式

主题目录

导航

  YSLib 是什么?

  返回目录查看其它内容。

目标读者

  本文预期的读者是对了解如何使用 YSLib 创建项目感兴趣的开发者

基础知识

  本文假定读者已经掌握或了解以下知识,不详细展开讨论:

  • 计算机体系结构常识
  • 了解规范 C++ 语言的标准(ISO/IEC 14882)
  • 了解什么是语言的实现(如编译器和链接器等)并掌握常见实现的使用方法(如 G++ 命令行)
  • 有必要时,能避免依赖只在特定实现支持的方言特性

概要

  本文档说明开发 YSLib 程序的简易操作。以下仅提供操作步骤和主要意义的解释。

注意 若需自行定制构建,参照以下引用的文档的全文,而非某个特定章节;再按照构建中的步骤执行。

  当前只有关于 Windows 下使用 MinGW32 的内容,基于 MSYS2 环境。

环境配置

  使用 YSLib 开发需要配置 YSLib 环境,以确保 YSLib 的库和相关环境可用。

  当前建议直接在本机环境中从源代码构建安装 YSLib ,参照以下步骤和要点:

  • 参照先决条件PC(MinGW32)一节给出的链接下载 MSYS2 并配置环境,执行脚本安装所需的工具;或者参照PC/Linux一节配置 Linux 开发环境。
  • 获取源代码
    • 若直接从版本库获取,直接构建可能找不到库而在链接时失败。可以自行参照文档构建缺少的外部依赖项,或从归档仓库下载二进制文件放置到指定的库文件路径中,详见开发说明
    • 文件不包含 POSIX 权限。若需在依赖文件权限的环境(包括典型的 Linux 环境)中直接运行 shell 脚本,需确保(可能被间接调用的)脚本文件可执行,如运行 find Tools -type f -name "*.sh" -exec chmod +x {} \;
  • 参照 Sysroot ,运行 Tools/install-sysroot.sh 脚本以构建 YSLib 并安装头所需的文件,得到 Sysroot 环境。然后,把 sysroot/usr/bin 目录的完整路径加入 PATH 环境变量(一般应添加在最前端)。
    • 注意 除非了解确切的作用,不要添加 YSLib 中的其它目录到 PATH ;添加不合适的目录可能会导致脚本运行失败。

开发基础

  以下介绍使用 YSLib 开发须知的基础要点,并说明如何开发示例程序。

控制台程序和图形用户界面(GUI) 程序

  需要注意,在 Windows 中控制台程序仍然可以包含 GUI 。

  YSLib 支持各种用户应用程序。为了简便起见,以下只介绍 GUI 程序的使用。更具体的说明参见 Windows 子系统

编写 Hello World 程序

  新建 C++ 源文件(名称任意,但需要.cpp 等作为扩展名以保证 SHBuild 作为 C++ 源文件处理),内容如下:

#include <YSBuild.h>
#include YFM_Helper_GUIApplication
#include YFM_YSLib_UI_Label
#include YFM_Helper_HostedUI

int
main()
{
	using namespace YSLib;
	GUIApplication app;
	UI::Label wgt({480, 360, 160, 24});

	wgt.Text = u"Hello world!";
	Host::ShowTopLevel(wgt, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, 0);
	Execute(app);
}

关于头文件

  可以安全地重复包含头文件。

  注意到 #include 后可以是一个宏。这里表示路径的宏 YFM_*<YSBuild.h> 保证定义,因此这个头文件需要在使用这些宏之前被包含。

  使用宏表示 YFramework 的大多数头文件名是兼容性的需要。用户程序不需要使用这种策略,尤其是集成开发环境可能会对这样引入的头文件的修改不敏感而导致的构建遗漏。

  MinGW32 平台的 Helper::HostedUI 的头文件已经保证包含了 <Windows.h> 中宿主窗口的声明,不需要显式包含。

使用 SHBuild-BuildApp 脚本构建程序

  把上面的文件保存到一个空的目录下,以下以 $SRC 指定这个目录名。

  执行以下命令:

bash -c "cd $SRC; SHBuild-BuildPkg.sh release ."

  在目录 $SRC/.release 下找到构建好的可执行文件(具体文件名取决于源文件名),执行观察结果。

说明

  bash -c 启动新的 shell 执行命令。

  cd $SRC 切换 shell 的当前工作目录到源代码目录。

  SHBuild-BuildPkg.sh 调用构建脚本。脚本的参数分别是:

  • release 是一个配置名称。配置名称决定保存生成的文件的输出目录相对当前工作目录的位置,这里输出目录是当前工作目录下的 .release 子目录。可以更换配置名称以指定不同的输出目录。   * 若配置名称以 debug 起始,启用调试配置,自动使用调试库和构建选项。
  • . 表示构建的目录源代码的根目录为当前工作目录。
  • 之后的可选参数在此省略。

  构建脚本以特定的选项调用 SHBuild 工具作为脚本解释器执行 NPLA1 脚本 SHBuild-BuildApp.txt ,详见 Sysroot

  SHBuild-BuildApp.txt 内部再次调用 SHBuild 工具进行构建。默认会递归扫描整个目录(除了名称以 . 起始的子目录外)。若存在多个源文件,这些文件都会被一起编译并链接。为了避免预期以外的结果,之前要求源文件在空目录中。

其它方法

  也可以直接调用 SHBuild 或者编译器命令行,但需要手动指定调用编译器的参数以及链接的库等,较为复杂,在此从略。

清理

  无论是 SHBuild 还是 SHBuild-BuildPkg.sh 当前都不提供清理功能。因为包括中间文件的输出文件都在同一个输出目录中,直接删除输出的目录即可。

进一步阅读

  参见开发说明的相应章节和进阶的教程

开发说明

  关于环境配置,详见运行。当前没有其它的面向最终用户的说明。

  以下为面向开发者的说明。

准备

  YSLib 项目文档位于 YSLib 项目而不是本 wiki 项目中。

  维护者参考的细节和一般规则详见 YSLib 项目文档 doc/ProjectRules.txt ;术语的完整定义详见 YSLib 项目文档 doc/CommonRules.txt

项目过程

  基本规则参见 YSLib 项目文档 doc/ProjectRules.txt

  本 wiki 项目作为用户手册和开发者补充文档的形式作为实现及之后阶段输出。

  实现的附加输出为库和工具。

  之前阶段(如设计)为前期过程,其文档和适用于维护过程的项目规则位于 YSLib 项目文档(位于 doc/ )。

  其中整体过程由 doc/Designation.txt 指定。当前内联设计以外的过程,因此不存在设计外前期过程的单独文档。

开发

平台

  关于外部依赖平台目标平台宿主平台等概念的一般定义参见术语概要

  YSLib 项目约定一个体系结构和使用的外部依赖是一个平台。

  YSLib 支持不同的目标平台。类似 ISO C/C++ 的独立实现(freestanding implementation) 和宿主实现(hosted implementation) ,平台分为两类:独立实现平台宿主实现平台。后者存在操作系统的支持而前者没有。

语言使用和实现要求

  本节适用于本项目,不直接限制依赖项和用户程序。项目中特定部分的规则及适用性详见 YSLib 项目文档 doc/ProjectRules.txt

  使用 ISO C++ 作为主要开发语言。

  不使用和 ISO C++03 以后被接受的特性不兼容的特性,包括但不限于:

  • 被取消的特性,如 export 关键字;
  • 在 ISO C++03 中标记为 deprecated 而在之后版本去除的特性,如 const char 数组类型左值到 char* 右值的转换,
  • 在 ISO C++03 中标记为 deprecated 但在之后版本重新取消 deprecated 的特性,如修饰命名空间作用域声明的 static
  • 实现的 Defect Report ,如 CWG 615

  注意即使使用特定模式,一些实现也可能引入之后的 Defect Report 而不保证兼容,如 GCC PR65890

  关于精确的特性使用规则、具体使用及备选的特性的清单等,详见标准使用(英文)

  以下对语言实现的要求和支持情况适用整个项目。具体内容可能会在未来变动。

基准实现要求

  默认基于 ISO C++11 环境,但并不要求实现完整支持所有特性。

  依赖 ISO C++ 独立实现或宿主实现,附加以下要求:

  • 满足 ISO C++11 [implimits] 建议的最小实现要求。
  • 标准库要求基于 ISO C++11 定义的宿主实现。
    • 需以下整数类型( ISO C++11 中为可选支持):
      • 定宽整数 std::intN_tstd::uintN_t (其中 N 为 8 、 16 、 32 或 64 );
      • 类型 std::uintptr_t
    • 满足以下实现定义行为的要求:
      • 至少支持 std::placeholders::_7(按 ISO C++11 Annex B [implimits] ,符合标准的下限为 10 )。
    • 假定用于迭代器 difference_type(含 std::ptrdiff_t )或坐标计算的有符号整数作为显式转换的目标类型且结果不能在范围内表示时,不引起副作用且结果的值不是能在此范围内表示的任意值(即为小于 0 的值)。
      • 当前标准中结果由实现定义。WG21 P0907 已提议修改使用补码表示,符合此要求。
    • 假定特定类型的特定操作无异常抛出(但不依赖异常规范的行为),当前包括:
      • std::string 的默认构造函数( WG21 N4002 引入了显式指定 noexcept ,仅从标准草案 WG21 N4296 起有效)。
  • 实现已解决标准使用(en-US) 中的 Workarounds 列出的 Defect Report 问题。
  • 假定被包含在具有外部链接实体的函数体或声明命名空间作用域中外部链接名称的被 ODR 使用(odr-used) 的 lambda 表达式相同。
  • 对宿主环境中程序外部的状态的并发修改不引起未定义行为。
    • 现有操作系统和文件系统提供的接口和实现普遍不能保证避免 TOCTTOU 访问(en-US) 导致的问题。具体修改的结果未指定,但应不直接引起无法预测的程序行为。
    • 除非另行指定,本项目的实现不保证检查外部程序的修改。

假定 YSLib 实现和用户程序的代码满足以下要求:

  • 假定异常和标准库 RTTI 对象满足 ODR ,即使是在使用动态库的宿主实现中,但影响用户代码生成的实现的二进制约定(如 ARM64 )除外。
    • 这要求用户代码不依赖影响相关符号可见性而导致 ODR 失效的特性。
      • 例如,这不允许如 dlopen 使用 RTLD_LOAD 加载具有相关符号的库。
    • 这允许 std::type_info 的比较操作的散列操作的高效实现。
      • 使用 libstdc++ 时,需要定义宏 __GXX_MERGED_TYPEINFO_NAMES1
        • 这对应默认选项的修改
        • 一般不调整 __GXX_TYPEINFO_EQUALITY_INLINE ,使用默认选项。
      • 其它实现暂不使用选项支持,以避免和二进制约定冲突。
        • libc++ 不支持另行调整,由实现根据平台环境指定 _LIBCPP_HAS_NONUNIQUE_TYPEINFO
    • 链接时除实现的二进制约定,假定 std::type_info 相关的符号被共享。
      • 这不允许在实现生成以外显式地隐藏相关的符号(如通过 #pragma 预处理指令或 -fvisibility=hidden 编译器命令行选项)。
      • 这一般要求在兼容 GNU ld 的链接器在命令行选项中使用 --dynamic-list-cpp-typeinfo 等方式导出相关符号(也允许但不要求使用 -rdynamic-export-dynamic )。
  • 假定在标准库宏 NDEBUG 被定义的翻译单元中的代码不违反异常规范。
    • 这允许改进代码生成,如使用 G++ 的 -fno-enforce-eh-specs 选项
    • 程序应不依赖违反异常规范时调用标准库的函数的行为。否则,程序行为未定义。

历史实现要求

  以下要求已被修改或取消。

  • 假定提供撤销标准库未定义行为的保证:
    • 撤销 [res.on.functions]/2.5 对特定不完整类型作为模板实际参数引起未定义行为的限制,包括:
      • 使用默认分配器( std::allocator 的实例)的 std::vectorvalue_type 类型。
        • 这被包含在 WG21 N4510
        • ystdex::pmr::pool_resource 的实现从 b843[2018-11-10] 起依赖这项特性。
        • 从 b863[2019-07-26] 起不使用不完整类型的元素而不再依赖这项特性。
      • 使用默认分配器( std::allocator 的实例)的关联容器(即 std::mapstd::set )的 value_type 类型。
        • std::vectorstd::liststd::forward_listWG21 N4510 引入了不完整类型的支持。这不在此处要求。关联容器的要求预期在未来被添加。
        • 已知 libstdc++ 的实现符合这个条件。
        • 在 YSLib 中仅被 YSLib::ValueNode 通过在 std::map 使用递归的键类型的实现从 b338[2012-09-13] 起依赖。
        • 因为使用 ystdex::map 替代 std::map ,从 b830[2017-08-11] 起取消这个要求,不再依赖标准库实现提供的扩展特性。
  • 假定特定类型的特定操作无异常抛出(但不依赖异常规范的行为),包括:
    • std::function::swapLWG 2062 起有效)。
      • 因为使用 ystdex::function 替代 std::function ,从 b848[2018-12-24] 起取消这个要求。

可选实现支持

  允许使用 ISO C++11 以后兼容最新标准草案的正式标准中的特性(可通过 __cplusplus 宏和 SG10 建议的特性检查判断)。

其它

  不依赖实现的方言扩展,但在确保实现能支持时,在特定的代码中可通过条件包含等方式选用。

  若实现默认具有不符合标准的特性,在本项目的代码中不依赖这些特性,即便外部依赖项可能对此进行配置(如 MinGW G++ 为了和 Microsoft VC++ 兼容启用的 -mms-bitfields ,而 MSYS2 安装的 freetype2 的 pkg-config 的 CFLAGS 隐含此参数)。

保留名称

  YSLib 项目中,除了 YBase.LibDefect 是对标准库实现的修正外,并不是语言的实现,因此公开接口遵循 ISO C++ 对保留名称的使用,如不引入以 __ 起始的标识符。

  对实现环境已经以保留标识符提供的接口,适用以下规则:

  • <ydef.h> 提供宏包装特定实现的标识符。
  • 除标准预定义的(如 __cplusplus )和用于特性检查的标识符(以 __cpp__has 起始),以及上述被包装时的宏定义,不在注解(作为宏 YB_ATTRYB_ATTR_STD 的参数)外直接使用保留标识符。

  <ydef.h> 和其它一些 YSLib 项目头文件保留特定的不被标准保留的标识符,详见 YSLib 项目文档 doc/Definitions.txt

库概述

  YSLib 项目由多个子项目组成。其中主要的有顶级子项目:YBase 和 YFramework 。它们是开发 YSLib 应用的必备的库。每个库被构建为单独的映像(静态库或动态库)。

  YSLib 的组件有些是依赖于特定平台的,但更多是平台中立的。关于库的组件在此的不同,详见下文的解释。

  静态库、动态库或其它可能被库构建时依赖的输入以及构建使用的工具是库构建的依赖项。关于依赖项的一般说明,详见术语中关于依赖管理的说明。

平台模拟

  除非另行指定,文档中的狭义的“模拟”概念指程序模拟。

  YSLib 项目中,**平台模拟(platform emulation)**主要指直接以运行时环境适配层嵌入宿主平台运行时,在具体程序中提供类似被模拟的目标平台的具体特性和接口。

  完整的定义详见 YSLib 项目文档 doc/CommonRules.txt

外部依赖项

  外部依赖项在构建项目的上下文中,指构建时可能使用的外部依赖,是不由本项目维护和单独发布的依赖项。

  YSLib 项目严格使用 ISO C++ 的子集和特定实现的可选的扩展。关于依赖的语言特性,参见这里(en-US)

  在所有目标平台上,除了系统库外,外部依赖项是相同的,但可能使用不同的版本,也不一定按相同的配置构建。系统库的概念和 GNU GPLv3system library exception 中的 system library 定义类似,在此指特定平台或操作系统提供运行时支持的、由特定第三方环境提供开发支持的外部依赖,例如提供特定平台的 ISO C++ 标准库部分实现的 libstdc++ 和提供 Windows API 实现的 GDI32 等。

  除了系统库外,一部分外部依赖项可选或必须使用自行构建的(可能被修改的)版本。这些外部依赖项的修改和构建脚本位于版本库的 3rdparty 目录,默认按原始许可证发行。

  YBase 只直接依赖 ISO C++ 标准库。

  YFramework 默认依赖经过修改的 FreeType2 和 FreeImage 。其中前者当前仅修改头文件,经过特别处理和官方发布的直接构建的版本二进制兼容,可以被系统库替换。

  当前版本中,不同宿主平台对应的静态库文件(后缀名为 .a )查找的目录如下:

  • /YFramework/DS/lib
  • /YFramework/MinGW32/lib
  • /YFramework/MinGW64/lib
  • /YFramework/Android/lib
  • /YFramework/Linux/lib

  其中,使用的 FreeImage 静态库对应 YFramework 的 debug 和非 debug 配置,文件名分别为 libFreeImaged.alibFreeImage.a 。这可在同一个目录树中共存。

  (当前 Android 和 Linux 仅支持单一本机体系结构,实际仅测试 Android ARMv7 和 Linux x86_64 。)

  构建 YFramework 时需包含 3rdparty/include 目录的头文件。 Sysroot 安装脚本 Tools/install-sysroot.sh 会复制包括上面的头文件在内的文件。

  当前已经使用的详细外部依赖项详见 YSLib 项目文档 doc/Dependencies.txt

注意 版本库历史中包括静态库(.a) 文件,但为减少版本库大小,不再更新且可能移除,使用外部源或自行构建的方式替代。参见归档获取单独配置或和源代码目录集成的已编译的外部依赖项。

  在 build 885 之前,版本库历史的对应的宿主平台中的静态库位于以下位置:

  • /YFramework/DS/lib
  • /YFramework/MinGW32/lib-i686
  • /YFramework/Android/lib
  • /YFramework/Linux/lib-x86_64

  其中 Android 平台只包括 FreeType2 ,Linux 平台只包括 FreeImage 。其它平台包括 FreeType2 和 FreeImage 库文件。

  其它平台中,只有随其它文件的发布版本包含完整更新,否则压缩包中可能只有其中一个库文件。

  关于自行构建外部依赖项的方法,参见构建说明

模块

  YSLib 项目组织为一个逻辑上的树形结构,其叶节点称为模块。类似文件系统,非叶节点称为模块目录。在源代码中使用模块路径来标识不同的模块,其分隔符为 :: 。在 YSLib 项目下直接划分的顶级子项目的名称仅在必要时出现在模块路径中,完整模块路径一般从次级子项目的名称起始。

  C 和 C++ 源代码的一个模块由以下三种形式之一构成:

  • 一个头文件
  • 一个非头文件的源文件
  • 一个头文件和对应的源文件

  作为公开接口的模块是公开模块。公开模块的头文件在单独的目录中以便部署。

  按 ISO C 和 ISO C++ 规定, C 或 C++ 模块中存在的非头文件的源文件和包含的头文件构成一个 C 或 C++ (预处理)翻译单元,简称单元。注意这里包含的头文件不仅限于模块中的头文件。

  关于模块的进一步说明以及模块路径的形式文法和头文件依赖的基本规则,参见 YSLib 项目文档 doc/ProjectRules.txt

文件系统布局

  作为 C++ 项目, YSLib 把每个顶级子项目的源文件和公开模块头文件分别保存在不同的目录中,即 includesource 。非公开模块若有头文件,也位于 source

  特定于目标平台配置的代码会直接位于 平台名 目录下,称为平台扩展。对应的两个目录为 平台名/include平台名/source

  除了平台扩展的内容,文件系统目录和模块目录的每一级对应。平台扩展的模块目录名是对应平台中立部分加上后缀 _(平台名)

  举例:顶级子项目 YFramework 下的次级子项目 Helper 的非平台扩展的源代码在目录 YFramework/include/HelperYFramework/source/Helper 中,它的 DS 平台扩展的源代码位于 YFramework/DS/include/HelperYFramework/DS/source/Helper 中。

  提供平台扩展的次级子项目只有 YCLib 和 Helper 。

  编译项目时包含的头文件是合并的,如编译器命令行 -IYFramework/DS/include -IYFramework/include 在一次编译中同时使用平台中立和特定于平台 DS 的模块的 YFramework 头文件。

YSLib 及其本体

  在 YBase 和 YFramework 分离之前, YSLib 是一整个库。原 YSLib 大部分仍然在 YFramework 中,仍然可称为 YSLib ,是一个 YFramework 下的次级子项目。注意和整个项目名的不同,以下称为 YSLib 库,以示区分。

  YSLib 库中, Adaptor 用于适配特定于具体外部依赖的接口。可以通过修改其中的代码替换外部依赖,包括部分标准库兼容接口。

  其它部分的接口和实现都是严格平台中立且不依赖外部特定接口而变化的,称为本体。本体中提供了 YSLib 的主要功能。

Helper

  若需要开发依赖平台特定的应用,本体接口可能不足,而需要使用平台扩展。此外,可能需要一些便利功能。

  在 YSLib 库之上,Helper 对此类需求提供了一致而灵活的接口。

  若需要更接近特定平台实现的接口,可以使用 YCLib 及其平台扩展。

  YCLib 和 Helper 在宿主实现上都提供了更加丰富的功能。

代码规范

  YSLib 项目维护的代码规范符合 YSLib 项目中的文档约定的规则,包括:

  • doc/CommonRules.txt 一般规范
  • doc/ProjectRules.txt 项目规范
  • doc/LanguageConvention.txt 语言使用约定

代码格式化

  doc/CommonRules.txt 中规定了命名风格和参考的代码格式。由于格式化代码涉及语义分析,并不保证可以完全自动化进行,需要在编码时注意调整。

  以下工具配置可以把其中的主要工作自动化进行:

  • clang-format
    • 可通过 MSYS2 包 mingw-w64-i686-clangmingw-w64-x86_64-clang 安装,以下配置以这里的 3.7 版本为基准测试
    • 配置选项的文档参见这里
    • 通过命令行 -style= 指定使用选项文件 Tools/YSLib.clang-format
    • 注意 至少以下格式需要手动调整
    • 通过命令行 -i 直接编辑文件而不是打印结果到标准输出
    • 命令行示例: find YBase YFramework YSTest -name "*.h" -o -name "*.hpp" -o -name "*. cpp" | xargs clang-format -i -style=file
    • 命令行示例: find YBase YFramework YSTest -name "*.h" -o -name "*.hpp" -o -name "*. cpp" | xargs -i sh -c "clang-format -i -style=file {}"
    • 命令行示例(同时替换 template < ): find YBase YFramework YSTest -name "*.h" -o -name "*.hpp" -o -name "*. cpp" | xargs -i sh -c "clang-format -i -style=file {} && sed -bi 's/template </template</g' {}"
  • astyle
    • 可通过 MSYS2 包 mingw-w64-i686-astylemingw-w64-x86_64-astyle 安装,以下命令行以这里的 2.05.1 版本为基准测试
    • (版本 2.05 )命令行选项的文档参见这里
      • --help 取得的文档可能有问题--delete-empty-lines 对应的短选项应为 -xe 而不是 -xd
    • 使用命令行选项 -A1 -T -p -U -k1 -xj -xy -xC80
      • 短选项可以缩写
      • 和上述 clang-format 比较,少了部分功能,主要有
        • AlignAfterOpenBracket: DontAlign
        • AlignTrailingComments: true
        • AlwaysBreakAfterReturnType: All
        • MaxEmptyLinesToKeep: 2
    • 注意 至少以下格式需要手动调整
      • 无法正确识别 constexpr 导致错误的缩进
      • 虽然右值引用识别问题已解决,但实测对模板参数无效
      • extern "C" 块冗余缩进
      • 断行后的缩进
      • lambda 表达式的捕获列表中的 = 周围的冗余空格以及对应的 { 断行
      • static_cast 等关键字后的 <> 周围的冗余空格
      • 宏实际参数列表头部的 ( 和作为第一个参数的标点可能有冗余空格
      • 宏实际参数列表尾部的 ,) 没有以空格隔离
      • 初始化数组的列表 { 和之前的 ] 存在冗余空格
    • 不使用 -xp ,尽管一些注释需要(移除行首 * 后保持一级缩进)的此类格式,但它会不必要地影响大部分 Doxygen 注释块
    • 默认备份文件后缀 .orig ;可选使用 -n 取消备份文件,或 --suffix= 修改备份文件后缀
    • 使用 -r 递归处理子目录
    • 可选使用 -v 显示详细过程
    • 可选使用 -Q 只显示被处理的文件
    • 可选使用 --dry-run 不实际处理文件
    • 命令行示例: astyle -vQnrA1TpUk1xjxyxC80 YBase/*.h* YBase/*.cpp YFramework/*.h* YFramework/*.cpp YSTest/*.h* YSTest/*.cpp

参考

  • YSLib 项目文档 doc/Dependencies.txt 了解组织结构、开发规则、默认使用的外部依赖项(包括语言实现)和相关约定
  • 结构和特性 中的树形结构
  • YSLib 项目文档 doc/ProjectRules.txt 了解组织结构、开发规则和相关约定
  • YSLib 项目文档 doc/YBase.txt 了解顶级子项目 YBase
  • YSLib 项目文档 doc/YFramework.txt 了解顶级子项目 YFramework
  • YSLib 项目文档 doc/YSLib.txt 了解 YFramework 的次级子项目 YSLib

先决条件

  特定历史版本依赖的详细环境和平台库版本参见开发文档 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 的 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 子系统(subsystem)

  Windows NT 内核以上支持不同的称为子系统 的用户模式运行时环境 ,主要包括 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 运行时
      • MinGW-W64 (目标三元组 i686-w64-mingw32 )。
      • MinGW.org (目标平台三元组 i686-pc-mingw32 )
    • 要求标准库多线程支持,否则只支持构建 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 。
    • 当前暂不支持 LLD( MSYS2 包 mingw32/mingw-w64-i686-lld )。

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

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

  支持的运行环境:

  • Microsoft Windows XP 或以上版本操作系统
    • 对于 64 位目标工具链构建的程序,需要 64 位操作系统
  • 构建环境匹配的附加运行库,默认支持的工具链包括:
    • libwinpthread-1.dll
    • libgcc_s_dw2-1.dll
    • libstdc++-6.dll

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

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

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

MSYS2

  建议使用 MSYS2 ,相关问题可参考官方 Wiki

  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.bat -mingw64 进入对应的 MSYS2 、 MinGW32 和 MinGW64 的 shell
      • 对未更新 filesystem-2016.05-2 或更新版本的包的 MSYS2 旧版本基础环境安装,分别运行 msys2_shell.cmdmingw32_shell.batmingw64_shell.bat 进入对应的 MSYS2 、 MinGW32 和 MinGW64 的 shell
    • 也可直接一次性设置 Windows 系统环境变量(注意需要符合 Windows 的路径格式,每个路径之间以分号分隔),这样可以对其它命令行环境(如 cmd )生效
      • 需要设置 bash 所在的 MSYS 工具的目录(即 MSYS2 根目录下的 /usr/bin )以及 MinGW 目标编译器和其它工具所在的目录(对 32 位的目标为 MSYS2 根目录下的 /mingw32/bin
      • 注意 因为 MSYS 和 MinGW 是不同的目标,使用不同的 GCC (可能被同时安装),需要保证 MinGW 编译器被优先搜索,所以 MinGW 目录一般应在 MSYS 目录之前
    • 一些构建环境可能会依赖环境变量 MSYSTEM 的值, MSYS2 根目录批处理文件进入的不同环境对此有不同的设置,但当前 YSLib 不依赖此变量,可以不另行设置
  • 确保能搜索到正确的 MinGW 编译器

    • 可以进入 Shell 执行命令 /usr/bin/which 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 子系统(subsystem)

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

  在 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 存在已知可导致并行构建失败的缺陷 ,以及可能有的其它问题 ,本项目不针对这些问题单独提供变通。

其它构建环境

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

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

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

获取源代码

  建议通过 MercurialGit 获取仓库中的最新代码。

注意 构建过程可依赖源代码中不直接提供的二进制文件。详见构建中的说明。

通过 Mercurial

  安装 Mercurial ,使用命令行

hg clone https://hg.osdn.net/view/yslib/YSLib YSLib

  得到源代码的本地副本。

  若已有本地副本,可使用

hg pull -u

  同步更新到最新版本。

  或者安装 GUI 客户端(如 TortoiseHg )进行以上操作。具体使用参考软件附带的手册。

通过 Git

  安装 Git ,使用以下命令行之一得到源代码的本地副本:

git clone https://github.com/FrankHB/YSLib.git YSLib
git clone https://gitee.com/FrankHB/YSLib.git YSLib

  若已有本地副本,可使用

git pull

  同步更新到最新版本。

  或者安装 GUI 客户端(如 TortoiseGit )进行以上操作。具体使用参考软件附带的手册。

注意 Git 版本库是 Mercurial 版本库的镜像。不同版本库可具有不同的传输性能;使用合适的镜像可能大幅改善同步的体验。上述版本库都是官方维护的,大多数时候不需要担心同步时效性,但镜像版本库的更新仍可能比主版本库稍晚数分钟到数小时。

下载已发布版本

  已经发布的版本列出了可以直接下载的测试发布版本。

  可以在以下归档中获得特定发布版本的源代码和部分二进制文件。

  注意这些代码通常比版本库中的旧。在 Beta 阶段前也不表示更稳定。

文件权限

已知缺陷 Windows 上的 Mercurial 不跟踪可执行位。

  若在其它环境中因此无法执行脚本,在 Tools 目录下执行以下命令变通:

find -type f -name *.sh -exec chmod +x {} \;

  因为约定总是使用 *.sh 作为可执行的脚本的扩展名,不需要考虑其它文件。

历史资源

  因为代码托管站点不再提供服务,以下资源已过时:

  • 曾经可用,当前服务已经停止:
    • Google Code: hg clone https://yslib.googlecode.com/hg/ YSLib
    • GitCafe: git clone https://gitcafe.com/FrankHB/YSLib.git YSLib
  • 已经无法同步:
    • Bitbucket: hg clone https://bitbucket.org/FrankHB/yslib YSLib
  • 被取代:
    • OSChina: git clone http://git.oschina.net/FrankHB/yslib.git YSLib(使用 Gitee 代替)

准备

外部依赖项构建

  这个步骤是可选的。若已获取二进制的库文件,可以跳过。

  YSLib 发布的文件和对应使用的外部依赖项(包括二进制的库文件)可以从归档仓库下载

  进入 3rdparty 对应库的目录查看 Readme 文件说明。按此说明进行构建,一般方法为:

  • 自行获取指定的公开发行的源代码
  • 复制 3rdparty 库的目录中的文件到源代码,替换源代码中的原始文件
  • 运行指定的构建脚本命令行

库和示例程序构建

  以下描述构建项目的默认目标:库和示例程序。

注意 除了 SHBuild 外,当前没有实现子项目间的依赖管理。由于非正式版不保证二进制兼容性,直接增量构建可能在更新代码后失败。此时可手动清理构建生成的中间目录即 build

  另见构建文档

SHBuild

  宿主平台的建议方式。

  详见 SHBuildSysroot

  b600 起用于发布和测试的二进制文件使用此方式构建。

Microsoft Visual Studio

  源代码包含 Microsoft Visual Studio 2012/2013 解决方案 .sln 文件。可以直接生成解决方案。注意若修改被依赖项目代码后直接生成,依赖项目也不会重新编译,需要手动清除或重新编译。

  当前包含了平台中立项目(便于源代码管理,不实际生成)、 DS 项目 、 MinGW32 项目和 Android 项目,但仅支持生成使用 make 的平台( DS 和 Android ,需要对应的工具链支持)。因为正确支持的语言特性不足, Visual Studio 使用的编译器不能正常生成 Win32 项目。

  使用 Microsoft Visual Studio 打开文件,需特定的环境变量以保证使用 makefile 的项目可构建。以下(使用 兼容 bash 的)路径仅为示例:

  DS 项目:

DEVKITPRO=/opt/devkitpro

  Android 项目:

ANDROID_SDK = /d/Android/sdk
PATH = /d/clang-android/bin:/c/Program\ Files/Java/jdk1.8.0_211/bin:$PATH

注意 Visual Studio 项目使用的 makefile 命令行依赖 bash 以及时检测到错误停止生成,可参见先决条件配置宿主环境。

  支持生成的 Visual Studio 项目包含依赖性,不需要另行设置;也支持清理命令。

Code::Blocks

  从 b217 (2011-06-13) 起支持。

  源代码包含 Code::Blocks 工作空间 .workspace 文件,建议使用 Code::Blocks 12.11 或以上版本打开。

注意 打开工作空间后直接生成,其中的项目不都能成功构建,因为并非所有项目都保证能生成。项目名没有平台后缀的不用于构建,仅作为项目原型便于开发。

  当前包含了平台中立项目(项目名不含下划线,便于源代码管理,不实际生成)、 DS 项目和 MinGW32 项目,支持构建 DS 项目和 MinGW32 项目,每个分别包含 debug 和 release 配置。除此之外, MinGW32 项目还支持 debug_DLL 配置和 release_DLL 配置,用于生成动态链接库或使用动态链接库生成可执行文件。

  对于 DS 可以分别编译其它各个项目,但不能运行。可以在工具菜单添加 DeSmuME 命令行运行。

  b599 (2015-05-21) 起支持通过脚本 GenerateProjects.sh 生成 .cbp 文件。和 Visual Studio 不同,项目文件的内容不保证最新。这些文件以后仅保证在发布版本更新。

  b600 前用于发布和测试的二进制文件使用此方式构建。因为编译时使用的文件路径不同等原因,构建的二进制文件和 SHBuild 不完全等价。

make 命令行

  和 Visual Studio 类似,Code::Blocks 项目文件仅用于查看项目文件,当前不作为首要的构建途径被支持。

  虽然 Code::Blocks 具有模块化设计,但仍有一些欠缺可配置性及文档的逻辑被集成在核心(使用 C++ 实现,且不容易改动)而造成问题,如:

  • 头文件搜索使用字符串匹配。
    • 这直接导致在编辑器中无法定位宏名形式的 #include 的路径。
    • 这种形式实际被 YFramework 及 FreeType 使用。
  • 在运行时环境插入 PATH 环境变量的前缀,不保证和构建时相同也不可由用户指定去除。
    • 前缀包括 . 、链接器和调试器的可执行文件所在的路径。
    • 因为是前缀,当前路径及链接器和调试器可执行文件的路径直接污染环境变量,无法通过其它设置去除。
    • 当这些路径具有和构建时不同版本的动态库时,使用 Code::Blocks 运行程序会使用错误的动态库。
    • 因此,使用 Code::Blocks 运行程序时,为了使用正确的动态库,不同的版本的动态库不能和工具链共存。

  由于这些自身的局限性,Code::Blocks 不适合作为现代的集成开发环境,没有在现状以外其它的改进支持的计划。

  使用 make 构建适用于使用 Makefile 的平台,当前包括 DS 和 Android 。

  设 $Configuration 是生成配置名称,则

  在各个项目目录下运行

make -r BUILD=$Configuration

  即可生成。

  在各个项目目录下运行

make -r BUILD=$Configuration rebuild

  即可重新生成。

  在各个项目目录下运行

make -r BUILD=$Configuration clean

  即可清除生成。

注意 因为不同子项目的 makefile 之间不追溯依赖关系,直接运行 makefie 需明确依赖顺序,参见项目依赖性

  和其它构建方式类似,YFramework 依赖于 YBase 。对 DS 项目,注意附加的项目依赖性以确定生成顺序:

  • YSTest/DS_ARM9 依赖 YFramework 。
  • YSTest 依赖 YSTest/DS_ARM7 和 YSTest/DS_ARM9 。

准备

  • 获取源代码
  • 安装带有图形界面前端的 Doxygen
  • 安装 Graphviz/Dot 工具(见注意事项)

构建

  使用 Doxywizard(Doxygen GUI) 打开目录下的 Doxygen 文件,选择 Run 选项卡,点击 Run doxygen 按钮等待完成即可。

  构建文档的内容主要来自源文件中的注释。

  默认的输出路径在 doc/html 。打开其中的 index.html 进入主页。

注意事项

  • Dot 工具的路径是被硬编码的。
    • 如果不确定安装的位置,使用前清空 DOT_PATH ,并设置 PATH 环境变量使二进制文件能被找到。可以直接编辑 Doxyfile 或者在 Expert 选项卡的 Dot 项中设置 DOT_PATH
  • 当前配置使用 DOT_IMAGE_FORMATsvg 而不是默认的 png ,生成的文件不支持 Intenet Explorer 9 以前版本的浏览器。

概述

  这是单列的测试顶级子项目。

  预期覆盖整个项目中的各个,但目前仅测试 YBase 。框架部分的主要测试由示例程序 YReader 完成。

准备

依赖

  当前测试脚本 test.sh 依赖工具脚本 ,并使用相同的解释环境。

运行

  测试脚本 test.sh 构建测试程序并运行。

  当前测试程序只包括 YBase::YStandardEx 的相关内容。

  以标准输出显示测试项的数量和每个测试项的结果。通过为 PASS. ,失败为 FAIL.

配置

  变量 TestDir 表示当前测试使用的目录,默认值即为 test 目录。

  和工具脚本类似,变量 SHBuild_ToolDir 指定工具脚本目录。测试脚本据此包含构建配置所需的工具脚本。因为默认定位到此路径,不需要依赖 Sysroot 安装脚本。

  在包含工具脚本前,测试脚本使用(当前被直接硬编码在脚本中)以下配置:

CXXFLAGS_OPT_UseAssert=true
SHBuild_Debug=debug
SHBuild_NoAdjustSubsystem=true

  脚本不会调用 SHBuild 。脚本直接接受的参数附加为使用 $CXX 构建时命令行选项。

  和构建 YBase 和 YFramework 库的工具脚本类似,测试脚本支持预编译头文件。但因为默认直接使用 TestDir 作为输出路径,修改配置后可能需要手动清理 gch 文件以免预编译头文件失效。

准备

平台环境

注意 示例程序最大化地使用了 YSLib 的平台模拟特性,支持特定的目标平台在运行时作为宿主平台对另一平台的平台模拟,即运行的原生示例程序和被模拟平台的原生程序保持基本相同的功能效果;但并不保证所有其它 YSLib 程序同样支持。

  被正式支持的平台模拟列表如下:

  • PC 模拟 DS

  被非正式支持的平台模拟列表如下:

  • Android 模拟 DS

硬件资源要求

  占用的硬件资源不确定,取决于平台配置以及具体应用程序。

注意 特定平台可能有额外限制,详见各个平台运行时环境的说明。

文件系统

  为最大化可移植性,原则上 YSLib 的程序逻辑不依赖自身组件具有显式编码的具体文件路径,因此默认不要求在具体系统约定的周知(well-known) 的文件系统位置(如 Windows DLL 搜索路径中的目录和 [FHS](https://zh.wikipedia.org/zh-cn/%E6%96%87%E4%BB%B 6%E7%B3%BB%E7%BB%9F%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84%E6%A0%87%E5%87%86) 定义的目录)部署。但具体平台配置可以自行限定目录布局作为默认运行时环境,如 Sysroot 。其中外部文件可有默认路径,参见以下相关章节。

  YSLib 中的库使用的文件系统路径具有以下约束:

  • 不依赖兼容 POSIX 的文件系统和路径表示。
    • 特别地,不依赖文件系统是否具有文件名的大小写敏感性。
    • 推论 为保证可移植性,文件系统路径大小写敏感,需要显式区分而加以明确。
    • 这样仍可兼容 FAT 等大小写不敏感的文件系统。
  • 要求支持符合 YSLib 项目规范的开发(参见项目的 doc/ProjectRules.txt )。

  一般地, YBase 不要求文件系统访问;使用 YFramework 框架的程序,由 YFramework 中的框架初始化等逻辑引入文件系统访问。

二进制依赖项

  按以上文件路径约定,构建得到的目标程序没有预设特定的位置限制,可按需转移。

  运行程序前,应确保程序能找到二进制依赖项:

  • 确保先决条件中的依赖项可以在 PATH 环境变量的目录被找到,或者复制到程序所在的目录。
  • 对于静态链接 YFramework 和 YBase 程序,不需要其它二进制程序文件的部署。
  • 使用 DLL 的程序可能依赖 YFramework.dll 和 YBase.dll ,或者 debug 配置的 YFrameworkd.dll 和 YBased.dll 。这些库已经在 sysroot 的 bin 目录下安装,因此可以直接把 bin 目录加入 PATH 环境变量,而不必复制或移动库文件。

说明 在任意被支持的平台上,YSLib 避免使用导致在特定平台上被特殊处理且无法可靠避免这种行为而确保兼容性一致的外部依赖项名称(若因为外部环境更新导致此类问题,则需在 YSLib 的新版本适当修改后支持)。例如,支持 API Set Schema 的 Windows 版本加载 DLL 时,LdrLoadDll 解析以 api-EXT- 起始的文件名进行重定位 ,因此设计时确保外部依赖项对应的文件名不以这些前缀起始。

外部文件

  外部文件包括:

  • 在文件系统中部署的外部二进制依赖项。
  • 配置文件:可被修改以改变程序的运行时行为。
  • 其它数据文件。

  数据文件提供程序运行时所需的必要或可选的信息。配置文件可能作为数据文件使用。

  外部文件的路径应符合前述关于文件路径的约定。

文件格式

  除非另行指定,使用以下文件格式:

  • 配置文件是内容为 NPL 配置的 UTF-8 文本文件,具有 UTF-8 BOM
  • 其它数据文件为二进制文件

文件系统布局

  除配置文件可能指定默认的具体位置(详见下文)外,YFramework 程序的不需依赖特别的文件系统布局。

  除非另行指定(暂无),YFramework 不创建文件系统目录。

  Sysroot 提供类 UNIX 系统使用的布局作为可选项。

文件访问约定

  除非另行指定,YFramework 对外部文件的访问适用本节约定。

注意 除非另行指定,程序访问配置文件的时机是未指定的。

基本要求

  应确保外部文件满足以下条件,否则运行时出错,或在另行指定(暂无)的特定情形下不保证行为符合预期:

  • 具有适当的(可读和可写)权限以允许程序访问其内容及元数据,或在必要时进行创建。
  • 需要写入的文件所在的位置应该具有足够的空间。

文件映射和内存映像

  文件读写使用 YCLib::MemoryMapping ,优先使用内存文件映射。在文件无法访问时,部分文件可能使用内存映像代替。

注意 除非使用内存映像,应确保外部文件的内容可读;否则,可在之后引发无法恢复的错误;参见当前实现使用的 YCLib::MemoryMapping 的注意事项

共享文件

  宿主平台使用协同锁(advisory lock) 对并发文件内容访问提供有限的共享保护,避免基于 YFramework 程序并发访问外部文件时的竞争。不使用强制锁(mandatory lock) 以利于提升性能。

注意 除检查文件创建外,不提供相关文件系统元数据并发访问保护。

注意 因为锁定非强制,宿主不保证其它机制访问文件的程序(如非 YFramework 程序)在这里产生冲突,有可能破坏文件内容。用户应避免对相关文件造成此类访问的破坏性编辑。

注意 因为访问顺序未指定,不同 YFramework 实例可能修改相同的文件(如配置文件)而导致外部可见的影响。

  未来可能添加完整的对共享文件内容修改的传递和检查的机制。

配置生成和输入输出

  配置文件可能提供默认内容,在外部文件不存在或读取失败时尝试创建。默认内容一般由框架直接提供。

  • 自动生成并保存外部文件时需确保程序可在指定目录下创建文件。
    • 具体目录视具体文件而定。
    • 可在运行前部署正确的配置文件以避免自动生成。
  • 若无法满足,生成保存在内存中的临时配置映像之后的修改不会保存到外部文件。
    • 注意 某些版本的 Windows (如 Windows Vista 以后的版本)在特定的目录(如 %PROGRAMFILES% )中创建文件默认需要管理员权限。

公共配置文件

  文件 yconf.txt 为 YFramework 程序的公共配置文件,在框架初始化时,先于其它配置文件之前处理。若不存在,提供默认内容。其位置是预先指定的,和平台相关。详见下一章对框架初始化的说明。

  为避免 YFramework 程序在运行时出错或行为不符合预期,注意确保满足前述访问约定的要求。若无法在程序映像文件所在目录(详见以下关于框架初始化的说明)创建文件,配置不能保存到外部文件。

  在 Win32 上一个正确的公共配置文件的内容可能是这样的:

YFramework 
(
	DataDirectory "C:\Data\\"
)
(
	FontDirectory "C:\Windows\Font\\"
)
(
	FontFile "C:\Windows\Font\FZYTK.TTF"
)

  这里指定的路径分别为数据目录路径、字体文件目录路径和字体文件路径。

数据目录

  用于存放 YFramework 程序必要的数据以及运行时的配置。

  通过 yconf.txt 中项 DataDirectory 的值指定数据目录的路径。

  自动生成的配置中数据目录的默认路径如下:

  • DS : /Data 目录
  • Win32 :同默认生成配置文件所在的目录
  • Android : SD 卡目录(自动检测同上)下的 Data 目录
  • 其它平台:当前工作目录

  当前可用数据文件位于 YSLib 项目的 /Data 下,可自行复制到数据目录。

CHRLib 的 GBK 转换例程初始化

  对使用 CHRLib 提供的 GBK 编码转换的程序,需保证数据目录下存在数据文件 cp113.bin

  对 Win32 平台, CHRLib 初始化 GBK 转换例程读取数据文件失败时,首先尝试使用 NLS 替代:

  • 通过读取注册表取得 NLS 文件路径,默认为系统目录下的 C_936.NLS
  • 注意 并非所有 Windows 安装带有指定的 NLS 文件。例如,某些版本的 64 位 Windows 10 可能在 %windir%\system32\C_936.NLS 但不存在 %windir\SysWOW64\C_936.NLS 。由于 64 位 Windows 默认对系统目录重定向,导致 32 位的 YFramework 初始化找不到注册表指定的默认 NLS 文件。当前不特别处理这种情况,因此 NLS 不可用。
  • 若 Win32 NLS 初始化仍然失败,则 CHRLib 初始化 GBK 转换例程失败。

  对其它平台,数据文件读取失败则 CHRLib 初始化 GBK 转换例程失败。

  初始化失败后,使用 CHRLib 转换 GBK 编码的程序在调用转换例程时抛出异常,可能导致程序非正常退出。

MIME 数据

  数据目录下的配置文件 MIMEExtMap.txt 存储 MIME 数据。若不存在,提供默认内容。

字体目录和文件路径

  只要其中之一有效即可(若没有成功指定字体文件路径,则默认字体文件路径不确定)。

  自动生成的配置中字体文件的默认路径如下:

  • DS : /Font/FZYTK.ttf
  • Win32 :系统字体目录下的 SimSun.ttc
  • Android : /system/fonts/DroidSansFallback.ttf
  • Linux : ./SimSun.ttc

  自动生成的配置中字体目录的默认路径如下:

  • DS : /Font 目录
  • Android : /system/fonts 目录
  • 其它平台:同数据目录

特定平台运行环境

DS

  以下说明中, $NDSEmulator 为模拟器 DeSmuME 可执行文件的绝对路径, $TargetPath 为 ROM 映像文件( .nds 文件)的路径, $FAT_Path为 FAT 目录路径(见以下说明)。

  之前经测试的最小版本为 0.9.6 。建议使用最新版本。

  运行时,需在运行模拟器的宿主机中准备一个目录作为映射到设备中的虚拟 FAT 目录。宿主的目录在运行中不会被 DeSmuME 修改;宿主目录的文件系统不要求为 FAT 。运行时会加载虚拟目录的内容。

注意 官方版的 DeSmuME 不支持包含非 ASCII 字符的宿主路径而忽略这些文件。部分修改版可能没有这个限制。

注意 因为 DS 模拟器和烧录卡需要加载 ROM 映像到 RAM 后才能运行,映像大小会影响可用运行内存,使用 debug 配置构建的 YSTest 示例版本不一定在 DS 上支持所有功能。相关支持限制及变更详见 YSLib 项目文档 doc/Test.txt

  可通过以下方式之一指定 FAT 目录。

Slot 1 映射

  Slot 1 (即 NDS ROM 卡槽,硬件介质可以是 NDS 卡带,或烧录卡和存储卡的组合)的模拟从 DeSmuME 0.9.8 版本起支持。

  运行命令行示例:

"$NDSEmulator" "$TargetPath" --preload-rom --slot1-fat-dir="$FAT_Path"

  其中 --preload-rom 对 0.9.10 和 0.9.11 版本是必须的(以支持自动 DLDI(en-US) 补丁),否则加载失败。这个选项可以在模拟器(Windows 版本)的 GUI 菜单中 ConfigROM Loading 中选择。最新版本的源码会对自制 ROM 自动启用 ROM 预先加载的选项而不用另行配置,可以省略这个选项。

Slot 2 映射

  Slot 1 (即 GBA ROM 卡槽,硬件介质可以是 GBA 卡带或其它扩展)的模拟需要配置为使用 GBA Movie Player (Compact Flash)

  运行命令行示例:

"$NDSEmulator" "$TargetPath" --cflash-path="$FAT_Path"

  对 0.9.10 和 0.9.11 版本,需同 Slot 1 映射添加 --preload-rom 或使用菜单设置加载选项,否则同样无法加载(尽管源码中表示 --preload-rom 是适用 Slot 1 而不是 Slot 2 的选项)。

  这个选项也可以通过 GUI 配置。在 0.9.9 版本前,使用菜单 EmulationGBA Slot 。自 0.9.9 版本起,使用菜单 ConfigSlot 2 (GBA Slot)

注意 DeSmuME svn4030 及之后的一些版本(至少包括 0.9.8 )会在载入 MPCF 映像时错误地忽略 --cflash-path 选项,以 仿真(Emulation) → GBA 插槽(GBA Slot) 菜单中的设置或对应配置文件 desmume.ini 中指定正确的路径。

  在 desmume.ini 中有效的最小配置:

[GBAslot]
type=1
[GBAslot.CFlash]
fileMode=0
path=H:\NDS\efsroot\

  这里 H:\NDS\efsroot$FAT_Path 的一个示例。

注意 自 Slot1 0.9.10 起,当 Slot 1 设置为 R4 时会覆盖 Slot 2 设置加载 R4 路径( Dev+ 版本显示自动 DLDI 补丁在 Slot 1 设置为 R4 从 GBA Movie Player (Compact Flash) 改为 R4(DS) - Revolution for DS ),因此需确保Slot 1 设置不为 R4 ,或正确设置了 Slot 1 R4 的路径(而改用 Slot 1 映射)。

MinGW32

  自 build 431 起,YFramework 使用的 FreeImage 修改版集成 libjepg-turbo ,需要 CPU 支持 SSE2 指令集扩展。

  除 2005 年前生产的硬件外绝大多数环境已经满足这个条件。当前几乎所有兼容 IA-32 的市售 CPU 都包含 SSE2 支持。特别地,支持 x86_64 指令集的 CPU 要求支持 SSE2 ,在使用 x86_64 的 64 位 Windows 上运行 32 位 Win32 程序(通过 WoW64 )也支持 SSE2 。

Android

  可使用 adb 命令安装 APK 包,如:

"$ANDROID_SDK/platform-tools/adb" -e install -r "$1"

  此处 -e 指定 TCP/IP 设备(通常是模拟器),若使用 USB 设备(通常是物理机器)应移除或使用较新的 adb-d 选项代替; "$1" 指定 APK 文件路径。

  之后,在 Android 的 GUI 环境下直接运行安装的程序。

  若因签名变更等原因无法覆盖安装或更新,需要先卸载后再安装。

注意 Android 安装 .apk 包时需要占用额外存储资源。为避免内置存储空间不足导致不直接表现安装失败(需要 logcat 查看)但直至运行时找不到二进制库而导致启动失败,应保留足够的空间,特别是对占用较大的 debug 配置构建的映像。保留空间的大小一般大于 .apk 作为 .zip 解压缩占用的空间。另见此处报告的未确认的类似问题

框架初始化

  框架初始化服务于整个框架。

  初始化的重要策略之一是在程序启动时减少不必要的初始化,以允许实现以下目的:

  • 减少可能的外部依赖(如不需要使用文字的程序就不初始化字体缓存,也不需要依赖外部字体文件和字体配置等)。
  • 减少可能的运行时程序资源占用。
  • 保留静态链接时优化去除没有调用的代码以减少二进制可执行文件大小的可能性。

  按当前框架的设计,框架初始化在 DS 平台在程序运行初始阶段完成。其它平台可延迟初始化,按需调用。

  并非所有 YFramework 中的 API 都要求框架初始化。以下功能隐含自动进行的框架初始化:

  • 使用默认字体缓存。
  • 使用 MIME 数据时。

  框架初始化加载配置文件,其中配置文件路径的确定方式参见以下节的说明。成功公共加载配置文件后,框架初始化检查配置文件的内容,并访问框架公共配置。若检查失败,抛出异常。

  修改 YFramework 模块 Helper::Initialization 重新编译后,可修改默认设置改变初始化行为。以下行为可能会在未来改变

根路径

  **根路径(root path)**是框架初始化时参考的基本路径,由如下方式确定:

  • Win32 和 Linux(除 Android ):程序映像所在的目录。
  • Android :SD 卡目录(自动按顺序检测 /sdcard/mnt/sdcard/storage/sdcard0 之一)。
  • 其它平台:第一次初始化时的当前工作目录。

  确定根路径在框架初始化或要求确定根路径时进行。若定位程序映像,同时会解析符号链接。若定位根路径失败,抛出异常。

  抛出的异常默认不被框架处理,可使程序退出。用户代码捕获特定异常可改变默认退出行为。

配置路径

  公共配置文件 yconf.txt 所在目录的路径前缀(结尾带有路径分隔符)称为框架的配置路径(configuration path),决定和平台相关的配置加载起始位置。配置路径和配置文件相对路径(对 yconf.txt ,即配置文件名)组合得到配置文件路径。

  配置路径的确定方式和平台相关。

  任意平台总能确定一个首选的配置路径。

  除首选的配置路径外,一些平台还支持一个或多个不同的后备(fallback) 配置路径。在读写特定的配置文件时,若根路径访问失败,但存在后备配置路径,依序使用这些路径重试直至成功或全部访问失败。这样的配置文件当前包括 yconf.txt 。具体应用可使用初始化 API 以类似的方式加载其它配置文件。

  以下是具有后备配置路径的平台中确定配置路径的顺序:

  • Linux(除 Android ):
    • 首先使用首选的配置路径。
    • 若环境变量 HOME 非空,则路径 $HOME/.YSLib/ 是后备配置路径。
  • Win32 :在 Linux 的基础上:若 $HOME 非空,则路径 $HOME/.YSLib/ 是后备配置路径。
    • 同 Linux 平台的使用顺序(对应使用 Win32 的环境变量和路径语法,即备份路径 %HOME%\.YSLib\ )。
    • 若环境变量 USERPROFILE 非空,则路径 %USERPROFILE%\.YSLib\ 是后备配置路径。

  后备配置路径中若子目录 .YSLib 不存在则被创建。若创建失败,配置路径访问失败。

  对不具有后备路径的平台,首选的配置路径总是根路径。否则,首选的配置路径由以下方式确定:

  • 程序映像所在的位置可推断出符合类似 FHS 的文件系统布局(称为局部 FHS 目录布局),则首选的配置路径为程序映像所在的目录的上一级目录的 var 子目录下的 YSLib 子目录。
    • 推断文件系统布局为以 POSIX 环境变量语法表示为 $PREFIX/$PREFIX/$BIN/$PREFIX/lib/$PREFIX/share/ 这些路径前缀都存在且可作为目录访问,其中 $PREFIX 是程序映像所在的目录的上级目录,而 $BIN 是程序映像所在的目录的名称(按 FHS 通常为 bin ,此处不检查)。
    • 这保证创建映像的可执行程序映像的目录中内容不被修改,以符合 FHS 。
  • 否则,首选的配置路径为根路径。
    • 确定配置路径要求确定根路径。

  对不具有后备路径的平台不检查文件系统布局,也不要求实现确保程序映像路径的操作,以简化实现。

注意 若后备配置路径的配置文件可访问,直接使用此配置文件保存配置,不再创建配置文件。若需要恢复在首选配置路径创建配置文件的行为,需确保后备配置路径的配置文件不可访问(例如,移除所有后备配置路径的这些配置文件)。

配置文件加载

  加载配置文件 yconf.txt 时,首先按上述的顺序确定各个配置路径,每确定一个路径时访问其中的配置文件。若全部失败(如找不到可读的文件),则尝试自动生成配置并创建配置文件。创建配置文件的位置和顺序同上述确定配置路径的顺序。若创建配置文件全部失败,则放弃创建配置文件,直接使用生成的配置。

  不存在配置文件时,配置不能通过 Helper::Initialization 的 API 持久化保存,尝试保存配置会失败。

其它初始化

  成功后,框架进一步处理公共配置文件以外的其它初始化;详见以上具体配置文件的相关章节。

版本库结构和文件说明

  以下只包括一级目录和少数特定的二级目录说明。

  • /.git Git 目录(可通过 hg-git 同步)
  • /.hg Mercurial 目录
  • /3rdparty 第三方依赖项
  • /Data 最终用户环境中部署的数据目录
  • /Tools 开发使用的(辅助)工具
    • /Tools/SHBuild SHBuild 构建工具
    • /Tools/Scripts 用于构建和建立 SHBuild 环境的工具脚本
  • /YBase 顶级子项目 YBase
  • /YFramework 顶级子项目 YFramework
  • /YSTest 测试用示例项目目录(项目名为 YSTest ,以实际内容命名的项目名为 YReader )
    • /YSTest/Android 示例项目 YReader 的 Android 平台项目(未完成正式支持)
    • /YSTest/DS_ARM7 示例项目 YReader 的 ARM7 项目(仅用于 DS 平台,用于生成 ARM7 ELF 二进制映像)
    • /YSTest/DS_ARM9 示例项目 YReader 的 ARM9 项目(包括 DS 平台 ARM9 部分,于生成 ARM9 ELF 二进制映像;源代码和其它平台共享)
    • /YSTest/DS 示例项目 YReader 的 DS 平台可执行文件项目(仅用于 DS 平台,用于生成 NDS 文件)
    • /YSTest/MinGW32 示例项目 YReader 的 MinGW32 平台可执行文件项目(仅用于 MinGW32 平台,用于生成 EXE 文件)
  • /build 默认构建目录
  • /doc 开发文档
  • /doc/vsd 架构示意 Visio 文档
  • /test 测试项目目录
  • /.hgignore Mercurial 忽略文件
  • /.hgtags Mercurial 标签文件
  • /CC BY-SA 3.0 legalcode.txt 文档许可证: Creative Commons Legal Code Attribution-ShareAlike 3.0 Unported
  • /Doxyfile Doxygen 配置文件
  • /FTL.TXT 许可证: The FreeType Project LICENSE
  • /gpl-2.0.txt 许可证: GNU GENERAL PUBLIC LICENSE Version 2
  • /gpl-3.0.txt 许可证: GNU GENERAL PUBLIC LICENSE Version 3
  • /LICENSE.txt 整体许可证
  • /LICENSE_HISTORY.txt 整体许可证:历史版本
  • /license-fi.txt 许可证: FreeImage Public License - Version 1.0
  • /Readme.zh-CN.txt 自述文件
  • /YSTest.sln Visual Studio 解决方案文件
  • /YSTest.workspace Code::Blocks 工作空间文件

  以下目录会被默认支持的构建配置生成:

  • /YDE/ 下以 . 起始的特定宿主平台为子目录名的构建目录是 stage 2 环境下的 YDE 项目的生成文件目录
  • /build/ 下以特定的宿主平台为子目录名的默认构建目录,默认配置构建时会创建不同的平台目录,其中的子目录可包括:
    • .stage1 stage 1 环境 构建和生成目录
    • .test 测试项目构建和生成文件目录
    • . 起始的其它 Sysroot 构建目录,用于创建 stage 2 环境的 YSLib 库以及基于 stage 2 环境的 Sysroot 方式的 YSTest 的构建
    • 其它非 Sysroot 的 YSLib 和 YSTest 项目生成文件目录
  • /sysroot 使用脚本构建的默认 Sysroot (含 stage 2 环境) 生成目录

项目结构和特性

  项目内容以模块为单位组织。关于模块的概念及其表示形式,详见 YSLib 项目文档 doc/ProjectRules.txt 。因为特性众多,在此只列出较上层的基本结构,不总是精确到具体模块。

YBase :YFramework 基础库

  详见 doc/YBase.txt

  替代标准库的特性另见 StandardUsing(en-US)

  • YStandardEx : YFramework 标准扩展库
  • LibDefect :标准库修正
  • YTest :YFramework 基础测试库

YFramework : YFramework 框架库

  详见 doc/YFramework.txt

  • CHRLib :字符编码处理库
    • 编码标识
    • 目前支持 UTF-8/UCS-2/UCS-4/GBK ,可扩充
    • 默认编码 UTF-8
  • YCLib : YSLib 基础库
    • Platform :平台定义
    • 平台相关 API 封装
    • 平台相关硬件抽象
    • Win32 专用接口(略)
  • YSLib :YShell 库(主体,暂定)
    • Adaptor :适配器层
      • Configuration : 库配置
      • YReference :智能指针封装(基于 Loki 实现【已移除】/使用 ISO C++11 标准库)
      • 简单的内存调试设施
      • 附加容器(可选 Loki 的 yasli 容器,默认不启用)
      • Anti-Grain Geometry 2.4 移植(修复了一处在 2.5 仍然存在的 bug ),因在 DS 上效率太低所以默认不启用【已移除】
      • Font :字体管理(基于 FreeType 2 实现)
      • Image :平台中立的图像输入和输出(基于 FreeImage 实现)
    • Core : YSLib 核心
    • Service :YSLib 服务
    • UI : YSLib 用户界面
    • NPL
    • Helper :助手库:初始化、宿主支持等

YReader :示例

  • ShlExplorer :文件列表浏览
  • 控件测试:按钮点击、窗口拖曳、 FPS (伪)显示等
  • Shell 切换
  • ShlReader :文本浏览
    • 读取并显示文本文件的内容
    • 随机跳转
    • 书签设置、读取和保存
  • HexBrowser:十六进制浏览

构建

  支持使用多种途径进行构建。支持多平台构建。另见 Sysroot 和以下的“轮子列表”章节。

  依赖以模块为单位组织。接口(如公开 API 头文件)不出现循环依赖。

  可通过修改代码以裁剪、定制库实现内部的模块构建(如为了减小编译后的二进制映像体积),但应注意在 YSLib 项目文档中列出的显式依赖规则。未来可能会支持构建时的定制配置工具。

ABI

  目前除 YBase::LibDefect 和具体实现兼容外,不保证 ABI 稳定。

  具体策略详见 YSLib 项目文档 doc/ 下各个库的文档。

API

  对各 API 的说明和注意事项详见 YSLib 项目中的源代码,可构建文档

平台相关 API 注意事项

  • YCLib::MemoryMapping 中 platform::MappedFile 的实现需确保文件内容可访问,否则取指针后,可在之后的操作中引发不可恢复的错误。
    • 在硬件支持 MMU 的平台上,使用内存映射实现。
      • 读取错误产生不可恢复的错误。
      • 因此不支持不可靠的远程文件。
    • 其它平台(当前包括 DS ),使用文件流模拟。
      • platform::MappedFile 初始化失败会直接抛出异常。除非用户代码忽略,可避免引发后续失败(引起未定义行为)。
    • 当前仅支持只读映射。若修改取得的映射指针指向的存储,在使用内存映射实现的平台上也可引发上述行为类似的不可恢复的错误。

标准库使用

  YSLib 对 C++ 标准库具有明确的要求,且仅使用明确的标准库特性

  和 LLVM 编码标准对 C++ 标准库的使用(en-US)类似, YSLib 强调尽可能依赖标准库的公开接口。仅在具有充足理由时不依赖标准库而提供和使用自定义 API (基本上总是因为设计和实现的质量不足够满足需求和以上要求的原因)。

  对标准库特性使用的具体限制见开发说明及 YSLib 项目文档 doc/LanguageConvention.txt 等规则。

  相关的其它原理另见下节。

轮子列表

  本项目发明了一些轮子。为了符合不重复发明轮子的项目内容规则,在发现更好的替代时,其中一些会被逐渐移除。

  但是,其余一些轮子,因为特定的原因,不视为对此规则的违反而得以保留,包括一些在当前实现中使用的和较新版本语言规范中提供的兼容的特性。

  主要包括以下内容:

  • YBase.YStandardEx
    • 为了兼容性需要,一些标准库接口的实现会被保留。但当合适的版本可用时,通过条件包含选择别名声明,优先使用标准库提供的版本。
    • Meta 、 TypeTraits 以及其它元编程设施
      • 其它元编程设施因为没有被标准化、风格和可用性问题,提供了 C++14 兼容的元函数和类似 Range-v3Boost.Hana 的实现使用的接口。
    • IntegerSequence
      • 主要接口兼容 C++14 的 std::integer_sequence ,但早于提案 N3493
      • 提供了更丰富的底层接口如 make_peano_sequence
    • Operators
      • 接口类似 Boost.Operators ,但有以下不同:
        • 要求 C++11 支持。
        • 使用代码量较少的紧凑的实现,不支持对不符合标准的编译器的多数实现细节上的变通。
        • 不支持链式模板参数(这是为了兼容不支持偏特化的编译器的变通)。
        • 提供对 noexcept 的支持。
      • 接口类似 The Art of C++ / Operators(原 df.operators )。
      • 除以上列出外,还有以下差异和特性:
        • 操作符模板使用别名而不保证是类。
        • 支持可选的操作符参数,默认推断 constexpr
        • 重载操作符实现为模板友元以支持推断 constexpr 同时允许在派生类中提供显式覆盖实现。
      • 此外,提供部分不在上述类似接口中提供的成员操作符重载。
    • Any
      • 接口类似 Boost.Any ,包括内部非公开的 unsafe_any_cast 作为扩展;此外 any 成员也有一些扩展。
      • 除了 any 外还提供底层实现相关的扩展,用于实现 AnyIterator ,这无法被简单取代
      • Any 的提案最早于 2006 年基于 Boost.Any 提出,未考虑 C++11 特性。此实现早于标准库提案的后续修订版本实现。
      • 现在和 WG21 N4081std::experimental::any 同步,但仍然保持扩展。
      • 使用了小对象优化实现,这也符合后来更新的提案中的建议。
      • 提供 emplace 相关扩展,可避免构造 any 对象或赋值时冗余初始化目标类型的值。
      • 提供 unchecked_* 成员和 unchecked_any_cast 模板扩展,要求参数非空,因为省略检查比对应的检查空值的接口( unchecked_any_cast 对应 unsafe_any_cast )更高效。
    • Optional
      • ISO C++17 的 <optional> 在 ISO C++11 下的移植和扩展。
      • 支持几乎所有特性,除 operator-> 因为核心语言特性限制不总是支持结果是常量表达式。
      • 支持少量扩展接口: make_optional_inplaceref_opt
    • Map
      • ISO C++17 的 <map> 在 ISO C++11 下的移植和扩展。
      • 支持不完整键类型,不依赖特定扩展(如 libstdc++ 的 std::map)。
    • Invoke
      • 提供 std::invoke 的替代。
    • Apply
      • 提供 std::apply 的替代。
    • Function
      • 提供 std::function 的替代。
    • Rational
      • 类模板 fixed_point 和提案 P0037R1 中的有相似之处,但模板参数类型更明确,且提出较早。
    • 一些非直接的(以同名接口一一替代的)标准库替代接口
      • 减少了标准库对应的限制,提升了易用性。
      • 不一定和标准库的对应功能的 API 同名。
      • lref 部分取代 std::reference_wrapper (涉及 std::bind 的使用无法取代)。
      • mapped_setystdex::map 模拟 std::set
        • 不要求键类型保持 const 。这意味着(和 C++98/03 类似)只要不影响比较操作的等价关系,元素可以使用无 mutable 修饰的成员而保持 const 类型检查。
        • 使用 ADL set_value_move 优化插入等操作,允许转移值。
        • 在 C++11 下即支持泛型查询接口。
        • 因为使用 ystdex::map ,支持不完整键类型。
    • 一些通常典型地用于标准库内部实现的接口
      • 实际上也适于被用户代码使用。
      • has_mem_valuehas_nested_allocatorenable_if_transparent_t 等检查类型要求的元编程设施。
      • search_map 提供关联容器查找,适合实现 map 等的 operator[]try_emplace 等设施。
        • 支持迭代器提示参数。使用比当前(2016-03) 最新开发版本的 libstdc++ 更紧凑的实现(而 libc++ 对 map::try_emplace,用 lower_bound 近似,也包括对用户代码提供提示参数的情况(直接忽略提示),后者尽管满足复杂度要求但特定情况下容易更低效。
    • 其它可在 C++11 下使用的标准库扩展
      • ISO/IEC TS 19568:2015 C++ Extensions for Library Fundamentals (最终草案 N4480) 以及 ISO/IEC DTS 19568 C++ Extensions for Library Fundamentals, Version 2 (草案 N4564)的一些接口在 C++11 下的实现和 YStandardEx 扩展。
        • 提供元函数 and_or_not_
          • 是早于提案 P0013R0 的实现。
          • 比原始提案及 libstdc++ 中使用的实现更简单。
          • 以别名模板的形式支持 P0013R1
        • 函数模板 apply 利用更加强大(投影到不同参数位置进行调用)的 call_projection 实现,而非直接基于 integer_sequence
        • 类模板 optional
        • any 大体兼容这里的接口规范。
        • 类模板 string_view
        • 类模板 observer_ptr
        • 部分比较操作使用 Operators 实现,保证一般预期的可用性同时简化实现及改善编译性能,但不完全和规范一致。
      • 函数模板 destroy 是早于提案 P0040R0 的实现。
        • 使用不同的参数形式被重命名为 destruct 等模板。
        • 实现和 P0040R2 兼容的相关接口。
      • 类型特征 unwrap_reference 早于提案 P0318R0 提供,功能近似。
  • YFramework
    • 一些接口存在第三方的高效实现,但不足以同时在性能和功能上取代现有接口和实现。(以下性能测试因为实际环境基准问题当前仅用于内部测试,未正式支持。)
    • CHRLib
      • 提供的 UTF-8 解码实现之一在主要支持平台(即 MinGW32 )上实测为当前已知最快的实现。
        • 第二快的是 RapidJSON 。虽然同样使用状态转移查找表,它使用刻意避免分支判断的实现机制,使用的表较大而对缓存可能不友好,导致在典型的实现中反而不一定更快。此外实测表明,使用 GCC 的 __attribute__((flatten)) 即能明显影响这里的性能,程度和算法优化相比无法忽视。
        • 其它朴素实现都明显落后于使用状态查找表算法的性能。
    • YSLib.Core.YEvent
      • 在不进行体系结构和 ABI 相关优化的限制前提下, YSLib::GEvent 的性能超过这里的除了 jl_signal 所有实现。而后者基于特定实现的 ABI 进行了较为复杂的优化。(待定:整合新的测试。)
      • 除了没有 Boost.Signal2 的线程安全和定制返回类型策略的接口外,所有功能都不弱于上述测试中的例子。
      • 此外,基于 ystdex::make_expanded 提供允许省略未使用的参数这个实用特性,是以上测试用例都不具备的。事实上,尚没有已知的 C++ 库中提供类似的特性。其它语言可能提供类似的特性简化 GUI 开发,如 {x:Bind} ,但实现原理上,其运行时性能不可能超过此处的方式(静态语言在翻译时确定参数列表)。

项目依赖性

  示例项目 YSTest 在 DS 上依赖 YSTest/DS_ARM7 和 YSTest/DS_ARM9 两个项目。 YSTest/DS_ARM9 依赖于 YFramework ;在其它平台直接依赖 YFramework 。

  YFramework 依赖 YBase 。

  除了 MinGW 外使用 Make 构建。需要添加静态库时,把相应的 .a 文件加入相应的 lib 目录下,否则需要手动修改对应的 Makefile

  MinGW 使用 Code::Block 或 Sysroot 构建。

生成路径

  默认构建的根目录位于版本库下的 build 目录。

注意 本节以下内容不适用于 Sysroot

  设 $(Platform) 是平台名称,$(Configuration) 是生成配置名称,则各个项目生成的文件和中间文件都在项目的 build/$(Platform)/$(Configuration) 子目录下。 修改 Makefile 的配置可以分离生成文件和中间文件的输出路径。

  默认生成配置名称可以是 debugrelease(注意此项的大小写会在 Makefile 中表现出区别)。

概述

  NPL 是 YSLib 提供的语言集合,它在语言规范层次上被设计为可扩展的。

  通过派生(derive) 现有的语言( NPL 方言),避免完全重新设计新的语言,来满足需要一些新语言的场合下的需求。被派生的语言是 NPL 的抽象语言实现。翻译或执行 NPL 或 NPL 抽象语言实现的程序是 NPL (方言)的具体语言实现。具有具体语言实现的方言仍可以派生新的语言作为领域特定语言

  派生领域特定语言的一个其它的例子是 XML

语法

  NPL 的语法基于形式文法上可递归构造的表达式,其中的子表达式在此称为

  非正式地, NPL 使用类似 S 表达式的基本语法,但不使用二元有序对(和终止符号)而直接支持列表;即表达式直接以是否为括号作为边界,分为列表表达式非列表表达式

  正式语法中,项可以是列表或非列表项的混合表达式(composite-expression) 规约列表项中的一部分代替有序对的地位,以要求任意项可被无歧义地进行从左到右的语法分析。

  NPL 只要求小括号作为列表表达式的边界。其它替代的括号由派生实现约定。对于适用于多个 NPL 实现的可移植代码,避免使用其它语言中习惯作为代替括号边界的字符表示替代的括号以外的含义,特别地, ISO C++ 文法 balanced-token 中的边界字符 ()[]{}

  NPL 对标识符的限制较为宽松。 ISO C 和 ISO C++ 的所有标识符都是 NPL 标识符。但派生实现可加以限制。

  NPL 不提供专用的注释语法。以特定形式的项(如表示字符串的字面量)替代注释是预期的惯用法(idiom) 。这不妨碍派生语言可能添加预处理器扩展特性。

语义

  NPL 提供了一些通用的概念但不构成语义规则。语义规则由派生实现约定。

实现

  在 YFramework/NPL 提供一些参考具体实现。当前 YFramework 主要使用抽象实现 NPLA 的具体派生(derived) 的实现 NPLA1 ,在这个基础上用于不同的目的,如程序配置动态加载的 GUI 等。

  这些实现基于模块 YSLib::Core::ValueNode 提供的数据结构,可以方便地修改和组合语法和语义节点的内容。

  NPLA 提供了比大多数现有的程序设计语言更强大的一般抽象。这集中体现在:

  • 和 NPL 的原始设计一致,不提供也不要求区分实现的阶段(phase) 。
  • 支持一等环境(first-class environment) 不修改现有语言的求值算法即可实现共享类似语法的新语言。
  • 允许以一般手段表达求值和未求值表达式的差异。

  这意味着 NPLA 是本质上动态的语言,但和一般语言不同,用户可以很大程度上动态地替换现有语言实现,包括在运行时替换一个解释实现为一个或多个优化编译器。这也意味着语言设计上既不需要区分解释实现和编译实现(本质上不对立),也不需要区分动态和静态(因为随时能从基础语言上构造出静态子集)。

  这样的特性设计在绝大多数语言中不存在并且几乎无法支持。作者已知唯一的例外是 Kernel ,在这些特性上有极大的相似,尽管实际上基本特性是独立设计的,并且在基本设计哲学上有极大不同( NPL 和 RnRK 中明确的 guidelines有很大不同且基本不兼容)。不过,考察设计的完整性, NPL 的派生语言也从中借鉴了一些重要的附加特性:

  • $vau合并子(combiner) /应用子(applicative) /操作子(operative) 等术语。
  • 在绑定构造中支持模式匹配的形式参数树(parameter tree) 。
  • 一些以合并子形式提供的操作。
    • 一般的作为接口提供的合并子在 NPL 中仍称为函数;合并子是作为表达式的函数的特定的求值结果。(在 Scheme 中,合并子中的应用子对应过程(procedure) 。)
    • 相似的操作主要体现在名称和语义上。因为一些基本设计的差异,不保证完全兼容。
    • 相似操作的实现不尽相同,但其中不通过宿主语言的直接的实现(称为派生(derivation) )有一部分几乎完全相同。
    • 使用 $ 作为一些标识符(如 $lambda )的前缀是独立设计的巧合;现在含义已和 Kernel 一致,表示 special form

  一些值得注意的和类似语言的主要设计差异(原理详见开发文档):

  • NPL 和 Kernel 类似,强调一等对象(first-class object) ,但含义有所不同。此处的“对象”和 ISO C 及 ISO C++ 中的定义类似,具有比 Kernel 更严格的含义。
    • 和 Kernel 合并子及 Scheme 过程类似, NPLA 默认使用按值调用(call by value) ;但与之不同,不隐式对实际参数别名(aliasing) ,不共享对象。
  • NPLA 和派生实现的语法和整体的求值类似 Scheme 和 Kernel 大多数基于 S 表达式的 Lisp 方言,但有一些显著的区别。
    • NPLA1 明确区分约定包括列表项的求值规则。和传统习惯不同, NPLA1 中括号明确不需要表示应用的含义,这可以减少一些场合(如命令行)需要输入的过多的连续括号。
    • 和 RnRS 定义的 Scheme 以及 Kernel 一致,不支持某些 Lisp 方言的方括号 [] 替代圆括号 () 的语法。
    • 不提供注释语法。
    • 语言实现中内置预处理处理中缀 ;, ,作为前缀合并子 $sequencelist 的语法糖。两者的含义和 Kernel 中的相同(类似 Scheme 的 beginlist )。
  • 和 Kernel 相似而和 Scheme 不同,使用操作子及一等环境和 eval 代替 Scheme 的卫生宏(hygienic macro)(en-US) 及宏展开的作用。
    • 和 Kernel 类似,鼓励使用直接求值风格而不是引用(quote) 。
    • 不过 NPLA 也提供了 $quote 的派生而非如 Kernel 一样完全避免。
  • 和 Kernel 不同, NPL 明确支持资源抽象,不保证支持循环引用,而 NPLA 明确不支持循环引用。
  • NPLA 明确支持基于 C++ 实现的对象模型和互操作,且明确不要求支持全局 GC
    • 从在互操作的目的出发,和 C++ 具有相似性和相容性。
      • 支持基于 C++ 抽象机语义的更一般的副作用(除原生 volatile 外)和一等状态(first-class states) 。
      • 和 ISO C++ 类似,在语言规格中保留特定的未定义行为,而不要求实现避免。
      • 暂时不直接支持多线程环境,但可以在不同线程上同时使用不同的实现的实例。
      • 函数默认使用不隐式别名的按值调用和返回传递复制或转移值,和 C++ 对应上下文的复制初始化(copy initialization) 语义一致。(不过求值为操作子的 NPL 函数在 C++ 没有直接的对应。)
    • vau 演算的论文 中,提及不支持全局 GC 有较大的 admistrative cost 但没有详细讨论和语言特性的联系。
  • 即便不支持全局 GC ,当前实现仍然明确支持 PTC(proper tail call) 。
    • PTC 基于语言规则而不是实现行为定义,详见 proper tail recursion ,这里和 Kernel 提供的保证含义一致。
    • 没有在其它语言发现这种不支持全局 GC 和支持类似 C++ 副作用的情形下的 PTC 支持的先例。
  • 和 Kernel 不同, NPLA 不完全强制对象类型的封装(encapsulation) ;且基于支持互操作的考虑,支持开放的类型系统,而不要求覆盖所有值(即要求对象类型分区(partition) )。
  • 对机器数(不论是整数还是浮点数)的操作被剥离了,当前不被支持,需要用户代码添加个别操作。
  • NPLA 的规约(reduction) 框架和 vau 演算的操作语义几乎完全一致,不过实际上(因为先前语言设计上的不确定)显著地保留了更多的可扩展和可修改性。

当前实现

  当前派生实现的 NPLA1 由 YFramework 提供 API 。其中包括 REPL (read-eval-print loop) 的解释实现。外部文件的形式的 NPLA1 脚本可被基于这些 API 实现的 stage 1 SHBuild 调用并用于 YFramework 的构建。

  由 YFramework 对外部编码的假设,NPLA1 实现加载的文件流的剩余内容的编码视为 UTF-8 ;同时支持 CR+LF 或 LF 为换行符。

进一步阅读

  语言特性设计的需求参见这里(en-US)

  关于 NPL 语言及当前使用的实现的规格,参照 YSLib 项目文档 doc/NPL.txt

Kernel 实现

  NPL 文法是 S-expression 语法和 Kernel 兼容语义的简化,某些 NPLA1 程序可以原封不动地作为 Kernel 程序运行。因为参考文献可用性以及相似性几乎独一无二,建议深入使用前参照 Kernel 相关的文档并实际使用,以和 NPL 进行比较(当前 NPL 开发文档也引用包括 RnRK 在内的一些规格说明)。现有较完整可用的一个 Kernel 实现是 Klisp

计划支持特性

  在 Kernel 中已存在但当前 NPLA1 未支持,而计划在未来添加的特性:

  • 一等续延(first-class continuation)
  • Promises
    • 虽然 NPLA1 之前有部分原生实现,但计划改用基于封装类型派生。
  • Keyed Variables
    • 有效的 keyed dynamic varabile 实现可能依赖一等续延数据结构。
    • 有效的 keyed static varabile 实现需要调整环境数据结构。
  • Ports
    • 需要调查内存映射文件和其它系统支持。
  • Libraries
    • 可能需要提供多种不同的接口。

  已提供但考虑可能优化实现的特性:

  • 封装类型
    • 需要调查互操作相关的特性和持久化支持。

  计划考虑提供其它设计替代选项的 Klisp 特性:

  • Characters
    • 满足互操作要求的前提下,使用设计更合理的类型替代。
  • Vectors
    • 使用更完善的用户自定义派生类型替代。

  其它 NPL 计划实现特性:

概述

  Sysroot 是具有特定逻辑布局根目录兼容的目录,一般在文件系统中实现。

  Sysroot 主要用于本机程序的开发环境构建和部署,以后也可能用于交叉构建(cross building) 。

  在利用 Sysroot 开发之前有必要了解开发注意事项:

  Sysroot 使用的文件系统路径满足运行环境对外部文件的路径的约定。

  当前 Sysroot 仅支持 MinGW 和 Linux 环境。

  关于本文档讨论以外的脚本的其它行为,参见脚本的有关说明。

布局

  在满足前述要求的前提下, Sysroot 部署实例使用的文件系统布局原则上和一般类 UNIX 系统使用的布局同构,具体子目录布局如下:

  • .shbuild :使用 SHBuild 构建时的临时目录(可以在部署后手动删除)。
  • 系统前缀字符串指定的作为安装路径前缀的最后一个路径组件的目录文件名(如 usr ):被部署的用户空间目录,其中的内容使用 Linux 等现代 UNIX 变体类似的约定:
    • bin :二进制文件。
    • include :头文件。
    • lib :库文件。
    • share :共享的数据文件。
      • share/NPLA1 :NPLA1 脚本部署位置。
    • var :程序运行时可修改的数据。

  其中,除 var 外,这些目录中的内容在安装或维护部署情形外通常应保持只读。

  对 MinGW32 和 MinGW64 平台,系统前缀字符串指定的路径和 MSYS2 构建系统的 /etc/msystem 脚本指定的 MSYSTEM_PREFIX 的值一致,对应 MSYS2 支持的两个 mingw 子系统路径

  上述 bin 目录可以加入环境变量 PATH 中以便其中的程序被命令行执行。当前若使用 YDE 构建脚本,这是必要的。

安装脚本

  YSLib 项目提供生成可打包的 Sysroot 的安装脚本,位于 Tools/Scripts/install-sysroot.sh 。输出的 Sysroot 的默认位置为版本库根目录下的 sysroot 目录。安装 Sysroot 时构建和部署多个项目,详见以下各节。

基本安装

  使用 SHBuild 构建和部署运行环境,包括库和工具。

建议阅读以下关于选项以及脚本说明后再运行命令。

  可进入 bash 运行以下 GNU bash 脚本:

Tools/install-sysroot.sh

  直接在默认输出位置构建和部署基础环境。

注意 当前构建脚本默认使用 uname 判断目标的体系结构。对于 MSYS2 等环境,结果为基本系统的体系结构而不一定和目标系统相同。若使用 64 位基本系统构建 32 位目标,使用以下命令代替:

SHBuild_Env_Arch=i686 Tools/install-sysroot.sh

  此处自动环境检测的机制同 shell 脚本 Tools/Scripts/SHBuild-common.sh 中的函数 SHBuild_CheckUName ,详见脚本的说明。

构建和部署

  构建过程包括 SHBuild 可用的多阶段构建

  构建时在 Sysroot 输出目录种保存中间输出。当前不清理这些中间输出。

  通过脚本选项,在 stage 2 SHBuild 需要的库时,也可生成其它的 YSLib 库(静态库和调试版本的库)。

  YSLib 库和依赖的外部的第三方库的二进制文件和对应的头文件在构建后被部署到 Sysroot ,并在之后用于构建 stage 2 SHBuild 。

  完成构建 stage 2 SHBuild 后,脚本部署 stage 2 SHBuild 和脚本(参见以下节)到 Sysroot 。

脚本部署

  在 stage 2 SHBuild 构建后,部署 SHBuild 同时安装(复制)版本库中的以下位置的 脚本文件(无视路径前缀)到 Sysroot 的对应安装路径:

  • NPLA1 脚本安装到 share/NPLA1
    • Tools/Script/SHBuild-BuildApp.txt
    • Tools/Script/SHBuild-YSLib-common.txt
  • Shell 脚本安装到 bin
    • Tools/Script/SHBuild-common.sh
    • Tools/Script/SHBuild-common-options.sh
    • Tools/Script/SHBuild-common-toolchain.sh
    • Tools/Script/SHBuild-BuildApp.sh
    • Tools/Script/SHBuild-BuildPkg.sh

可选工具

  通过脚本选项,在部署 stage 2 SHBuild 后,也可安装 Tools 下的其它工具:

构建时的警告

  除引导 stage 1 SHBuild 最后的链接器警告外,因为升级或更换编译器和/或选项,导致预编译头文件( .gch 文件)不能被识别的警告也可被安全忽略。

  • 此时编译器应能自动忽略这些文件。
  • 若需要预编译头文件在后续重复构建时的性能提升,可以清理这些文件,一般在对应项目生成的相同目录;可手动搜索构建目录中所有 .gch 文件并删除后再运行构建脚本,默认包括以下位置:
    • 项目中的 /Tools/SHBuild 用于 stage 1 SHBuild 构建。
    • 项目中的 /build 构建目录。
    • 安装 stage 1 SHBuild 后默认在部署的 /sysroot/.shbuild 继续构建目录。
  • 若不需要使用预编译头文件,可参考脚本说明设置变量。
  • 若仅需避免产生警告,确保编译器命令行使用恰当选项,如添加 -Wno-invalid-pch

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

Sysroot 开发指令

  使用 Sysroot 开发,首先需安装 Sysroot 环境,参见以上安装脚本的说明。

应用程序构建脚本

  YSLib 应用程序可使用 SHBuild 构建。为简化构建流程,使用应用程序构建脚本包装对 SHBuild 的调用。

  应用程序构建脚本不限制实现使用的语言,但在版本库中提供的脚本应符合公共的约定;此外,具体脚本可能需要指定适当的 PATH 以确保外部的工具可被调用。

  典型地,应用程序构建脚本是 shell 脚本,可依赖 Sysroot 环境已构建的 Sysroot 环境,并调用 NPLA1 脚本。

  YSTest 支持使用脚本 /YSTest/SHBuild-YSTest.sh 构建,可作为例子参考。和其它在安装脚本部署的 stage 2 应用不同,当前默认情况下使用版本库中的 build 目录下的平台目录存放生成的文件(中间文件和生成的可执行程序示例)。

部署

  除安装脚本外,当前不提供直接部署程序。

  参照运行确定二进制依赖项位置和调整运行时的配置。

概述

  YDE 是 YSLib Desktop Environment 的简称,预期作为一个基于 YFramework 的桌面环境。

  当前是一个 YSLib 的顶级子项目,构建需要 Sysroot 支持。

  YDE 包含一系列的包(package) 在单独的目录中作为次级子项目。

构建

  当前只提供 build-all.sh 使用 SHBuild-BuildApp.txt 构建所有包。

准备

  • 参见开发说明
  • 参见 Sysroot入门 的说明配置环境,确保 Sysroot 部署的 usr/bin 目录在 PATH
  • 运行 build-all.sh ,可以提供参数

  构建的结果参见 SHBuild-BuildApp.txt 的文档。

包列表

  • ImageBrowser 图像浏览工具
  • Clock 模拟时钟

运行

  参见运行了解所有基于 YFramework 的程序的说明。

使用配置 yconf.txt ,详见关于运行的说明

ImageBrowser

  运行程序会打开命令行第一个参数作为路径的文件。支持从资源管理器拖拽到程序。

  支持 YFramework 支持的图像格式:

  • BMP
  • GIF
  • PNG
  • 非渐进 JPEG

  支持滚轮缩放。

  单击右上角退出按钮退出程序。

  右键单击界面其它部分弹出上下文菜单。有以下菜单项:

  • 退出:关闭窗口,退出程序。
  • 查看原始大小:当显示的图像不是原始大小时,缩放图像到原始大小。
  • 翻转:旋转 180° 。
  • 顺时针旋转:顺时针旋转 90° 。
  • 逆时针旋转:逆时针旋转 90° 。
  • 复制:复制当前显示的(可能经过缩放的)图像内容到剪贴板。

  旋转时保持图像中心位置不变。

  中键单击界面其它部分查看原始大小。

  支持键盘快捷键:

  • Ctrl+C 复制

Clock

  右键单击界面退出程序。

概要

  本文档记录发布工程(release engineering) 相关的规则、历史记录和相关计划。

  发布策略控制版本更新。

  关于版本(revison) 的详细规则参见 YSLib 项目文档 doc/ProjectRules.txt

分支(Branching)

  一个项目可有多个分支(branch) ,包括至少一个保持工作进行的活动(active) 分支。

  发布时使用活动分支,以项目版本库的分支为准。

  当前只有主分支(master branch) 。

标识(Identification)

  阶段(phase) 标识连续的版本,描述一个分支在一个时期内版本的发布状态。

  当前位于 Alpha 非正式发布阶段。

迭代阶段(Iteration phase)

  迭代阶段是工程意义上的版本标识,适用于所有在开发、测试和维护生命周期中的分支,包括仅包含开发和测试版本的场合。

  PreAlpha 阶段不对 API(应用程序编程接口)稳定性进行任何保证。

  Alpha 阶段尽量保证公开 API 的非向后兼容的修改最小化,但仍然不保证兼容。

  Beta 阶段保证主要项目的 API 向后兼容性。非兼容的改动不再在当前迭代周期内引入,否则视为缺陷。

  Beta 阶段开始提供面向非开发者的部署方案。

  允许在每个迭代周期中按以上顺序补充新的阶段。

  关于项目内的提交版本(revision) ,详见项目文档 doc/Dependencies.txt 的约定。

发布阶段(Release phase)

  发布阶段使用的版本标识是被用户用于区分产品特性的标识。

  正式标记形式为以 V 起始,跟随符合语义化版本规范语法的版本号。

  版本号同时符合语义化版本规范的语义:在语言实现保持兼容的前提下,相同主版本(major version) 的发布应保持公开的命令行调用接口、API 和 ABI 向后兼容。主版本变化可引入不和先前迭代周期中保证兼容的改动。

  由公开的兼容性约定,除非另行指定,作为公开的命令行接口的工具在相邻的次版本(minor version) 之间向后兼容。一般地,若工具实现的公开功能被继续支持,命令行工具不在提供向后兼容功能的替代工具前被移除。

注意 非标记为发布版本的开发版本不需要保证以上要求。

  不兼容未来计划的改动的特性可标记为弃用(deprecated) 以表示可能在之后不继续支持。

非正式版

  非正式版的版本号小于 1.0.0 ,不保证任何 ABI(应用程序二进制接口)兼容性。

  所有非正式版共享一组迭代阶段。

正式版

  正式版的初始版本号为 1.0.0 。

  正式版提供版本检查的 API 。

  正式版对应的开发和测试版本使用以上除 PreAlpha 以外的阶段,具有上述相同的要求。

支持策略

  支持策略基于发布规则。

  当前仅对最新的非正式版及版本库活动开发分支上的最新提交版本(tip) 提供公开支持。

  正式版适用的规则另行具体指定。

持续集成(Continuous integration)

构建

  提供有限的构建自动化(build automation) 支持。

  关于使用的构建工具,参见先决条件,并参见构建过程。

  在宿主环境下使用项目内自行开发的工具支持,参见 SHBuildSysroot

里程碑和路线图

  本节略述发布版本的参照目标,包括重要的特性实现。

  关于包含较详细特性变更说明的发布版本的发布注记(release note) ,参见版本库中的文档 doc/Dependencies.txt ;关于提交版本的详细变更记录(change log) ,参见项目文档 doc/ChangeLog.*.txt

已实现的重要特性

PreAlpha

  PreAlpha 阶段实现平台中立的基础设施和 GUI 。每个发布版本包含重要的新增特性。

  • PreAlpha 1 实现可在 DS 和 DeSmuME 运行的 GUI 程序。
  • PreAlpha 2 完善 GUI 部件并提供框架。
  • PreAlpha 3 支持 MinGW32 移植和动态库:平台中立设计的验证实现。
  • PreAlpha 4 支持基于 NPL 的配置设置、构建工具 SHBuild 和运行时加载的 GUI 。
  • PreAlpha 5 支持桌面程序特性:界面风格、动画及分离构建等。

Alpha

  Alpha 阶段仍包含若干重要特性改进,但发布版本不再以添加单一特性为重点,而侧重提升环境的整体可用性。

  • V0.6 完善项目结构并提升宿主环境下的开发可用性支持。
    • 添加整体测试。
    • 添加桌面环境 YDE 。
      • 当前主要用于示例。
    • 添加和完善若干专用于支持开发的工具。
      • 添加 ProjectGenerator ,支持生成 Code::Blocks 项目。
      • 支持宿主环境下的 SHBuild 自举 Sysroot 部署。
  • V0.7 完善各个平台的实现行为和互操作接口。
    • 替换 DS 的文件系统实现。
    • 支持宿主环境下的 YSLib 多个映像实例共存。
      • 每个映像实例包括动态库和配置文件等运行时支持环境
      • 映像实例可以是 Sysroot ,也可以手动部署。
      • 不要求映像实例具有相同的版本。
      • 当前对环境变量透明;必要时,仍需手动指定 PATH
      • 当前全面支持仅限 MinGW32 :配置位置不再依赖当前工作目录。
    • 按独立的语言解释实现添加 NPL 接口。
  • V0.8 完善内部互操作性和部署。
    • 改进运行时对象操作 API 。
    • 扩充 NPLA/NPLA1 。
      • 设计和实现新的求值规则。
      • 提供较完整的 REPL 支持。
    • 在 SHBuild 中使用 NPLA1 代替系统默认的 shell 环境,用于实现部分 Sysroot 部署。
  • V0.9 增强 NPL 和部署环境。
    • 继续完善 NPL 接口并提升实现性能。
      • 默认使用异步调用实现,避免嵌套调用过深时的未定义行为,并支持 PTC 。
      • 节点和环境等数据结构支持分配器。
      • 显著优化分析器和求值的性能。
      • 添加 NPLA1 源代码信息支持,并增强错误信息。
      • 添加更多的标准库操作。
    • 增强配置管理。
      • 支持后备路径。
      • 支持检测类 FHS 的文件系统布局。
    • Sysroot 安装构建脚本。

重点计划目标

  • V0.10 计划进一步增强 NPL 和构建环境。
    • 继续完善 NPL 接口并提升实现性能。
    • 支持多个运行时实例交互。
    • 基于 Sysroot 的多平台自动化部署方案。

待定事项(TODOs)

  版本发布的待定事项参照上述目标。

  贡献到问题跟踪系统的内容可能包含特性请求和没有立刻解决的缺陷记录,其实现会被考虑列入待定事项。

  完整列表当前仅被内部参照,没有公开。

版本发布记录

  发布页可能包括后续开发信息。

  关于被发布的资源,参见归档

PreAlpha 发布页

PreAlpha 1

http://tieba.baidu.com/p/767225536 。

http://www.yayabo.cn/forum.php?mod=viewthread&tid=3878 。

PreAlpha 2

http://tieba.baidu.com/p/1043526998 。

http://www.yayabo.cn/forum.php?mod=viewthread&tid=17543 。

PreAlpha 3

http://tieba.baidu.com/p/1511876559 。

http://www.yayabo.cn/forum.php?mod=viewthread&tid=22988 。

PreAlpha 4

http://tieba.baidu.com/p/2288320823 。

http://www.yayabo.cn/forum.php?mod=viewthread&tid=25961 。

PreAlpha 5

http://tieba.baidu.com/p/3069607390 。

http://www.yayabo.cn/forum.php?mod=viewthread&tid=26450 。

Alpha 发布页

0.6

http://tieba.baidu.com/p/3747376832 。

http://www.yayabo.cn/forum.php?mod=viewthread&tid=26718 。

0.7

http://tieba.baidu.com/p/4701412006 。

版本日程记录

  记录的时间来自存档和提交记录,使用时区 UTC+8 。

  发布版本的计划时间为截止时间。评估计划完成情况时,实际时间应早于此时间。

PreAlpha

  早期开发版本计划未定。发布版本为每 100 个开发更新版本中形成。

  计划(追溯)及里程碑版本:

  • PreAlpha 0 2009-02 W3
    • PALibTest: 2009-10-10
  • PreAlpha 1 2010-03 W1
    • YSTest b98: 2010-05-05
  • 使用 Mercurial
    • YSLib b132 2010-07-13

  使用版本控制,开发更新版本对应提交版本。提交版本仅主分支版本。更新频率逐步控制为 8 提交版本/月,其中月以自然月计,折合 4 周工作量。

  计划及实际发布版本:

  • PreAlpha 2 2011-03 W4
    • YSLib b200: 2011-04-11
  • PreAlpha 3 2012-04 W2
    • YSLib b300: 2012-04-12
  • PreAlpha 4 2013-04 W4
    • YSLib b400: 2013-04-24
  • PreAlpha 5 2014-05 W2
    • YSLib b500: 2014-05-30

Alpha

  保持提交和发布版本更新频率不变。

  计划及实际发布版本:

  • V0.6 2015-05 W4
    • YSLib b500: 2015-05-26
  • V0.7 2016-06 W2
    • YSLib b500: 2016-06-11

  为便于特性整合和进度统计, 2017 Q2 计划提交和发布版本基准周期增加 1 倍。

  新的发布计划日程安排于 2017-07-01 启用。追溯 Alpha 发布历史并调整截止日程:

  • V0.6 2016-06 W2
  • V0.7 2018-07 W2

  使用以下日程同步计划过渡到新的截止日期:

  • 同步目标外推 4 次,并对每个发布版本递增添加 4 周发布准备,至 V0.11 2027-01 W2 。
  • 计划使用在新的基准周期外的至多和原提交周期相同的额外缓冲时间和截止日程同步。
    • 因此,提交版本周期至多为原周期的 3 倍;即当前更新频率控制为至少 8/3 提交版本/月 。
  • 同时,抽取 6 周用于 V0.8 发布准备。
    • 原计划外推 V0.8 发布时间为 2017-06 W4 ,推迟后为 2017-08 W2 。
    • 新计划外推 1 次 2018-08 W2 ,同步版本后相差 24 月,补充到后续发布版本中。

  随之改订的计划及待定发布版本:

  • V0.8 2017-08 W2
    • YSLib b800: 2017-08-10
  • V0.9 2020-10 W2
    • YSLib b900: 2020-10-13
  • V0.10 2023-12 W2
    • YSLib b1000: TBD
  • V0.11 2027-01 W2
    • YSLib b1100: TBD

Beta

  待定。

概要

  归档文件目前存放于以下位置:

注意 作为归档的压缩包文件一般统一使用 7z ,但不同的归档使用不同的压缩算法和选项,对系统资源要求不尽相同。作为极端情况, V0.6 后的 doc 下的压缩包使用具有 1.5GiB 字典的 PPMd 达到约 5% 的压缩比,这一般也要求解压缩时需预留 20 倍压缩包大小的空余空间,以及 1.5GiB 空余(物理)内存

命名规约

  文件名使用 [平台环境标识-]包名-版本[-配置].后缀 。“[]”中为可选项。特定平台的目录名可参照此规约。

  对于二进制文件和库文件,平台环境标识使用目标三元组分类:archc-OS-toolchain ;不限定体系结构的使用 "any" 。

  发布时若文件没有更新,则不另行更新版本。若某个包不存在预期的版本,尝试使用之前最近的版本代替。

顶级目录结构

  • src 可用于直接构建的源代码(包括外部依赖项的二进制库文件)包
  • example 示例代码
  • doc 文档(打包的 Doxygen 文档)
  • any 体系结构中立的文件(头文件和数据文件)
  • arm-ds-eabi DS 平台文件
  • i686-w64-mingw32 Win32 平台文件
  • arm-linux-androideabi Android ARM 平台文件
  • x86_64-linux-gnu Linux x64 平台文件

注意 因为包含所有平台的库文件过大且文件重复,考虑到存储和传输开销,V0.9 起不提供 YSLib 整体的源代码包(位于 src)。请直接参照获取源代码中的来源,同步版本库或下载源代码,再下载所需平台的外部依赖项的归档文件,并按开发说明存储到相应位置。Sysroot 归档中仍包含对应的外部依赖项。

包概要

以下为各个具体体系结构目录下的包的概要(并不一定保证每个体系结构具有所有这些包)。

  • External 外部依赖项
  • Sysroot 打包的 Sysroot 文件
  • YSTest YSTest 二进制文件
  • YDE 二进制文件

  内容详见以下二进制文件说明。

  以下为 any 目录下的包的概要。

  • yslib-data YSLib 运行时依赖的数据文件,参见运行说明
  • ybase-header YBase 头文件
  • yframework-header YFramework 头文件

V0.6 起不单独提供头文件,可使用源代码包或 Sysroot 包代替。

  此外,源代码包名以 -src 为后缀,在 src 目录下;而 Doxygen-html 是通过 Doxygen 生成的 HTML/XHTML 文档的包名,在 doc 目录下。

二进制文件说明

  Beta 阶段前,二进制文件不用于对所有被支持的平台提供完整可用的环境。

  除以下另行指定, V0.6(build 600) 起,仅第一类支持(支持等级详见 YSLib 项目文档 doc/ProjectRules.txt )且具有 Sysroot 的平台配置提供完整的二进制文件,包括库和示例项目等。

External

  单独构建外部依赖项,一般是二进制库文件。对所有支持的平台提供。

  V0.6(build 600) 起版本库中不再保持二进制文件。源代码包 src-*.7z 中包括已经编译的外部依赖项。此外,各个平台目录下的 External-*.7z 单独对依赖项打包,可参照前文中的位置自行放置。

Sysroot

  b600 起提供在 release 配置下构建部署的 MinGW Sysroot ,包名为 Sysroot

  因为归档文件限制,符号链接压缩为空文件。如需使用符号链接位置的库,可以手动恢复,流程参见构建脚本

YSTest

  源代码中默认构建的测试用示例项目,按内容命名为 YReader 。

YDE

  b600 起提供 release 配置下在 Sysroot 上构建的 YDE 合集,包名为 YDE

  其中的可执行文件依赖 YBase 和 YFramework 动态库。

构建环境

  这里提供了 YSLib 历史和当前版本使用的构建环境相关的归档,其中 YSLib 目录即上述发布仓库。

基本环境和工具链

  仅提供宿主环境操作系统为 Windows 的二进制文件。

MinGW32 目标和宿主环境

DS

Android

Linux

文档工具

外部依赖项的源代码

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 执行其它构建命令。

RevisionPatcher

  位于 Tools/RevisionPatcher ,是开发过程中用于修改版本工具。

  当前只支持从标准输入中提取版本号,内容要求为补丁文件。

  默认使用标准输出打印结果,内容为从补丁文件提取的目标文件名以及新的版本号。

  不修改任何其它文件。

  版本号通过补丁内的信息计算。使用规则参见 YSLib 项目文档 doc/ProjectRules.txt

  仅测试了 hg diff 导出的补丁文件。

构建

  依赖 YBase 和 YFramework 库,没有特别的构建支持,可以使用 stage 2 SHBuild ,详见 sysroot 安装脚本

清单(manifest) 文件

  因为文件名包含 patchWindows 可能默认要求以管理员权限运行 。安装脚本使用 manifest 文件指定免除此需要。

RevisionPatcher

  位于 Tools/SXML2XML ,用于转换 SXML 文档到 XML 文档。

  当前只支持 UTF-8 编码,不支持 XML 命名空间。

  默认使用标准输出打印结果。

构建

  依赖 YBase 和 YFramework 库,没有特别的构建支持,可以使用 stage 2 SHBuild ,详见 sysroot 安装脚本

ProjectGenerator

  位于 Tools/ProjectGenerator ,用于生成项目文件。

  当前只支持 UTF-8 编码的 Code::Blocks .cbp 文件。

  使用标准输出打印结果。

构建

  依赖 YBase 和 YFramework 库,没有特别的构建支持,可以使用 stage 2 SHBuild ,详见 sysroot 安装脚本

概述

  YSLib 项目提供一系列工具脚本。这些脚本主要集中位于 ToolsTools/Scripts 。其余特定局部用途的脚本可能位于其它目录。

解释环境

  脚本解释器要求宿主环境(符合 YSLib 源码 YF_Hosted 定义支持的平台,指具有操作系统的环境)。

  除非另行指定,脚本以文件的形式部署。

脚本文件

  脚本文件总是使用以下约定的扩展名。

  除了 Windows 命令解释器使用的 .cmd 文件以及 NPLA1 脚本使用的 .txt 文件,所有脚本使用 Shebang 明确需要使用的解释环境(详见 Shell 脚本的说明)。

  Windows 命令解释器脚本因为实现限制使用本机 ANSI 代码页的编码,约定为兼容 ASCII 。

  NPLA1 脚本约定使用带有 BOM 的 UTF-8 编码(去除 BOM 的脚本可能兼容 ASCII )。详见 stage 1 SHBuild 中关于 NPL 支持的说明

外部环境

  • 除非另行指定,脚本不假定自身的存储位置。
    • 一般地,这允许脚本的内容不总是可通过文件系统访问。这包括执行时脚本的来源被移除和不公开以文件的形式部署等情形。
  • 对文件系统中的脚本:
    • 脚本文件总是普通文件或可解析到普通文件的有效的符号链接。
    • 除非另行指定,不假定脚本文件所在的位置或其父路径可写。

  项目中提供的脚本在版本库中具有固定的相对路径。除解释环境适用的公共的约定(如提供一般类 UNIX 系统使用的文件系统布局的 FHS(文件系统层次结构标准)),脚本不预设绝对路径的假定。

警告 小心处理路径。当前脚本直接或间接使用的所有涉及文件系统递归操作均不假设检查遍历的目标之间是否重复,若使用不恰当的目录链接,可能造成未预期的行为(如复制指向父目录的目录链接时可引起无限递归)。部署时应提前确保不存在这样的链接。

  脚本实现假定没有可能冲突的并发文件访问。

接口约定

  脚本变量可能被读取和加载。除非另行指定,非导出的变量和名称以 _ 结尾的变量,都不是公开接口。

路径

  路径(path) 是由有限的路径组件构成的序列。在不引起歧义时,路径即指文件系统路径。文件系统的路径组件能以字符串形式表示。

  在支持相对路径的环境中,是否支持相对路径取决于具体脚本。

  内部的路径的分隔符使用 / 。通过脚本提供的 SHBuild_2w 等函数(见以下有关章节),可转换为带有不同路径分隔符的路径字符串。这种转换通常仅在必要时(如明确作为外部工具的输入)使用。

  字符串形式的路径(即路径字符串)可能是保证不以分隔符结尾的文件名和确保以分隔符结尾的目录路径字符串。目录路径指目录路径字符串或其对应的非字符串形式的路径。

  两个路径字符串的拼接可构成新的路径字符串。这两个路径字符串分别是路径前缀和路径后缀。除非另行指定,作为路径前缀使用的路径字符串是文件名。这要求通过串接路径后缀构成访问前缀指定的目录的新的路径时,路径后缀需要以分隔符起始。

注意 YBase 的 ystdex::path 和 YFramework 的 YSLib::IO::Path 等数据结构表示根路径外无视结尾分隔符的非字符串形式的路径,因为有效的分隔符仅在根路径中出现。这些实现一般不检查分隔符的合法性,如其中具有包含分隔符的路径组件,也可能正常转换为字符串形式的合法路径。当前脚本只使用字符串形式的路径。

Shell 脚本

  扩展名 .sh 的脚本文件是 shell 脚本文件。大多数脚本需要使用 GNU bash 运行,如:

#!/usr/bin/bash

  需要考虑兼容性时,一般使用以下替代:

#!/usr/bin/env bash

  其它可以直接兼容 POSIX shell 的 .sh 脚本使用 Shebang 如:

#!/usr/bin/sh

  需要考虑兼容性时,一般使用以下替代:

#!/usr/bin/env sh

  为简化脚本代码,用户需要保证调用 shell 脚本时,环境应满足以下条件,否则行为未指定:

  • 使用满足要求的 Shell 语言实现:
    • 对 bash 脚本:
      • 满足版本要求:当前 Bash 最低版本为 4.0 。
      • 不使用 POSIX 兼容模式。
      • 保证能使用 mapfilebash 内建命令。
    • 对其它 POSIX shell 脚本:
      • 使用符合 POSIX 的 shell ,或使用以上要求相同的 bash 运行 shell 脚本。
  • 变量 IFS 未设置或设置为默认值 :
  • bash-p 选项启用时效果相同。
    • 用户应保证不设置 CDPATH-p 忽略的环境变量及 $BASH_ENV 等启动文件以避免未预期的不同行为。
  • 脚本文件不是目标在不同目录中的符号链接。
    • 对 bash 脚本,允许使用变量 BASH_SOURCE 的值(如 ${BASH_SOURCE[0]}${BASH_SOURCE%/*} 等形式) 较可靠地判断脚本文件的路径。此时,隐含需要附加假定通过脚本文件路径确定其它资源的位置。
    • 部分脚本可能有更进一步的使用限制或不依赖 . 命令及命令解释器调用的差异。此时,可直接使用 "$0" 判断路径。
  • 不使用和脚本中函数名冲突的别名。
    • 在 bash 中,这默认不需要关注,需使用 shopt -s expand_aliases 显式启用引起冲突的功能。

  脚本实现中的调用不受以上限制。

  若脚本可以确保兼容 POSIX shell ,使用后者而不是前者。

  如果对应解释器位于其它目录,可以符号链接到上面指定的路径。

  除非另行指定,本文档约定使用的路径字符串的分隔符为 / ,不连续出现在路径中,且不在结尾出现。例外:

  • 平台相关的绝对路径转义可出现 //
  • 构成路径的路径前缀可能以分隔符结尾,直接表示上层目录。

注意 当前版本库中的文件不保证跟踪权限。在一些环境中可能因为可执行权限问题导致无法立即执行脚本,参见这里的说明

  正式支持的发布版本中的公开 Shell 脚本应保证用 ShellCheck 0.7 或以上版本(任选)检查没有诊断消息。检查的命令行为 shellcheck -x -P SCRIPTDIR 跟随文件名。除非另行指定,使用明确的方式避免引起检查的问题而不是使用指令消除检查的结果,如使用 ${BASH_SOURCE[0]} 代替 $BASH_SOURCE 以避免 ShellCheck 警告 SC2128 。

Shell 语言使用规约

  除非另行指定,已定义的 shell 函数假定不被其它变量覆盖。这允许实现省略 readonly -fdeclare -g -r -f 声明,且允许使用相同的定义覆盖以简化调试。

  除非另行指定,脚本不区分未设置的环境变量和已设置但具有空值的环境变量。这两种情形脚本都可能指定一个非空的初始值,称为变量的默认值(default value)

  除非另行指定,返回非数值的 shell 函数使用 echo 输出返回的值。

  非生成的代码中不使用包含 __ 的名称。

  公开函数的函数名及公开的变量名不以 _ 结尾,否则以一个 _ 结尾。

  对 SHBuild 相关工具使用的函数,使用前缀 SHBuild

  函数出错且无法恢复时退出脚本。

  版本库中的提供的脚本一般应能通过 ShellCheck 检查。对需要使用 ShellCheck 指令指定脚本起始构造的检查时,在之前添加一行空命令(对 bash 脚本使用 : ,非 bash 脚本命令使用 true )以避免非预期地使指令作用于整个脚本。

环境变量

  Shell 脚本可使用以下能通过外部环境指定值的环境变量:

  • 用于指定入口位置:
    • SHBuild :外部 SHBuild 可执行文件路径。
      • 具体默认值和特定脚本被设计适应的部署环境相关(例如,视不同情形,脚本可使用 BASH_SOURCE"$0" )。
    • SHBuild_ToolDir :工具目录中的脚本目录,由脚本根据版本库所在目录确定。
  • 用于指定版本库中的资源:
    • SHBuild_BaseDir : SHBuild 目录,是工具目录(参见以下有关章节)中提供 SHBuild 源代码的目录。
    • YSLib_BaseDir :YSLib 目录,即版本库的工作目录。
  • 用于指定输出目录:
    • SHBuild_BuildDir :构建使用的中间输出文件路径。
      • 对不依赖 Sysroot 或 YSLib/YSTest 目录下的项目构建脚本,默认值是在完整的版本库中和 "$YSLib_BaseDir/build/$SHBuild_Host_Platform" 相同的目录;否则,默认值是当前工作目录 .
    • SHBuild_SysRoot :输出的 Sysroot 根路径。
      • 默认值是 "$YSLib_BaseDir/sysroot"
  • 用于配置构建环境:
    • SHBuild_Env_Arch :构建系统架构。
      • 由脚本 Tools/Scripts/SHBuild-common.sh 的函数 SHBuild_CheckUName 指定默认值和初始化。
    • SHBuild_Env_OS :构建系统操作系统。
      • 初始化和确定值的方式同 SHBuild_Env_Arch
    • SHBuild_Host_Arch :宿主架构。
      • 由脚本 Tools/Scripts/SHBuild-common.sh 的函数 SHBuild_PrepareBuild 初始化。
      • 默认值同 SHBuild_Env_Arch 初始化后的值。
    • SHBuild_Host_OS :宿主操作系统。
      • 初始化的方式同 SHBuild_Host_Arch
      • 默认值同 SHBuild_Env_OS 初始化后的值。
    • SHBuild_Host_Platform :宿主平台前缀。
      • 由脚本 Tools/Scripts/SHBuild-common.sh 中的函数 SHBuild_Platform_Detect 指定默认值和初始化。
    • SHBuild_SystemPrefix :系统前缀,在 Sysroot 根路径下决定安装路径。
      • 值由脚本 Tools/Scripts/SHBuild-common.sh 中的函数 SHBuild_GetSystemPrefix 确定。
    • SHBuild 构建使用的变量:详见 SHBuild 的帮助信息。
    • 其它构建脚本使用的变量:详见以下具体脚本的说明。

  一般地,部署的 shell 脚本需引用其它脚本时,以如下方式使用指定入口的环境变量:

  • 若脚本只支持 Sysroot ,以 SHBuild 在 Sysroot 的安装位置推断其它脚本的路径。
  • 若脚本只支持工具目录中的脚本目录布局,以 SHBuild_ToolDir 指定。
    • 这隐含目录在版本库中的布局,可以此初始化 YSLib_BaseDir 等变量的默认值。
  • 若脚本同时支持 Sysroot 中部署的位置和工具目录中的脚本目录布局:则不使用以上的变量。
    • 引用其它脚本文件时可直接指定包含,如:. "$(dirname "${BASH_SOURCE[0]}")/SHBuild-common.sh"

  除指定入口的环境变量,是否支持外部可覆盖默认值的上述环境变量是可选的,取决于各个脚本的具体支持。

NPLA1 脚本

  NPLA1 脚本可被 SHBuild 调用。SHBuild 支持特定的选项作为 NPLA1 的脚本解释器。脚本解释器支持 NPLA1 脚本文件。此外,在 shell 脚本中,NPLA1 脚本代码可能以字符串的形式存储和被 SHBuild 调用。

环境变量

  NPLA1 脚本可使用和 shell 脚本通用的环境变量,如 SHBuild

  除 stage 1 外,shell 脚本使用环境变量 NPLA1_ROOT 指定的根目录作为 SHBuild 加载 NPLA1 脚本使用的起始目录。

  脚本(包括直接或间接调用 NPLA1 脚本的其它脚本)除默认值外不需要依赖 Sysroot 的安装路径下的目录和文件布局,环境变量 SHBuildNPLA1_ROOT 可分别指定相互无依赖的路径。当仅指定 SHBuild 时,通过指定的 SHBuild 路径推断 NPLA1_ROOT 默认值,此时使用假定符合 Sysroot 约定的相对路径。

  NPLA1 脚本可使用以上约定含义和默认值的 shell 环境变量,但部分变量初始化方式可能不同:

  • 对 NPLA1 脚本,在 Tools/Scripts/SHBuild-YSLib-common.txt 中直接初始化变量 SHBuild_Env_ArchSHBuild_Env_OS

NPLA1 函数

  NPLA1 脚本可提供部分 shell 脚本中的同名函数。除非另行指定,这些函数的调用接口以及功能和 shell 脚本中的同名函数一致,但实现和以下行为不保证相同:

  • 出错时的诊断方式;
  • 缓存的变量及相关的输出提示信息;
  • 性能;
  • 影响的非公开环境变量等其它外部环境状态。

  作为公开接口的 NPLA1 函数另见 doc/NPL.txt 中的描述。

构建脚本

  一些开发脚本被用于构建。构建脚本的一般形式提供配置和生成阶段的自动化功能。

  配置阶段设置交互环境(典型地,通过执行命令前设置的环境变量)。

  生成阶段调用合适的工具完成构建。

  配置阶段的接口可能对外隐藏,此时使用默认配置进行构建。

  一些公用的构建脚本可适用于整个项目。其它的构建脚本可构建具体子项目中的目标。

  构建脚本可以是 makefile 或其它可执行的脚本。其中,makefile 可能使用以上约定含义的 shell 环境变量,但不保证可被外部指定覆盖脚本中指定的默认值。

Tools

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

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

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

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

Tools/install-sysroot.sh

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

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

  当前所有部署都指定到 YSLib 版本库根目录下的 build/$SHBuild_Host_Platform 目录,其中 $SHBuild_Host_Platform 是宿主平台目录名,调用 SHBuild-common.sh 中的函数 SHBuild_CheckHostPlatform 后确保非空。

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

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

基本使用

  脚本中使用以下配置传递至 SHBuild

: ${SHBuild_BuildOpt:="-xj,6"}
: ${SHBuild_LogOpt:="-xlogfl,128"}
: ${SHBuild_Opt:="${SHBuild_LogOpt} ${SHBuild_BuildOpt}"}

  因此可以直接用 export 或直接在命令行指定变量覆盖默认行为,如

SHBuild_BuildOpt=-xj,2 Tools/install-sysroot.sh

  使用 2 个并行线程构建。

  脚本也支持变量配置构建使用的路径:

: ${SHBuild_SysRoot="$YSLib_BaseDir/sysroot"}
: ${SHBuild_BuildDir:="$YSLib_BaseDir/build/$SHBuild_Host_Platform"}

  其中,各个变量的作用参见以上 shell 环境变量的说明。

  在 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 的命令。默认直接使用 which ProjectGenerator 的结果,一般要求可执行文件在环境变量 PATH 中。

Tools/Scripts/PatchRevision.sh

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

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

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

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

变量 PatchBegin

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

变量 PatchBegin

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

变量 RevisionPatcher

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

Tools/Scripts/SHBuild-bootstrap.sh

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

  其中指定了静态链接需要依赖的 YSLib 源文件以及头文件路径等。

Tools/Scripts/SHBuild-build.sh

  编译 stage 1 SHBuild 的脚本。

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

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

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

Tools/Scripts/SHBuild-BuildApp.sh

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

  这个脚本是公开的工具,被 Tools/install-sysroot.sh 部署到安装路径下的 bin 目录下。

Tools/Scripts/SHBuild-BuildPkg.sh

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

  这个脚本是公开的工具,被 Tools/install-sysroot.sh 部署到安装路径下的 bin 目录下。

Tools/Scripts/SHBuild-common.sh

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

  这个脚本是公开的工具,被 Tools/install-sysroot.sh 部署到安装路径下的 bin 目录下。

函数 SHBuild_Put

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

函数 SHBuild_Puts

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

  换行符由变量 SHBuild_EOL 指定。当前默认值通过检查 $COMSPEC 是否定义,以确保 Windows 环境(包括 MSYS )使用 CR+LF ,其它情况使用 LF 。

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

函数 SHBuild_AssertNonempty

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

  使用 eval 实现。

函数 SHBuild_CheckedCall

  断言第一参数为名称的变量非空,若空则使用 eval 对后续求值并初始化第一参数指定的只读变量。若发生初始化则在标准输出中显示。

函数 SHBuild_InitReadonly

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

  使用 hash 实现以优化性能。

函数 SHBuild_CheckUName

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

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

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

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

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

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

函数 SHBuild_PrepareBuild

  初始化环境,并描述宿主平台的变量 SHBuild_Host_ArchSHBuild_Host_OS 具有非空的初始值。

函数 SHBuild_2m

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

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

函数 SHBuild_2u

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

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

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

函数 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 ,然后在目标上设置可执行权限。

函数 SHBuild_Install_HardLink

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

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

函数 SHBuild_Install_HardLink_Exe

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

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

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

函数 SHBuild_Install_Link

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

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

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

函数 SHBuild_Pushd

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

函数 SHBuild_Popd

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

函数 SHBuild_EchoEscape

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

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

函数 SHBuild_EchoVar

  接受 2 个参数 x 和 y ,以特定颜色显示为 x = y 的形式。

函数 SHBuild_EchoVar_N

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

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

函数 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_GetSystemPrefix

  按参数指定的平台名称字符串返回系统前缀字符串。

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

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

  当前支持的结果包括:

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

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

函数 SHBuild_Platform_Detect

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

  当前支持的结果包括:

  • MinGW64
  • MinGW32
  • 第一个参数指定的操作系统名

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

  • 若环境变量 MSYSTEM 设置为 MINGW64MINGW32 ,结果对应为 MinGW64MinGW32
  • 否则,若操作系统名为 Win32
    • 若体系结构为 x86_64 ,则结果为 MinGW64
    • 否则,结果为 MinGW32
  • 否则,结果为操作系统名。

函数 SHBuild_CheckHostPlatform

  调用 SHBuild_CheckUName ,且当变量 SHBuild_Host_Platform 非空时初始化它的值。

  变量 SHBuild_Host_Platform 的值表示宿主平台目录名,用于初始化路径等。初始化的值为以变量 SHBuild_Env_OSSHBuild_Env_Arch 的值作为参数调用函数 SHBuild_Platform_Detect 的结果。

函数 SHBuild_BuildGCH

  接受第一个参数指定的路径的头文件安装到第二个参数指定的路径下并使用第三个参数指定的命令行构建 GNU 预编译头。

函数 SHBuild_CheckPCH

  检查是否设置了非空的 SHBuild_NoPCH ,否则调用 SHBuild_BuildGCH 并生成 GNU 风格预编译头文件并设置内部变量 SHBuild_IncPCH 为合适的命令行选项用于包含生成的预编译头文件。

  支持两个参数,同 SHBuild_BuildGCH 的前两个参数。

Tools/Scripts/SHBuild-common-options.sh

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

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

  这个脚本是公开的工具,被 Tools/install-sysroot.sh 部署到安装路径下的 bin 目录下。

  包含 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 -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

变量 LDFLAGS_STRIP

  链接器剥离符号选项,默认值为 -s

变量 C_CXXFLAGS_ARCH

  C 和 C++ 编译器共用的体系结构相关选项,默认值为空。

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

变量 C_CXXFLAGS_PIC

  C 和 C++ 编译器共用的 PIC ( Position Independent Code ,位置无关代码)生成选项,默认值在 Win32 上为空,其它平台上为 -fPIC

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

变量 C_CXXFLAGS_COMMON

  C 和 C++ 编译器共用的公共选项,默认值为 -pipe $C_CXXFLAGS_GC $C_CXXFLAGS_ARCH -pedantic-errors

变量 C_CXXFLAGS_OPT_LV

  C 和 C++ 编译器优化等级选项,默认值为 -O3

变量 C_CXXFLAGS_WARNING

  C 和 C++ 编译器共用的警告命令行选项,默认值包括以下列表中的内容:

  • -Wall
  • -Wcast-align
  • -Wdeprecated
  • -Wdeprecated-declarations
  • -Wextra
  • -Wfloat-equal
  • -Wformat=2
  • -Winvalid-pch
  • -Wmissing-declarations
  • -Wmissing-include-dirs
  • -Wmultichar
  • -Wno-format-nonliteral
  • -Wredundant-decls
  • -Wshadow
  • -Wsign-conversion

  使用符合项目要求支持的 Clang++ 和 G++ 应支持这些选项。

变量 C_CXXFLAGS_IMPL_WARNING

  和特定实现相关的 C 和 C++ 编译器共用的警告命令行选项,默认值包括若干特定实现的选项。

变量 CXXFLAGS_IMPL_WARNING

  和特定实现相关的 C++ 编译器警告命令行选项,默认值包括若干特定实现的选项。

变量 CXXFLAGS_IMPL_COMMON

  和特定实现相关的 C++ 编译器一般命令行选项,默认值包括若干特定实现的选项。

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

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

注意 当前不检查失败原因。参见函数 SHBuild_GetTempDir 的已知限制。

  当前暂不支持判断其它环境。

变量 CXXFLAGS_IMPL_OPT

  和特定工具相关的 C++ 编译器优化命令行选项,默认值包括若干特定实现的选项。

变量 CFLAGS_STD

  指定 C 标准的编译器命令行选项,默认值为 -std=c11

变量 CFLAGS_WARNING

  C 编译器警告命令行选项,默认值为 $C_CXXFLAGS_WARNING $C_CXXFLAGS_IMPL_WARNING

变量 CFLAGS_COMMON

  C 编译器一般命令行选项,默认值为 $C_CXXFLAGS_COMMON $CFLAGS_STD $CFLAGS_WARNING

变量 CXXFLAGS_STD

  指定 C++ 标准的编译器命令行选项,默认值为 -std=c++11

变量 CFLAGS_WARNING

  C 编译器警告命令行选项,默认值包含以下列表中的内容:

  • 变量 CFLAGS_WARNING 的内容
  • -Wctor-dtor-privacy
  • -Wnon-virtual-dtor
  • -Woverloaded-virtual
  • -Wsign-promo
  • 变量 CXXFLAGS_IMPL_WARNING 的内容

变量 CXXFLAGS_COMMON

  C++ 编译器一般命令行选项,默认值为 $CXXFLAGS_STD $C_CXXFLAGS_COMMON $CXXFLAGS_WARNING $CXXFLAGS_IMPL_COMMON

变量 CXXFLAGS_OPT_DBG

  C++ 编译器优化和调试相关的命令行选项。在未设置非空的 SHbuild_Debug 时,默认值包含以下列表中的内容:

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

变量 CFLAGS

  C 编译器使用的命令行选项,默认值为 $C_CXXFLAGS_PIC $CFLAGS_COMMON $C_CXXFLAGS_COMMON_IMPL_ $CXXFLAGS_OPT_DBG 。其中,C_CXXFLAGS_COMMON_IMPL_ 是根据支持的编译器在内部定义的非公开变量。

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

变量 CXXFLAGS

  C++ 编译器使用的命令行选项,默认值为 $C_CXXFLAGS_PIC $CXXFLAGS_COMMON $C_CXXFLAGS_COMMON_IMPL_ $CXXFLAGS_OPT_DBG 。其中,C_CXXFLAGS_COMMON_IMPL_ 是根据支持的编译器在内部定义的非公开变量。

变量 LDFLAGS_OPT_DBG

  链接器优化和调试相关的命令行选项。在未设置非空的 SHbuild_Debug 时,默认值为 $LDFLAGS_STRIP $LDFLAGS_IMPL_OPT $LDFLAGS_GC

变量 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_EXTRA $LDFLAGS_DYN

变量 LIBS_RPATH

  用于指定在运行时 ELF 映像需要的动态库的路径的链接器选项。在 Win32 默认不设置,其它平台默认值为 -Wl,-rpath,'\$ORIGIN:\$ORIGIN/../lib'

变量 LIBPFX

  库前缀。在 Win32 默认不设置,其它平台默认值为 lib

变量 DSOSFX

  动态库文件名后缀。在 Win32 默认为 .dll ,其它平台默认值为 .so

变量 EXESFX

  可执行文件名后缀。在 Win32 默认为 .exe ,其它平台默认不设置。

变量 LDFLAGS

  链接器使用的命令行选项,默认值依次包含以下内容:

  • 变量 C_CXXFLAGS_PIC 的内容。
  • 和变量 CXXFLAGS_IMPL_COMMON 中等价的线程命令行选项。
  • 变量 LDFLAGS_OPT_DBG 的内容。
  • 生成可执行程序时且要求按需调整链接器参数时,附加的值:
    • 当需要生成 Win32 子系统程序时,附加 -mwindows
  • 动态可执行程序时,变量 LIBS_RPATH 的内容。
  • 动态链接库时,变量 LDFLAGS_DYN 的内容。

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

Tools/Scripts/SHBuild-common-toolchain.sh

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

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

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

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

  • CC
    • 默认值为 gcc
  • CXX
    • 默认值为 g++
  • AR
    • 默认值为变量 CXX 指定的 C++ 编译器确定的自动检测结果;若非 Clang++ 和 G++ ,则使用 ar
  • ARFLAGS
    • 默认值为 rcs
  • LD
    • 默认值为变量 CXX 的值。

  这个脚本是公开的工具,被 Tools/install-sysroot.sh 部署到安装路径下的 bin 目录下。

函数 SHBuild_CheckCC

  尝试调用参数指定的编译器以检查 C 编译器风格。结果是以下之一:

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

函数 SHBuild_CheckCXX

  尝试调用参数指定的编译器以检查 C++ 编译器风格。结果是以下之一:

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

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.dll 和 YBase.dll 。

Tools/Scripts/SHBuild-YSLib*.txt

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

  • Tools/Scripts/SHBuild-YSLib-common.txt :被 Tools/Scripts/SHBuild-YSLib-build.txt 加载的 NPLA1 脚本。
  • Tools/Scripts/SHBuild-YSLib-build.txt :使用 SHBuild 构建 debug 或 release 配置的 YBase 和 YFramework 库的 NPLA1 脚本,被 Tools/install-sysroot.sh 调用,其中 SHBuild 默认为 stage 1 SHBuild 。
  • Tools/Scripts/SHBuild-YSLib.sh :当前被保留。

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

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

Tools/Scripts/SHBuild-YSLib-common.txt

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

  • 生成变量默认值的选项之间的空白符可能不同(通常可确保为一个空格)。
  • 按需初始化变量。配置时为确定变量的默认值的检查的调用顺序可能不同。
  • 使用 debug 模式时,CXXFLAGS_OPT_DBG 设置为 -O0 -g -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC ,不再被环境变量覆盖。
  • 附加支持构建应用的配置,在导出的 LDFLAGS 的值中添加 LIBS_RPATH 的值。

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

  可以在外部调用这个脚本的命令行设置变量以覆盖直接指定需要的选项,如:

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

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

  这个脚本是公开的工具,被 Tools/install-sysroot.sh 部署到安装路径下的 var/NPLA1 目录下。

Tools/Scripts/SHBuild-YSLib-build.txt

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

  脚本支持 SHBuild_ 为前缀的环境变量指定构建和部署目标:

  • 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 后的开发工具构建和安装。

  以下配置行为的环境变量(其中 SS 表示 SHBuild Settings )被支持:

  • SS_DebugEnv 值非空时启用脚本执行时系统环境相关的调试输出,当前包括:
    • 对环境变量修改时输出修改的变量名和对应的值。
  • SS_Verbose 值非空时启用详细消息输出,当前包括:
    • LDFLAGS 变量中附加 -mwindows 时提示。

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

  • SHBuild_YF_Libs_freetype :freetype 库链接参数。
    • 默认值为 -lfreetypepkg-config --libs freetype2 的输出结果。
      • 其中存在 Sysroot libfreetype.a 时默认值为前者。
  • SHBuild_YF_Libs_FreeImage :FreeImage 库链接参数。
    • 默认值为 -lFreeImaged-lFreeImage ,对应 debug 和非 debug 配置。

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

  在 stage 1 构建时,接受以下环境变量:

  • INCLUDES_freetype 指定覆盖包含路径的编译器命令行选项,默认值以 -I 起始,使用版本库目录下的 3rdparty/freetype/include 目录带有适当引号的完整路径。

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

  • INCLUDES 包含路径,和非 SHBuild 中的 Makefile 惯用法含义类似。
  • LDFLAGS 链接命令行选项。
  • LIBS 作为命令行选项的链接时使用的库路径。
  • LIBS_RPATH 非 Windows 平台使用的 rpath 路径。

Tools/Scripts/SHBuild-BuildApp.txt

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

  这个脚本是公开的工具,被 Tools/install-sysroot.sh 部署到安装路径下的 var/NPLA1 目录下。

基本原理

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

  脚本通过设置特定的环境变量并调用 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 库的编译器命令行。若有必要,可设置 SHBuild 使用的变量 SHBuild_CFLAGSSHBuild_CXXFLAGS 作为前缀。

  脚本已经导出了用于链接器的包含使用 YSLib 库命令行参数的变量 LDFLAGSLIBS 。若有必要,可设置变量 SHBuild_LDFLAGSSHBuild_LIBS 作为前缀。

准备

  在开始教程前,掌握以下知识:

  并对以下内容有基本了解:

内容目录

基础约定

关于头文件的补充说明

  在入门中已经解释了头文件宏的使用。

  公开的头文件宏的命名是模块路径的直接应用:替换 ::_ ,加上前缀 YFM_YFM_平台名

  这些宏名直接定义在各个 include 目录的 YModules.h 中。而头文件 <YSBuild.h> 则包含了一系列的 YModules.h 和其它模块的头文件,因此可以直接包含它来简化使用。

命名空间

  YSLib 中不同的次级子项目引入不同的命名空间。

  关于每个顶级子项目下不同的命名空间参见 doc/YBase.txtdoc/YFramework.txt 以及 Doxygen 生成的文档。

  在以下讨论中,若没有特别说明,所有非宏名的标识符都在 namespace YSLib 中。

  注意避免命名空间使用冲突。除非是在一个很有限的块作用域内,一般而言, using namespace std; 总是不被推荐的,但 using namespace YSLib;非头文件中则是被允许的。

  在 YSLib 的头文件中,无论是 using 声明还是 using 指令或是命名空间别名,都是经过慎重考虑的,特别是为了实现平台中立的兼容。

  • 如 YCLib::Mutex 模块支持标准库的对应接口,即使语言的实现如 libstdc++ 在单线程平台上不提供支持,也通过回退到 YBase::PseudoMutex 而允许不改动用户代码并直接保证空行为。允许不改动用户代码的性质可通过 using namespace platform::Concurrency 实现。

  所有其它不经意的在头文件中使用都应被避免。

标识符命名

因为无法完全避免使用不同风格命名的外部依赖, YSLib 强调区分命名的来源而不是使用单一命名风格。

YBase 使用和 ISO C++ 标准库相容的风格。 YFramework 则约定使用框架名称,其中可能包含一些前缀,如 I 表示只有抽象方法的类(接口类), G 表示用于泛型(与元编程目的相区别)的类模板的名称等。

详细的命名规约参见 doc/CommonRules.txtdoc/YFramework.txt

YSLib 应用程序基本模型

程序的启动、运行和终止

  启动一个应用一般可以分为两个部分:创建内容;让内容被显示。 YSLib 对此提供了整体性的便利解决方案。以下说明以典型的 GUI 程序为例(非 GUI 程序实际上不必要使用特别的支持)。

  Helper::GUIApplication 模块提供的 GUIApplication 类的单例对象初始化中集成了 GUI 程序必要的初始化。之后,可以部署必要的操作,例如决定哪些内容被初始地呈现。程序通过 Helper::GUIApplication 提供的函数 Execute 调用被封装的消息循环(message loop) ,接受用户输入并按需响应。最后,当特定条件被满足时,退出 Execute 函数,程序结束。

消息循环、消息和消息队列

  消息循环,或称事件循环(event loop) ,是交互式应用的典型实现方式。程序通过处理(handling) 不同的消息(message) 完成期望的行为。除了少数特殊消息(例如表示“退出”以结束程序的消息),消息循环自身通常不能决定如何处理一个消息,因此需要分发(dispatching) 到用户提供程序中。

  基本的消息循环的是一个轮询(polling) 操作,一次循环尝试确定一个需要被处理的消息。所有被处理的消息储存于消息队列(message queue) 内。当消息循环从消息队列取得消息时,通常即在队列中删除此消息。适当的操作产生消息发送至消息队列内以待处理。这种机制能让消息之间具有一定的顺序保证。但要注意,为了满足调度的需要,此处的队列并不一定需要是严格先进先出的。 YSLib 使用模块 YSLib::Core::YMessage 提供的 Messaging::Message 类表示消息, Messaging::MessageQueue 类表示支持优先级的消息队列。

  当没有消息需要被处理时即进入空闲(idle) 状态,库需要保证消息循环不被立刻终止,可以采取如下操作:

  • 发送特定的空闲消息并立即处理。
  • 当可能有其它机制发送消息至消息队列时,放弃处理器资源以便节约能源或(在多任务环境中)使其它程序被调度,预定等待一定时间后再次轮询。
  • 结合以上操作。

  交互式程序中,用户动作和其它外部输入可以被抽象为一个消息。输入消息包含必要的状态数据。用户程序指定此处的响应逻辑,更新特定应用的状态,绘制屏幕图形等。由于一个 GUI 程序在此需要完成的任务具有典型性,可以在更高层次上加以抽象,不一定需要直接控制消息循环。但了解消息循环仍然是必要的。

Shell

  YSLib 提供称为 Shell 的抽象使交互式程序易于被分隔为不同的实现。每个 Shell 类可以通过覆盖的虚函数 OnGotMessage 提供响应不同的消息一整套逻辑。

进一步阅读

图形支持

  YSLib 现阶段不强调图形学功能。作为 GUI 的基础, YSLib 主要在命名空间 Drawing 内提供以下两类图形接口:

  • 在 YSLib::Core::YGDIBase 描述图形的位置、大小等几何属性的对象 PointSizeRect
  • 在 YSLib::Service 中提供简单图形和字形的光栅化、像素操作和块传输等绘制功能。

  在了解 YSLib 开发时会少量涉及上述的第一类接口,需要了解其意义和简单的用法。进一步描述详见接口文档。

标量类型

  YSLib 默认使用整数坐标。表示屏幕坐标位置的有符号数类型 SPos 和大小的无符号数类型 SDst 的范围和平台相关,由 YCLib 提供,一般保证至少 16 位,但应避免依赖其具体范围。

类模板和类类型

  类模板 GBinaryGroup 表示两个标量的有序对,被用于表示屏幕坐标。以 SPos 作为模板参数的实例 PointVec 表示点的位置和二维向量,当前是一致的。

  类 Size 包括两个 SDst 分量,用于表示大小。

  类 Rect 约定了一个边和屏幕坐标系总是共线的矩形:保存一个左上角位置的 Point 和表示宽度和高度的 Size 对象。

  一个 Rect 对象可以直接通过位置和大小构造:

Rect r1(Point(10, 20), Size(40, 50));
Rect r2({10, 20}, {40, 50}); // 同上。
Rect r3(10, 20, 40, 50); // 同上。
Rect r4{10, 20, 40, 50}; // 同上。

  类模板 GGraphics 表示二维图形接口上下文 ,是一个表示缓冲区的指针(不保证具有所有权)和大小组成的数据结构。一般使用的是其实例 GraphicsConstGraphics

  类 PaintContext 包含了 GUI 绘制中的一些必要信息,其中由 Graphics 对象表示目标, Point 对象表示参考位置, Rect 对象表示需要保证绘制的边界范围。

GUI 应用接口概述

Shell 和 GUIState

  Helper::GUIShell 模块提供的类 Shells::GUIShell 是专用于不同平台 GUI 程序处理的 shell ,它隐藏了控制和响应 GUI 需要处理的具体消息,使用户输入被分发到更高级的 UI::GUIState 类的对象中。

  GUIState 是模块 YSLib::UI::YGUI 提供的平台中立的 GUI 公共逻辑处理的实现。默认 GUIState 对象预先构造的单态(monostate) 对象,即被全局共享,可以储存和 GUI 相关的公共状态。

  通过 YSLib::UI::YGUI 提供的函数 UI::FetchGUIState 取得取默认图形用户界面公共状态:

using namespace UI;
auto& state(FetchGUIState());

事件(event)

  UI::GUIState 的成员函数被 Shells::GUIShell 直接或间接调用以按需构造不同的事件

  一般意义的事件本质上是可以容纳回调(callback) 的对象,是发布-订阅模式的实现。用户通过事件提供的接口注册回调,在事件被触发调用时订阅者可以调用这些被预先发布的回调。

  YSLib 事件由模块 YSLib::Core::YEvent 提供的 GEvent 类模板提供,包含多播支持,即 GEvent 中可以有多个回调函数,在触发事件时依优先级和插入顺序调用这些回调函数。 GEvent 支持的回调通过事件处理器(event handler) GHEvent 类模板提供,除限定返回类型 void 外,使用方式基本兼容于 std::function (提供 ISO C++ 定义的可调用对象(callable object) 作为回调),此外提供两个方面的增强:

  • 可比较相等。这意味着 GEvent 不需要保存特定的引用即可支持查询或移除特定回调(若可调用对象自身支持 == 则通过 == 操作定义结果,否则总是认为同类型可调用对象都相等)。
  • 通过 YBase 库模块 YStandardEx::Functional 的 ystdex::make_expanded 模板提供允许比事件处理器提供模板更少参数的可调用对象的支持,允许省略在右边的若干参数。缺乏此支持时,一个可调用对象的函数形参即使未被使用,仍然需要出现在声明的参数列表中,带来一些不便。

  另外, GEvent 的 operator() 会忽略回调抛出的 std::bad_function_call 异常。

  和消息不同, YSLib 的事件默认总是被同步处理的。不同的事件使用不同的枚举标识,携带特定类型的事件参数(event argument) 对象。

  用户通过给事件提供不同的可调用对象作为回调,在其中可以实现应用程序特定的逻辑。

部件(widget)

  部件是 GUI 的可见元素抽象。体现 GUI 逻辑的事件最终被分发到具体的部件上,在部件持有的事件上进行响应。

  部件具有一系列基本的可视化属性,例如位置和大小。其它一些状态决定它如何被绘制以及和其它部件的关系或者具有用户程序关心的数据。 YSLib 中的部件实现模块 YSLib::UI::YWidget 提供的 UI::IWidget 接口以及作为基类的 UI::Widget ,通过处理 UI::Paint 事件使其被绘制。

  基本的部件只能处理 UI::Paint 标识的绘制事件,可以处理其它事件(例如直接响应表示用户输入的事件)的部件称为控件(control) 。模块 YSLib::UI::YControl 提供了控件的基类 UI::Control 。其它大部分部件派生于这个类以提供不同的功能。

  调整部件的特定属性即可以基本完成一个 GUI 应用。

  模块 YSLib::UI::YWidgetEvent 提供了 UI::VisualEvent 枚举标识默认支持的 GUI 事件,其中不同的枚举项表示不同的 GUI 事件,可能对应不同的事件参数类型。默认支持的事件参数类型都是类类型的右值引用类型,但和标准库的右值引用参数类型不同,约定被转移后状态可预测。

  从一个控件取得一个指定事件标识的的事件左值,可以使用 YSLib::UI::YControl 提供的函数模板 UI::FetchEvent 。可以直接在取得的事件上进行操作,所以不必要直接声明一个变量。

using namespace Drawing; // 使用 Drawing::Size 等。模块 YSLib::UI::YControl 已在命名空间 YSLib 中有此声明,若包含了对应的头文件,可以省略。
using namespace UI;
Control ctl(Size(80, 20)); // 创建一个 Control 类型的控件 ctl ,初始大小为 (80, 20) 。
auto& paint_event(FetchEvent<Paint>(ctl)); // 取 ctl 的 UI::Paint 事件,通常是不必要的。

// 使用 lambda 表达式添加回调是简便的做法:
FetchEvent<Click>(ctl) += [](CursorEventArgs&&){
	std::cout << "Control clicked!" << std::endl; 
};
FetchEvent<Click>(ctl) += []{ // 得力于 GHEvent 允许省略参数的特性,这里可以省略没有用到的形式参数。
	std::cout << "Control clicked again!" << std::endl; 
};

  当 ctl 被点击时,上面 UI::Click 事件上添加的两个回调会被依次执行,在标准输出上输出两行字符串。

指定部件的视图属性

  部件的视图属性包括位置大小等。

  上例中通过指定 Size 对象表示部件初始化时的大小。这个类型和下面涉及的位置以及边界类型都由模块 YSLib::Core::YGDIBase 提供,头文件默认已经被包含在 GUI 中所以不需要显式包含。

  位置由二维的点 Point 类型表示。此处并没有明确位置是相对于哪个坐标系的。创建部件以后,并没有直接指定部件应在哪被显示,所以这里的位置本身只具有相对意义。

  也可以通过直接指定 Rect 类型的矩形的边界

Control ctl2(Rect(10, 20, 40, 20)); // 位置为 (10, 20) ,大小为 (40, 20) 。
Control ctl3({10, 20, 40, 20}); // 同上。

  出于动态加载部件的需要, YSLib 提供的部件总是可以通过一个 Rect 值构造以及默认构造(相当于 Rect 为空),因此不限于 UI::Control 使用。

  在创建部件之后,使用函数 GetLocationOfGetSizeOfGetBoundsOf 等查询这些属性;相对地,使用函数 SetLocationOfSetSizeOfSetBoundsOf 等设置这些属性。通过这些函数设置位置和大小会分别触发 MoveResize 事件。

视图树和容器

  YSLib 提供了单一的视图树结构作为显示视图的抽象。通过指定部件所在的容器限定显示的范围。容器自身是一个部件,可以嵌套在另外的部件中。容器中的部件(子部件)的位置使用容器部件的边界的左上角作为原点,即位置表示子部件的边界的左上角相对于容器的边界的左上角。这样的结构典型地构成一颗树,只有作为树根的顶层部件没有容器。

  容器通过 UI::IWdiget 提供一般的迭代遍历支持。不是所有容器都支持动态添加子部件。模块 YSLib::UI::YPanel 提供一般的面板容器 UI::Panel 支持这个特性:

using namespace Drawing;
using namespace UI;
Panel pnl(Size(200, 100));
Control ctl({10, 20, 100, 40});

pnl += ctl; // ctl 作为 pnl 的子部件,在 pnl 左上角的位置 (10, 20) 显示。
yassume(&pnl == FetchContainerPtrOf(ctl)); // 宏 yassume 由 YBase 提供,默认和标准库的宏 assert 行为一致,表示断言; 函数 FetchContainerPtr 取得指向容器的指针。

顶层窗口(top level window)

  部件最终需要通过顶层部件的 UI::Paint 事件被显示。在独立实现中,顶层部件一般是模块 YSLib::UI::YDesktop 提供的 UI::Desktop 。在宿主实现中,由于需要和宿主环境的 GUI 集成,使用不同的接口。在一个有桌面环境的宿主平台中,这样的顶层部件一般称为顶层窗口

  Helper 模块对顶层窗口提供了和平台相关的实现。通过模块 Helper::HostedUI 提供的函数 Host::ShowTopLevel 使一个部件成为一个顶层窗口。

using namespace UI;
Control ctl(Size(200, 100));

Host::ShowTopLevel(ctl);

  对 Windows , Host::ShowTopLevel 支持更多的样式和扩展样式参数调整宿主窗口。具体使用详见 MSDN 。当调用 Host::ShowTopLevel 时,会自动创建具有独立线程和( Win32 意义上的)消息循环 Windows 窗口,这个过程可能发生阻塞。

常用部件

  UI 命名空间下除了 WidgetControlPanelYDesktop 几类直接作为框架必要类型的部件外,还有更多提供不同实用功能的部件。

  注意,非控件的部件不能取 UI::Paint 外的事件,否则会抛出异常。

UI::Label

  这是显示文本标签的部件。

  简单的用法是创建部件后,修改 Text 属性。它接受的是模块 YSLib::Core::YString 提供的 String 类型的 UCS-2 字符串,可以直接通过 std::u16stringconst char16_t* 等构造。因此内建的 u 前缀的字面量可以直接用于赋值 Text 。 YSLib 中 GUI 的其它部分也使用这样的字符串。

UI::Button

  按钮控件。

  类似 UI::Label 可以显示文本,但它是一个控件,可以点击并添加 UI::Click 事件回调。

动态加载

  模块 YSLib::UI::Loader 提供了在运行时读取 NPLA1 配置加载部件视图树的 API 。

  这些 API 当前相对不稳定,可能较容易改变,因此不作详细介绍。具体用法可参照示例程序 YReader 的源代码。

小结

  通过以上讨论,读者可以回顾入门中的示例,分析其中的各个部分的具体意义。

  在这个基础上,参阅 Doxygen 文档查找 UI 命名空间下的其它 API 以开发自己的 GUI 应用。

程序配置概述

  因为可移植性需求,YSLib 不直接使用特定平台提供的机制(如 Windows 注册表)。考虑表达能力和实现冗余, YSLib 不使用 INI 等简单的配置格式。考虑实现复杂性和用户输入配置的简便性, YSLib 避免使用 SGML 及其派生的标记语言,特别地, XML 及其派生语言实现作为配置格式。

  YSLib 提供相关解决方案为基于 NPL 派生实现 NPLA1 的配置,在 YFramework 模块 NPL::Configuration 中提供相关 API 。

规则和意义

  除了整个文件构成的 NPL 表达式外,每一个 NPL 表达式的第一个项应为标识符,表示配置项的名称。其后的项可以是字符串或列表,表示配置项的内容。

用例

  YFramework 的一部分使用配置决定程序运行时需要的信息,如字体文件的位置。参照程序运行

术语概要

  本文档概述及约定 YSLib 基本的概念含义,主要用于开发

项目管理

依赖(dependency) 管理

  项目管理的客体被分解为特定关联的依赖项。任意两个依赖项之间存在反对称传递二元关系称为依赖关系严格依赖关系是反自反的依赖关系。

  依赖项和依赖项之间的严格依赖关系统称为依赖

依赖引用

  因为依赖关系的传递性,多个依赖关系可能存在无法满足严格依赖关系的情形,即循环依赖。这导致以确定的顺序解析依赖不可行,增加维护成本。

  为了避免一定层次上的循环依赖,以该层次内组件为顶点的依赖关系的关系图应明确组织为有向无环图。 在最简单情况下依赖关系可退化为线性顺序依赖。

内部依赖和外部依赖

  项目中的组成部分之间的依赖称为内部依赖,其它依赖为外部依赖

源代码(source code)

  源代码用于生成指定目标代码(target code) 。

  通常源代码以文件形式保存,即源代码文件(source code file) ,简称源文件(source file) 。

版本库(repository)

  本项目使用的版本控制(version controll) 的存储实体。

  当前使用的主要版本控制系统为 Mercurial 。因为是分布式版本控制,也用于直接分发源代码。

  每个文件系统上存储的版本库实例中, .hg 目录存储版本库元数据。

设计和模型

环境(environment)

  程序中的某一部分的外界称为环境。根据限定程序的范围,可以有更确切的定义,如实现环境(对一类语言实现而言)、运行时环境(对共享实现环境的一类程序而言)。

  一般地,实现环境可以分为独立环境(freestanding environment)宿主环境(hosted environment) ,区分依据为是否依赖宿主(对部署在单一计算机上的实现,一般指操作系统)的支持。因此,环境有时指操作系统及其提供的外部服务的集合。

  一些语言,如 ISO C 和 ISO C++ ,可以同时支持宿主环境和独立环境的实现,对应独立实现(freestanding impementation)宿主实现(hosted impementation)

平台(platform) 环境

  环境中决定程序适用环境的被依赖的特定资源集合称为平台环境,简称平台。平台的典型例子有:

  平台的内涵是资源的集合,其构成并非任意。构成平台的特定准则应使之保持相对的稳定和可预期,即可配置;即平台是名义的(nominal) 可配置的资源集合。

  若平台包含的资源是已知的,则不需要平台的观念,分析其资源子集(即便不构成平台)即可解决几乎平台抽象涉及的所有技术问题(同时这也是定义一个具体平台的基础)。但在简化资源集合的全局性质分析(如比较资源配置方案)和名义抽象以隐藏实现(如为开发者提供预设环境集合)的应用角度上,平台仍有被单独讨论的意义。

兼容性(compatibility) 和可移植性(portability)

  若一个依赖项对应的平台可以替换,则此依赖项和此平台兼容(compatible) 。兼容性不是一种等价关系,因为不保证传递。

  替换平台的过程称为移植(porting) 。移植的可行性称为可移植性

  兼容任意平台的依赖项被称为是平台中立(platform-neutral) 的。

  当平台中立的依赖项的依赖能被自动满足而不需要考虑时,是平台无关(platform-independent) 的。平台中立实质蕴含平台无关。

依赖和外延

  若平台之间不出现平台的实现(如开发语言的实现)和环境自身的相互依赖,则这些平台相互独立。总是保持相互独立的一组平台称为独立平台(independent platforms) 。每一组独立平台保证可以相对于其它独立平台分离开发和测试。

  注意以上术语和 ISO C 和 ISO C++ 定义的宿主实现(hosted implementation)独立实现(freestanding implementation) 的关联和区别。

  典型的应用场景约定以下类型的平台:

  • 构建平台(build platform) 运行开发环境的平台。
  • 宿主平台(host platform) 运行构建平台输出代码的平台。
  • 目标平台(target platform) 运行最终目标代码的平台。

  若宿主平台和构建平台一致,称为本机构建(native build);否则,称为交叉构建(corss build)

  通常构建工具在本机构建时提供对构建平台的检查以确定自身是否能够运行;交叉构建环境需要显式指定。

  目标平台通常和宿主平台一致。指定目标平台的理由是,存在最终不一定在宿主平台上运行的程序,其运行的环境可能需要宿主平台不保证支持的特性,这典型地包括:

  • 构建的程序自身是生成其它程序的程序,如编译器和链接器。这些程序生成的平台是目标平台,不需要和它们的宿主平台相同。
  • 构建的程序可以在宿主平台上运行,但在其它平台上具有更完全的特性集。后者被作为目标平台。

注意 此处的宿主平台具有相对意义,不一定脱离被运行的目标平台。一个宿主平台通常自身是宿主实现平台,但这点不被保证。

模拟(emulation) 和仿真(simulation)

  模拟指适配和运行为不同平台设计的程序,广义上包括以下两类:

  • 环境模拟(environment emulation) :使用模拟器(emulator) 或虚拟机(virtual machine) 等作为宿主平台的程序,模拟运行环境的通用解决方案;
  • 程序模拟(program emulation) :直接以运行时环境适配层嵌入宿主平台运行时,在具体程序中提供类似被模拟的目标平台的具体特性和接口。

  运行模拟程序的环境和被模拟环境分别是宿主平台和目标平台。

  注意虚拟机在这个意义下是广义的模拟器,但一般仍然分别对待。

  环境模拟和程序模拟的主要差异为是否独立的、专用的宿主平台程序作为中介以维护目标平台和宿主平台的隔离。

  在一般意义上,仿真指对需要分析的问题建立的模型(model) 的过程、方法和机制,在软件工程以外也被称为模拟,如计算机模拟(computer simulation) 。对于以计算机系统为目标的仿真,建立的模型可以是具体的实物(包括硬件和软件),称为仿真器(simulator) 。以软件接口为主要操作方式实现的仿真器同时实现了环境模拟,但侧重不同:精确重现需要分析行为,而非实用的功能等价性和体系中的可替换性。

平台配置

  实际的平台实现可能复用部分实现,配置之间可存在某种构成依赖关系的偏序关系(如继承关系)。这些在项目中所有被配置的平台称为公共平台(common platform) ,其中能对应生成输出的称为具体平台(concrete platform) ,否则为抽象平台(abstract platform)

标识

  不同平台可以标识符加以区分。由于平台受到不同环境因素决定的正交性,通常此类标识符可以分解为表示这些正交环境的标识符的元组形式,用 - 等字符分隔。

  一种常用的方式是 GNU 构建系统的系统类型(en-US),经典表示方式为三元组(triplet) ,或其省略形式:

  • 一般包括体系结构、系统厂商和系统软件环境
  • 第一项不可省略,之后的项可省略
  • 体系结构一般指定 CPU 要求的最小指令集架构
  • 系统厂商指集成平台的环境厂商
  • 系统软件环境保证满足 ABI 要求,可以包含操作系统及本机语言运行时实现的名称

  确定为宿主环境时,系统软件同时指定操作系统和运行时环境而拆分为两项,三元组扩充为四元组,如 Gentoo 使用的 CHOST (en-US)

  在不够充分体现平台的必要差异(尤其是体系结构相关的配置)时也可通过自行定义标识符并指定与三元组的对应关系,如 Debian multiarch (en-US)

  除非必要时另行指定, YSLib 使用三元组作为指定平台标识的基本形式。

多平台构建

  构建系统中可能涉及多个平台。

  运行构建系统的环境和被构建的程序的环境不需要相同,对应的平台分别称为宿主平台(host platform) 和目标平台(target platform) 。宿主平台和目标平台相同时称为本机(native) 构建;不同时称为交叉(build) 构建。

  多个构建过程可能串联组成更大的构建过程。不同构建过程存在输出和输入之间的依赖。此时,前一过程输出的目标平台需要兼容于后一过程作为输入的宿主平台,否则无法直接运行。典型情况下这些平台是相同的,但也可以存在平台之间自身保证二进制互操作兼容性(如支持 x86_64 的体系结构上混用 i686 和 x86_64 )的情况。

  一些构建系统如 GNU 工具链(en-US) 使用更复杂的术语,单独引入构建(build) 平台。为确保一般性并简化模型, YSLib 不使用这个概念,而把构建平台作为第一级构建过程(即 GNU autoconf 的“配置”)的宿主平台。

Introduction

This page specifies the language features from the standard shall be used in this project, by introducing several rules and then clearifying which features are applied to the project from specific project build revision and time.

This page also includes some related information of external projects about various language implementations.

The interface documentation for this project may be specified in the doc directory of the repository, in the pages of wiki, or in the Doxygen comments around the declarations in the header files in the source code. All of them are in zh-CN by default.

Unless otherwise specified, notations of date and time are in UTC+8.

Notation

"NOTE" indicates note for maintainers and it is not directly from the source of the concerned contents.

References

Some external materials are referenced here by links in several categories. Entries in same category are listed ordinally specified by document numbers (if any).

Since only adopted revisions are applied, most superseded reversions are placed together. A paper of a collection of issues can have multiple revisions and it can be adopted more than once (e.g. P0165); these revisions does not superseds each other.

Revision and timestamp

Revisions are designated in forms of brevision-number[time], where revision-number is the number of revision and time is the timestamp issued for that revision in any of ISO 8601:2004 calendar time formats. The timestamp is usually a date conventionally with YYYY-MM-DD.

List of items

Items of features are categorized in different lists with various status. The indentation of a list indicates the context: items with less indentation level cover the topic covering items with more indentation level.

Items and tags

Each item in a list is normally specified by (committee) document or CWG/LWG/EWG/LEWG issue/DR(defect report) number with a link and a title. Paper as editor's report or issue/DR list (but not list about contents out of these contents, e.g. specifically drafted resolution paper of one ore more DRs) should be collectively listed in a few list (so issues can be top-level items otherwise). Each item may be noted with following tags:

  • "adopted" indicating the feature has been incorperated into the working paper (but not in this document) since the followed time which is usually the content of "Disposition" column from the official document list
  • "based on" indicating one of the base specifications
  • "dropped" indicating abandoned in development
  • "overriden by" indicating new item taking effect instead of the current one
  • "part of" or "parts of" indicating not all contents of the specification
  • "revised" indicating one of the revised specifications
    • is often unique
    • should be significant, e.g. adopted previously; otherwise it can already be indexed by other lists of items, and if there are no other list is appropriate, it shall be in the "outdated" list
  • "see" pointing to revised revisions
  • "see also" for related materials
  • "see other derivation" pointing to siblings
  • "see subsequent" pointing to subsequent new series
  • "since" with initial project build revision and time of applying (which is only applicable for features adopted or tentatively adopted in this document)
  • "split from" for the original item containing the material
  • "subsumed by" for the target of migration (e.g. for duplicated issues)
  • "with" indicating additional specifications not covered by specified one in the context

Basic rules

The Forwarding Compatibility Rule: All language features incompatible with published/normative future versions of the language specification shall not be mandated or depend on.

The Baseline Implementation Rule: Each feature being used shall have been implemented in general available version of at least 2 FOSS implementations.

General status

The default configuration, baseline, is specified here. The features explicitly introduced to clearify dependences on the language implementations are also listed in this and following sections.

Conformance

The conformance of languages and environments used in this project is specified using published versions of standards and technicle specifications, as well as drafts and proposals. For purpose of specification in this project, all of them are designated as specifications.

Several C++0x features are used since b206[2011-05-03]. These features are also in ISO C++11(ISO/IEC 14882:2011). Previously C++03 with TR1(ISO/IEC TR 19768:2007) was used. New version of ISO C++ and technicle specifications are also considered:

  • ISO C++14(ISO/IEC 14882:2014)
  • ISO C++17(ISO/IEC 14882:2017)

Baseline

C++11 is now default to conform.

As per the forwarding compatibility rules, all C++03 features conflicted with future versions of C++ (e.g. export) and all features already removed from C++17 (e.g. std::auto_ptr) are disallowed to rely on.

TR1 features are avoided and have been substituted by their C++11 counterparts.

Draft standard is considered in sake of avoiding conflicts with future versions of the standard.

Additional specifications

The considered and (possibly incompletely) reviewed technical specifications beyond C++11 are:

  • ISO/IEC TS 19568:2015 Programming Languages — C++ Extensions for Library Fundamentals

(See here for information about adoption in C++17.)

Replacements

Several features in specifications beyond C++11 is not directly relied on, but this project provides some replacements (possibly with some custom extensions) as features to ease the work about compatibility.

Replacements are provided in a "(mostly) drop-in" manner, i.e. the base name of API are same, but with allowence of difference on qualified prefix and/or prefixe (of namespaces, mostly, to std; or of headers to be included). This allows user code replacing interface with a few alias declarations without changing of the program well-formedness and behavior. It is easy to change the underlying set of API as well as to pick a subset of them on purpose.

The replacements provided most compatibility are bidirectionally drop-in replaceable, which can be used interchangably with the features they replace, except the compatibility exceptions specified below. However, such replacements are not guaranteed to be mixed arbitrary with the feature being replacements. The granularity of mixture with guaranteed usablity is a type or a template with any related operations relying on the type signature derived from that entity, unless otherwise specificed in documentation.

Some of other replacements are ony-way drop-in replacements, i.e., guaranteed being able to replace the correspoinding features in specifications without changing of meaning but not the other way.

Compatibility exceptions

Several features cannot be implemented portably due to ISO C++ core language features are not available in virous target environments (e.g. in the baseline).

Emulation of (esp. core language) features involved such cases is limited, and it would be implemented in replacements with best effort. Corollary: such features are available conditionally depending on which language dialect is being used.

For cases where the replaced features cannot be implemented portably in the baseline, the limitations shall be documented on related interface with \warning command to inform users the existence of portability risks and the condition of availablity (i.e. which dialects it is guaranteed to work). To avoid frequent need, features totally unusable (e.g. features relying on variable templates) are not provided at all, thus only a few cases should be concerned.

Currently, compatibility limitations include:

  • To determine whether a class is declared with final.
    • It is not implementable without some implementation support before C++14 introduces std::is_final.
    • Note that std::is_empty are not implementable without such support. However, std::is_empty is provided by C++11 (in the baseline), so there shall be no limitation on determine whether a class is empty.
  • To get pointer value to an object of arbitrary type in a constant-expression.
    • Even the type is complete, there is no guarantee to rule out user-defined overloaded operator& on the object.
    • In cases where operator& is used, C++11 provides std::addressof to get the correct result. However, it is not designated with constexpr, which is available portably only since C++17.

For better compatibility to evolution, additional exceptions are granted here:

  • Type equivalence between provided and replaced types is not guaranteed even if they coexist in a same configuration of C++ implementation.
    • This allows mixture of different components served as different parts of the replaced interface at same time, as well as complement of interface already (insufficiently) implemented by the current C++ implementation.
    • Types may provided based on old revision of specification (e.g. by inheritance of classes).
  • The constexpr specifier may be effectively omitteed in interface or implementation of the library when the environment is limited in a configuration with insufficient core language support.
    • The constexpr guaranteed by C++14 is not guaranteed available in a configuartion ealier than C++14, since it may be missing of relaxing constraints support in the core langauge implementation.
    • Any constexpr on lambda-expressions is not guaranteed available in a configuration eariler than C++17 even after adoption of constexpr lambda, since it may be missing in the core langauge implementation.
  • Operators may be introduced in declarations different to current version of specifications.
    • This is like [objects.within.classes] for private class members.
    • Comparison operators are no longer guaranteed accessible as independent entities (e.g. as operand of & or accessing using qualified-id).
      • This is same to the direction of future standardization proposed in P0790R0.
      • This dependes on C++20 <=> operator, but it is not the only way.
    • Other operators can be similar to get potentional great simplication of implementation.
      • Notably, with Barton–Nackman trick, simplification can be achived partially as <=> on most overloadable operators (not only comparison).
      • Currently, most operators in this project is simplified by using of YBase.YStandard.Operatos API.

Subproject structure

All of the replacements live in the top-level subproject YBase. The overall structure concerned here is:

  • YBase
    • YDefinition (header file ydef.h)
    • LibDefect
    • YStandardEx
    • others
  • other YSLib or YSLib-like top-level subprojects

For YBase, all interface of C++ code is in the namespaces specified here. This includes replacements.

There is no well-defined behavior guaranteed if library-wise rules are violated. The rules are:

  • No namespaces name can be introduced as top-level (directly enclosed in the global namespace) namespace names except the namespaces specified here:
    • Namespaces specified by the standard are used according to these rules.
    • The namespace ystdex provides most code not from YBase.LibDefect.
    • Namespace name (glob) pattern 'ystdex_*' are reserved.
      • Some of them may be used as top-level namespaces providing code additional to namespace ystdex without clash in ystdex, e.g. when ADL(argument dependent lookup) is unavoidable.
    • Reserved namespace with public interface as well as namespace ystdex are collectively specified as public top-level namespaces.
      • Currently public top-level namespaces are:
        • namespace ystdex
        • namespace ystdex_swap
    • To simplify the code, any top-level names without explicit qualified preifx :: shall be used as-if they are prefixed with with ::.
  • Only YBase.LibDefect can inject names into namespace std and other namespaces specified by the standard (as parts of implementation) when necessary in provide being conforming. Otherwise, they shall be conform to the rules of the library user code.
  • Documented reserved marco names besides the standard rules shall be also avoided by the library user code.
  • All other cases are conform to the standard rules except that the namespaces provided by the standard are replaced by the top-level namespaces specified above.

Except for the file specified as "drop-in replacement", a header specified by a rule of published standard or specification may or may not be directly aligned to the actual one in YBase, but there are clear many-interface-to-one-header relationship across the interface and headers by splitting the standard header to plural correspoinding header files. The purpose is to break down dependencies and to reduce the overhead of inclusion performed in preprocessing phase.

For other top-level subprojects, no replacements need to be considered. Unless otherwise specified, the baseline applies directly. If there needs replacements, use interface proveded by YBase for preference (but usually not YBase.LibDefect).

Components

Replacements in YBase consist of following components with caveats:

  • YDefinition, i.e. ydef.h, provides various vendor-neutral compatible interface of language implementation by conditioanlly-defined preprocessing macros.
    • A few replacemnets are same to YStandardEx direct replacements below, except provided in the top-level namespace directly.
  • LibDefect implementation provide some interface conform directly to the standard, as complement of the language implementations provided by system and toolchain vendors.
    • The public headers shall be capable for direct use with any implementation meeting the requirements specified by the YSLib documentation (including following sections) as in-drop replacements for corresponding standard library headers.
  • YStandardEx replacements provide remain interface meet the functionality needs.
    • YStandardEx direct replacements provide adaptive interface compatible and (almost) conforming to multile version of specifications.
      • To support adaptive use, the direct part of replacements may conditionally include different source, whose interface is specified as "conditionally" in this document.
      • The comformance requirements shall be clear to each interface.
      • Nonconforming interface may only occur with exactly same or one-to-one mapping of interface between namespace std and ystdex in the user code.
      • Nonconforming interface shall not introduce differences on requirements on the program using that interface.
      • Nonconforming interface shall be still compatible to other rules. That is, use of the interface shall not alter well-formness and the well-defined behavior of the program, except cases restricted by compatibility limitations.
    • YStandardEx dedicated replacements provide interface compatible to specifications as well as their drafts by less conformance requirements compared to direct replacements.
      • Nonconformance may occur in a form same to that in the case of YStandardEx direct replacements.
      • Nonconformance shall occur in a form that loosing the requirements of rules in the published standard or specification, or in a form with explicitly supported extensions which are not compatible to these rules; otherwise, the interface should be designed as direct replacements or non replacements.

See following paragraphs for precise definition of components and more detailed descriptions on policies of their use.

Evolution

For compatibility, the project may use different sets of rules in each parts. YBase is more stable and conservative to utilize new C++ features.

Longterm policy

The longterm policy holds as:

  • ydef.h: For compatibility reasons, only a subset of C++11 would be mandated. The precise subset is unspecified and can vary between revisions.
  • YBase except LibDefect discussed above: Library features beyond C++11 would be used only available.
  • Other parts of the project: C++ features would be used aggressively (but still restrictd by the rules here, esp. the basic rules). Currently it is still in the baseline.

Core language compatibility features

Some core language feature have fallback in C++03 (e.g. constexpr) or library (e.g. alignof), mostly workaround in ydef.h, as well as some optional extensions (e.g. __has_feature and __builtin_expect) wrapped as implementation details. They are provided by YDefnition.

Some core language features not in the standard but provided by various adapted language implementations have been wrapped in a platform-neutral interface provided by YDefinition.

Library implementation patches

Due to limitations of specific environments, some standard library features might be not usable without alternative implementations. They may be enabled by using additional headers in the module YBase.LibDefect instead of the corresponding standard headers.

As patches, namely parts of language implementations, the code in YBase.LibDefect can be highly implementation-specific. It has significant differences (which may cause undefined behavior without further guarantees) to the usual library and user code:

  • It can be directly intrusive to the global namespace, namespace std and other implementation-specific namespaces, which may be reserved by the standard.
  • As part of the standard library implementation, it may use names reserved by the standard.
  • It may have implementation-specific contents intended only for internal use and guarded by conditional inclusion, because they are direct replacements for the standard library.

The code has been carefully tuned to be compatible to supported environments, to keep out undefined behavior merely caused by this implementation.

Library compatibility features

To reduce impact on user code to adopt new versions of specifications, several post-C++03 library features are provided in the top-level namespace ystdex (with inlined namespace if the features have been in published standards) in module YBase.YStandardEx, either by using declarations from namespace std iff. provided by the standard library, or being implemented from scratch when the features are not available from the standard library (not the library implementation, i.e. implementation-specific interface are still forbidden).

They are designed to be (bidirectionally) drop-in replacements (with necessary filename change in #include directives) of corresponding specific version of std or std::experimental interface, with a few exceptions:

  • Except for some specialization of standard library templates, the enclosing namespace is not std so name lookup may behave differently to the standard library interface.
    • Use additional 'using ystdex::NAME;' to enable ADL(argument dependent lookup) for NAME.
    • Note [global.functions]/4 is still conforming similarly. Any ADL beyond namespace ystdex shall be specified by the interface documentation.
  • The overloaded operators may be implemented by ADL-only manner, i.e. declared as friend functions, rather than namespace scope entities.
    • Currently no entities are declared in this manner except for interface are ready for post-C++14 standard library features.
  • It is unspecified that whether the concerned types of replacement API is identical to the types in the standard.
    • It is important to know this to avoid type introspection based on wrong type identical assumptions, including:
      • Using static_assert or some other meta operations based on static type equivalence.
      • RTTI or exception handling based on dynamic type identity.

They are collectively called as YStandardEx direct replacements for the corresponding features being replaced.

YBase user code may use interface in public top-level namespaces instead of the counterparts in the namespaces mentioned above to simplify the migration. For components of direct replacements interface beyond ISO C++11, they are in correspoinding enclosed standard replacement namespaces which are inline namespaces enclosed unambiguously in public namespaces with a common namespace prefix pattern with same nested namespaces to the standard interface. For example:

  • Interface first occurred or last updated in ISO C++14 in namespace std is in inline namespace ystdex::cpp2014.
  • std::pmr interface introduced since ISO C++17 is in inline namespace ystdex::pmr::cpp2017.

Note that a similar approach is also proposed for std separatedly as shadow namespace in P1473R0 for some slightly different purposes.

If there are multiple published versions of standard having modification on some entities denoted by a same name, there shall be one candidate or at least one extra alias declaration to reference it in the public top-level namespaces unambiguously, allowing omission of the inline namespace name normally but distinguishing on need. Deprecated features is not guaranteed provided unless explicitly specified to reduce confusion and restriction as per the future direction of feature using implied in this document. To avoid misconceptions, other replacements shall neither be provided in standard replacement namespaces or their enclosing namespaces thereof.

Ambiguity across different namespaces with mixture use of them shall also be avoided.

Components for the upcoming standard (in the working draft or Technicle Specifications, but not the published Internaltional Standard) are deliberately experimental as library compatibility features, so they are directly declared in public top-level namespaces.

As per the compatibility limitations of replacements, exceptional rules of compatibility to std interface are granted hereby:

  • For entities used specifically in tag dispatching, only such use is required to be compatible as drop-in replacement. The differences shall be defined in documents about the replacement.

Revised components of library compatibility features shall not be deprecated in the current (newest formal) standard.

Extended library compatibility features

Some other interfaces in YBase.YStandardEx are designed as replacements for corresponding specific versions of std or std::experimental interface, as the compatibility features above, but with extra extensions, and with no restriction about the solution of LWG 2013 (that is, they may be with extra constexpr). They can be used as ony-way drop-in replacements.

Entities with extended library compatibility features to the replaced entites are collectively called as YStandardEx dedicated replacements of the corresponding features being replaced, where each of them meets following requirements:

  • Except extensions, it shall be able to one-to-one mapped to the entity being replaced with exact functionality (albeit the name can be different in several cases, see below).
  • If it is neither a type nor a template of type (class template or alias template), or it is provided as some part of other compatibility features, its base name (unqualified-id) shall be same to the name of entity being replaced.
  • Its name shall be declared in public top-level namespaces or enclosed namespaces thereof, except the namespaces excluded by the rules specified previously.

Components of extended library compatibility features not being dedicated replacements shall be declared in public top-level namespaces and may be declared in the same header of the compatibility features above.

Potential library compatibility features

Some other interfaces in YBase.YStandardEx are designed close to correspongding specific versions of std or std::experimental interface, to be an implemantation base of above compatibility library features or extended library compatibility features. They are not replacements as they are not designed to be conforming to any version of the standard or technical specifications, nor always provided in a drop-in manner. Nevertheless, they may have features which can be directly mapped to the said specifications, with or without some resolutions of LWG issues applied.

Although as implementation of above features, they are totally in details, they can also be used as public interfaces as other parts of YSLib.

Reviewed

The following editor's report has been fully reviewed (b593[2015-04-23]), which means all the resolutions in the paper are categorized in the following clauses:

NOTE There might exist minor differences between editor's report and the paper in the list, e.g. N3059 (rev 5.2) in N3091 is (rev 5.1). For these cases, only the later revisions at the point of time are reviewed and probably would not be updated unless necessary.

To be done

Reviewing of following defect reports and resolutions are work in progress.

  • CWG 215: Template parameters are not allowed in nested-name-specifiers
  • CWG 218: Specification of Koenig lookup (see also CWG 113 and CWG 143)
  • CWG 397: Same address for string literals from default arguments in inline functions?
  • CWG 667: Trivial special member functions that cannot be implicitly defined
  • CWG 1135: Explicitly-defaulted non-public special member functions
    • CWG 1136: Explicitly-defaulted explicit constructors
    • CWG 1140: Incorrect redefinition of POD class
    • CWG 1145: Defaulting and triviality
    • CWG 1149: Trivial non-public copy operators in subobjects
    • CWG 1208: Explicit noexcept in defaulted definition
  • N4320: Make exception specifications be part of the type system

Reviewing of following editor's reports is work in progress.

No actions

There are nothing to do of coding and further documentations for some resolutions.

Note in WG21 terms, NAD means "not a defect", and TC1 means "Technical Corrigendum 1".

In the baseline

These issues are resolved as NAD and thus have been rejected by WG21 in the baseline, and there are no further changes to reopen:

  • CWG 37: When is uncaught_exception() true?
  • CWG 61: Address of static member function "&p->f"
  • CWG 109: Allowing ::template in using-declaration​s
  • CWG 130: Sequence points and new-expression​s
  • LWG 84: Ambiguity with string::insert()
  • EWG 91: [tiny] Core issue 622, Relational comparisons of arbitrary pointers
    • CWG 622: Relational comparisons of arbitrary pointers (see EWG 91)
  • parts of N2173: Core Extensions for Evolution
    • CWG 13: extern "C" for Parameters of Function Templates
    • CWG 107: linkage of operator functions
    • CWG 168: C linkage of static members
    • CWG 229: Partial specialization of function templates
    • CWG 294: can static_cast drop exception specs (see also CWG 87)
    • CWG 359: Type definition inside anonymous union

These issues were once confirmed but are in NAD status now due to newer feature changes which have been adopted by the standard and by this project, so there are nothing further to do:

  • CWG 395: Conversion operator template syntax
  • LWG 2386: function::operator= handles allocators incorrectly (see also P0302R1)

These resolutions are already adopted as TC1, i.e. in C++03, and still effective (probably revised) in later versions of the standard:

  • CWG 25: Exception specifications and pointers to members
  • CWG 30: Valid uses of "::template"
  • CWG 84: Overloading and conversion loophole used by auto_ptr
  • CWG 137: static_cast of cv void*
  • CWG 178: More on value-initialization (see also CWG 543)
  • CWG 304: Value-initialization of a reference
  • LWG 61: Exception-handling policy for unformatted output
  • LWG 129: Need error indication from seekp() and seekg()
  • LWG 136: seekp, seekg setting wrong streams?
  • LWG 209: basic_string declarations inconsistent
  • LWG 227: std::swap() should require CopyConstructible or DefaultConstructible arguments
  • N1219: PROPOSED RESOLUTION TO LIBRARY ISSUE 60
    • LWG 60: What is a formatted input function?

Not related to user code

These issues are resolved as NAD or NAD editorial and thus nothing to do for user code:

  • CWG 1384: reinterpret_cast in constant expressions
  • CWG 1415: Change "declararation or definition" to "declaration"
  • CWG 1520: Alias template specialization vs pack expansion (see also CWG 1558)
  • LWG 299: Incorrect return types for iterator dereference
  • LWG 392: 'equivalence' for input iterators
  • LWG 526: Is it undefined if a function in the standard changes in parameters?
  • LWG 529: The standard encourages redundant and confusing preconditions
  • LWG 580: unused allocator members
  • LWG 2006: emplace broken for associative containers
    • proposed by N3178: emplace broken for associative containers
  • LWG 2204: reverse_iterator should not require a second copy of the base iterator

These post-C++03 draft resolutions are non-normative, purely editorial or conceptional, so no actions could be taken (revised b843[2018-11-10]):

  • CWG 113: Visibility of called function
  • CWG 119: Object lifetime and aggregate initialization
  • CWG 357: Definition of signature should include name
  • CWG 404: Unclear reference to construction with non-trivial constructor (NOTE partially superseded by new wording in [basic.life] proposed by CWG 1751 and CWG 2256)
  • CWG 413: Definition of "empty class"
  • CWG 452: Wording nit on description of this, partially adopted
  • CWG 538: Definition and usage of structure, POD-struct, POD-union, and POD class
    • CWG 327: Use of "structure" without definition
  • CWG 582: Template conversion functions
  • CWG 594: Coordinating issues 119 and 404 with delegating constructors (see CWG 119 and CWG 404)
  • CWG 618: Casts in preprocessor conditional expressions
  • CWG 627: Values behaving as types
  • CWG 999: “Implicit” or “implied” object argument/parameter?
  • LWG 542: shared_ptr observers
  • LWG 610: Suggested non-normative note for C++0x (i.e. small function object optimization)
  • LWG 616: missing 'typename' in ctype_byname
  • LWG 628: Inconsistent definition of basic_regex constructor
  • LWG 640: 27.6.2.5.2 does not handle (unsigned) long long (i.e. for ostream::operator<<), outdated
  • LWG 972: The term "Assignable" undefined but still in use
  • LWG 2135
    • LWG 2240: Probable misuse of term "function scope" in [thread.condition]
  • LWG 2310: Public exposition only member in std::array
  • LWG 2434: shared_ptr::use_count() is efficient
  • LWG 2755: §[string.view.io] uses non-existent basic_string_view::to_string function
  • N2775: Small library thread-safety revisions
  • N3066: Iterators in C++0x
  • N3966: Fixes for optional objects (revised as N4078)
  • editorial change in N4714
  • P0134R0: Introducing a name for brace-or-equal-initializer​s for non-static data members
  • P0583R0: std::byte is the correct name
  • P1076R1: Editorial clause reorganization with modification
  • P0509R1: Updating "Restrictions on exception handling" (adopted: accepted by N4664)
    • see national body comments GB 41 and GB42 in N4664: ISO/IEC CD 14882, C++ 2017, National Body Comments

These post-C++03 draft resolutions would never be depended on because they are only intended useful for language implementations and there shall be no compatibility problems for conforming code (revised b593[2015-04-23]):

  • N2194: decltype for the C++0x Standard Library

Outdated

These resolutions are only about TR1 or features have been formally deprecated/removed from current ISO C++, so shall never be depended on:

  • LWG 527: tr1::bind has lost its Throws clause
  • LWG 588: requirements on zero sized tr1::arrays and other details (for std::array, resolved by LWG 776)

These issues are duplicate (in "dup" status):

  • CWG 133: Exception specifications and checking (subsumed by CWG 87 and CWG 92)
  • CWG 595: Exception specifications in templates instantiated from class bodies (subsumed by CWG 1330)
  • CWG 1300: T() for array types (duplicate of CWG 914)
  • CWG 1568: Temporary lifetime extension with intervening cast (duplicate of CWG 1376)
  • LWG 479: Container requirements and placement new (duplicate of LWG 580)
  • LWG 486: min/max CopyConstructible requirement is too strict (duplicate of LWG 281)
  • LWG 2775: reverse_iterator is does not compile for fancy pointers (duplicate of LWG 1052)

These resolutions are superseded by later modification on the working paper:

These resolutions are overriden by later issues after publication:

  • CWG 2022: Copy elision in constant expressions (overriden by CWG 2278)
  • LWG 235: No specification of default ctor for reverse_iterator (overriden by LWG 1012)

These resolutions are superseded and resolved by later issues before the publication:

These papers are superseded and newer revisions have been reviewed, so no further actions would be taken:

  • N1599: Issue 431: Swapping containers with unequal allocators (see subsequent N2525)
  • N1890: Initialization and initializers (see subsequent N1919)
  • N1919: Initializer lists (revised as N2100)
  • N1932: Random Number Generation in C++0X: A Comprehensive Proposal (revised as N2032)
  • N1961: Wording for range-based for-loop (revised as N2196)
  • N1968: Lambda expressions and closures for C++ (revised as N2329: Lambda expressions and closures for C++ (Revision 1))
  • N2032: Random Number Generation in C++0X: A Comprehensive Proposal, version 2 (revised as N2079)
  • N2062: POD's Revisited (revised as N2102)
  • N2079: Random Number Generation in C++0X: A Comprehensive Proposal, version 3 (revised as N2111)
  • N2100: Initializer lists (Rev 2.) (revised as N2215)
  • N2102: POD's Revisited; Resolving Core Issue 568 (Revision 1) (revised as N2172)
  • N2151: Variadic Templates for the C++0x Standard Library (revised as N2192)
  • N2172: POD's Revisited; Resolving Core Issue 568 (Revision 2) (revised as N2230)
  • N2192: Variadic Templates for the C++0x Standard Library (Revision 1) (revised as N2242)
  • N2196: Wording for range-based for-loop (revision 1) (revised as N2243)
  • N2210: Defaulted and Deleted Functions (revised as N2326)
  • N2202: C99 Compatibility : __func__ and predeclared identifiers (revised as N2251)
  • N2215: Initializer lists (Rev. 3) (revised as N2385)
  • N2217: Placement Insert for Containers (revised as N2268)
  • N2230: POD's Revisited; Resolving Core Issue 568 (Revision 3) (revised as N2294)
  • N2236: Towards support for attributes in C++ (revised as N2379)
  • N2243: Wording for range-based for-loop (revision 2) (revised as N2394)
  • N2251: C99 Compatibility : __func__ and predeclared identifiers (revision 1) (revised as N2340)
  • N2268: Placement Insert for Containers (Revision 1) (revised as N2345)
  • N2294: POD's Revisited; Resolving Core Issue 568 (Revision 4) (revised as N2342)
  • N2326: Defaulted and Deleted Functions (revised as N2346)
  • N2329: Lambda expressions and closures for C++ (Revision 1) (revised as N2413)
  • N2345: Placement Insert for Containers (Revision 2) (revised as N2642)
  • N2379: Towards support for attributes in C++ (Revision 2) (revised as N2418)
  • N2385: Initializer lists WP wording (revised as N2531)
  • N2394: Wording for range-based for-loop (revision 3) (revised as N2778)
  • N2413: Lambda Expressions and Closures: Wording for Monomorphic Lambdas (revised as N2487)
  • N2418: Towards support for attributes in C++ (Revision 3) (revised as N2553)
  • N2477: Uniform initialization design choices (Revision 2) (revised as N2532)
  • N2487: Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 2) (revised as N2529)
  • N2529: Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 3) (revised as N2550)
  • N2531: Initializer lists WP wording (Revision 2) (see subsequent N2575)
  • N2532: Uniform initialization design choices (Revision 2) (see subsequent N2575)
  • N2550: Lambda Expressions and Closures: Wording for Monomorphic Lambdas (Revision 4) (revised as N2927)
  • N2553: Towards support for attributes in C++ (Revision 4) (revised as N2751; the unavailable revised revision N2663 is wrong on document list)
  • N2575: Initializer Lists — Alternative Mechanism and Rationale (revised as N2640)
  • N2635: Local and Unnamed Types as Template Arguments (revised as N2657)
  • N2640: Initializer Lists — Alternative Mechanism and Rationale (v. 2) (revised as N2672)
  • N2642: Proposed Wording for Placement Insert (revised as N2680)
  • N2751: Towards support for attributes in C++ (Revision 5) (revised as N2761)
  • N2778: Wording for range-based for-loop (revision 4) (revised as N2930)
  • N2820: Adding heterogeneous comparison lookup to associative containers (revised as N2882)
  • N2882: Adding heterogeneous comparison lookup to associative containers for TR2 (Rev 1) (revised as N3465)
  • N2904: Defining default copy and move (revised as N2953)
  • N2953: Defining Move Special Member Functions (revised as N2987)
  • N2987: Defining Move Special Member Functions (revised as N3044)
  • N3044: Defining Move Special Member Functions (revised as N3053)
  • N3149: From Throws: Nothing to noexcept (revised as N3195)
  • N3248: noexcept Prevents Library Validation (revised as N3279)
  • N3433: Clarifying Memory Allocation (revised by N3537)
  • N3465: Adding heterogeneous comparison lookup to associative containers for TR2 (Rev 2) (revised as N3657)
  • N3537: Clarifying Memory Allocation (revised by N3664)
  • N3597: Relaxing constraints on constexpr functions (revised as N3652)
  • N3598: constexpr member functions and implicit const (revised as N3652)
  • N3727: A proposal to add invoke function template (revised as N4169)
  • N3873: Improved insertion interface for unique-key maps (revised as N4006 and N4240)
  • N4002: Cleaning‐up noexcept in the Library (revised by N4227)
  • N4006: An improved emplace() for unique-key maps (dropped; see other derivation of N3873)
  • N4017: Non-member size() and more (revised as N4155)
  • N4056: Minimal incomplete type support for standard containers (revised as N4371)
  • N4151: TriviallyCopyable reference_wrapper (revised as N4277)
  • N4155: Non-member size() and more (Revision 1) (revised as N4280)
  • N4227: Cleaning-up noexcept in the Library (Rev 2) (revised by N4258)
  • N4228: Refining Expression Evaluation Order for Idiomatic C++ (see subsequent P0145R0)
  • N4240: Improved insertion interface for unique-key maps (revised as N4279)
  • N4334: Wording for bool_constant (revised as N4389)
  • N4371: Minimal incomplete type support for standard containers, revision 2 (revised as N4390)
  • N4390: Minimal incomplete type support for standard containers, revision 3 (revised as N4510)
  • N4429: Rewording inheriting constructors ((core issue 1941 et al) (revised by P0136R0)
  • N4446: The missing INVOKE related trait (i.e. is_callable) (revised by P0077R2)
  • P0136R0: Rewording inheriting constructors ((core issue 1941 et al) (revised by P0136R1)
  • P0145R0: Refining Expression Evaluation Order for Idiomatic C++ (Revision 1) (revised by P0145R1)
  • P0068R0: Proposal of [[unused]], [[nodiscard]] and [[fallthrough]] attributes. (revised by P0188R0 and P0189R0 in parts, see subsequent P0212R0)
  • P0077R0: is_callable, the missing INVOKE related trait (revised by P0077R1)
  • P0077R1: is_callable, the missing INVOKE related trait (revised by P0077R2)
  • P0145R1: Refining Expression Evaluation Order for Idiomatic C++ (Revision 2) (revised by P0145R2)
  • P0145R2: Refining Expression Evaluation Order for Idiomatic C++ (revised by P0145R3)
  • P0188R0: Wording for [[fallthrough]] attribute. (revised by P0188R1)
  • P0189R0: Wording for [[nodiscard]] attribute. (revised by P0189R1)
  • P0212R0: Wording for [[maybe_unused]] attribute. (revised by P0212R1)
  • P0302R0: Deprecating Allocator Support in std::function (revised by P0302R1)
  • P1089R2: Sizes Should Only span Unsigned (see subseqent P1227R1)
  • P1227R0: Signed ssize() functions, unsigned size() functions (revised by P01227R1)
  • P1227R1: Signed ssize() functions, unsigned size() functions (revised by P01227R2)

These papers have been previously adopted but superseded by newer adopted papers, so no further actions would be taken:

  • N2525: Allocator-specific Swap and Move Behavior (adopted 2008-03, in editor's report N2589; revised as N2982)
  • N3672: A proposal to add a utility class to represent optional objects (Revision 4) (adopted 2013-04; revised as N3793)
  • P0077R2: is_callable, the missing INVOKE related trait (adopted 2016-02; revised as P0604R0)

These features were still under development but the approved versions were superseded (note that the superseded versions may still newer than currently adopted version), and not adopted in this document:

  • EWG 22: N4030, 3745, N3694 Feature-testing recommendations for C++, N3435 Standardized feature-test macros (for adopted version, see N4200)
    • N3435: Standardized feature-test macros
    • N3694: Feature-testing recommendations for C++
    • N3745: Feature-testing recommendations for C++
    • N4030: Feature-testing recommendations for C++
    • P0096R0: Feature-testing recommendations for C++
    • P0096R4: Feature-testing recommendations for C++ (see subsequent P0941R0)
    • P0941R0: Integrating feature-test macros into the C++ WD
    • P0941R1: Integrating feature-test macros into the C++ WD
  • N3890: Container<Incomplete Type> (partially superseded by N4056)

Revoked

These features were once adopted by the working paper but later removed away, so no actions would be taken until introduced to the draft again:

  • CWG 1308: Completeness of class type within an exception-specification (see CWG 1330)
  • LWG 1029: Specialized algorithms for memory management need to be concept-constrained templates
  • LWG 1001: Pointers, concepts and headers (see LWG 1178)
  • N2525: Allocator-specific Swap and Move Behavior (i.e. allocator_propagate_*)
  • N2620: Concepts for the C++0x Standard Library: Diagnostics library
  • N2736: Concepts for the C++0x Standard Library: Numerics (Revision 3)
  • N2755: Concepts for the C++0x Standard Library: Chapter 17 -Introduction (Revision 2)
  • N2758: Iterator Concepts for the C++0x Standard Library (Revision 5)
  • N2759: Concepts for the C++0x Standard Library: Algorithms (Revision 5)
  • N2768: Allocator Concepts, part 1 (revision 2)
  • N2770: Concepts for the C++0x Standard Library: Utilities (Revision 5)
  • N2773: Proposed Wording for Concepts (Revision 9)
  • N2774: Foundational Concepts for the C++0x Standard Library (Revision 5)
  • N2776: Concepts for the C++0x Standard Library: Containers (Revision 4)
  • N2777: Concepts for the C++0x Standard Library: Iterators (Revision 4)
  • N2779: Concepts for Clause 18: Part 2
  • N2780: Named Requirements for C++0X Concepts, version 2
  • N2786: Simplifying unique_copy (Revision 1)

There are actions taken by the committee to remove away some former working draft features which are never used in this project:

  • N2549: Excision of Clause 31 (i.e. <date_time>)

Non defects

These out-of-baseline issues are resolved as NAD:

  • CWG 1005: Qualified name resolution in member functions of class templates (see also CWG 1017; note CWG 515 is still effective)
  • CWG 1334: Layout compatibility and cv-qualification
  • LWG 466: basic_string ctor should prevent null pointer error
  • LWG 760: The emplace issue (see LWG 2164 which is still open)
  • LWG 763: Renaming emplace() overloads (N2680 renamed one of the overloads to emplace_hint; for related discussion see LWG 1302)
  • LWG 1202: integral_constant needs a spring clean
  • LWG 1302: different emplace semantics for sequence and associated containers
  • LWG 2311: Allocator requirements should be further minimized
  • LWG 2319: basic_string's move constructor should not be noexcept

Not applicable

Some proposals are not approved.

  • N3400: A proposal for eliminating the underscore madness that library writers have to suffer

Some proposals are not applicable yet and to be resolved in future. There also may be workaround provided by C++ implementation extensions or user code.

  • N2683: issue 454: problems and solutions
    • LWG 454: basic_filebuf::open should accept wchar_t names

In development

These issues are in "extension" state and not ready to be adopted:

  • CWG 476: Determining the buffer size for placement new (see also CWG 256)

Adoption

C++11 core language features and headers below now are being used.

Note: the "adopted" time notes listed in following entries are relative to working paper.

Imported TR1 Headers

TR1(see N1836) headers imported to C++11 are used:

  • <array> (since b218[2011-06-14])
  • <type_traits> (since b206[2011-05-03])
  • <tuple> (since b206[2011-05-03])
    • with LWG 1191: tuple get API should respect rvalues
    • with LWG 1382: pair and tuple constructors should forward arguments
    • with LWG 1384: Function pack_arguments is poorly named (i.e. forward_as_tuple; since b206[2011-05-03])
    • with N2244: Wording for decay, make_pair and make_tuple
    • with N2299: Concatenating tuples, with modification (since b303[2012-04-23])
  • <unordered_map> (since b206[2011-05-03])
  • <unordered_set> (since b206[2011-05-03])

New headers

New headers after C++03 may be used.

C++11 baseline

New non-TR1 headers from C++11 are used:

  • <atomic> (for all platforms from b590[2015-04-03]; for platforms supporting multithreading since b328[2011-07-25]; for platform MinGW32 since b299[2013-04-08])
  • <chrono> (since b291[2012-03-07])
  • <forward_list> (since b218[2011-06-14]; see N2543)
  • <initializer_list> (since b297[2012-03-27]; see N2672)
  • <typeindex> (since b468[2014-01-20])
  • <regex> (since b795[2017-06-11])
  • <system_error> (since b476[2014-02-16]; see N2241)

Multithreading

For all implementations supporting multithreading, these headers are also used:

  • <condition_variable> (since b328[2011-07-25]; for platform MinGW32 since b299[2013-04-08])
  • <future> (since b520[2014-07-23])
  • <mutex> (since b328[2011-07-25]; for platform MinGW32 since b299[2013-04-08])
  • <thread> (since b328[2011-07-25]; for platform MinGW32 since b299[2013-04-08])

Note: LWG 1360 specified single-threaded program should be able to use <atomic>, and resolved by N3256. However, the current YSLib doesn't require it for single-threaded programs.

Beyond C++11

For rules of baseline, new headers are only used conditionally, mostly for avoiding need of replacements in non-C++11 modes where the specified headers are available.

  • `<memory_resource> (since b842[2018-10-27]
    • replacement provided by <ystdex/memory_resource.h> if not available
  • `<string_view> (since b833[2018-07-31]
    • replacement provided by <ystdex/string_view.hpp> if not available
  • <optional> (since b831[2018-07-13])
    • replacement provided by <ystdex/optional.h> if not available

Technical Specifications

Technical Specifications are retargetted to standards finally. Not all features are used until they are adopted to the standard draft.

TR1

TR1 features was once used, but now retired and corresponding ISO C++ features shall be used, since they are imported from TR1 (see editor's report N2008) (since b206[2011-05-03]):

  • TR1 <type_traits> including metafunctions and std::tr1::aligned_storage (since b175[2010-12-23])
    • replaced by C++11 std::aligned_storage, see N2341 (since b206[2011-05-03])
  • TR1 <memory> std::tr1::shared_ptr (since b203[2011-04-22])

Some TR1 features are not used, as C++11 features are used instead:

  • TR1 <memory> std::tr1::function is preferred by std::function (since b207[2011-05-09])
    • with LWG 2132: std::function ambiguity

Other TSes

Although not used directly for evolution rules, some adopted modifications have already in the final draft of technical specifications:

  • N4480: Programming Languages — C++ Extensions for Library Fundamentals
    • with N4288: Strike string_view::clear from Library Fundamentals (adopted 2014-11)
  • N4562: Working Draft, C++ Extensions for Library Fundamentals, Version 2
    • parts on N3793: A proposal to add a utility class to represent optional objects (Revision 5)
      • revised previously-adopted N3672: A proposal to add a utility class to represent optional objects (Revision 4) (adopted 2013-04)
        • moved to Library TS by LWG motion 6 in N3769
    • with N3765: On Optional
    • based on N4282: A Proposal for the World's Dumbest Smart Pointer, v4

They are listed here for exposition-only use. The actual adoption depends on items depending them on.

Adopted changes

Features adopted shall be compatible with rules for general status.

To be reviewd

These pre-C++11 resolutions are believed have been relied on. It is yet to determine the "since" cluase (reviewed b865[2019-08-30]).

  • CWG 624: Overflow in calculating size of allocation (see also CWG 476)
    • CWG 256: overflow calculating size of new array

Restrictive improvement

The conformance of following lists of clearer specification with probable stronger restrictions (to the implementation and program-provided code including this project) or fixed specifications aligned with all existed implementations are concerned and took into account (revised b865[2019-08-17]).

For specifications before C++11:

  • CWG 96: Syntactic disambiguation using the template keyword
  • LWG 201: Numeric limits terminology wrong
  • CWG 220: require de-allocation not throw
  • LWG 274: a missing/impossible allocator requirement (partially overriden by LWG 2447)
  • LWG 294: User defined macros and standard headers
  • LWG 300: list::merge() specification incomplete
  • LWG 386: Reverse iterator's operator[] has impossible return type
  • LWG 416: definitions of XXX_MIN and XXX_MAX macros in climits, reworded slightly
  • LWG 422: explicit specializations of member functions of class templates, reworded slightly
  • LWG 456: Traditional C header files are overspecified
  • LWG 420: is std::FILE a complete type?

For specifications between C++11 and C++14:

  • CWG 1376: static_cast of temporary to rvalue reference (see also CWG 1568)
  • CWG 1430: Pack expansion into fixed alias template parameter list
  • CWG 1493: Criteria for move-construction
  • CWG 1570: Address of subobject as non-type template argument
  • CWG 1596: Non-array objects as array[1]
  • CWG 1629: Can a closure class be a literal type?
  • CWG 1672: Layout compatibility with multiple empty bases
  • CWG 1751: Non-trivial operations vs non-trivial initialization
  • CWG 1885: Return value of a function is underspecified
  • LWG 2013: Do library implementers have the freedom to add constexpr? (see also here)
  • LWG 2014: More restrictions on macro names
  • LWG 2447: Allocators and volatile-qualified value types
  • N3436: std::result_of and SFINAE
  • N3644: Null Forward Iterators (adopted 2013-04)

For specifications between C++14 and C++17:

For specification beyond C++17 (including drafting and WP state):

  • CWG 2256: Lifetime of trivially-destructible objects
  • LWG 3140: COMMON_REF is unimplementable as specified (adopted 2018-11, in editor's report N4792)

Deprecation

Features in the following adopted deprecation are not depended on (revised b863[2019-08-01]):

  • P0174R2: Deprecating Vestigial Library Parts in C++17 (adopted 2016-06; since b835[2018-08-13])
  • deprecation of shared_ptr unique in P0521R0: Proposed Resolution for CA 14 (shared_ptr use_count/unique) (adopted 2016-11; since b835[2018-08-14])
    • LWG 2776: shared_ptr unique() and use_count()
    • see national body comment CA 14 in P0488R0: WG21 Working Paper, NB Comments, ISO/IEC CD 14882
  • P0767R1: Deprecate POD
    • CWG 2323: Expunge POD
    • see national body comment US 101 in P0488R0: WG21 Working Paper, NB Comments, ISO/IEC CD 14882 (adopted 2017-11; since b853[2018-02-15])
  • P0806R2: Deprecate implicit capture of this via [=] (adopted 2018-06)

Removal

Several features removed in C++17 are not depended on (revised b853[2019-02-15]):

  • LWG 2385: function::assign allocator argument doesn't make sense
  • LWG 2487: bind() should be const-overloaded, not cv-overloaded
    • in libstdc++ this is an extension (although declared deprecated by _GLIBCXX_DEPR_BIND) but the implementation (std::__volget) is essentially not type-safe (with const_cast to remove volatile in the calls)
  • P0302R1: Removing Allocator Support in std::function (rev 1) (adopted 2016-06)
    • N2308: Adding allocator support to std::function for C++0x, with modification
    • LWG 2370: Operations involving type-erased allocators should not be noexcept in std::function
    • LWG 2501: std::function requires POCMA/POCCA
    • LWG 2502: std::function does not use allocator::construct
    • see also the replacement ystdex::function

C++11 features

C++11 library features used indirectly (not mandated, but with design in mind that could make more interface usable, e.g. macro substitution or template instantiations):

  • N2761: Towards support for attributes in C++ (Revision 6)

Other C++11 core and library features used directly (without the features the program will either be ill-formed or has unexpected behavior for some input allowed by the API):

  • CWG 45: Access to nested classes (since b273[2012-01-01])
    • CWG 8: Access to template arguments used in a function return type and in the nested name specifier
    • CWG 10: Can a nested class access its own class name as a qualified name if it is a private member of the enclosing class?
  • CWG 87: Exception specifications on function parameters (see also CWG 25, CWG 92 and CWG 133; since b249[2011-10-15])
  • CWG 208: Rethrowing exceptions in nested handlers (since b461[2013-12-23])
  • CWG 222: Sequence points and lvalue-returning operators (since b297[2012-03-27])
    • with CWG 637: Sequencing rules and example disagree
  • CWG 226: Default template arguments for function templates (since b387[2013-03-11])
  • CWG 254: Exception types in clause 19 are constructed from std::string (since b643[2015-10-08]; i.e. const char* parameter in constructor of standard exception classes)
  • CWG 302: Value-initialization and generation of default constructor (since b206[2011-05-03])
  • CWG 339: Overload resolution in operand of sizeof in constant expression (since b591[2015-04-10])
  • CWG 382: Allow typename outside of templates (since b421[2013-07-03])
  • CWG 542: Value initialization of arrays of POD-structs (since b206[2011-05-03])
  • LWG 49: Underspecification of ios_base::sync_with_stdio (since b599[2015-05-21])
  • LWG 280: Comparison of reverse_iterator to const reverse_iterator (since b408[2013-05-30])
  • LWG 438: Ambiguity in the "do the right thing" clause (since b274[2012-01-04])
  • LWG 611: Standard library templates and incomplete types (since b206[2011-05-03])
  • CWG 765: Local types in inline functions with external linkage (since b282[2012-02-04])
  • CWG 1104: Global-scope template arguments vs the <: digraph (since b493[2014-04-16])
  • CWG 1330: Delayed instantiation of noexcept specifiers (since b792[2017-06-05])
  • LWG 49: Underspecification of ios_base::sync_with_stdio (since b565[2015-01-16])
  • LWG 91: Description of operator>> and getline() for string<> might cause endless loop (since b663[2015-12-18])
  • LWG 130: Return type of container::erase(iterator) differs for associative containers (since b216[2011-06-08])
  • LWG 254: Exception types in clause 19 are constructed from std::string (since b643[2015-10-08])
  • LWG 265: std::pair::pair() effects overly restrictive (since b206[2011-05-03])
  • LWG 371: Stability of multiset and multimap member functions (since b216[2011-06-08])
  • LWG 376: basic_streambuf semantics (since b616[2015-07-21])
  • LWG 419: istream extractors not setting failbit if eofbit is already set (since b437[2015-01-16])
  • LWG 453: basic_stringbuf::seekoff need not always fail for an empty stream (since b617[2015-07-25])
  • LWG 534: Missing basic_string members (i.e. basic_string pop_back, back and front; since b315[2012-06-08])
  • LWG 559: numeric_limits<const T>, reworded slightly (since b440[2013-08-29])
  • LWG 564: stringbuf seekpos underspecified (since b743[2016-11-21])
  • LWG 589: Requirements on iterators of member template functions of containers (since b216[2011-06-08])
  • LWG 596: 27.8.1.3 Table 112 omits "a+" and "a+b" modes (since b326[2012-07-19])
  • LWG 704: MoveAssignable requirement for container value type overly strict (since b206[2011-05-03])
  • LWG 711: Contradiction in empty shared_ptr (since b784[2017-04-29])
  • LWG 762: std::unique_ptr requires complete type? (since b238[2011-09-07])
  • LWG 811: pair of pointers no longer works with literal 0 (since b206[2011-05-03])
    • partially superseded when N4387 is conditonally used
  • LWG 868: Default construction and value-initialization (since b206[2011-05-03])
  • LWG 771: Impossible throws clause in [string.conversions] (since b375[2013-01-22])
  • LWG 772: Impossible return clause in [string.conversions] (since b375[2013-01-22])
  • LWG 806: unique_ptr::reset effects incorrect, too permissive (since b206[2011-05-03])
  • LWG 809: std::swap should be overloaded for array types (since b620[2015-08-02])
  • LWG 817: bind needs to be moved (since b401[2013-05-02])
  • LWG 900: Stream move-assignment (tentatively since b620[2015-08-01]; since b727[2016-09-17])
  • LWG 911: I/O streams and move/swap semantic (tentatively since b620[2015-08-01]; since b727[2016-09-17])
  • LWG 922: [func.bind.place] Number of placeholders (since b437[2013-08-22])
  • LWG 929: Thread constructor (since b384[2013-03-01])
  • LWG 993: _Exit needs better specification (since b565[2015-01-16])
  • LWG 1019: Make integral_constant objects useable in integral-constant-expression​s (since b590[2015-04-10])
  • LWG 1040: Clarify possible sameness of associative container's iterator and const_iterator (since b496[2014-05-01])
  • LWG 1178: Header dependencies (since b338[2012-09-13])
    • LWG 343: Unspecified library header dependencies (see also N2259)
  • LWG 1192: basic_string missing definitions for cbegin / cend / crbegin / crend (since b546[2014-10-17])
  • LWG 1382: pair and tuple constructors should forward arguments (since b206[2011-05-03])
  • N1626: Proposed Resolution for Core Issue 39 (Rev. 1) (since b447[2013-09-25])
    • CWG 39: Conflicting ambiguity rules
  • N1653: Working draft changes for C99 preprocessor synchronization (since b257[2011-11-04]; used GCC extensions previously for variadic macros and empty macro arguments only)
  • N1720: Proposal to Add Static Assertions to the Core Language (Revision 3) (since b206[2011-05-03])
    • with CWG 676: static_assert-declaration​s and general requirements for declarations
  • N1757: Right Angle Brackets (Revision 1) (since b206[2011-05-03])
  • N1780: Comments on LWG issue 233: Insertion hints in associative containers (since b216[2011-06-08])
  • N1811: Adding the long long type to C++ (Revision 3) (since b206[2011-05-03])
  • N1822: A Proposal to add a max significant decimal digits value to the C++ Standard Library Numeric limits (since b260[2011-11-12]; i.e. numeric_limits::max_digits10)
    • without LWG 613: max_digits10 missing from numeric_limits
  • N1836: Draft Technical Report on C++ Library Extensions (Built-in type traits) (since b206[2011-05-03])
    • with LWG 1182: Unfortunate hash dependencies
    • with LWG 1255: declval should be added to the library (since b260[2011-11-14])
    • with LWG 1270: result_of should be moved to <type_traits> (since b245[2011-09-23])
  • cbegin/cend/crbegin/crend from N1913: A Proposal to Improve const_iterator Use (version 2) (since b206[2011-05-03])
  • N1858: Rvalue Reference Recommendations for Chapter 23, reworded (since b216[2011-06-08])
  • N1984: Deducing the type of variable from its initializer expression (revision 4) (since b206[2011-05-03]; i.e. auto-typed variables)
    • with CWG 615: Incorrect description of variables that can be initialized
  • N1986: Delegating Constructors (revision 3) (since b311[2011-05-25])
  • N1987: Adding "extern template" (version 2) (since b206[2011-05-03])
  • N2179: Language Support for Transporting Exceptions between Threads (since b538[2014-09-28]; i.e. exception_ptr and current_exception, etc)
    • with LWG 829: current_exception wording unclear about exception type
    • with LWG 1130: copy_exception name misleading (i.e. make_exception_ptr; since b550[2014-11-04])
    • with N3195: From Throws: Nothing to noexcept (version 2)
  • N2235: Generalized Constant Expressions—Revision 5 (since b246[2011-09-23]; i.e. constexpr)
  • N2238: Minimal Unicode support for the standard library (revision 3) (since b253[2011-10-18])
  • N2239: A finer-grained alternative to sequence points (revised) (since b297[2012-03-27]; notably order of aggregate initialization, see also CWG 1030)
  • N2240: Two missing traits: enable_if and conditional, added specification when B is false (since b206[2011-05-03])
  • N2241: Diagnostics Enhancements for C++0x (Rev. 1), reworded (since b476[2014-02-16]; i.e. <system_error>)
    • with LWG 805: posix_error::posix_errno concerns (since b550[2014-11-04]; i.e. errc)
  • N2242: Proposed Wording for Variadic Templates (Revision 2) (since b251[2011-10-08])
  • N2244: Wording for decay, make_pair and make_tuple (since b206[2011-05-03])
  • features from N2246: 2 of the least crazy ideas for the standard library in C++0x (i.e. next/prev/is_sorted_until/is_heap_until)
    • next/prev (since b375[2013-01-22])
  • N2249: New Character Types in C++, library part reworded (since b253[2011-10-18])
  • N2255: Minor Modifications to the type traits Wording Revision 2, reworded (since b206[2011-05-03])
  • N2258: Templates Aliases (since b433[2013-08-01])
  • N2259: Specify header dependency for <iostream> (since b338[2012-09-13]; see also LWG 343)
  • features(e.g. alignof) from N2341: Adding Alignment Support to the C++ Programming Language / Wording
    • std::aligned_storage used instead of std::tr1::aligned_storage since b206[2011-05-03]
    • other features except std::aligned_union used since b315[2012-06-08]
  • N2342: POD's Revisited; Resolving Core Issue 568 (Revision 5) (since b206[2011-05-03])
    • CWG 543: Value initialization and default constructors
    • CWG 568: Definition of POD is too strict
  • N2343: Decltype (revision 7) (since b206[2011-05-03])
  • N2346: Defaulted and Deleted Functions (since b207[2011-05-05])
  • N2347: Strongly Typed Enums (revision 3), with modification (since b261[2011-11-19])
  • N2348: Wording for std::numeric_limits<T>::lowest() (since b242[2011-09-16])
  • N2349: Constant Expressions in the Standard Library — Revision 2, with modification (since b260[2011-11-12])
  • N2350: Container insert/erase and iterator constness (Revision 1) (since b531[2014-08-31])
  • N2351: Improving shared_ptr for C++0x, Revision 2 (i.e. make_shared etc; since b529[2014-08-24])
  • N2431: A name for the null pointer: nullptr (revision 4) (since b206[2011-05-03]; compatible layer introduced since b204[2011-04-26])
  • N2437: Explicit Conversion Operator Draft Working Paper (revision 3) (since b260[2011-11-15])
  • N2439: Extending move semantics to *this (revised wording) (since b591[2015-04-11])
  • N2442: Raw and Unicode String Literals; Unified Proposal (Rev. 2)
    • unicode string literals used since b253[2011-10-18]
    • raw string literals used since b431[2013-07-23]
    • other features used since b434[2013-08-04]
  • N2530: Making It Easier to Use std::type_info as an Index in an Associative Container (since b468[2014-01-20]; i.e. type_info::hash_code)
  • N2535: Namespace Association ("inline namespace") (since b427[2013-07-11])
  • N2540: Inheriting Constructors (revision 5) (since b538[2014-09-24])
  • N2541: New Function Declarator Syntax Wording (since b207[2011-05-05])
  • N2543: STL singly linked lists (revision 3) (since b218[2011-06-04]; i.e. <forward_list>)
  • N2544: Unrestricted Unions (Revision 2) (since b569[2015-01-29])
  • N2546: Removal of auto as a storage-class specifier (since b206[2011-05-03])
  • N2559: Nesting Exception Objects (Revision 1) (since b477[2014-02-19])
    • with LWG 819: rethrow_if_nested
    • with LWG 1136: Incomplete specification of nested_exception::rethrow_nested()
  • N2634: Solving the SFINAE problem for expressions (since b591[2015-04-10])
    • CWG 339: Overload resolution in operand of sizeof in constant expression
  • N2657: Local and Unnamed Types as Template Arguments (since b206[2011-05-03])
    • CWG 488: Local types, overload resolution, and template argument deduction
    • with CWG 765 above
  • N2659: Thread-Local Storage (since b425[2013-07-08])
    • with CWG 810: Block-scope thread_local variables should be implicitly static (since b425[2013-07-08])
  • N2672: Initializer List proposed wording (since b297[2012-03-27])
    • CWG 1030: Evaluation order in initializer-lists used in aggregate initialization (since b297[2012-03-27]; see also N2239)
  • N2680: Proposed Wording for Placement Insert (Revision 1) (since b286[2012-02-19])
  • N2709: Packaging Tasks for Asynchronous Execution (since b520[2014-07-23]; i.e. packaged_task)
  • N2756: Non-static data member initializers (since b360[2013-04-29])
  • N2764: Forward declaration of enumerations (rev. 3) (since b658[2015-12-08])
  • N2844: Fixing a Safety Problem with Rvalue References: Proposed Wording (Revision 1) (since b206[2011-05-03])
    • CWG 1138: Rvalue-ness check for rvalue reference binding is wrong (since b206[2011-05-03])
  • N2927: New wording for C++0x Lambdas (rev. 2) (since b212[2011-05-27])
  • N2930: Range-Based For Loop Wording (Without Concepts) (since b316[2011-06-11])
  • features from N2982: Allocators post Removal of C++ Concepts (Rev 1)
    • std::addressof used since b288[2012-02-26]
      • LWG 970: addressof overload unneeded
    • std::allocator_traits except propagation traits used since b592[2015-04-19]
    • propagation traits in std::allocator_traits used since b830[2018-07-08]
      • LWG 431: Swapping containers with unequal allocators
  • N3050: Allowing Move Constructors to Throw (Rev. 1) (since b319[2012-06-24]; i.e. noexcept and std::move_if_noexcept)
    • with LWG 1349: swap should not throw
    • with N3180: More on noexcept for the Strings Library (since b329[2012-08-05])
    • with N3279: Conservative use of noexcept in the Library (since b461[2013-12-23])
  • N3052: Converting Lambdas to Function Pointers (since b360[2012-12-07])
  • features except in <type_traits> from N3053: Defining Move Special Member Functions (since b230[2011-08-07])
    • with LWG 1309: Missing expressions for Move/CopyConstructible
      • LWG 1283: MoveConstructible and MoveAssignable need clarification of moved-from state
  • N3143: Proposed wording for US 90 (since b206[2011-05-03]; i.e. std::forward)
  • N3168: Problems with Iostreams Member Functions (Amended from US 137) (since b805[2017-09-26])
  • N3189: Observers for the three handler functions (since b550[2014-11-04])
  • N3272: Follow-up on override control (since b311[2011-05-25])

Tentatively applied

All adopted changes are confirmed being included in the newest working paper and would not be removed in future unless they are not in the working paper or published standard any longer.

Platform-dependent features

Some features only are relied in platform-dependent implementation details where all of supported platforms of the project has been confirmed to support. Currently (revised b848[2018-12-24]) there are none.

Conditionally used features

Some C++11 features are not requried to reduce compatibility impact on implementations, but can be utilized when available, i.e. used conditionally (by conditional inclusion or being transparent):

  • N2340: C99 Compatibility : __func__ and predeclared identifiers (revision 2) (since b638[2015-09-24])

Some post-C++11 features are used conditionally:

  • CWG 616: Definition of “indeterminate value” (since b663[2016-01-11]) (see also CWG 1213)
    • without CWG 129: Stability of uninitialized auto variables
    • without CWG 240: Uninitialized values and undefined behavior (see also CWG 129)
    • without CWG 312: “use” of invalid pointer value not defined (see also CWG 623)
    • without CWG 623: Use of pointers to deallocated storage (see also CWG 312)
  • CWG 1581: When are constexpr member functions defined? (since b834[2016-08-03])
  • CWG 1558: Unused arguments in alias template specializations (since b653[2015-11-25]; see also CWG 1430, CWG 1520 and CWG 1554)
  • LWG 2285: make_reverse_iterator (since b595[2015-05-01])
    • replaced by ystdex::make_reverse_iterator conditionally since b833[2018-07-29]
  • N3421: Making Operator Functors greater<> (since b679[2016-03-19]; see also N3657)
  • N3478: Core Issue 1512: Pointer comparison vs qualification conversions (since b562[2014-12-22])
    • CWG 73: Pointer equality
    • CWG 1512: Pointer comparison vs qualification conversions
  • N3493: Compile-time integer sequences (since b589[2015-04-03])
  • N3652: Relaxing constraints on constexpr functions/constexpr member functions and implicit const (adopted 2013-04; since b591[2015-04-15])
  • N3655: TransformationTraits Redux, v2 (since b595[2015-05-01])
  • N3656: make_unique (Revision 1) (since b617[2015-07-23])
  • N3657: Adding heterogeneous comparison lookup to associative containers (rev 4) (adopted 2013-04; rev 3 not in the list)
    • without is_transparent since b678[2016-03-17]
    • with is_transparent since b679[2016-03-19]
  • N3671: Making non-modifying sequence operations more robust: Revision 2 (since b627[2015-08-30])
  • N3778: C++ Sized Deallocation (since b842[2018-10-29])
  • N4169: A proposal to add invoke function template (Revision 1) (since b617[2015-07-23])
  • pair constructors improvement in N4387: Improving pair and tuple, revision 3 (adopted 2015-05; since b850[2019-01-14])
    • missed in N4528, see this commit.
    • without LWG 2051: Explicit tuple constructors for more than one parameter
    • without partially addressed LWG 2312: tuple's constructor constraints need to be phrased more precisely
    • LWG 2397: map::emplace and explicit V constructors
      • see also EWG 114: N4074 Let return {expr} Be Explicit, Revision 2, N4131 explicit should never be implicit, N4094 Response To: Let return {expr} Be Explicit, N4029 Let return Be Direct and explicit, N3452 (unpublished) Let {x,y,z} => explicit (resolved as NAD)
  • N4389: Wording for bool_constant, revision 1 (since b617[2015-07-23])
  • P0188R1: Wording for [[fallthrough]] attribute. (adopted 2016-02; since b793[2017-06-06])
  • P0189R1: Wording for [[nodiscard]] attribute. (adopted 2016-02; since b823[2018-07-26])
  • P0212R1: Wording for [[maybe_unused]] attribute. (adopted 2016-02; since b823[2018-07-26])
  • P0386R2: Inline Variables (adopted 2016-06; since b831[2018-07-13])
  • part (with only the signature available in C++11) of P0674R1: Extending make_shared to Support Arrays (adopted 2017-07; since b849[2018-12-30])
    • LWG 2070: allocate_shared should use allocator_traits::construct

Feature testing

Following Feature Testing study group (SD-6 recommendations approved by SG 10) documents after EWG 22 have been reviewed, with some of them applied or updated:

  • N4200: Feature-testing recommendations for C++ (since b591[2015-04-15]; i.e. __has_cpp_attribute, etc; see subsequent N4440)
  • N4440: Feature-testing recommendations for C++ (superseded)
  • N4535: Feature-testing preprocessor predicates for C++17 (i.e. __has_include and __has_cpp_attribute, see below)
  • P0096R1: Feature-testing recommendations for C++ (since b679[2016-03-20]; see subsequent P0941R0)
  • P0941R2: Integrating feature-test macros into the C++ WD (rev. 2) (since b831[2018-07-12])

Following documents override feature testing paper which is incorporated into the standard draft as normative features:

  • P0061R1: __has_include for C++17 (adopted 2015-10; since b831[2018-07-12])

Some additional feature testing support are also conditionally reviewd. Some are already extensions of Clang++ and other implementations for several revisions. The identifiers with __has_ in following list are being used and considered for conditional inclusion:

  • __has_attribute since b628[2015-09-01], after in macro detection candidate list since b492[2014-04-10]
  • __has_builtin since b535[2014-09-14]
  • __has_extension and __has_feature since b484[2013-03-09]

Tentatively not applied

Used deprecations

There are no features eventually removed in future versions of ISO C++ are yet to be resolved currently.

Workarounds

Several acknowledged but not adopted (by the draft) issues (revised b834[2018-07-31]) are assumed not effect user code with workarounds provided by implementations, including:

  • LWG 2472: Heterogeneous comparisons in the standard library can result in ambiguities
    • no effect on YStandardEx replacement as there is no std::rel_ops-like operators in namespace ystdex
  • LWG 2858: LWG 2472: actually an incompatibility with C++03 (see LWG 280)
    • no effect on ystdex::reversed_iterator

Primarily replaceable

The following features are not relied on, but confirmed still being compatible, with further rules to incooperate:

  • part of P0551R3: Thou Shalt Not Specialize std Function Templates! (adopted 2018-03)
    • though not relied on, any of the entities overloadable with standard components as the subset of the direct replacements specified in following clauses conform to the definition of the term customization point specified here
    • designated customization point is extended to any direct replacments implicitly (i.e. a direct replacement is also implied to be customized by user code if it comforms to a designated customization point specified here), or explicitly following the designation otherwise specified by the interface documentation and with further rules to be intercooperated

The following changes about standard library are not depended on, but were considered some replacements have been used as forcing the requirements for implementations other than using of YStandardEx replacements:

  • part of N4258: Cleaning up noexcept in the Library (Rev 3) (adopted 2014-11)
    • only for part of noexcept which is not exclusively covered by the applying specified below, as noexcept can be added in user-code by introducing new classes meets the changes here like direct replacements (e.g. inheriting the base containers) when direct replacements is not yet provided by YStandardEx

Replaced directly

These post-C++11 library features are not depended on currently (revised b865[2018-08-23]) but direct replacements (to be used conditionally once the draft standard is approved) are provided in YBase:

  • parts of LWG 1234: "Do the right thing" and NULL
    • replaced by ystdex::basic_string
    • see also dedicated ystdex::list
  • LWG 2108: No way to identify allocator types that always compare equal
    • with part of N4258: Cleaning-up noexcept in the Library (Rev 3)
    • with LWG 2467: is_always_equal has slightly inconsistent default
    • std::allocator_tratits::is_always_equal is provided as member of ystdex::allocator_traits; see also dedicated ystdex::map for one of the drop-in replacements
  • LWG 2188: Reverse iterator does not fully support targets that overload operator&
    • replaced by ystdex::reverse_iterator
    • adopted by LWG motion 3 in editor's report N3938 with editorial fix
  • LWG 2268: Setting a default argument in the declaration of a member function assign of std::basic_string
    • replaced by ystdex::basic_string
  • parts of LWG 2193: Default constructors for standard library containers are explicit
    • replaced by ystdex::basic_string
    • see also dedicated ystdex::map
  • LWG 2247: Type traits and std::nullptr_t
    • replaced by ystdex::is_null_pointer
  • LWG 2296: std::addressof should be constexpr
    • replaced by ystdex::addressof with compatibility excptions
      • implemented in a best effort way: constepxr works with most usual but not all cases like C++17 due to compatibility limitations where no __builtin_addressof is supported by the implementation
      • with LWG 2598: addressof works on temporaries
    • adopted by part of LWG motion 16 in editor's report N4583
  • part of LWG 2455: Allocator default construction should be allowed to throw
    • replaced by ystdex::basic_string
  • LWG 2579: Inconsistency wrt Allocators in basic_string assignment vs. basic_string::assign
    • replaced by ystdex::basic_string
  • LWG 2583: There is no way to supply an allocator for basic_string(str, pos)
    • replaced by ystdex::basic_string
  • LWG 2778: basic_string_view is missing constexpr
    • replaced by ystdex::basic_string_view
  • LWG 2788: basic_string range mutators unintentionally require a default constructible allocator
    • replaced by ystdex::basic_string
  • LWG 2812: Range access is available with <string_view>
    • replaced by "string_view.hpp"
  • N3911: TransformationTrait Alias void_t
    • replaced by void_t in namespace ystdex::cpp2017, with workaround for CWG 1558
    • see N3843 for motivation
  • parts of N4258 (adopted 2014-11)
    • replaced by ystdex::allocator_traits::is_always_equal; see LWG 2108
    • replaced by ystdex::basic_string
    • see also dedicated ystdex::map
    • see also LWG 2455 of change on std::vector (not replaced)
  • N4277: TriviallyCopyable reference_wrapper (Revision 1)
    • with P0357R2: reference_wrapper for incomplete types
    • replaced by ystdex::lref
  • N4280: Non-member size() and more (Revision 2) (adopted 2014-11)
    • replaced by size, empty and data in namespace ystdex::cpp2017 conforming to designated customization point specified by P0551R3, also ystdex::range_size with addtional interface for std::initializer_list
  • N4436: Proposing Standard Library Support for the C++ Detection Idiom
    • partially replaced by is_detected, detected_t, detected_or, detected_or_t, is_detected_exact and is_detected_convertile in namespace ystdex
  • std::experimental::fundamentals_v2::observer_ptr in N4562
    • replaced feature based on N4282: A Proposal for the World's Dumbest Smart Pointer, v4
  • P0007R1: Constant View: A proposal for a std::as_const helper function template (adopted 2015-11)
  • P0013R1: Logical Operator Type Traits (revision 1) (adopted 2015-10)
    • replaced by conjunction, disjunction and negation in namespace ystdex, based on and_, or_ and not_ (see dedicated replacements below)
  • parts of P0031R0: A Proposal to Add Constexpr Modifiers to reverse_iterator, move_iterator, array and Range Access
    • partially replaced by reverse_iterator, begin, cbegin, end, cend, rbegin, crbegin, rend and crend in namespace ystdex
    • adopted by part of LWG motion 16 in edtitor report N4583
  • P0091R3: Template argument deduction for class templates (Rev. 6) (adopted 2016-06)
  • interface in headers <optional>, <string_view> and <memory_resource> in P0220R1: Adopt Library Fundamentals V1 TS Components for C++17 (R1)
    • <optional> replaced by <ystdex/optional.hpp>
      • std::bad_optional_access replaced by ystdex::bad_optional_access
      • std::optional replaced by ystdex::cpp2017::optional
    • <string_view> replaced by <ystdex/string_view.hpp>
      • std::basic_string_view replaced by ystdex::cpp2017::basic_string_view
      • std::string_view replaced by ystdex::cpp2017::string_view
      • std::wstring_view replaced by ystdex::cpp2017::wstring_view
      • std::u16string_view replaced by ystdex::cpp2017::u16string_view
      • std::u32string_view replaced by ystdex::cpp2017::u32string_view
    • <memory_resource> replaced by <ystdex/memory_resource.h>
      • std::pmr::memory_resource replaced by ystdex::pmr::cpp2017::memory_resource
      • std::pmr::polymorphic_allocator replaced by ystdex::pmr::cpp2017::polymorphic_allocator
      • std::pmr::new_delete_resource replaced by ystdex::pmr::cpp2017::new_delete_resource
      • std::pmr::null_memory_resource replaced by ystdex::pmr::cpp2017::null_memory_resource
      • std::pmr::set_default_resource replaced by ystdex::pmr::cpp2017::set_default_resource
      • std::pmr::get_defualt_resource replaced by ystdex::pmr::cpp2017::get_defualt_resource
      • std::pmr::pool_options replaced by ystdex::pmr::pool_options
      • std::pmr::cpp2017::synchronized_pool_resource replaced by ystdex::pmr::cpp2017::synchronized_pool_resource
      • std::pmr::unsynchronized_pool_resource replaced by ystdex::pmr::cpp2017::unsynchronized_pool_resource
      • std::pmr::monotonic_buffer_resource replaced by ystdex::pmr::cpp2017::monotonic_buffer_resource
    • std::apply in <tuple> replaced by ystdex::apply
      • N3915: apply() call a function with arguments from a tuple (V3) (adopted 2014-02)
      • with LWG 2418: [fund.ts] apply does not work with member pointers
    • partially adopted by LWG motion 6 in editor's report N4583
      • <optional>, <string_view>, <memory_resource> and in parts of LWG motion 6: P0220R1 "Adopt library fundamentals v1 TS components for C++17") (incompletely applied from N4562)
      • with LWG 2283: [fund.ts] optional declares and then does not define an operator<() (this is actually targetting the standard draft, not the library fundmental draft)
      • with N4078: Fixes for optional objects (adopted 2014-06)
    • with P0254R2: Integrating std::string_view and std::string (adopted 2016-06, by LWG motion 14 in N4603)
      • replaced by ystdex::basic_string and ystdex::basic_string_view
      • with LWG 2742: Inconsistent string interface taking string_view
      • with LWG 2758: std::string{}.assign("ABCDE", 0, 1) is ambiguous
        • LWG 2757: std::string{}.insert(3, "ABCDE", 0, 1) is ambiguous
      • with LWG 2771: Broken Effects of some basic_string::compare functions in terms of basic_string_view (see LWG 2758)
    • with P0337R0: Delete operator= for polymorphic_allocator (adopted by LWG motion 26 in N4603)
    • with changes on pmr::memory_resource in P0619R4
    • with LWG 2724: The protected virtual member functions of memory_resource should be private
    • conditionally with LWG 2740: constexpr optional<T>::operator->
      • only with constexpr addressof (i.e. since C++17 or with some extensions)
    • with LWG 2756: C++ WP optional<T> should 'forward' T's implicit conversions
    • without LWG 2825: LWG 2756 breaks class template argument deduction for optional, as the resolution need deduction guides unsupported here yet
    • with LWG 2806: Base class of bad_optional_access
    • with LWG 2842: in_place_t check for optional::optional(U&&) should decay U
    • with LWG 2843: Unclear behavior of std::pmr::memory_resource::do_allocate()
    • with part (for optional) of LWG 2857: {variant,optional,any}::emplace should return the constructed value
      • partially replaced by ystdex::any
    • with LWG 2900: The copy and move constructors of optional are not constexpr
    • with LWG 2961: Bad postcondition for set_default_resource (similart to LWG 2522 targetting Library Fundamentals V2)
    • with LWG 2969: polymorphic_allocator::construct() shouldn't pass resource()
    • with parts (concerned with polymorphic_allocator) of LWG 2975: Missing case for pair construction in scoped and polymorphic allocators
    • with LWG 3000: monotonic_memory_resource::do_is_equal uses dynamic_cast unnecessarily
    • with LWG 3036: polymorphic_allocator::destroy is extraneous
    • with LWG 3037: polymorphic_allocator and incomplete types
    • with LWG 3038: polymorphic_allocator::allocate should not allow integer overflow to create vulnerabilities
    • with LWG 3113: polymorphic_allocator::construct() should more closely match scoped_allocator_adaptor::construct()
  • P0185R1 Adding [nothrow-]swappable traits, revision 3 (adopted 2016-02)
    • replaced by is_swappable_with, is_swappable, is_nothrow_swappable_with and is_nothrow_swappable in namespace ystdex, and swap in namespace ystdex_swap (see also P0879R0)
    • LWG 2456: Incorrect exception specifications for 'swap' throughout library
    • LWG 2554: Swapping multidimensional arrays is never noexcept
    • see also LWG 2766
  • P0209R2 make_from_tuple: apply for construction (adopted 2016-06, by LWG motion 23 in N4603)
    • replaced by ystdex::make_from_tuple
  • P0298R3: A byte type definition
    • replaced by ystdex::byte, except when the core language support unavailable before C++17, where the name is provided as an alias of unsigned char
    • see also P0583R0.
  • P0318R1: unwrap_ref_decay and unwrap_reference (adopted 2018-11)
    • replaced by ystdex::unwrap_ref_decay and ystdex::unwrap_reference, with extensions for ystdex::lref
  • P0550R2: Transformation Trait remove_cvref
    • replaced by ystdex::remove_cvref
  • P0604R0: Resolving GB 55, US 84, US 85, US 86 (adopted 2017-03)
    • partially replaced by invoke_result, invoke_result_t, is_invocable, is_invocable_r, is_nothrow_invocable and is_nothrow_invocable_r in namespace ystdex::cpp2017
    • revised previously-adopted P0077R2: is_callable, the missing INVOKE related trait (adopted 2016-02)
    • GB 55, US 84, US 85, US 86 accepted with modifications in N4664
    • LWG 2017: std::reference_wrapper makes incorrect usage of std::result_of
    • LWG 2021: Further incorrect usages of result_of
    • with LWG 2219: INVOKE-ing a pointer to member with a reference_wrapper as the object expression
    • LWG 2767: not_fn call_wrapper can form invalid types
  • all new function templates in P0591R4: Utility functions to implement uses-allocator construction (adopted 2018-11)
    • std::uses_allocator_construction_args replaced by ystdex::uses_allocator_construction_args
    • std::make_obj_using_allocator replaced by ystdex::make_obj_using_allocator
    • std::uninitialized_construct_using_allocator replaced by ystdex::uninitialized_construct_using_allocator
  • P0607R0: Inline Variables for the Standard Library
    • depends on CWG 1713), the "minimalistic suggestion" and "additional suggestion" in paper are fully (both) taken in N4659, which is not explicitly indicated by the editor's report N4661
    • partially replaced by ystdex::nullopt
  • P0619R4: Reviewing Deprecated Facilities of C++17 for C++20
    • std::reference_wrapper partially replaced by ystdex::lref
    • std::iterator is not used (see also LWG 2438)
    • changes on std::pmr::memory_resource is implemented for ystdex::pmr::memory_resource
  • P0653R2: Utility to convert a pointer to a raw pointer (adopted 2017-11)
    • std::to_address is replaced by ystdex::to_address
  • P0879R0: Constexpr for swap and swap related functions
    • partially replaced by swap in namespace ystdex_swap
    • LWG 2800: constexpr swap
    • this is now in the working draft, though not in the list of official page as of b834[2018-08-03]
    • adopted by LWG motion 21 in editor's report N4764

Some applied resolution also works on replacements, listed here for exposition-only use:

  • LWG 280: Comparison of reverse_iterator to const reverse_iterator
    • partially replaced by ystdex::reverse_iterator
  • LWG 386: Reverse iterator's operator[] has impossible return type
    • replaced by ystdex::reverse_iterator::operator[]

Replaced alternatively

These features were once adopted by the working paper but later removed away, and further actions different to the committee are considered by this project for practical reasons (e.g. compatibility and availability in lack of other features):

  • parts of P0032R3: Homogeneous interface for variant, any and optional (Revision 3) (adopted 2016-06)
    • see national body comment CH 3 relavent to parts of P0032R3 in P0488R0: WG21 Working Paper, NB Comments, ISO/IEC CD 14882
    • see P0504R0: Revisiting in-place tag types for any/optional/variant
    • removed by this commit
    • this is not always taken in the direct replacements in namespace ystdex::cpp2017 to avoid impaction from lack of varaible template support

Replaced dedicately

There are several core language issues are resolved by YDefinition core language compatiblitiy features conditioanlly, even though they may be still not adopted or even without a concrete proposed resolution currently (revised b835[2018-08-14]):

  • CWG 2097: Lambdas and noreturn attribute

There are several YBase features which can currently (revised b831[2018-07-11]) be used as replacement for similar post-C++11 library features. See also Features(zh-CN).

  • ystdex::and_, ystdex::or_ and ystdex::not_ are provided to replace logical operation traits introduced in P0013R1
    • currently aliases of them are also direct replacements in namespace cpp2017
  • ystdex::lref is provided as a replacement for std::reference_wrapper with less verbosity
    • supports N4277: TriviallyCopyable reference_wrapper (Revision 1)
    • otherwise mostly same to boost::reference_wrapper besides its name and constexpr requirements (needing core language support)
      • no deprecated members of std::reference_wrapper, see P0619R4: Reviewing Deprecated Facilities of C++17 for C++20
      • supports incomplete value type, see P0357R2
      • not same type to any instance of std::reference_wrapper so not treated specially by std::bind and other std API
    • with part of P0604R0
    • with part of LWG 2993
  • ystdex::any is provided as a replacement for std::any with richer features and greater availability
    • already with following C++17 std::any features
      • LWG 2769
      • parts of P0032R3
      • NOTE: LWG 2509 is superseded by the resolution and mostly not applicable because of the support of non CopyConstructible types (see below)
      • NOTE: LWG 2754 is not applicable because the exact same reason above
    • supports non CopyConstructible types (if a ystdex::any object holding an object of such type is eventually copied, exception would be thrown
    • with underlying interface for custom holders and handlers (for ystdex::any_iterator, etc)
    • supports constructor overload with minimal construction overhead for the empty object with ystdex::default_init_t parameter (at the cost of not supporting constepxr as the default constructor)
    • supports unsafe cast operations and more extensions to bypass checks with narrow contracts
    • early available before several standard proposals, including the any class itself and members like emplace (see P0032R0)
      • actually being first to replace boost::any before std::any was proposed as a post-C++11 feature by N3390: Any Library Proposal (Revision 1)
      • see also the original proposal N1939: Any Library Proposal for TR2
  • ystdex::function is provided as a replacement for std::function with richer features
    • with LWG 2062 not depending on C++17
    • with allocator support in construction like the feature removed by P0302R1
  • ystdex::list is proveded as a replacement for std::list with draft ISO C++20 features support
    • part of LWG 1234: "Do the right thing" and NULL
    • part of N4510: Minimal incomplete type support for standard containers, revision 4
    • part of P0084R2: Emplace Return Type (Revision 2) (adopted 2016-06)
  • ystdex::map is provided as a replacement for std::map provided (other containers TBD) including follwing enhancement (full ISO C++17 features support):

Neutral of existence

These post-C++03 (adopted, any proposed or any not proposed but theorotically allowed having well-defined behavior) resolutions or features (with diagnostic suggestions) are not depended on currently (revised b865[2019-08-23]) but confirmed still being compatible (however, user code can still be affected; some resolutions may have been applied to similar other interface of YBase, see sections above):

  • CWG 446: Does an lvalue-to-rvalue conversion on the "?" operator produce a temporary?
    • CWG 86: Lifetime of temporaries in query expressions
  • CWG 462: Lifetime of temporaries bound to comma expressions
  • CWG 468: Allow ::template outside of templates
  • CWG 475: When is std::uncaught_exception() true? (take 2)
  • CWG 515: Non-dependent references to base class members (see also GCC PR 21008)
  • CWG 569: Spurious semicolons at namespace scope should be allowed
  • CWG 573: Conversions between function pointers and void* (see also CWG 195/CWG 1120)
  • CWG 760: this inside a nested class of a non-static member function
  • CWG 903: Value-dependent integral null pointer constants
    • NOTE: This is actually adopted after C++11 despite the compatibility clause is agianst to C++03.
  • CWG 1120: reinterpret_cast and void* (depends on CWG 573)
  • CWG 1164: Partial ordering of f(T&) and f(T&&)
  • CWG 1213: Array subscripting and xvalues (see also CWG 616)
  • CWG 1227: Mixing immediate and non-immediate contexts in deduction failure
  • CWG 1255: Definition problems with constexpr functions
  • CWG 1301: Value initialization of union
    • CWG 1324: Value initialization and defaulted constructors
    • CWG 1368: Value initialization and defaulted constructors (part 2)
  • CWG 1310: What is an “acceptable lookup result?”
  • CWG 1399: Missing non-deduced context following a function parameter pack
    • CWG 1388: Deduction with multiple function parameter packs
  • CWG 1402: Move functions too often deleted
    • CWG 1491: Move construction and rvalue reference members
  • CWG 1412: Problems in specifying pointer conversions
  • CWG 1579: Return by converting move constructor
  • CWG 1591: Deducing array bound and element type from initializer list
  • CWG 1626: constexpr member functions in brace-or-equal-initializers
  • CWG 1665: Declaration matching in explicit instantiations
  • CWG 1693: Superfluous semicolons in class definitions (depends on CWG 569)
  • CWG 1713: Linkage of variable template specializations
  • CWG 1875: Reordering declarations in class scope
  • CWG 1895: Deleted conversions in conditional operator operands
    • CWG 1932: Bit-field results of conditional operators
  • CWG 1952: Constant expressions and library undefined behavior
  • CWG 1980: Equivalent but not functionally-equivalent redeclarations
  • CWG 2137: List-initialization from object of same type
  • CWG 2248: Problems with sized delete
  • CWG 2267: Copy-initialization of temporary in reference direct-initialization
  • CWG 2278: Copy elision in constant expressions reconsidered
  • CWG 2313: Redeclaration of structured binding reference variables
  • LWG 281: std::min() and max() requirements overly restrictive
  • LWG 283: std::replace() requirement incorrect/insufficient
  • LWG 387: std::complex over-encapsulated
  • LWG 402: wrong new expression in [some_]allocator::construct
  • LWG 497: meaning of numeric_limits::traps for floating point types
  • LWG 531: array forms of unformatted input functions (i.e. for istream::get)
  • LWG 543: valarray slice default constructor
  • LWG 551: <ccomplex>
  • LWG 565: xsputn inefficient
  • LWG 566: array forms of unformatted input function undefined for zero-element arrays (i.e. for istream::get)
  • LWG 576: find_first_of is overconstrained
  • LWG 578: purpose of hint to allocator::allocate()
  • LWG 586: string inserter not a formatted function
  • LWG 593: __STDC_CONSTANT_MACROS
  • LWG 619: Longjmp wording problem
  • LWG 643: Impossible "as if" clauses
  • LWG 646: const incorrect match_result members
  • LWG 659: istreambuf_iterator should have an operator->()
  • LWG 776: Undescribed assign function of std::array (i.e. array::fill)
  • LWG 779: Resolution of #283 incomplete
  • LWG 787: complexity of binary_search
  • LWG 807: tuple construction should not fail unless its element's construction fails
  • LWG 844: complex pow return type is ambiguous
  • LWG 848: Missing std::hash specializations for std::bitset/std::vector<bool>
  • LWG 850: Should shrink_to_fit apply to std::deque? (i.e. deque::shrink_to_fit)
  • LWG 852: unordered containers begin(n) mistakenly const
  • LWG 900: Stream move-assignment
  • LWG 1004: Clarify "throws an exception"
    • see national body comment UK 179 in N2837: C++0X, CD 1, National Body Comments
  • LWG 1012: reverse_iterator default ctor should value initialize (adopted by LWG motion 1 in N3001)
  • LWG 1071: is_bind_expression should derive from integral_constant<bool>
  • LWG 1334: Insert iterators are broken for some proxy containers compared to C++03
  • LWG 1399: function does not need an explicit default constructor
  • LWG 1402: nullptr constructors for smart pointers should be constexpr
  • LWG 2005: unordered_map::insert(T&&) protection should apply to map too
    • partially replaced by ystdex::map
    • with LWG 2571: §[map.modifiers]/2 imposes nonsensical requirement on insert(InputIterator, InputIterator)
      • replaced by ystdex::map
  • LWG 2059: C++0x ambiguity problem with map::erase
  • LWG 2103: std::allocator_traits<std::allocator<T>>::propagate_on_container_move_assignment (see also LWG 2108)
  • LWG 2104: unique_lock move-assignment should not be noexcept
  • LWG 2112: User-defined classes that cannot be derived from (i.e. is_final)
  • LWG 2135: Unclear requirement for exceptions thrown in condition_variable::wait()
  • LWG 2247: Type traits and std::nullptr_t (i.e. is_null_pointer)
  • LWG 2321: Moving containers should (usually) be required to preserve iterators
    • replaced by ystdex::map and some other containers in YBase.YStandardEx which support the resolution
  • LWG 2354: Unnecessary copying when inserting into maps with braced-init syntax
  • LWG 2360: reverse_iterator::operator*() is unimplementable (see also LWG 2204)
  • LWG 2362: unique, associative emplace() should not move/copy the mapped_type constructor arguments when no insertion happens (see also LWG 2006)
  • LWG 2393: std::function's Callable definition is broken
  • LWG 2408: SFINAE-friendly common_type/iterator_traits is missing in C++14
  • LWG 2437: iterator_traits::reference can and can't be void
  • LWG 2438: std::iterator inheritance shouldn't be mandated
  • LWG 2442: call_once() shouldn't DECAY_COPY()
  • LWG 2466: allocator_traits::max_size() default behavior is incorrect
  • LWG 2470: Allocator's destroy function should be allowed to fail to instantiate (split from LWG 2447)
  • LWG 2483: throw_with_nested() should use is_final
  • LWG 2485: get() should be overloaded for const tuple&&
  • LWG 2509: [fund.ts.v2] any_cast doesn't work with rvalue reference targets and cannot move with a value target
    • NOTE: The proposed resolution is targeting the working paper of the TS. It is not applied to std::any in ISO C++17 and it is still not in post-C++17 working draft N4778, and it is overriden by the resolution of LWG 2769 partially.
  • LWG 2547: Container requirements (and other library text) should say "strict total order", not just "total order"
  • LWG 2549: Tuple EXPLICIT constructor templates that take tuple parameters end up taking references to temporaries and will create dangling references
  • LWG 2567: Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits
    • LWG 2568: [fund.ts.v2] Specification of logical operator traits uses BaseCharacteristic, which is defined only for UnaryTypeTraits and BinaryTypeTraits
  • LWG 2577: {shared,unique}_lock should use std::addressof
  • LWG 2591: std::function's member template target() should not lead to undefined behaviour
  • LWG 2729: Missing SFINAE on std::pair::operator=
  • LWG 2754: The in_place constructors and emplace functions added by P0032R3 don't require CopyConstructible
  • LWG 2766: Swapping non-swappable types
  • LWG 2769: Redundant const in the return type of any_cast(const any&)
  • LWG 2781: Contradictory requirements for std::function and std::reference_wrapper
    • replaced by ystdex::function with the resolution
    • see also GCC PR66284
  • LWG 2794: Missing requirements for allocator pointers
  • LWG 2857: {variant,optional,any}::emplace should return the constructed value
    • partially replaced by ystdex::any
  • LWG 2993: reference_wrapper<T> conversion from T&&
    • partially replaced by ystdex::lref
  • LWG 3017: list splice functions should use addressof
  • LWG 3087: One final &x in §[list.ops]
  • N1981: Uniform Use of std::string Revision 1
  • N1990: Proposed Text for minmax (N1840) (i.e. minmax and minmax_element in <algorithm>)
  • N1991: Proposed Text for defaultfloat (N1842) (i.e. defaultfloat in <ios>)
  • N2007: Proposed Library Additions for Code Conversion
  • N2111: Random Number Generation in C++0X: A Comprehensive Proposal, version 4
    • with LWG 609: missing static const
  • N2253: Extending sizeof to apply to non-static data members without an object (revision 1)
  • N2292: Standard Library Applications for Deleted Functions
  • N2321: Enhancing the time_get facet for POSIX® compatibility, Revision 2
  • N2353: A Specification for vector<bool>
  • N2547: Allow atomics use in signal handlers
  • N2554: The Scoped Allocator Model (Rev 2)
  • N2760: Input/Output Library Thread Safety
  • N2765: User-defined Literals (aka. Extensible Literals (revision 5))
  • N2782: C++ Data-Dependency Ordering: Function Annotation (i.e. [[carries_dependency]])
  • N3026
    • CWG 408: sizeof applied to unknown-bound array static data member of template
    • CWG 490: Name lookup in friend declarations
    • CWG 722: Can nullptr be passed to an ellipsis?
    • CWG 734: Are unique addresses required for namespace-scope variables?
    • CWG 935: Missing overloads for character types for user-defined literals
    • CWG 1000: Mistaking member typedefs for constructors
  • N3059: Proposal to simplify pair (rev 5.2) (i.e. piecewise_construct_t, etc.)
    • LWG 1321: scoped_allocator_adaptor construct and destroy don't use allocator_traits
  • N3282: Resolution for core issues 1207 and [1017](](http://wg21.cmeerw.net/cwg/issue1017)
  • N3664: Clarifying Memory Allocation (adopted 2013-04)
  • N3843: A SFINAE-Friendly std::common_type
  • N4081: Working Draft, C++ Extensions for Library Fundamentals (see N4480)
  • N4279: Improved insertion interface for unique-key maps (Revision 2.3) (adopted 2014-11)
  • N4510: Minimal incomplete type support for standard containers, revision 4 (adopted 2015-05; however, similar requirements for associative containers (not proposed yet) were required when replacments were not used, see here (zh-CN))
    • partially replaced by ystdex::map
  • P0083R3: Splicing Maps and Sets (Revision 5)
    • LWG 839: Maps and sets missing splice operation
    • LWG 1041: Add associative/unordered container functions that allow to extract elements
    • partially replaced by ystdex::map
  • P0136R1: Rewording inheriting constructors (core issue 1941 et al) (adopted 2015-10)
    • CWG 1573: Inherited constructor characteristics
    • CWG 1645: Identical inheriting constructors via default arguments
    • CWG 1715: Access and inherited constructor templates
    • CWG 1736: Inheriting constructor templates in a local class
    • CWG 1903: What declarations are introduced by a non-member using-declaration?
    • CWG 1941: SFINAE and inherited constructor default arguments
    • CWG 1959: Inadvertently inherited copy constructor
    • CWG 1991: Inheriting constructors vs default arguments
  • following resolution of P0165R3: C++ Standard Library Issues to be moved in Issaquah (adopted 2016-10)
    • LWG 2062: Effect contradictions w/o no-throw guarantee of std::function swaps
      • replaced by ystdex::function since (revised b848[2018-12-24])
  • P0409R2: Allow lambda capture [=, this] (adopted 2017-07)
  • P0458R2: Checking for Existence of an Element in Associative Containers (adopted 2018-06)
    • partially replaced by ystdex::map
  • P0588R1: Simplifying implicit lambda capture (adopted 2017-11)
    • CWG 1913: decltype((x)) in lambda-expressions
    • CWG 1632: Lambda capture in member initializers
  • P0600R1: [[nodiscard]] in the Library, Rev1 (adopted 2017-11)
  • P0616R0: de-pessimize legacy <numeric> algorithms with std::move (adopted 2017-11)
    • LWG 2055: std::move in std::accumulate and other algorithms
  • P0641R2: Resolving Core Issue #1331 (const mismatch with defaulted copy constructor) (adopted 2017-11)
    • CWG 1331: const mismatch with defaulted copy constructor
      • see also CWG 1426: Allowing additional parameter types in defaulted functions
  • P1227R2: Signed ssize() functions, unsigned size() functions (Revision 2) (adopted 2019-03)

Avoided

These already adopted (by the standard or the working paper) post-C++11 resolutions (which may need no modification on a previous conforming C++ implementation) are not depended on currently (revised b803[2017-09-08]) but confirmed still being compatible, and also would not be relied on in future based on the fact of reducing expresiveness in the language and lacking of portable extensions to prevent underming of code quality based on current status:

  • P0145R3: Refining Expression Evaluation Order for Idiomatic C++ (adopted 2016-06)

List of reported issues

There are some issues related reported, or originally found and forwarded by author of this project. Some issues are related to the to language or enviornment specifications. See reported issues for details.

Introduction

There are some issues related reported, or originally found and forwarded by author of this project. Some issues might block the project in some sense. To review them conveniently, reported issues are collect in this document.

Unless otherwise specified, notations are same to those in StandardUsing.

List of reported issues

Issues not rejected or withdrawn are collected and listed here (revised b840[2018-10-07]).

Specifications

Some issues are related to the to language or enviornment specifications.

The entries may duplicate with above.

ISO/IEC 14882 (ISO/IEC JTC1 SC22/WG21 issue list)

Implementations of standards or specifications

Some issues are related to the to implementations of language or enviornment specifications.

GNU C++ (Bugzilla)

  • PR 53872: [C++11] ADL bug in std::thread (RESOLVED FIXED 4.7.2)
  • PR 53873: [C++11] strange error message for template overloading (RESOLVED DUPLICATE of bug 53862)
    • PR 53862[4.6/4.7 regression] [C++11] sorry, unimplemented: use of 'type_pack_expansion' in template (RESOLVED FIXED 4.7.1)
  • PR 54216: Missing diagnostic for ill-formed anonymous enum declarations (RESOLVED FIXED 4.9.0)
  • PR 55053: std::is_explicitly_convertible should be removed (RESOLVED WORKSFORME 4.8.0)
  • PR 56699: [4.8/4.9 regression] Failed for sizeof (non-static member) in lambda expression (RESOLVED FIXED mainline/4.8.1)
  • PR 57183: [C++11] auto and -Wunused-variable (RESOLVED FIXED 4.8.1)
  • PR 57444: [4.8/4.9 Regression] ICE in instantiate_type for invalid use of member with using-declaration (RESOLVED DUPLICATE of bug 58457)
    • PR 58457: [4.8/4.9 Regression] ICE when placement new operator is used with using keyword and custom constructor (RESOLVED FIXED 4.8.2/4.9.0)
  • PR 58395: Undefined behavior vs. exception (RESOLVED WONTFIX)
  • PR 59682: Invalid syntax accepted: new-placement without expression-list (RESOLVED FIXED 6.0)
  • PR 59931: Wrong wording of diagnostic about imaginary "member function type"
  • PR 60709: [C++11]ICE when using a braced-init-list as function argument to initialize a reference to array (RESOLVED FIXED 4.8.3)
  • PR 61019: ICE: incomplete type of class template as pseudo-destructor-name (RESOLVED FIXED 6.0)
  • PR 63400: [C++11]precision of std::chrono::high_resolution_clock (UNCONFIRMED)
  • PR 65343: unexpected exception thrown during destruction of static object in debug mode
    • Since some version of Windows 10, the crash dialog would not show, made it less annoying.
  • PR 65748: [C++11][C++14]Invalid copy elision on operand of throw-exception (RESOLVED DUPLICATE of bug 57533)
    • PR 57533: When throwing local variable, it's being move-constructed even if not going out of scope. (NEW)
    • This misfeature is carefully avoided in YSLib source.
  • PR 65890: [C++03]sizeof(qualified-id) accepted when the operand denotes a non-static member (RESOLVED INVALID)
    • This does not effect YSLib since C++11 is the baseline.
  • PR 67238: [C++11][C++14]cc1plus crash for nested decltype expression in parameter pack in trailing return type when '-g' enabled (RESOLVED FIXED 6.0)
    • This was worked arounded in YSLib source, before 6.0 is actually depended on.
  • PR 67795: Wrong code generated for conditional expression with cast (NEW)
    • This still blocks some code.
  • PR 70480: Reduce RTTI code bloat for specified types (NEW)
    • For DS platform, YSLib uses ystdex::type_id instead typeid to worked around.
  • YSLib issue 30
    • PR 71444: Error constants for MinGW-w64 (RESOLVED FIXED 5.5, 6.4 and 7.1)
    • This was worked around in YSLib source and fixed since G++ 7.1.
  • PR 86734: [DR 2188] reverse_iterator::operator-> does not support overloaded operator& (RESOLVED FIXED 7.4 8.3)
    • See upstream LWG 2188.
    • This is conditionally avoided by replacement ystdex::reverse_iterator.
  • PR 90966: [9/10 Regression] ICE in tsubst_copy, at cp/pt.c:16155 (RESOLVED FIXED 9.3 and 10)
  • PR 91127: Incorrect checking of nonnull attribute with argument to a constructor of class with a virtual base (NEW)
  • PR 91480: Nonconforming definitions of standard library feature-test macros (NEW)
  • PR 91531: _Rb_tree's copy assignment should respect to POCCA regardless of is_always_equal (NEW)
  • PR 91541: [C++17] Exception specification of operator= of node-based containers may be broken (RESOLVED WONTFIX)
  • PR 91620: std::[forward_]list::remove_if/unique should respect to DR 526 (ASSIGNED)
  • PR 93470: [C++2a] [9 Regression] [C++2a] std::reference_wrapper to function type is broken with Clang (RESOLVED FIXED 9.3)
  • PR 94602: wrong semantic check to prvalue as decltype operand (UNCONFIRMED)

LLVM/Clang (Bugzilla)

  • PR 25306: __attribute__((returns_nonnull)) does not work for std::add_pointer_t<T> (NEW)
  • PR 27504: Inherited constructor with dependent base class introduced by a typedef-name may not work (NEW)
  • PR 27443: [CWG 734] Nonconforming aliasing of block scope objects (RESOLVED DUPLICATE of bug 18538)
    • PR 18538: non-conforming optimization -fmerge-all-constants is enabled by default
    • Note they are not identical. PR 27443 is for ISO C++ and PR 18538 is for ISO C.
  • PR 43275: Pure attribute and C++ exceptions (NEW)
  • PR 45542: wrong semantic check to prvalue as decltype operand (NEW)

Microsoft Visual C++

New issues are now reported to Microsoft Visual Studio Developer Community.

As [Microsoft Connect](Microsoft Connect) is down now, any status would not be updated. Note some posts have been inaccessible even before the service stopped.

  • Microsoft Connect issue 1641428: Wrong Win32 error to errno mapping (ACTIVE)
    • YSLib code does not rely on Universal source, instead implements the functionality spearatedly, so it has no effect.
    • This seems to be fixed before Microsoft Connect closed.
  • YSLib issue 33
  • YSLib issue 34: [Win32] std::unique_ptr::operator-> not conforming in Microsoft VC++ 2015
  • problem 417142: [LWG 2070][P0674R1] std::allocate_shared is not conforming (Under Investigation)
  • YSLib issue 35: [Win32] Microsoft VC++ 2017 failed to evaluate the dependent noexcept expression inside noexcept-specifier
    • problem 431598: VC++ fails to compile the noexcept expression inside noexcept-specifier with a template-parameter instantiated from an explicit destruct call (Closed - Fixed)(Fixed In: Visual Studio 2019 version 16.1)(Fixed In: Visual Studio 2019 version 16.1 Preview 1)
  • YSLib issue 36: [Win32] Microsoft VC++ 2017 failed to initialize with string arrays with a constexpr u8 string literal
    • problem 431628: VC++ fails to initialize with string arrays with a constexpr u8 string literal (Closed - Fixed)(Fixed In: Visual Studio 2019 version 16.0)(Fixed In: Visual Studio 2019 version 16.0 Preview 5)
  • YSLib issue 37: [Win32] Microsoft VC++ 2017 internal compiler error when building SHBuild
    • problem 431665: VC++ 2017 internal error for overloaded qualified function template function call in the function default argument (Closed - Fixed)(Fixed In: Visual Studio 2019 version 16.1)(Fixed In: Visual Studio 2019 version 16.0)
  • YSLib issue 38: [Win32] Microsoft VC++ 2017 failed to select expected std::swap specialization
    • problem 431904 (Closed - Fixed)(Fixed In: Visual Studio 2019 version 16.1)(Fixed In: Visual Studio 2019 version 16.1 Preview 2)(Fixed In: Visual Studio 2019 version 16.1 Preview 1)
  • YSLib issue 39: [Win32] Microsoft VC++ 2017 rejects dependent noexcept-specifier in template partial specializations

Other projects

As complement, some issues are related to other tools used by the project or referenced in documentation of this project, which may loosely concern with issues listed above.

DrMemory

devkitPro

libfat

  • pull request 1: Removed redundant check (Merged)
  • issue 2: Wrong root sectors count determined for FAT12 and FAT16? (Open)
  • issue 3: Redundant function calls (Open)
  • issue 4: _FAT_directory_entryFromPosition issues (Open)
  • issue 5: Redundant call of _FAT_directory_getRootEntry for "/" (Open)
  • issue 6: ENOTDIR vs ENOENT for invalid path prefix (Open)
  • issue 7: Pathname with or without trailing slashes for directories (Open)
  • issue 10: Setting errno when removing a non-empty directory (Open)

libnds

newlib

  • issue 5: Nonconforming return type of ftell (Closed FIXED)

Klisp

  • issue 12: A problem of proper tail call (NEW)

Resolved implementation issues

Some issues were tagged BLOCKED status previously. Issues known resolved and confirmed to work would be put in this chapter.

General

Scope

This document describes a set of rules for creating and maintaining documentations or some other kinds of materials, which is not project-specific. This document is also self-conforming to these rules.

Notation

Specific formats may be used. The visual output may depend on the method of rendering.

Texts intended to be handled differently (for example, portions of program source code) may be in some specific format. Other texts are considered normal.

Hyperlinks may be used in normal texts pointing to external references, local pages, or anchors in specific documents.

Normal text empasized in general are in the specific format, usually (visually) bold.

Local terms in the normal text are emphasized at first appearence in the specific format, usually (visually) italic.

For terms used globally in this document and any other derivations, see below.

Terms and definitions

Resources

Contents of materials are split as resources (e.g. files) in possibly nested namespaces (e.g. directories). A namespace is also considered as a resource for convenience.

Paths and identifiers

A path is used to identifying or locating a resource, which can be in various forms (e.g. filesystem path or URL).

A path may have several components denoting different levels of namespace or the last level non-namespace resource.

An empty path is a path without any components.

A path with more than one components shall have syntactic separators (e.g. a slash(/) or whitespace) to split different components.

An identifier is a path with exactly one components without any separators, which can be used to differentiate resources in the same namespace or to collectively name some sets of resources in various namespaces.

A resource may be denoted with not necessarily the unique identifier or path. However, all resources this document discussed below are named.

Languages

Rules of natural languages are specified in this subclause. They have effects on normal texts.

Normal text of noun phrases may have embedded translations for different natural languages or more detailed descriptions following its first occurence, in parentheses (( and )).

Different letter cases (if appropriate) may be used for sentences, acronyms and words in the titles of clauses.

Editions in languages

A set of documentation may be in one (natural) language. The IETF language tag with at least one subtag and an additional prefix dot(.) shall be placed in the end of identifier of the resource before the dot and the extension name (if any). Otherwise the documentation shall be in multiple languages or without text contents (e.g. containing only ideographic images), and no language code shall be in the identifier of the resource.

When the additional dot and tag is removed, all different resource with same names shall refer to the same set of contents only in different languages, or at least one of them shall be incomplete which means to be completed as in former case. The resource is one edition in the specific language of the documentation.

Unless explicitly specified, when the meaning is in conflict for multiple editions in different languages, the complete one shall be valid over others. If there is not only one complete edition, the validity is specified in following order:

  • en-US
  • en
  • zh-CN
  • zh

If no one edition in above languages is complete, the documentation is defective.

A language tag may be used to annotate one or more words in text. An annotation of such use is a language tag annotation, which consists of a tag combined with one pair of enclosing parentheses (namely, ( and )).

Hyperlinks in pages should preferrably link to localized contents corresponding to the language or one of the major languages used in the page (if any) when suitable. If contents of the linked target is in other languages (esp. when there are more than one semantically identical editions in multiple languages), at least one language tag for majority of the contents should be noted subsequent to the hyperlink; otherwise, the tag should be omitted.

For compatibility of client programs, each link of URI should be encoded in form of normalized Percent-Encoding in RFC 3986.

Additionally, several hyperlinks are normalized with the same form for a specific language. Currently the rule consists of following cases:

In English

Stylistic usage of letter cases shall be respected in the following precedence:

  1. All uppercase should not be used normally.
  2. Acronyms and other proper noun (pharses) shall be in the appropriate styles.
  3. The title case style shall be used for page or document titles.
  4. Either the title case or the sentence case shall be used in the titles in a page. This shall be consistent within a document.
  5. Either the title case or the sentence case shall be used in the detailed descriptions for acronyms in parentheses. This may vary in the same page.
  6. Detailed descriptions for acronyms in parentheses may use title case or sentence case.
  7. All lowercase style shall be used for words in the embedded translations or detailed descriptions in parentheses in other cases.
  8. Sentence case should be used otherwise.

English wording documentation is intended to be conforming to the ISO/IEC directive, part 3. Note the use of modal verbs is distinct with RFC 2119. For RFC documents, RFC 2119 is preferred, but not necessary with the case clarification (i.e. RFC 8174) for documents published earlier than RFC 8174 due to compatibility issues.

The following grammartical forms of English (with en or en-US tags) are considered idiomatic and application of such forms may be preferred:

  • answer ellipsis to elide the subject in the summary of commit messages where a question for the topic of the log message is assumed
  • bare passive clause omitting the auxiliary verb for short descriptive notes (e.g. commit messages in repositories and assertions messages in programs)
  • null subject and pronoun dropping in imperative forms
  • zero article for singular form of a countable noun denoting a specialized term being referenced, usually used in a terse-style title or in a list term (like this line)

Informative notes: The tense and mood used in the logs in version control systems are opinion-based. However, the implied rules are choosed here to avoid imperative forms by default, because:

  • First, it should be respected same in all information processing system: to make sure who are the messages in the logs serve to.
    • Version control systems are capable for reading and writing operations on the version history, with asymmetric operational frequency in general.
      • For most stakeholders to a repository in most cases, read-only accesses of the version history are more frequent compared to changing opertions.
      • This is also consistent with the idiom pattern used in programming: do not abuse imperative updates with side effects.
    • For most users, commit logs are entries of journal of the version history.
      • They do not and should not care about imperative changes in the logical perspective.
  • Unconstrained changes in the version history as effectful operations can make messes easily.
    • They are usually only well-behaved enough within some local context (e.g. in a single branch of a reliable instance of the version history).
    • They often make troubles in other cases (e.g. when stripped as patches possibly reordered).
  • Messages in the logs may be cooperated with other instances of version history.
    • No imperative mood can essentially assume the changes described will always be applied in the exactly same way.
    • As mentioned above, out-of-order changes make messes. If the messages are precise, they also make messes like other changed contents.
  • In general, messages in the logs work for distributed repositories.
    • There is simply no standpoint for the global view of the universe of the version history by default.
    • Messages should be ready to be audited by random accesses, besides being applied subsequently in some replays.
    • These facts further undermines the necessity of imperative changes.

Format-specific rules

Text files

Unless otherwise specified, all text files should be encoded as UTF-8 with BOM enabled.

Any use of encoding which may not be converted verbatim and losslessly in binary form to UTF-8 shall be explicit specified in documantation.

BOM should be omitted for text files dedicated to tools without capability of properly handling it. Otherwise, BOM shall be used as possible when it can clarify the encoding being used.

Unless definitely intended and explictly specified in documentation, newlines shall be consistent. Default use of newline is CR+LF.

Two subsequent newlines indicate an EOF logically. Subsequent newlines out of verbatim quoted text (including source code) should only be used at EOF.

Except at the first of line, each word which consists of alphanumeric characters should be seperated by a single space character(U+0020) with other words.

No space characters should be at EOL.

To keep the semantics rules clear, use horizontal tab character(U+0009) instead of other spaces(i.e. U+0020) to indent, unless the text is verbatim quoted.

Markdown

Names of markdown files should be with .md extension.

Dialects

Unless explicitly specified elsewhere, only common dialects are to be used. Currently this should be GFM. And if the content may be presented on Bitbucket wiki, more strict rules applies, notably there is currently no inline HTML support.

Syntactic restrictions

As text files, markdown files shall obey the same rules above. The indentation rule is necessary to avoid some compatibility issues, e.g. this.

As specified, reserved characters defined by RFC 3986 should be percentage-encoded. Notably, the parentheses(()) in hyperlinks shall be encoded to make it more fault-tolerent for some editors.

Headers should be prefixed by #s.

For sake of compact annotation representation, there should be no redundant characters allowed between the annotated words and annotation (esp. whitespace characters), even there are whitespaces in the words. The annotation in this rule includes any language tag annotation defined in previous subclause.

The whitespace rules in the language annotation is also

Cross references

This document is used by the YSLib project. It may be also referenced by other repositories.

Except for the following list, do not edit unless ultimately necessary.

Known refereced by: