[英]Can PyInstaller pack shared object files into executable?
I've written a Python app which uses the tkinter module (among others) on Linux.我编写了一个 Python 应用程序,它在 Linux 上使用了 tkinter 模块(以及其他模块)。
Python(3.10) with tkinter support was compiled by myself in a custom location (~/local), as well as the non-python dependencies like tk/tcl, libfreetype2, libpng, etc.支持 tkinter 的 Python(3.10) 由我自己在自定义位置 (~/local) 以及非 Python 依赖项(如 tk/tcl、libfreetype2、libpng 等)编译。
I've then packaged the script with PyInstaller using the --one-file
option.然后,我使用
--one-file
选项将脚本与 PyInstaller 打包在一起。 The resulting executable works if I execute it myself.如果我自己执行生成的可执行文件,它就可以工作。
But copying it to another location and executing it as a different user leads to an ImportError: /home/*****/local/lib/libtcl8.6.so: cannot open shared object file: Permission denied
, because of course that folder is not readable by that user.但是将其复制到另一个位置并以其他用户身份执行会导致
ImportError: /home/*****/local/lib/libtcl8.6.so: cannot open shared object file: Permission denied
,因为当然该用户无法读取文件夹。
I've tried bundling the.so file with both the --add-data
and --add-binary
option of PyInstaller, but none of it works.我尝试将 .so 文件与 PyInstaller 的
--add-data
和--add-binary
选项捆绑在一起,但都不起作用。 Even if I copy the files manually, it's still looking in the custom path.即使我手动复制文件,它仍在查看自定义路径。
Is there a way to specify to PyInstaller to package the needed shared object files into the executable or at least change any absolute path into a relative one, so I can bundle the files manually?有没有办法将 PyInstaller 指定为 package 所需的共享 object 文件到可执行文件中,或者至少将任何绝对路径更改为相对路径,以便我可以手动捆绑文件?
You should have a.spec file created first time you have created an executable, Explicitly add all the files which need to be shipped with executable in the spec file data.您应该在第一次创建可执行文件时创建一个 .spec 文件,在规范文件数据中显式添加所有需要与可执行文件一起提供的文件。
https://pyinstaller.org/en/stable/spec-files.html https://pyinstaller.org/en/stable/spec-files.html
For example, add datafiles and add it to datas in spec file:例如,添加数据文件并将其添加到规范文件中的数据中:
data_files = [(os.path.join(some_path,some_file), '.'), ]
block_cipher = None
a = Analysis(['minimal.py'],
pathex=['/Developer/PItests/minimal'],
binaries=None,
datas=data_files,
hiddenimports=[],
hookspath=None,
runtime_hooks=None,
excludes=None,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,... )
coll = COLLECT(...)
Now to generate pyinstaller executable use this spec file.现在要生成 pyinstaller 可执行文件,请使用此规范文件。
pyinstaller somename.spec
Do note that in your script dont directly load the files shipped in executable using explict paths instead load in this way, since pyinstaller during runtime in other environments dont pick the embedded files through explict paths but store in its file system so this take care of it:请注意,在您的脚本中,不要使用显式路径直接加载可执行文件中提供的文件,而是以这种方式加载,因为 pyinstaller 在其他环境中的运行时不会通过显式路径选择嵌入文件,而是存储在其文件系统中,因此会处理它:
folder_path = getattr(sys, '_MEIPASS', some_path)
file_path = os.path.join(folder_path,some_file)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.