如何将 PySide 正确安装到可重定位的 virtualenv 中?
How to properly install PySide into relocatable virtualenv?
我正在将 PySide 安装到 virtualenv 中:
sudo virtualenv --always-copy $VENV
source $VENV/bin/activate
sudo $VENV/bin/pip install pyside
sudo $VENV/bin/python $VENV/bin/pyside_postinstall.py -install
deactivate
virtualenv 运行良好,我可以 运行 我的 Python/PySide 脚本没有问题:
$VENV/bin/python $SCRIPT
现在,我使我的 virtualenv 可重定位:
virtualenv --relocatable $VENV
我动了:
mv $VENV $VENV_RELOCATED
...再次 运行 我的脚本:
source $VENV_RELOCATED/bin/activate
$VENV_RELOCATED/bin/python $SCRIPT
这一次,我遇到了一个错误:
Traceback (most recent call last):
File "script.py", line 1, in <module>
from PySide import QtCore, QtGui, QtUiTools
ImportError: dlopen(/absolute/path/to/relocated_venv/lib/python2.7/site-packages/PySide/QtCore.so, 2): Library not loaded: @rpath/libpyside-python2.7.1.2.dylib
Referenced from: /absolute/path/to/relocated_venv/lib/python2.7/site-packages/PySide/QtCore.so
Reason: image not found
脚本内容如下:
from PySide import QtCore, QtGui, QtUiTools
请注意:错误信息中打印两次的绝对路径是$VENV_RELOCATED
这一切都在 OS X 10.11.0 与 Python 2.7.10 和 PySide 1.2.2 上。
问题:如何将 PySide 正确安装到可重定位的 virtualenv 中?
事实证明,下一个 PySide 版本(发布时可能标记为“1.2.3”)修复了此问题:https://github.com/PySide/PySide/issues/129
但是,我还让 PySide 1.2.2 在 OS X 10.11 (El Capitan) 上的可重定位 virtualenv 中工作。为此,我修改了 $VIRTUALENV/bin/pyside_postinstall.py 脚本中的 localize_libpaths()
函数。
补丁详情:如果脚本执行时检测到virtualenv,将不会使用@rpath
。相反,它将使用 @executable_path
并从 virtualenv 中的 python 二进制文件进行相对搜索。由于 PySide 模块始终安装在 virtualenv 中的同一位置,我认为这应该适用于所有场景。
def localize_libpaths(libpath, local_libs, enc_path=None):
""" Set rpaths and install names to load local dynamic libs at run time
Use ``install_name_tool`` to set relative install names in `libpath` (as
named in `local_libs` to be relative to `enc_path`. The default for
`enc_path` is the directory containing `libpath`.
Parameters
----------
libpath : str
path to library for which to set install names and rpaths
local_libs : sequence of str
library (install) names that should be considered relative paths
enc_path : str, optional
path that does or will contain the `libpath` library, and to which the
`local_libs` are relative. Defaults to current directory containing
`libpath`.
"""
if enc_path is None:
enc_path = abspath(dirname(libpath))
install_names = osx_get_install_names(libpath)
need_rpath = False
for install_name in install_names:
if install_name[0] in '/@':
continue
if hasattr(sys, 'real_prefix'):
# virtualenv detected - use @executable_path
back_tick('install_name_tool -change %s @executable_path/../lib/python2.7/site-packages/PySide/%s %s' %
(install_name, install_name, libpath))
else:
# not a virtualenv - use @rpath
back_tick('install_name_tool -change %s @rpath/%s %s' %
(install_name, install_name, libpath))
need_rpath = True
if need_rpath and enc_path not in osx_get_rpaths(libpath):
back_tick('install_name_tool -add_rpath %s %s' %
(enc_path, libpath))
在 Windows 上,重新定位其中包含 PySide 的 virtualenv 没有问题。但是,对于 Linux 我还没有设法找到解决方案。我想等待 PySide 1.2.3 是去这里的方法。
我正在将 PySide 安装到 virtualenv 中:
sudo virtualenv --always-copy $VENV
source $VENV/bin/activate
sudo $VENV/bin/pip install pyside
sudo $VENV/bin/python $VENV/bin/pyside_postinstall.py -install
deactivate
virtualenv 运行良好,我可以 运行 我的 Python/PySide 脚本没有问题:
$VENV/bin/python $SCRIPT
现在,我使我的 virtualenv 可重定位:
virtualenv --relocatable $VENV
我动了:
mv $VENV $VENV_RELOCATED
...再次 运行 我的脚本:
source $VENV_RELOCATED/bin/activate
$VENV_RELOCATED/bin/python $SCRIPT
这一次,我遇到了一个错误:
Traceback (most recent call last):
File "script.py", line 1, in <module>
from PySide import QtCore, QtGui, QtUiTools
ImportError: dlopen(/absolute/path/to/relocated_venv/lib/python2.7/site-packages/PySide/QtCore.so, 2): Library not loaded: @rpath/libpyside-python2.7.1.2.dylib
Referenced from: /absolute/path/to/relocated_venv/lib/python2.7/site-packages/PySide/QtCore.so
Reason: image not found
脚本内容如下:
from PySide import QtCore, QtGui, QtUiTools
请注意:错误信息中打印两次的绝对路径是$VENV_RELOCATED
这一切都在 OS X 10.11.0 与 Python 2.7.10 和 PySide 1.2.2 上。
问题:如何将 PySide 正确安装到可重定位的 virtualenv 中?
事实证明,下一个 PySide 版本(发布时可能标记为“1.2.3”)修复了此问题:https://github.com/PySide/PySide/issues/129
但是,我还让 PySide 1.2.2 在 OS X 10.11 (El Capitan) 上的可重定位 virtualenv 中工作。为此,我修改了 $VIRTUALENV/bin/pyside_postinstall.py 脚本中的 localize_libpaths()
函数。
补丁详情:如果脚本执行时检测到virtualenv,将不会使用@rpath
。相反,它将使用 @executable_path
并从 virtualenv 中的 python 二进制文件进行相对搜索。由于 PySide 模块始终安装在 virtualenv 中的同一位置,我认为这应该适用于所有场景。
def localize_libpaths(libpath, local_libs, enc_path=None):
""" Set rpaths and install names to load local dynamic libs at run time
Use ``install_name_tool`` to set relative install names in `libpath` (as
named in `local_libs` to be relative to `enc_path`. The default for
`enc_path` is the directory containing `libpath`.
Parameters
----------
libpath : str
path to library for which to set install names and rpaths
local_libs : sequence of str
library (install) names that should be considered relative paths
enc_path : str, optional
path that does or will contain the `libpath` library, and to which the
`local_libs` are relative. Defaults to current directory containing
`libpath`.
"""
if enc_path is None:
enc_path = abspath(dirname(libpath))
install_names = osx_get_install_names(libpath)
need_rpath = False
for install_name in install_names:
if install_name[0] in '/@':
continue
if hasattr(sys, 'real_prefix'):
# virtualenv detected - use @executable_path
back_tick('install_name_tool -change %s @executable_path/../lib/python2.7/site-packages/PySide/%s %s' %
(install_name, install_name, libpath))
else:
# not a virtualenv - use @rpath
back_tick('install_name_tool -change %s @rpath/%s %s' %
(install_name, install_name, libpath))
need_rpath = True
if need_rpath and enc_path not in osx_get_rpaths(libpath):
back_tick('install_name_tool -add_rpath %s %s' %
(enc_path, libpath))
在 Windows 上,重新定位其中包含 PySide 的 virtualenv 没有问题。但是,对于 Linux 我还没有设法找到解决方案。我想等待 PySide 1.2.3 是去这里的方法。