docs: 记录 Android GBK 编解码的已知问题(挂起)

用户决定:先保证 macOS 可用,Android 后期再想办法。本次只记录根因,
不动 text_codec.cpp。

症状:build-android.sh 默认 API 24 下 extension/src/net/text_codec.cpp 报
use of undeclared identifier 'iconv_open'。

根因:text_codec.cpp:10 用 __has_include(<iconv.h>) 探测;NDK 里该头在任何
API 等级都存在,但声明被 __BIONIC_AVAILABILITY_GUARD(28) 挡住。用
NDK 28.2 的 clang++ -fsyntax-only 实测:android24 报 3 处 undeclared,
android28 通过。

但升 API 不是解法:NDK iconv.h 写明 bionic 只支持 utf8/ascii/usascii/
utf16{be,le}/utf32{be,le}/wchart,没有 GB2312/GBK。升到 28 后
iconv_open("GB2312","UTF-8") 运行期返回 -1,encode_one()/decode_wire()
对所有输入都返回 false——连纯 ASCII 也被拒,比现有 #else 的 ASCII 回退
分支(text_codec.cpp:104-127)更糟。且 APK min_sdk 要跟着 >=28,
config/android/pyconfig.h 是 API 24 下 configure 的,需返工。

将来的修法写进了 PORT-PLAN 的新小节。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-23 09:57:27 +09:00
co-authored by Claude Opus 5
parent 19a9b18554
commit 389b643863
2 changed files with 22 additions and 0 deletions
+21
View File
@@ -341,6 +341,27 @@ extension/third_party/cpython-2.7.18/ # 静态库(2P 批次
| ~~Linux x86_64~~ | 不做(2026-09-23 定,见第 1 节) |
| ~~Windows x64~~ | 不做(2026-09-23 定,见第 1 节)。记录原因备查:上游 2.7 只支持 MSVC + `PC/pyconfig.h`,而本仓库的 Windows 门禁是 mingw-w64 交叉编译,`PC/pyconfig.h` 的 gnu-win32 分支不设 `HAVE_UNISTD_H`,`posixmodule.c`/`dynload_win.c` 与 MinGW 头文件冲突。因此 mingw 门禁下不建 `mtpython`,`port_logic`/`port_platform` 自动排除 ScriptLib |
### 已知问题:Android 的 GBK 编解码(挂起,2026-09-23)
**优先级:macOS 先跑通,Android 后面再说**(用户 2026-09-23 定)。
`extension/src/net/text_codec.cpp:10` 用 `__has_include(<iconv.h>)` 探测 iconv。NDK 里这个头文件在
任何 API 等级都存在,但函数声明被 `__BIONIC_AVAILABILITY_GUARD(28)` 挡住,所以 `build-android.sh`
的默认 API 24(`build-android.sh:14`)下编译报 `use of undeclared identifier 'iconv_open'`。
**升到 API 28 不是解法**:NDK `iconv.h` 原文写明 bionic 只支持
`utf8/ascii/usascii/utf16be/utf16le/utf32be/utf32le/wchart`,**没有 GB2312/GBK**。升级后
`iconv_open("GB2312","UTF-8")` 运行期返回 `-1`,`encode_one()`/`decode_wire()` 对所有输入都
返回 false——连纯 ASCII 也被拒,比现在 `#else` 的 ASCII 回退分支(`text_codec.cpp:104-127`)更糟。
附带成本:APK `min_sdk` 必须跟着 ≥28,且 `config/android/pyconfig.h` 是 API 24 下 configure 出来的
(`HAVE_LANGINFO_H` 因 `nl_langinfo` 需 API 26 被关掉),要重跑 `gen_pyconfig.sh android` 并重验内建模块表。
将来动手时分两步:
1. 探测条件从「头文件在不在」改成「这个平台的 iconv 能不能用」——`#if __has_include(<iconv.h>) && !defined(__ANDROID__)`,
Android 一律走回退分支,先把交叉编译修绿。**不要**写成 `__ANDROID_API__ >= 28`。
2. 补真正的转换:Android 需要自带 GBK↔Unicode 表(约 22k 码位)。40250 原客户端走 Windows
`MultiByteToWideChar(CP949/CP936)`,跨平台没有对应物;macOS 能用只是因为系统 libiconv 恰好带 GBK。
### 批次 2V0–2V3:纵向切片
2A 先根据真实 `#include` 和 Python import 生成每个切片的机器可读单元清单;清单提交到 `audit/`,进入切片前不得仍有