用PyInstaller打包多个脚本

6 投票
1 回答
7755 浏览
提问于 2025-04-17 10:24

我正在使用PyInstaller把两个脚本打包成一个可执行文件,其中一个脚本会调用另一个。现在我遇到的问题是,我不知道怎么把这两个脚本打包在一起,同时又能让它们互相引用:

导致问题的代码是,其中一个脚本 script1.py 包含:

subprocess.call(['gksudo','python script2.py'])

当我正常运行这些脚本时,这个调用是没问题的,但一旦它们被PyInstaller打包后,我就不知道怎么让这个调用正常工作了。

1 个回答

2

我觉得pyinstaller自己处理这种打包方式有点困难,至少我没能成功配置。如果你的应用比较大,并且有一些地方需要调用

subprocess.Popen('python ' ... )

我最后让它工作的办法是:

  1. 把你的子进程调用修改为使用不同的python,比如 subprocess.call(['gksudo','./python script2.py'])。为入口点和其他脚本分别创建两个分析,比如:

    a1 - 分析script1.py

    a2 - 分析script2.py

  2. 只从入口点脚本创建exe文件:

    pyz = PYZ(a1.pure)
    exe = EXE(pyz,
      a1.scripts,
      exclude_binaries=1,
      name={name here},
      debug=False,
      strip=False,
      upx=True,
      console=1 )
    
  3. 从所有脚本中收集信息:

        coll = COLLECT( exe,
           a1.binaries,
           a1.zipfiles,
           a1.datas,
           a2.binaries,
           a2.zipfiles,
           a2.datas,
       python_tree, 
           *additional_trees,
           strip=False,
           upx=True,
           name={})
    
  4. 把python复制到你的分发包中,放在所有子进程调用中指定的位置,并添加pyinstaller没有找到的任何额外需求(我有一些像matplotlib、pylab等)

  5. 创建一个启动脚本,首先更改任何需要的环境变量,以指向你的包,然后启动应用。在我的情况下,需要从调用目录执行:

     export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
     export LD_RUN_PATH=`pwd`:$LD_RUN_PATH
    

这些步骤都是为了确保应用能在没有安装python的机器上运行,或者即使机器上有python,也能确保应用使用的是分发包中的所有库,而不是本地的库。如果你的目标机器上已经安装了python,我觉得这些步骤就不必要了,前面提到的前三个步骤就足够了。

撰写回答