如何使用GnuPGgpg可执行文件和依赖项冻结python应用PyInstaller

问题描述

使用PyInstaller构建应用程序时,如何包括import Link from 'next/link'; import useSWR from 'swr'; const Contests = (props) => { const url = '/api/VoterInfo'; const fetcher = (url) => fetch(url).then((r) => r.json()); const { data,error } = useSWR(url,fetcher); if (error) return ( <div className='alert alert-danger' role='alert'> <span className='sr-only'>Failed to load data!</span> </div> ); if (!data) return ( <div className='spinner-border spinner-border-lg text-danger' role='status' style={{ margin: '10rem',width: '20rem',height: '20rem' }} ></div> ); if (data && data !== null) { const { contests } = data.data; const primaryElections = []; const generalElections = []; const referendums = []; contests.map((contest) => { if (contest.type === 'Referendum') { referendums.push(contest); } else if (contest.type === 'General') { generalElections.push(contest); } else if (contest.type === 'Primary') { primaryElections.push(contest); } }); console.log(primaryElections,generalElections,referendums); return ( <div> <table className='table table-hover'> <caption>List of contests in your area</caption> {primaryElections.length > 0 && ( <> <thead style={{ fontFamily: 'Righteous,sans-serif' }}> <tr> <th scope='col' style={{ width: '10px' }}> # </th> <th scope='col'>Type</th> <th scope='col'>Office</th> <th scope='col'>dist Name</th> <th scope='col'>dist ID</th> <th scope='col'>dist Scope</th> </tr> </thead> <tbody> {primaryElections.map((election,idx) => ( <tr key={idx}> <td style={{ width: '10px' }}>{idx + 1}</td> <td>{election.type}</td> <td>{election.office}</td> <td>{election.district.name}</td> <td>{election.district.scope}</td> <td>{election.district.id}</td> </tr> ))} </tbody> </> )} {generalElections.length > 0 && ( <> <thead style={{ fontFamily: 'Righteous,sans-serif' }}> <tr> <th scope='col' style={{ width: '10px' }}> # </th> <th scope='col'>Type</th> <th scope='col'>Office</th> <th scope='col'>dist Name</th> <th scope='col'>dist ID</th> <th scope='col'>dist Scope</th> </tr> </thead> <tbody> {generalElections.map((election,idx) => ( <tr key={idx}> <td style={{ width: '10px' }}>{idx + 1}</td> <td>{election.type}</td> <td>{election.office}</td> <td>{election.district.name}</td> <td>{election.district.scope}</td> <td>{election.district.id}</td> </tr> ))} </tbody> </> )} {referendums.length > 0 && ( <> <thead style={{ fontFamily: 'Righteous,sans-serif' }}> <tr> <th scope='col' style={{ width: '10px' }}> # </th> <th scope='col'>Type</th> <th scope='col'>Title</th> <th scope='col'>Subtitle</th> <th scope='col'>Language</th> <th scope='col'>district</th> <th scope='col'>Scope</th> <th scope='col'>Open Civic Data ID</th> </tr> </thead> <tbody> {referendums.map((referendum,idx) => ( <tr key={idx}> <td style={{ width: '10px' }}>{idx + 1}</td> <td>{referendum.type}</td> <td>{referendum.referendumTitle}</td> <td>{referendum.referendumSubtitle}</td> <td> <Link href={`${referendum.referendumUrl}`}> <a>{referendum.referendumUrl}</a> </Link> </td> <td>{referendum.district.name}</td> <td>{referendum.district.scope}</td> <td>{referendum.district.id}</td> </tr> ))} </tbody> </> )} </table> </div> ); } }; export default Contests; (及其所有依赖项)?

我正在使用gpg将python应用程序发布为Linux,Windows和MacOS的独立可执行文件。我需要使用PyInstaller,所以我使用的是python-gnupg模块-基本上只是将它们封装到系统上本地安装的gpg二进制文件中。

因为我的应用程序被设计为“便携式”可执行文件(我使用gpg将其与PyInstaller解释程序和所有其他依赖项一起提供),所以我想包含python使用我的发行版,因此用户无需在计算机上安装它。

如何使用针对Linux,Windows和MacOS的gpggpg模块添加python-gnupg二进制文件及其所有依赖项?

解决方法

您可以通过添加gpg二进制文件及其所有依赖项using the Analysis.datas key来将GnuPG与PyInstaller构建的应用程序打包。

Windows

在Windows上,我可以通过反复试验来解决这个问题。首先,我只是在整个系统中搜索gpg.exe二进制文件。在Powershell中:

> Get-Command gpg
0.0.0.0    C:\Program Files\Git\usr\bin\gpg.exe
> 

然后我通过更改此部分将其添加到我的PyInstaller .spec文件中

a = Analysis(['..\\src\\main.py'],pathex=['.\\'],binaries=[],datas=[],hiddenimports=['pkg_resources.py2_warn','libusb1'],hookspath=[],runtime_hooks=[],excludes=[],win_no_prefer_redirects=False,win_private_assemblies=False,cipher=block_cipher,noarchive=False)

进入

a = Analysis(['..\\src\\main.py'],datas=
              [
               ('C:\\Program Files\\Git\\usr\\bin\\gpg.exe','.'),],noarchive=False)

完成上述更改后,我的应用会弹出一个警告错误,例如:

The code execution cannot proceed because msys-bz2-1.dll was not found. Reinstalling the program may fix this problem.

一个接一个,我一直在查找(如上所示在powershell中使用Get-Command)并添加它抱怨的.dll文件,直到我在上面的spec文件中的datas有以下内容有效:

             datas=
              [
               ( '..\\KEYS','.' ),('C:\\Program Files\\Git\\usr\\bin\\gpg.exe',('C:\\msys64\\usr\\bin\\msys-bz2-1.dll',('C:\\msys64\\usr\\bin\\msys-assuan-0.dll',('C:\\msys64\\usr\\bin\\msys-gcrypt-20.dll',('C:\\msys64\\usr\\bin\\msys-gpg-error-0.dll',('C:\\msys64\\usr\\bin\\msys-2.0.dll',('C:\\msys64\\usr\\bin\\msys-readline8.dll',('C:\\msys64\\usr\\bin\\msys-z.dll',('C:\\msys64\\usr\\bin\\msys-sqlite3-0.dll',('C:\\msys64\\usr\\bin\\msys-iconv-2.dll',('C:\\msys64\\usr\\bin\\msys-intl-8.dll',('C:\\msys64\\usr\\bin\\msys-ncursesw6.dll',

您可以在此处查看我的完整构建脚本和.spec文件:

MacOS

在MacOS中,我发现不必添加任何依赖关系,而只需添加可执行文件即可。

             datas=[ ('/usr/local/bin/gpg','.') ],

您可以在此处查看我的完整构建脚本和.spec文件:

Linux

实际上我没有使用PyInstaller为Linux构建发行版,因为我使用的是AppImage。

要查看我的Linux完整构建脚本,请参阅: