Skip to content

Commit

Permalink
Merge pull request #189 from xen0n/issue188
Browse files Browse the repository at this point in the history
Fix mux operation with Nuitka 2.4
  • Loading branch information
xen0n authored Sep 2, 2024
2 parents 606ed91 + 38c9338 commit 35d89b0
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "ruyi"
version = "0.17.0-alpha.20240901"
version = "0.18.0-alpha.20240902"
description = "Package manager for RuyiSDK"
keywords = ["ruyi", "ruyisdk"]
# license = { file = "LICENSE-Apache.txt" }
Expand Down
2 changes: 2 additions & 0 deletions ruyi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,7 @@ class NuitkaVersion(typing.NamedTuple):
no_docstrings: bool
no_annotations: bool
module: bool
main: str
onefile_argv0: str | None

__compiled__: NuitkaVersion
3 changes: 2 additions & 1 deletion ruyi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
del ssl_patch

from ruyi.cli import main
from ruyi.utils.nuitka import get_nuitka_self_exe
from ruyi.utils.nuitka import get_nuitka_self_exe, get_argv0

# note down our own executable path, for identity-checking in mux, if not
# we're not already Nuitka-compiled
Expand All @@ -48,6 +48,7 @@
else:
self_exe = __file__

sys.argv[0] = get_argv0()
ruyi.record_self_exe(sys.argv[0], __file__, self_exe)

sys.exit(main(sys.argv))
9 changes: 8 additions & 1 deletion ruyi/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@
import sys
from typing import Callable, List

# Should be all-lower for is_called_as_ruyi to work
RUYI_ENTRYPOINT_NAME = "ruyi"

ALLOWED_RUYI_ENTRYPOINT_NAMES = (
RUYI_ENTRYPOINT_NAME,
f"{RUYI_ENTRYPOINT_NAME}.exe",
f"{RUYI_ENTRYPOINT_NAME}.bin", # Nuitka one-file program cache
"__main__.py",
)

def is_called_as_ruyi(argv0: str) -> bool:
return os.path.basename(argv0) in {RUYI_ENTRYPOINT_NAME, "__main__.py"}
return os.path.basename(argv0).lower() in ALLOWED_RUYI_ENTRYPOINT_NAMES


CLIEntrypoint = Callable[[argparse.Namespace], int]
Expand Down
16 changes: 16 additions & 0 deletions ruyi/utils/nuitka.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import sys


def get_nuitka_self_exe() -> str:
Expand All @@ -15,3 +16,18 @@ def get_nuitka_self_exe() -> str:
import ruyi

return os.path.join(ruyi.__compiled__.containing_dir, "ruyi")


def get_argv0() -> str:
import ruyi

try:
if ruyi.__compiled__.onefile_argv0 is not None:
return ruyi.__compiled__.onefile_argv0
except AttributeError:
# Either we're not packaged with Nuitka, or the Nuitka used is
# without our onefile_argv0 patch, in which case we cannot do any
# better than simply returning sys.argv[0].
pass

return sys.argv[0]
11 changes: 11 additions & 0 deletions scripts/dist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ do_inner() {
poetry install --with=dist --without=dev
endgroup

if [[ -d ${REPO_ROOT}/scripts/patches/nuitka ]]; then
green "patching Nuitka" group
pushd /home/b/venv/lib/python*/site-packages > /dev/null
for patch_file in "$REPO_ROOT"/scripts/patches/nuitka/*.patch; do
echo " * $(basename "$patch_file")"
patch -Np1 < "$patch_file"
done
popd > /dev/null
endgroup
fi

exec ./scripts/dist-inner.py
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
From eebb54e73ce3c5e7c5760b091217dd00ba51620f Mon Sep 17 00:00:00 2001
From: WANG Xuerui <[email protected]>
Date: Mon, 2 Sep 2024 14:59:09 +0800
Subject: [PATCH] Onefile: Preserve the original argv[0] in
__compiled__.onefile_argv0

In commit 9b0406b2a ("Fix, need to make sure sys.argv[0] is absolute
for best usability"), the original argv[0] as received by the onefile
binary is thrown away, breaking applications needing this information.

To support these cases, record the original argv[0] in the
NUITKA_ONEFILE_ARGV0 environment variable, for exposure via
__compiled__.onefile_argv0. The field is made None if the onefile mode
is not in use, or if the binary is not launched via the onefile
bootstrapper.
---
nuitka/build/include/nuitka/helpers.h | 5 +++++
nuitka/build/static_src/CompiledCodeHelpers.c | 14 ++++++++++++++
nuitka/build/static_src/OnefileBootstrap.c | 2 ++
.../templates/CodeTemplatesConstants.py | 4 ++++
4 files changed, 25 insertions(+)

diff --git a/nuitka/build/include/nuitka/helpers.h b/nuitka/build/include/nuitka/helpers.h
index 3dd7f5462..da633f899 100644
--- a/nuitka/build/include/nuitka/helpers.h
+++ b/nuitka/build/include/nuitka/helpers.h
@@ -378,6 +378,11 @@ extern char const *getBinaryDirectoryHostEncoded(bool resolve_symlinks);
// Get the containing directory as an object with symlinks resolved or not.
extern PyObject *getContainingDirectoryObject(bool resolve_symlinks);

+// Get the original argv[0] as recorded by the onefile bootstrap stage.
+// Returns None if not being invoked by the onefile bootstrapper, or if
+// onefile mode is not in use.
+extern PyObject *getOnefileArgv0Object(void);
+
#ifdef _NUITKA_STANDALONE
extern void setEarlyFrozenModulesFileAttribute(PyThreadState *tstate);
#endif
diff --git a/nuitka/build/static_src/CompiledCodeHelpers.c b/nuitka/build/static_src/CompiledCodeHelpers.c
index db90c7c23..a33001afa 100644
--- a/nuitka/build/static_src/CompiledCodeHelpers.c
+++ b/nuitka/build/static_src/CompiledCodeHelpers.c
@@ -1904,6 +1904,20 @@ PyObject *getContainingDirectoryObject(bool resolve_symlinks) {
#endif
}

+PyObject *getOnefileArgv0Object(void) {
+#if defined(_NUITKA_EXE) && defined(_NUITKA_ONEFILE_MODE)
+ environment_char_t const *onefile_argv0 = getEnvironmentVariable("NUITKA_ONEFILE_ARGV0");
+ if (onefile_argv0 != NULL) {
+ PyObject *result = Nuitka_String_FromFilename(onefile_argv0);
+ unsetEnvironmentVariable("NUITKA_ONEFILE_ARGV0");
+ return result;
+ }
+#endif
+
+ Py_INCREF_IMMORTAL(Py_None);
+ return Py_None;
+}
+
static void _initDeepCopy(void);

void _initBuiltinModule(void) {
diff --git a/nuitka/build/static_src/OnefileBootstrap.c b/nuitka/build/static_src/OnefileBootstrap.c
index 3e9095685..f95559e41 100644
--- a/nuitka/build/static_src/OnefileBootstrap.c
+++ b/nuitka/build/static_src/OnefileBootstrap.c
@@ -1156,6 +1156,8 @@ int main(int argc, char **argv) {
#endif
setEnvironmentVariable("NUITKA_ONEFILE_BINARY", binary_filename);

+ setEnvironmentVariable("NUITKA_ONEFILE_ARGV0", argv[0]);
+
NUITKA_PRINT_TIMING("ONEFILE: Preparing forking of slave process.");

#if defined(_WIN32)
diff --git a/nuitka/code_generation/templates/CodeTemplatesConstants.py b/nuitka/code_generation/templates/CodeTemplatesConstants.py
index bc0a7e4a0..12188743a 100644
--- a/nuitka/code_generation/templates/CodeTemplatesConstants.py
+++ b/nuitka/code_generation/templates/CodeTemplatesConstants.py
@@ -134,6 +134,7 @@ static void _createGlobalConstants(PyThreadState *tstate) {
{(char *)"no_annotations", (char *)"boolean indicating --python-flag=no_annotations usage"},
{(char *)"module", (char *)"boolean indicating --module usage"},
{(char *)"main", (char *)"name of main module at runtime"},
+ {(char *)"onefile_argv0", (char *)"original argv[0] as received by the onefile binary, None otherwise"},
{0}
};

@@ -234,6 +235,9 @@ static void _createGlobalConstants(PyThreadState *tstate) {
#endif
PyStructSequence_SET_ITEM(Nuitka_dunder_compiled_value, 12, main_name);

+ PyObject *onefile_argv0 = getOnefileArgv0Object();
+ PyStructSequence_SET_ITEM(Nuitka_dunder_compiled_value, 13, onefile_argv0);
+
// Prevent users from creating the Nuitka version type object.
Nuitka_VersionInfoType.tp_init = NULL;
Nuitka_VersionInfoType.tp_new = NULL;
--
2.45.2

0 comments on commit 35d89b0

Please sign in to comment.