ubuntu22 python2 pyinstaller 打包报错:'NoneType' object has no attribute 'groups'
前言
最近有个需求,需要在 ubnutu22 上使用 pyinstaller 打包一个python2 的文件。
中间遇到了一些问题:
- pip2 install pyinstaller 报错
解决方案:
pip2 install pyinstaller == 3.6
- python2 和 python3 的 pyinstaller 如何同时存在,我想把 python2 的 pyinstaller 命名为 pyinstaller2,
把 python3 的 pyinstaller 不重名。
# 如果安装了 python3 的 pyinstaller,需要先卸载
pip3 uninstall pyinstaller
# 1. 安装python2 的 pyinstaller
pip2 install pyinstaller == 3.6
# 2. 找到 pyinstaller 位置 (我的环境是在 /usr/local/bin/pyinstaller)
whereis pyinstaller
# 3. 重命名 python2 的 pyinstaller 为 pyinstaller2
cd /usr/local/bin/
mv pyinstaller pyinstaller2
# 4. 检查
pyinstaller2 --version
# 5. 重新安装 python3 的 pyinstaller
pip3 install pyinstaller
# 6. 检查python3 的 pyinstaller
pyinstaller --version
然后,使用命令,打包出现报错
pyinstaller2 -F tst.py -p /usr/lib/python2.7/dist-packages/
1463 INFO: Python library not in binary dependencies. Doing additional searching...
Traceback (most recent call last):
File "/usr/local/bin/pyinstaller2", line 8, in <module>
sys.exit(run())
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/__main__.py", line 114, in run
run_build(pyi_config, spec_file, **vars(args))
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/__main__.py", line 65, in run_build
PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/building/build_main.py", line 734, in main
build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/building/build_main.py", line 681, in build
exec(code, spec_namespace)
File "/mnt/wallE_code_u22/pytest/pythonApiTst/code_u22/christie3_ctl.spec", line 17, in <module>
noarchive=False)
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/building/build_main.py", line 244, in __init__
self.__postinit__()
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/building/datastruct.py", line 160, in __postinit__
self.assemble()
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/building/build_main.py", line 478, in assemble
self._check_python_library(self.binaries)
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/building/build_main.py", line 568, in _check_python_library
python_lib = bindepend.get_python_library_path()
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/depend/bindepend.py", line 915, in get_python_library_path
python_libname = findLibrary(name)
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/depend/bindepend.py", line 775, in findLibrary
utils.load_ldconfig_cache()
File "/usr/local/lib/python2.7/dist-packages/PyInstaller/depend/utils.py", line 400, in load_ldconfig_cache
path = m.groups()[-1]
AttributeError: 'NoneType' object has no attribute 'groups'
下面,将描述我的解决方案
正文
chatgpt 建议使用 sudo ldconfig 刷新共享库缓存,我试了但是还是报上面的错误。
后来 view /usr/local/lib/python2.7/dist-packages/PyInstaller/depend/utils.py 400 行,找到了报错的地方
try:
text = compat.exec_command(ldconfig, ldconfig_arg)
except ExecCommandFailed:
logger.warning("Failed to execute ldconfig. Disabling LD cache.")
LDCONFIG_CACHE = {}
return
text = text.strip().splitlines()[splitlines_count:]
LDCONFIG_CACHE = {}
for line in text:
# :fixme: this assumes libary names do not contain whitespace
m = pattern.match(line)
path = m.groups()[-1]
if is_freebsd or is_openbsd:
# Insert `.so` at the end of the lib's basename. soname
# and filename may have (different) trailing versions. We
# assume the `.so` in the filename to mark the end of the
# lib's basename.
bname = os.path.basename(path).split('.so', 1)[0]
name = 'lib' + m.group(1)
assert name.startswith(bname)
name = bname + '.so' + name[len(bname):]
else:
name = m.group(1)
# ldconfig may know about several versions of the same lib,
# e.g. differents arch, different libc, etc. Use the first
# entry.
if not name in LDCONFIG_CACHE:
LDCONFIG_CACHE[name] = path
这里path = m.groups()[-1]
的 m 是个 None 类型,然后 m的来源是 m = pattern.match(line)
, line 是获取共享库后逐行读取的字段。那就是 m = pattern.match(line)
出现了异常。
打印 m 报错 None 时 line 的值
,发现此时 line: 缓存生成方: ldconfig (Ubuntu GLIBC 2.35-0ubuntu3.6) stable release version 2.35
, 程序就是在解析这句时报错,原因是格式不匹配。
使用系统指令
sudo ldconfig -p
发现打印的信息最后一行就是:缓存生成方: ldconfig (Ubuntu GLIBC 2.35-0ubuntu3.6) stable release version 2.35
解决方案,修改 utils.py 中的处理过程,略过 m 为 None 的部分
LDCONFIG_CACHE = {}
for line in text:
# :fixme: this assumes libary names do not contain whitespace
m = pattern.match(line)
# brian add 2024-05-09
if m is None:
print(line)
continue
# brian add end
path = m.groups()[-1]
if is_freebsd or is_openbsd:
# Insert `.so` at the end of the lib's basename. soname
# and filename may have (different) trailing versions. We
# assume the `.so` in the filename to mark the end of the
# lib's basename.
bname = os.path.basename(path).split('.so', 1)[0]
name = 'lib' + m.group(1)
assert name.startswith(bname)
name = bname + '.so' + name[len(bname):]
else:
name = m.group(1)
# ldconfig may know about several versions of the same lib,
# e.g. differents arch, different libc, etc. Use the first
# entry.
if not name in LDCONFIG_CACHE:
LDCONFIG_CACHE[name] = path
添加了这个字段
# brian add 2024-05-09
if m is None:
print(line)
continue
# brian add end
果然python2 停止维护后,还需要手动修改bug,很难忘的过程,在此记录,以做参考。