如何用PyInstaller打包依赖含非Python CLI可执行文件的Python应用?
问题分析与解决方案
问题根源:PyInstaller打包后会将应用解压到临时运行目录,原相对路径完全失效;同时PyInstaller默认不会自动收集依赖包(Package A)的package_data资源,导致CLI可执行文件未被打包进最终程序。
步骤1:修正Package A中CLI路径的获取逻辑
不能用硬编码的相对路径,改用Python官方资源访问API,确保正常运行和打包后都能定位到文件。
推荐方案(Python 3.9+):importlib.resources
替换Package A中调用CLI的代码:
from importlib.resources import files import subprocess # 获取CLI可执行文件的绝对路径 cli_exec_path = files("PackageA").joinpath("CLIExecutable", "executable.exe") # 执行CLI命令 subprocess.run([str(cli_exec_path)], check=True)
兼容旧版本方案:pkg_resources
import pkg_resources import subprocess cli_exec_path = pkg_resources.resource_filename("PackageA", "CLIExecutable/executable.exe") subprocess.run([cli_exec_path], check=True)
步骤2:让PyInstaller强制包含Package A的资源
打包Package B时,必须明确告知PyInstaller要打包Package A的CLI文件,有两种实现方式:
方式一:命令行参数--add-data
Windows系统:
pyinstaller --add-data "path/to/PackageA/CLIExecutable/executable.exe;PackageA/CLIExecutable/" your_package_b_entry.py
Linux/macOS系统:
pyinstaller --add-data "path/to/PackageA/CLIExecutable/executable.exe:PackageA/CLIExecutable/" your_package_b_entry.py
(注意路径分隔符:Windows用;,类Unix系统用:)
方式二:通过.spec文件配置
如果已生成.spec文件,修改Analysis模块的datas参数:
a = Analysis( ['your_package_b_entry.py'], datas=[('path/to/PackageA/CLIExecutable/executable.exe', 'PackageA/CLIExecutable')], # 保留其他原有参数 )
然后用.spec文件打包:
pyinstaller your_package_b_script.spec
步骤3:完善Package A的打包配置(可选)
在Package A根目录创建MANIFEST.in文件,确保资源被PyPI分发包和PyInstaller同时识别:
include CLIExecutable/*
配合原setup.py中的package_data和include_package_data=True配置,进一步避免资源遗漏。
内容的提问来源于stack exchange,提问作者Adib B
相关产品推荐
相关产品推荐

