我试图在PyInstaller分析阶段获得 git describe
的输出,并使其可用于Python运行时变量,以便为应用程序提供从构建环境派生并在运行时显示的修订字符串 .
为此,我假设PyInstaller钩子是最好的方法,因为它们允许在构建导入树时在钩子文件中执行任意Python代码 . 但是,我还没有找到一种方法将PyInstaller分析阶段的变量值传递给运行时变量,以便它可以由作为生成的 .exe
文件运行的应用程序显示 .
示例:钩子文件 hook-rev.py
,当遇到 import rev
时由PyInstaller分析机制导入:
import git
rev = git.Repo().git.describe()
print('got rev = {}'.format(rev))
mymodule.py
包含:
import rev
rev.py
包含:
global AppRev
try:
# Get the revision from the hook file
AppRev = rev
except:
print('rev is not defined')
运行PyInstaller:
pyinstaller --additional-hooks-dir=. mymodule.py
确认在PyInstaller分析阶段触发了钩子文件导入,并且当PyInstaller构建导入树时,print语句显示 git describe
的正确结果被分配给钩子文件范围内的变量 rev
. 但生成的 .exe
文件会产生:
rev is not defined
当然,鉴于代码示例,这是正确的,因为 rev
不在本地或其他可访问的命名空间中 . 我不知道钩子文件的命名空间是什么,因此 rev
变量是什么 .
通过添加此print语句
print('module name = {}'.format(__name__))
在钩子文件中 hook-rev.py
我看到PyInstaller的钩子导入机制将名称 __PyInstaller_hooks_0_rev
分配给导入的钩子模块 . 但是此导入仅在构建期间存在,因此尝试在 run.py
中在运行时访问 rev
变量为 __PyInstaller_hooks_0_rev.rev
失败,因为模块 __PyInstaller_hooks_0_rev
在运行时未知 .
是否有另一种方法可以在运行时和PyInstaller钩子导入处理之间桥接命名空间?
1 回答
作为参考,这是一种实现所需功能的方法 . 它不是一个理想的解决方案,因为它依赖于另外两个Python文件(钩子文件,PyInstaller和运行时之间共享的生成文件)来实现我希望只用钩子文件可能实现的目标 . 它还有一个缺点,即在开发环境中显示的应用程序修订版本反映了PyInstaller最后设置的修订版本 . 我不会将此标记为已接受的答案,除非很明显更简单的方法是不可能的 .
大纲是:
在应用程序中,使用
import rev
触发PyInstaller钩子机制,在分析阶段查找要导入的文件hook-rev.py
在
hook-rev.py
中构造修订字符串并写出一个Python文件,例如buildrev.py
包含对变量的修订字符串赋值在
rev.py
中使用import buildrev
并定义get_rev()
,返回buildrev.rev
在应用程序文件中,通过调用
rev.get_rev()
访问修订字符串实现此方案的文件如下所示 .
mymodule.py
(主要应用):rev.py
(定义get_rev()
,返回修订字符串):hook-rev.py
(PyInstaller在分析阶段导入的钩子文件生成buildrev.py
):在生成的文件
buildrev.py
中,修订字符串反映了PyInstaller导入树构建时的工作副本修订 . 当使用普通的Python解释器访问时,如在开发环境中的IDE中,该修订字符串仍然反映最后一次运行PyInstaller时工作空间的版本,这可能是不准确的 . VCS不应跟踪buildrev.py
.