blob: 35cdfc47e0e7cf86bc77347b6d6151ad227b4e53 [file] [log] [blame]
Brett Brotherton8c7c65e2025-03-12 20:56:07 -07001
2import os
Dan Willemsen707542f2018-11-29 21:39:59 -08003import runpy
Brett Brotherton8c7c65e2025-03-12 20:56:07 -07004import shutil
Dan Willemsen707542f2018-11-29 21:39:59 -08005import sys
Brett Brotherton8c7c65e2025-03-12 20:56:07 -07006import tempfile
7import zipfile
8
9from pathlib import PurePath
10
Dan Willemsen707542f2018-11-29 21:39:59 -080011
12sys.argv[0] = __loader__.archive
13
14# Set sys.executable to None. The real executable is available as
15# sys.argv[0], and too many things assume sys.executable is a regular Python
16# binary, which isn't available. By setting it to None we get clear errors
17# when people try to use it.
18sys.executable = None
19
Brett Brotherton8c7c65e2025-03-12 20:56:07 -070020# Extract the shared libraries from the zip file into a temporary directory.
21# This works around the limitations of dynamic linker. Some Python libraries
22# reference the .so files relatively and so extracting only the .so files
23# does not work, so we extract the entire parent directory of the .so files to a
24# tempdir and then add that to sys.path.
25tempdir = None
26with zipfile.ZipFile(__loader__.archive) as z:
27 # any root so files or root directories that contain so files will be
28 # extracted to the tempdir so the linker load them, this minimizes the
29 # number of files that need to be extracted to a tempdir
30 extract_paths = {}
31 for member in z.infolist():
32 if member.filename.endswith('.so'):
33 extract_paths[PurePath(member.filename).parts[0]] = member.filename
34 if extract_paths:
35 tempdir = tempfile.mkdtemp()
36 for member in z.infolist():
37 if not PurePath(member.filename).parts[0] in extract_paths.keys():
38 continue
39 if member.is_dir():
40 os.makedirs(os.path.join(tempdir, member.filename))
41 else:
42 z.extract(member, tempdir)
43 sys.path.insert(0, tempdir)
44try:
45 runpy._run_module_as_main("ENTRY_POINT", alter_argv=False)
46finally:
47 if tempdir is not None:
48 shutil.rmtree(tempdir)