aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyside_postinstall.py170
-rw-r--r--setup.py68
-rw-r--r--utils.py10
3 files changed, 69 insertions, 179 deletions
diff --git a/pyside_postinstall.py b/pyside_postinstall.py
index 146d313b9..9230a55ad 100644
--- a/pyside_postinstall.py
+++ b/pyside_postinstall.py
@@ -1,9 +1,9 @@
#!/usr/bin/env python
# Postinstall script for PySide
#
-# Generates the qt.conf file
-#
-# This file is based on pywin32_postinstall.py file from pywin32 project
+# TODO:
+# This file can be removed after OSX support
+# is implemented in pyside_build.update_rpath()
import os, sys, traceback, shutil, fnmatch, stat
from os.path import dirname, abspath
@@ -11,25 +11,6 @@ from subprocess import Popen, PIPE
import re
-try:
- # When this script is run from inside the bdist_wininst installer,
- # file_created() and directory_created() are additional builtin
- # functions which write lines to Python23\pyside-install.log. This is
- # a list of actions for the uninstaller, the format is inspired by what
- # the Wise installer also creates.
- file_created
- is_bdist_wininst = True
-except NameError:
- is_bdist_wininst = False # we know what it is not - but not what it is :)
- def file_created(file):
- pass
-
-def install():
- if sys.platform == "win32":
- install_win32()
- else:
- install_posix()
-
def filter_match(name, patterns):
for pattern in patterns:
if pattern is None:
@@ -38,19 +19,6 @@ def filter_match(name, patterns):
return True
return False
-def set_exec(name):
- mode = os.stat(name).st_mode
- new_mode = mode
- if new_mode & stat.S_IRUSR:
- new_mode = new_mode | stat.S_IXUSR
- if new_mode & stat.S_IRGRP:
- new_mode = new_mode | stat.S_IXGRP
- if new_mode & stat.S_IROTH:
- new_mode = new_mode | stat.S_IXOTH
- if (mode != new_mode):
- print("Setting exec for '%s' (mode %o => %o)" % (name, mode, new_mode))
- os.chmod(name, new_mode)
-
def back_tick(cmd, ret_err=False):
""" Run command `cmd`, return stdout, or stdout, stderr if `ret_err`
@@ -152,7 +120,7 @@ def osx_get_rpaths(libpath):
return rpaths
-def localize_libpaths(libpath, local_libs, enc_path=None):
+def osx_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
@@ -185,7 +153,7 @@ def localize_libpaths(libpath, local_libs, enc_path=None):
(enc_path, libpath))
-def install_posix():
+def post_install_osx():
# Try to find PySide package
try:
import PySide
@@ -195,40 +163,17 @@ def install_posix():
pyside_path = os.path.abspath(os.path.dirname(PySide.__file__))
print("PySide package found in %s..." % pyside_path)
- executables = ['shiboken']
- if sys.platform.startswith('linux'):
- executables.append('patchelf')
- patchelf_path = os.path.join(pyside_path, "patchelf")
- from distutils.spawn import spawn
-
- def rpath_cmd(pyside_path, srcpath):
- cmd = [patchelf_path, '--set-rpath', pyside_path, srcpath]
- spawn(cmd, search_path=False, verbose=1)
-
- pyside_libs = [lib for lib in os.listdir(pyside_path) if filter_match(
- lib, ["Qt*.so", "phonon.so", "shiboken"])]
- elif sys.platform == 'darwin':
- pyside_libs = [lib for lib in os.listdir(pyside_path) if filter_match(
- lib, ["*.so", "*.dylib", "shiboken"])]
-
- def rpath_cmd(pyside_path, srcpath):
- localize_libpaths(srcpath, pyside_libs, pyside_path)
-
- else:
- raise RuntimeError('Not configured for platform ' +
- sys.platform)
-
- # Set exec mode on executables
- for executable in executables:
- execpath = os.path.join(pyside_path, executable)
- set_exec(execpath)
+ pyside_libs = [lib for lib in os.listdir(pyside_path) if filter_match(
+ lib, ["*.so", "*.dylib", "shiboken"])]
# Update rpath in PySide libs
for srcname in pyside_libs:
- if os.path.isdir(srcname):
- continue
srcpath = os.path.join(pyside_path, srcname)
- rpath_cmd(pyside_path, srcpath)
+ if os.path.isdir(srcpath):
+ continue
+ if not os.path.exists(srcpath):
+ continue
+ osx_localize_libpaths(srcpath, pyside_libs, pyside_path)
print("Patched rpath in %s to %s." % (srcpath, pyside_path))
# Check PySide installation status
@@ -240,93 +185,6 @@ def install_posix():
print("The PySide package not installed: %s" % traceback.print_exception(*sys.exc_info()))
-def install_win32():
- # Try to find PySide package
- try:
- from PySide import QtCore
- except ImportError:
- print("The PySide package not found: %s" % traceback.print_exception(*sys.exc_info()))
- return
- pyside_path = os.path.dirname(QtCore.__file__)
- pyside_path = pyside_path.replace("\\", "/")
- pyside_path = pyside_path.replace("lib/site-packages", "Lib/site-packages")
- print("PySide package found in %s..." % pyside_path)
-
- # Since version 1.2.0 there is no need to run post install procedure on win32
- from PySide import __version_info__ as pyside_version_info
- if pyside_version_info >= (1,2,0):
- return
-
- if is_bdist_wininst:
- # Run from inside the bdist_wininst installer
- import distutils.sysconfig
- exec_prefix = distutils.sysconfig.get_config_var("exec_prefix")
- else:
- # Run manually
- exec_prefix = os.path.dirname(sys.executable)
-
- # Generate qt.conf
- qtconf_path = os.path.join(exec_prefix, "qt.conf")
- print("Generating file %s..." % qtconf_path)
- f = open(qtconf_path, 'wt')
- file_created(qtconf_path)
- f.write("""[Paths]
-Prefix = %(pyside_prefix)s
-Binaries = %(pyside_prefix)s
-Plugins = %(pyside_prefix)s/plugins
-Translations = %(pyside_prefix)s/translations
-""" % { "pyside_prefix": pyside_path })
- print("The PySide extensions were successfully installed.")
-
- # Install OpenSSL libs
- for dll in ["libeay32.dll", "ssleay32.dll"]:
- dest_path = os.path.join(exec_prefix, dll)
- src_path = os.path.join(pyside_path, "openssl", dll)
- if not os.path.exists(dest_path) and os.path.exists(src_path):
- shutil.copy(src_path, dest_path)
- file_created(dest_path)
- print("Installed %s to %s." % (dll, exec_prefix))
-
-def uninstall():
- print("The PySide extensions were successfully uninstalled.")
-
-def usage():
- msg = \
-"""%s: A post-install script for the PySide extensions.
-
-This should be run automatically after installation, but if it fails you
-can run it again with a '-install' parameter, to ensure the environment
-is setup correctly.
-"""
- print(msg.strip() % os.path.basename(sys.argv[0]))
-
-# NOTE: If this script is run from inside the bdist_wininst created
-# binary installer or uninstaller, the command line args are either
-# '-install' or '-remove'.
-
-# Important: From inside the binary installer this script MUST NOT
-# call sys.exit() or raise SystemExit, otherwise not only this script
-# but also the installer will terminate! (Is there a way to prevent
-# this from the bdist_wininst C code?)
-
if __name__ == '__main__':
- if len(sys.argv)==1:
- usage()
- sys.exit(1)
-
- arg_index = 1
- while arg_index < len(sys.argv):
- arg = sys.argv[arg_index]
- if arg == "-install":
- install()
- elif arg == "-remove":
- # bdist_msi calls us before uninstall, so we can undo what we
- # previously did. Sadly, bdist_wininst calls us *after*, so
- # we can't do much at all.
- if not is_bdist_wininst:
- uninstall()
- else:
- print("Unknown option: %s" % arg)
- usage()
- sys.exit(0)
- arg_index += 1
+ if sys.platform == "darwin":
+ post_install_osx()
diff --git a/setup.py b/setup.py
index 942cf644a..442aaefb2 100644
--- a/setup.py
+++ b/setup.py
@@ -102,6 +102,7 @@ from utils import option_value
from utils import update_env_path
from utils import init_msvc_env
from utils import regenerate_qt_resources
+from utils import filter_match
# Declare options
OPTION_DEBUG = has_option("debug")
@@ -233,11 +234,13 @@ for pkg in ["pyside_package/PySide", "pyside_package/pysideuic"]:
pkg_dir = os.path.join(script_dir, pkg)
os.makedirs(pkg_dir)
+# TODO:
+# This class can be removed after OSX support
+# is implemented in pyside_build.update_rpath()
class pyside_install(_install):
def run(self):
_install.run(self)
- # Custom script we run at the end of installing - this is the same script
- # run by bdist_wininst
+ # Custom script we run at the end of installing
# If self.root has a value, it means we are being "installed" into
# some other directory than Python itself (eg, into a temp directory
# for bdist_wininst to use) - in which case we must *not* run our
@@ -250,7 +253,6 @@ class pyside_install(_install):
cmd = [
os.path.abspath(sys.executable),
filename,
- "-install"
]
run_process(cmd)
@@ -650,12 +652,8 @@ class pyside_build(_build):
return self.prepare_packages_posix(vars)
def prepare_packages_posix(self, vars):
+ executables = []
if sys.platform.startswith('linux'):
- # patchelf -> PySide/patchelf
- copyfile(
- "{script_dir}/patchelf",
- "{dist_dir}/PySide/patchelf",
- vars=vars)
so_ext = '.so'
so_star = so_ext + '.*'
elif sys.platform == 'darwin':
@@ -694,7 +692,7 @@ class pyside_build(_build):
"{dist_dir}/PySide/scripts/uic.py",
force=False, vars=vars)
# <install>/bin/* -> PySide/
- copydir(
+ executables.extend(copydir(
"{install_dir}/bin/",
"{dist_dir}/PySide",
filter=[
@@ -702,7 +700,7 @@ class pyside_build(_build):
"pyside-rcc",
"shiboken",
],
- recursive=False, vars=vars)
+ recursive=False, vars=vars))
# <install>/lib/lib* -> PySide/
copydir(
"{install_dir}/lib/",
@@ -740,7 +738,7 @@ class pyside_build(_build):
if sys.platform == 'darwin':
raise RuntimeError('--standalone not yet supported for OSX')
# <qt>/bin/* -> <setup>/PySide
- copydir("{qt_bin_dir}", "{dist_dir}/PySide",
+ executables.extend(copydir("{qt_bin_dir}", "{dist_dir}/PySide",
filter=[
"designer",
"linguist",
@@ -748,7 +746,7 @@ class pyside_build(_build):
"lupdate",
"lconvert",
],
- recursive=False, vars=vars)
+ recursive=False, vars=vars))
# <qt>/lib/* -> <setup>/PySide
copydir("{qt_lib_dir}", "{dist_dir}/PySide",
filter=[
@@ -769,6 +767,9 @@ class pyside_build(_build):
copydir("{qt_translations_dir}", "{dist_dir}/PySide/translations",
filter=["*.qm"],
vars=vars)
+ # Update rpath to $ORIGIN
+ if sys.platform.startswith('linux'):
+ self.update_rpath("{dist_dir}/PySide".format(**vars), executables)
def prepare_packages_win32(self, vars):
pdbs = ['*.pdb'] if self.debug or self.build_type == 'RelWithDebInfo' else []
@@ -923,6 +924,41 @@ class pyside_build(_build):
"{dist_dir}/PySide/pyside-python{py_version}{dbgPostfix}.pdb",
vars=vars)
+ def update_rpath(self, package_path, executables):
+ if sys.platform.startswith('linux'):
+ pyside_libs = [lib for lib in os.listdir(package_path) if filter_match(
+ lib, ["*.so", "*.so.*"])]
+
+ patchelf_path = os.path.join(self.script_dir, "patchelf")
+
+ def rpath_cmd(srcpath):
+ cmd = [patchelf_path, '--set-rpath', '$ORIGIN/', srcpath]
+ if run_process(cmd) != 0:
+ raise RuntimeError("Error patching rpath in " + srcpath)
+
+ # TODO: Add support for OSX platform
+ #elif sys.platform == 'darwin':
+ # pyside_libs = [lib for lib in os.listdir(package_path) if filter_match(
+ # lib, ["*.so", "*.dylib"])]
+ # def rpath_cmd(srcpath):
+ # utils.osx_localize_libpaths(srcpath, pyside_libs, None)
+
+ else:
+ raise RuntimeError('Not configured for platform ' +
+ sys.platform)
+
+ pyside_libs.extend(executables)
+
+ # Update rpath in PySide libs
+ for srcname in pyside_libs:
+ srcpath = os.path.join(package_path, srcname)
+ if os.path.isdir(srcpath):
+ continue
+ if not os.path.exists(srcpath):
+ continue
+ rpath_cmd(srcpath)
+ print("Patched rpath to '$ORIGIN/' in %s." % (srcpath))
+
try:
with open(os.path.join(script_dir, 'README.rst')) as f:
@@ -938,14 +974,6 @@ setup(
version = __version__,
description = ("Python bindings for the Qt cross-platform application and UI framework"),
long_description = README + "\n\n" + CHANGES,
- options = {
- "bdist_wininst": {
- "install_script": "pyside_postinstall.py",
- },
- "bdist_msi": {
- "install_script": "pyside_postinstall.py",
- },
- },
scripts = [
"pyside_postinstall.py"
],
diff --git a/utils.py b/utils.py
index bf93579a8..7b40bb2ac 100644
--- a/utils.py
+++ b/utils.py
@@ -233,6 +233,8 @@ def copyfile(src, dst, force=True, vars=None):
log.info("Copying file %s to %s." % (src, dst))
shutil.copy2(src, dst)
+
+ return dst
def makefile(dst, content=None, vars=None):
@@ -269,13 +271,14 @@ def copydir(src, dst, filter=None, ignore=None, force=True,
if not os.path.exists(src) and not force:
log.info("**Skiping copy tree %s to %s. Source does not exists. filter=%s. ignore=%s." % \
(src, dst, filter, ignore))
- return
+ return []
log.info("Copying tree %s to %s. filter=%s. ignore=%s." % \
(src, dst, filter, ignore))
names = os.listdir(src)
+ results = []
errors = []
for name in names:
srcname = os.path.join(src, name)
@@ -283,14 +286,14 @@ def copydir(src, dst, filter=None, ignore=None, force=True,
try:
if os.path.isdir(srcname):
if recursive:
- copydir(srcname, dstname, filter, ignore, force, recursive, vars)
+ results.extend(copydir(srcname, dstname, filter, ignore, force, recursive, vars))
else:
if (filter is not None and not filter_match(name, filter)) or \
(ignore is not None and filter_match(name, ignore)):
continue
if not os.path.exists(dst):
os.makedirs(dst)
- copyfile(srcname, dstname, True, vars)
+ results.append(copyfile(srcname, dstname, True, vars))
# catch the Error from the recursive copytree so that we can
# continue with other files
except shutil.Error as err:
@@ -308,6 +311,7 @@ def copydir(src, dst, filter=None, ignore=None, force=True,
errors.extend((src, dst, str(why)))
if errors:
raise EnvironmentError(errors)
+ return results
def rmtree(dirname):