port(2P step 3c): stage python27.zip into the mobile sandbox
CPython opens the stdlib zip with its own stdio, so it needs a real path.
On the desktop res:// is a directory and globalize_path() is enough; in an
exported build res:// is inside the PCK, which nothing outside Godot reads.
make_stdlib_zip.py now also writes <out>.sha256
mtpython_stdlib_project copies python27.zip + .sha256 into project/
(gitignored), and both export presets' include_filter lists them, so
they enter the PCK — checked with --export-pack
extension/src/python_stdlib.{h,cpp} (Metin2Python.stdlib_path in
GDScript): reads the bytes out of the PCK, writes
user://python27.zip.part, hashes the file as written against the
shipped digest, then renames. A sandbox copy is reused only when it
matches, so a first start killed mid-copy and a zip replaced by a new
build both re-stage instead of feeding zipimport a torn file.
PythonHost::SetDefaultStdLibPath / DefaultStdLibPath() answer with that
path ($MT_PYTHON_STDLIB still wins). python_stdlib.cpp is the only unit
that knows res:// / user://; port_platform stays godot-free.
Also fixes the Windows gate, which step 3b broke: without mtpython the
MinGW build compiled UserInterface/StdAfx.h (it includes ScriptLib/StdAfx.h,
as the original PCH does). port/CMakeLists.txt excludes that header and
PythonPackModule.cpp with ScriptLib, and platform/CMakeLists.txt excludes
platform/ScriptLib/ the same way.
Not done: on-device staging. The macOS test drives the mobile path with
force_stage=true, and nothing in the app boot calls it yet — the
interpreter only starts in the process with 2V0.
gates: python_stdlib_test.gd PASS (in-place path, staging, sha256, bytes
equal res://, no .part, ZIPReader finds encodings/__init__.py, no re-copy
on a second call, corrupted copy re-staged) · macOS ctest 27/27 ·
mingw + android + ios port_platform compile clean · port_map.py check 0
errors · key leak check 8/8 none.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,13 +94,24 @@ bool InstallStdLib(const char* stdlib_path, std::string* error)
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string g_staged_path;
|
||||
}
|
||||
|
||||
void SetDefaultStdLibPath(const char* stdlib_path)
|
||||
{
|
||||
g_staged_path = stdlib_path ? stdlib_path : "";
|
||||
}
|
||||
|
||||
std::string DefaultStdLibPath()
|
||||
{
|
||||
// The environment still wins, so a developer can point a build at another stdlib without rebuilding.
|
||||
if (const char* env = getenv("MT_PYTHON_STDLIB"))
|
||||
return env;
|
||||
// Step 3c stages python27.zip out of the packed assets on Android/iOS and answers here; until then
|
||||
// the caller passes the path (the build tree's copy, for the native tests).
|
||||
return "";
|
||||
// Whatever staged the zip for this platform (extension/src/python_stdlib.cpp inside Godot; nothing
|
||||
// in the native tests, which pass the build tree's copy on the command line).
|
||||
return g_staged_path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,9 @@ void Configure(const char* program_name = "eter.python");
|
||||
// and re-registers the codec search function. False leaves *error set.
|
||||
bool InstallStdLib(const char* stdlib_path, std::string* error);
|
||||
|
||||
// The stdlib path this build was given: $MT_PYTHON_STDLIB when set, else the python27.zip next to
|
||||
// the executable, else "". Mobile staging (copy out of the app resources, checked against the
|
||||
// manifest sha256) is 批次 2P step 3c and will answer here too.
|
||||
// Where the host put the stdlib: $MT_PYTHON_STDLIB when set, else whatever SetDefaultStdLibPath was
|
||||
// given, else "". Inside Godot that is the staged python27.zip (extension/src/python_stdlib.h), which
|
||||
// on Android/iOS is the sandbox copy of the one in the read-only bundle.
|
||||
std::string DefaultStdLibPath();
|
||||
void SetDefaultStdLibPath(const char* stdlib_path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user