Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.17.x] Fix mux operation with Nuitka 2.4 #190

Merged
merged 3 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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))
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 <git@xen0n.name>
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