CGraphicText, CGraphicFontTexture and CGraphicDib are the 40250 bodies verbatim; CGraphicTextInstance is verbatim except that its D3D draws become UI render commands (one image quad per glyph, Bar for cursor/underline). - platform/Win32Gdi.cpp: the GDI subset those files call, over vendored FreeType 2.13.3, following GDI's LOGFONT cell height, win metrics and gasp rules; system font lookup with substitute and CJK fallback faces - Win32Crt: MultiByteToWideChar / WideCharToMultiByte (UTF-8 and 1252 by hand, other code pages through iconv) - CGraphicImageTexture memory textures: glyph pages reach Godot as "mem:<id>@<revision>"; Metin2PythonHost.memory_texture + Canvas cache - Util.cpp code page / font face table, SetDefaultCodePage at boot, DefaultFont_* block, fnt resource type, GetMaxTextureWidth/Height - TextTag, StringCodec, Arabic, Vietnamese copied from 40250 - tests: port.text (Tahoma 12 metrics, alignment, CP949), port.app_loop and python_host_test.gd now check glyph quads instead of text commands Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
173 lines
11 KiB
Markdown
173 lines
11 KiB
Markdown
# Third-party native dependencies
|
|
|
|
The GDExtension links five native libraries that are **not** part of Godot or
|
|
godot-cpp. Phase 1 (macOS) pulled the first three from Homebrew; that stops
|
|
working the moment we cross-compile for the Android NDK or the iOS SDK (BACKLOG
|
|
F1/F2), so as of 2026-08-30 they are built from source as part of our own CMake
|
|
build. Crypto++ joined later (2026-09-02) with the `MT_PROTOCOL=classic` 40250
|
|
backend and was vendored the same way from the start.
|
|
|
|
CPython joined on 2026-09-23 with 批次 2P (the embedded 40250 script layer) and is
|
|
vendored source as well. FreeType joined the same day with 批次 2V0-g (the 40250
|
|
font path over an emulated GDI).
|
|
|
|
Everything lives under `extension/third_party/` and is wired by
|
|
`extension/third_party/CMakeLists.txt`, which exposes five aliases:
|
|
|
|
| Alias | Backing target | Consumed by |
|
|
|-------------------|------------------|------------------------------------|
|
|
| `mt3p::sodium` | `sodium` | `mtnet`, `mtpack`, `mtproto` |
|
|
| `mt3p::zstd` | `libzstd_static` | `mtpack` |
|
|
| `mt3p::minilzo` | `minilzo` | `mtproto` |
|
|
| `mt3p::cryptopp` | `cryptopp` | `mtnet` (classic backend) |
|
|
| `mt3p::python` | `mtpython` | the script layer (`py_embed_test`) |
|
|
| `mt3p::freetype` | `freetype` | `port_platform` (`platform/Win32Gdi.cpp`) |
|
|
|
|
No source file changed: `#include <sodium.h>`, `#include <zstd.h>`,
|
|
`#include <lzo/lzo1x.h>` and `#include <cryptopp/…>` all still resolve (the LZO
|
|
one via a 1-line shim header, see below).
|
|
|
|
## libsodium — via `robinlinden/libsodium-cmake`
|
|
|
|
* **Submodule:** `extension/third_party/libsodium-cmake` @ `9b2848d`
|
|
* itself carries `jedisct1/libsodium` @ `93a7d0d` (libsodium 1.0.20 line) as a
|
|
**nested** submodule — clones need `--recursive`.
|
|
* **Why the wrapper:** upstream libsodium is autotools-only. This MIT-licensed
|
|
wrapper is a pure CMakeLists over an untouched libsodium checkout; it generates
|
|
`version.h`, sets `CONFIGURED`, and builds clean for macOS / iOS / Android /
|
|
Windows. Used by many mobile projects.
|
|
* **Build options we force:** `SODIUM_DISABLE_TESTS=ON`, `SODIUM_MINIMAL=OFF`
|
|
(we need `crypto_kx`, `crypto_auth`, `crypto_aead_xchacha20poly1305`,
|
|
`crypto_stream_xchacha20`, `crypto_generichash`/BLAKE2b — all outside the
|
|
"minimal" set).
|
|
* **License:** ISC (libsodium) + MIT (wrapper). Ship-safe.
|
|
|
|
## libzstd — `facebook/zstd`
|
|
|
|
* **Submodule:** `extension/third_party/zstd` @ tag **v1.5.6** (`794ea1b0`).
|
|
* Built through upstream `build/cmake` with:
|
|
`ZSTD_BUILD_PROGRAMS/SHARED/TESTS/CONTRIB=OFF`, `ZSTD_BUILD_STATIC=ON`,
|
|
`ZSTD_LEGACY_SUPPORT=OFF`, `ZSTD_MULTITHREAD_SUPPORT=OFF` (the eterpack path
|
|
only does single-shot `ZSTD_compress`/`ZSTD_decompress`).
|
|
* Target consumed: `libzstd_static` (carries its own public include dir).
|
|
* **License:** BSD-3-Clause / GPLv2 dual. Ship-safe under BSD.
|
|
|
|
## miniLZO — vendored source (not a submodule)
|
|
|
|
* **Files:** `extension/third_party/minilzo/{minilzo.c,minilzo.h,lzoconf.h,lzodefs.h}`
|
|
copied verbatim from **lzo-2.10** (`minilzo.c` sha1 `019debb3…`), plus
|
|
`README.LZO`, `COPYING`, `AUTHORS` as required by the LZO license.
|
|
* Upstream LZO has no git repo (oberhumer.com tarball only), and miniLZO is a
|
|
4-file amalgamation, so it is copied in rather than submoduled.
|
|
* **Shim:** `minilzo/lzo/lzo1x.h` is a 1-line `#include "../minilzo.h"` so
|
|
`extension/src/proto/proto.cpp` keeps `#include <lzo/lzo1x.h>` unchanged.
|
|
miniLZO's API (`lzo_init`, `lzo1x_decompress_safe`, `LZO_E_OK`, `lzo_uint`) is a
|
|
strict subset of full LZO and covers everything the CLZO path uses.
|
|
* **License:** **GPLv2**. Acceptable for this internal, non-published,
|
|
non-commercial project on the same footing as `libgr2/src/oodle1.c` — but LZO
|
|
must be removed, replaced, or commercially licensed before any public release
|
|
or commercial use. (item_proto/mob_proto are the only LZO consumers; a
|
|
clean-room LZO1X decompressor is the eventual fix.)
|
|
|
|
## Crypto++ — vendored source (not a submodule)
|
|
|
|
* **Files:** `extension/third_party/cryptopp/` (~6.6 MB), copied from the 40250
|
|
client tree (`ClientVS22/extern/include/cryptopp`), `CRYPTOPP_VERSION 840` =
|
|
**8.4.0**. The 40250 server links this exact version
|
|
(`Server/.../extern/cryptopp_8_4_0.tar.gz`), so the version is pinned by
|
|
wire compatibility, not preference.
|
|
* **Why:** the `MT_PROTOCOL=classic` backend's `_IMPROVED_PACKET_ENCRYPTION_`
|
|
cipher — DH2 key agreement + hint-selected block ciphers (Twofish default) in
|
|
CTR mode. Only consumer is `extension/src/net/classic/classic_cipher.{h,cpp}`.
|
|
The m2dev backend does not use it (that one is libsodium/XChaCha20).
|
|
* **No upstream CMakeLists**, so `cryptopp/CMakeLists.txt` is ours: it globs the
|
|
library TUs and drops the cryptest / benchmark / adhoc / FIPS-selftest ones
|
|
(`adhoc`, `bench1..3`, `datatest`, `dlltest`, `fipsalgt`, `fipstest`, `pch`,
|
|
`regtest1..4`, `test`, `validat0..10`).
|
|
* **ASM disabled everywhere** (`CRYPTOPP_DISABLE_ASM` / `_SSSE3` / `_AESNI`) so
|
|
one pure-C++ build works on macOS, the Android NDK and the iOS SDK; the classic
|
|
cipher needs no AES-NI / SHA-ext. Android additionally compiles the NDK's
|
|
`sources/android/cpufeatures/cpu-features.c` in, because upstream `cpu.cpp`
|
|
includes `cpu-features.h` unconditionally under `__ANDROID__`.
|
|
* Built with `-w` (upstream is not warning-clean under `-Wall`) and
|
|
`-fno-strict-aliasing`.
|
|
* **License:** **public domain** — the compilation carries Wei Dai's copyright,
|
|
but every individual file is placed in the public domain by its authors
|
|
(`extension/third_party/cryptopp/License.txt`). Ship-safe; unlike miniLZO it
|
|
imposes no obligation before a public or commercial release.
|
|
|
|
## CPython 2.7.18 — vendored source (not a submodule)
|
|
|
|
* **Files:** `extension/third_party/cpython-2.7.18/` (~25 MB), the official
|
|
`Python-2.7.18.tgz` (sha256 `b62c0e7937551d0cc02b8fd5cb0f544f9405bafc9a54d3808ed4594812edef43`)
|
|
trimmed of what an embedded interpreter never builds or ships: `Doc Demo Tools
|
|
Mac PCbuild`, `Modules/{_ctypes,expat,zlib,_sqlite}`, the stdlib test trees and
|
|
the pre-VS2010 `PC/` project files. `Lib/` stays: the `mtpython_stdlib` target
|
|
packs it into `<build>/python27.zip` with `tools/py_embed/make_stdlib_zip.py`,
|
|
which is what the host puts on `sys.path` (batch 2P step 3). Entries are
|
|
**stored, never deflated** — the `zlib` module is trimmed out above, so
|
|
`zipimport` has nothing to inflate with. The zip and its `.sha256` are copied
|
|
into `project/` (gitignored) so the exporter packs them; on Android/iOS
|
|
`extension/src/python_stdlib.cpp` stages the zip out of the PCK into `user://`
|
|
and checks that digest, because CPython opens it with its own stdio.
|
|
* **Why vendored:** 2.7 is end-of-life, so there is no package to fetch on the
|
|
four target SDKs, and the build must keep working offline and on the
|
|
cross-build machines. It is the version the 40250 scripts are written for
|
|
(`ScriptLib` embeds 2.7), so it is pinned by the scripts, not by preference.
|
|
* **Built by our own `cpython-2.7.18/CMakeLists.txt`**, not autotools: one
|
|
`mtpython` static library from the exact 133 objects the reference
|
|
`libpython2.7.a` contains. The source list and the built-in module table
|
|
(`config/config.c`, `config/Setup.static`, 39 entries) are **shared**;
|
|
`pyconfig.h` is **not** — it is a probe result, so each platform keeps its own
|
|
under `config/<platform>/`, regenerated by `tools/py_embed/gen_pyconfig.sh`.
|
|
Off by default: `-DMTGODOT_EMBED_PYTHON=ON` builds it.
|
|
* **Three vendor patches** (everything else is verbatim upstream):
|
|
1. `configure` + 2. `configure.ac` — add `arm64) MACOSX_DEFAULT_ARCH="arm64"`
|
|
to both `case \`/usr/bin/arch\`` blocks; upstream predates Apple silicon and
|
|
dies with "Unexpected output of 'arch' on OSX".
|
|
3. `Modules/posixmodule.c` — after the "all other compilers" block that
|
|
hard-defines `HAVE_SYSTEM`/`FORK`/`EXECV`/`WAIT`/`POPEN` regardless of
|
|
`pyconfig.h`, undefine them again under `TARGET_OS_IPHONE`: the iphoneos SDK
|
|
marks `system()` unavailable and the sandbox forbids the rest.
|
|
* **Platform notes:** Android API 24 turns off `HAVE_LANGINFO_H` (bionic declares
|
|
`nl_langinfo` only from API 26); iOS derives its `pyconfig.h` from the macOS one
|
|
(2.7's configure refuses a darwin cross build) and drops process control plus
|
|
`<sys/random.h>`/`getentropy`, but keeps `HAVE_GETGROUPS` because
|
|
`posixmodule.c` defines `MAX_GROUPS` — which its `setgroups` path needs — only
|
|
inside that `#ifdef`. **Windows is out of scope** (decided 2026-09-23, PORT-PLAN §1: the
|
|
targets are macOS arm64 and Android arm64). It is also not buildable as-is:
|
|
upstream supports MSVC + `PC/pyconfig.h`, while the mingw-w64 portability gate
|
|
cross-compiles with MinGW, where `PC/pyconfig.h`'s gnu-win32 branch leaves
|
|
`HAVE_UNISTD_H` unset and `posixmodule.c` / `dynload_win.c` then collide with
|
|
the MinGW headers. So that gate simply builds no `mtpython`, and `port_logic` /
|
|
`port_platform` drop ScriptLib there.
|
|
* **License:** PSF License Agreement (`cpython-2.7.18/LICENSE`). Ship-safe; the
|
|
only obligation is keeping the license and a change notice, which this section
|
|
and the patched files' comments serve.
|
|
|
|
## FreeType 2.13.3 — vendored source, trimmed (not a submodule)
|
|
|
|
* **Files:** `extension/third_party/freetype-2.13.3/` (~5 MB): the official
|
|
`freetype-2.13.3.tar.xz` (source URL and sha256 in the directory's
|
|
`CMakeLists.txt` header) cut down to `include/`, `src/{base,sfnt,truetype,smooth,raster,psnames,gzip}`,
|
|
`LICENSE.TXT` and `docs/FTL.TXT`.
|
|
* **Build:** our own `CMakeLists.txt` (upstream's pulls in optional deps we don't
|
|
want); `mt-config/freetype/config/ftmodule.h` replaces the stock module list with
|
|
TrueType + sfnt + the mono and gray rasterizers. No upstream file is modified.
|
|
* **Why:** 40250's `CGraphicFontTexture` / `CGraphicDib` render glyphs with GDI
|
|
(`CreateFontIndirect`, `TextOutW` into a DIB section). `platform/Win32Gdi.cpp`
|
|
implements that GDI subset over FreeType with GDI's cell-height, win-metric and
|
|
gasp rules, so the 40250 font code stays verbatim.
|
|
* **License:** FreeType License (`docs/FTL.TXT`, BSD-style with credit clause):
|
|
the shipped product's documentation must credit "Portions of this software are
|
|
copyright © The FreeType Project (www.freetype.org)".
|
|
|
|
## Rebuilding / fetching
|
|
|
|
`./build.sh` auto-runs `git submodule update --init --recursive` if any of the
|
|
three submodules (godot-cpp, zstd, libsodium-cmake+libsodium) is missing.
|
|
miniLZO, Crypto++ and CPython are vendored source and need no fetch.
|
|
|
|
Homebrew `libsodium` / `zstd` / `lzo` are no longer referenced by the build and
|
|
can be uninstalled.
|