aboutsummaryrefslogtreecommitdiffstats
path: root/setup.py
diff options
context:
space:
mode:
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py131
1 files changed, 110 insertions, 21 deletions
diff --git a/setup.py b/setup.py
index 5f5235da3..ccce48e9c 100644
--- a/setup.py
+++ b/setup.py
@@ -38,6 +38,7 @@
#############################################################################
from __future__ import print_function
+from distutils.version import LooseVersion
"""This is a distutils setup-script for the PySide2 project
@@ -131,7 +132,6 @@ from utils import memoize, has_option, get_python_dict
OPTION_SNAPSHOT_BUILD = has_option("snapshot-build")
script_dir = os.getcwd()
-
@memoize
def get_package_timestamp():
return int(time.time())
@@ -207,7 +207,7 @@ except ImportError:
pass
from qtinfo import QtInfo
-from utils import rmtree
+from utils import rmtree, detectClang
from utils import makefile
from utils import copyfile
from utils import copydir
@@ -279,8 +279,10 @@ OPTION_REUSE_BUILD = has_option("reuse-build")
OPTION_SKIP_CMAKE = has_option("skip-cmake")
OPTION_SKIP_MAKE_INSTALL = has_option("skip-make-install")
OPTION_SKIP_PACKAGING = has_option("skip-packaging")
+OPTION_MODULE_SUBSET = option_value("module-subset")
OPTION_RPATH_VALUES = option_value("rpath")
OPTION_QT_CONF_PREFIX = option_value("qt-conf-prefix")
+OPTION_QT_SRC = option_value("qt-src-dir")
OPTION_ICULIB = option_value("iculib-url") # Deprecated
OPTION_VERBOSE_BUILD = has_option("verbose-build")
OPTION_SANITIZE_ADDRESS = has_option("sanitize-address")
@@ -363,6 +365,9 @@ this_file = os.path.abspath(this_file)
if os.path.dirname(this_file):
os.chdir(os.path.dirname(this_file))
+def is_debug_python():
+ return getattr(sys, "gettotalrefcount", None) is not None
+
if OPTION_NOEXAMPLES:
# Remove pyside2-examples from submodules so they will not be included.
for idx, item in enumerate(submodules):
@@ -376,6 +381,8 @@ def prefix():
name += str(sys.version_info[0])
if OPTION_DEBUG:
name += 'd'
+ if is_debug_python():
+ name += 'p'
return name
# Initialize, pull and checkout submodules
@@ -444,10 +451,14 @@ def prepareBuild():
pkg_dir = os.path.join(script_dir, pkg)
os.makedirs(pkg_dir)
# locate Qt sources for the documentation
- qt_src_dir = qtinfo.src_dir
- if qt_src_dir:
- global qtSrcDir
- qtSrcDir = qt_src_dir
+ if OPTION_QT_SRC is None:
+ installPrefix = qtinfo.prefix_dir
+ if installPrefix:
+ global qtSrcDir
+ if installPrefix.endswith("qtbase"): # In-source, developer build
+ qtSrcDir = installPrefix
+ else: # SDK: Use 'Src' directory
+ qtSrcDir = os.path.join(os.path.dirname(installPrefix), 'Src', 'qtbase')
class pyside_install(_install):
def __init__(self, *args, **kwargs):
@@ -763,7 +774,20 @@ class pyside_build(_build):
qt_version = get_qt_version()
# Update the PATH environment variable
- update_env_path([py_scripts_dir, qt_dir])
+ additionalPaths = [py_scripts_dir, qt_dir]
+
+ # Add Clang to path for Windows. Revisit once Clang is bundled with Qt.
+ if sys.platform == "win32" and LooseVersion(self.qtinfo.version) >= LooseVersion("5.7.0"):
+ clangDir = detectClang()
+ if clangDir[0]:
+ clangBinDir = os.path.join(clangDir[0], 'bin')
+ if not clangBinDir in os.environ.get('PATH'):
+ log.info("Adding %s as detected by %s to PATH" % (clangBinDir, clangDir[1]))
+ additionalPaths.append(clangBinDir)
+ else:
+ log.error("Failed to detect Clang by checking LLVM_INSTALL_DIR, CLANG_INSTALL_DIR, llvm-config")
+
+ update_env_path(additionalPaths)
build_name = "py%s-qt%s-%s-%s" % \
(py_version, qt_version, platform.architecture()[0], build_type.lower())
@@ -800,6 +824,9 @@ class pyside_build(_build):
if OPTION_FINAL_INSTALL_PREFIX:
setuptools_install_prefix = OPTION_FINAL_INSTALL_PREFIX
+ # Save the shiboken build dir path for clang deployment purposes.
+ self.shiboken_build_dir = os.path.join(self.build_dir, "shiboken2")
+
log.info("=" * 30)
log.info("Package version: %s" % get_package_version())
log.info("Build type: %s" % self.build_type)
@@ -1007,9 +1034,20 @@ class pyside_build(_build):
cmake_cmd.append("-DPYTHON_EXECUTABLE=%s" % self.py_executable)
cmake_cmd.append("-DPYTHON_INCLUDE_DIR=%s" % self.py_include_dir)
cmake_cmd.append("-DPYTHON_LIBRARY=%s" % self.py_library)
+ if OPTION_MODULE_SUBSET:
+ moduleSubSet = ''
+ for m in OPTION_MODULE_SUBSET.split(','):
+ if m.startswith('Qt'):
+ m = m[2:]
+ if moduleSubSet:
+ moduleSubSet += ';'
+ moduleSubSet += m
+ cmake_cmd.append("-DMODULES=%s" % moduleSubSet)
# Add source location for generating documentation
- if qtSrcDir:
- cmake_cmd.append("-DQT_SRC_DIR=%s" % qtSrcDir)
+ cmake_src_dir = OPTION_QT_SRC if OPTION_QT_SRC else qtSrcDir
+ cmake_cmd.append("-DQT_SRC_DIR=%s" % cmake_src_dir)
+ log.info("Qt Source dir: %s" % cmake_src_dir)
+
if self.build_type.lower() == 'debug':
cmake_cmd.append("-DPYTHON_DEBUG_LIBRARY=%s" % self.py_library)
@@ -1240,12 +1278,10 @@ class pyside_build(_build):
"{pyside_package_dir}/PySide2/support",
vars=vars)
if not OPTION_NOEXAMPLES:
- # <sources>/pyside2-examples/examples/* -> <setup>/PySide2/examples
- folder = get_extension_folder('pyside2-examples')
- copydir(
- "{sources_dir}/%s/examples" % folder,
- "{pyside_package_dir}/PySide2/examples",
- force=False, vars=vars)
+ # examples/* -> <setup>/PySide2/examples
+ copydir(os.path.join(self.script_dir, "examples"),
+ "{pyside_package_dir}/PySide2/examples",
+ force=False, vars=vars)
# Re-generate examples Qt resource files for Python 3 compatibility
if sys.version_info[0] == 3:
examples_path = "{pyside_package_dir}/PySide2/examples".format(**vars)
@@ -1261,6 +1297,9 @@ class pyside_build(_build):
else:
self.prepare_standalone_package_linux(executables, vars)
+ # Copy over clang before rpath patching.
+ self.prepare_standalone_clang(is_win=False)
+
# Update rpath to $ORIGIN
if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
self.update_rpath("{pyside_package_dir}/PySide2".format(**vars), executables)
@@ -1519,12 +1558,10 @@ class pyside_build(_build):
vars=vars)
if not OPTION_NOEXAMPLES:
- # <sources>/pyside2-examples/examples/* -> <setup>/PySide2/examples
- folder = get_extension_folder('pyside2-examples')
- copydir(
- "{sources_dir}/%s/examples" % folder,
- "{pyside_package_dir}/PySide2/examples",
- force=False, vars=vars)
+ # examples/* -> <setup>/PySide2/examples
+ copydir(os.path.join(self.script_dir, "examples"),
+ "{pyside_package_dir}/PySide2/examples",
+ force=False, vars=vars)
# Re-generate examples Qt resource files for Python 3 compatibility
if sys.version_info[0] == 3:
examples_path = "{pyside_package_dir}/PySide2/examples".format(**vars)
@@ -1649,6 +1686,8 @@ class pyside_build(_build):
filter=[filter],
recursive=False, vars=vars)
+ self.prepare_standalone_clang(is_win=True)
+
# pdb files for libshiboken and libpyside
copydir(
"{build_dir}/shiboken2/libshiboken",
@@ -1661,6 +1700,56 @@ class pyside_build(_build):
filter=pdbs,
recursive=False, vars=vars)
+ def prepare_standalone_clang(self, is_win = False):
+ """ Copies the libclang library to the pyside package so that shiboken exceutable works. """
+ log.info('Finding path to the libclang shared library.')
+ cmake_cmd = [
+ OPTION_CMAKE,
+ "-L", # Lists variables
+ "-N", # Just inspects the cache (faster)
+ "--build", # Specifies the build dir
+ self.shiboken_build_dir
+ ]
+ out = run_process_output(cmake_cmd)
+ lines = [s.strip() for s in out]
+ pattern = re.compile(r"CLANG_LIBRARY:FILEPATH=(.+)$")
+
+ clang_lib_path = None
+ for line in lines:
+ match = pattern.search(line)
+ if match:
+ clang_lib_path = match.group(1)
+ break
+
+ if not clang_lib_path:
+ raise RuntimeError("Could not finding location of libclang library from CMake cache.")
+
+ if is_win:
+ # clang_lib_path points to the static import library (lib/libclang.lib), whereas we want
+ # to copy the shared library (bin/libclang.dll).
+ clang_lib_path = re.sub(r'lib/libclang.lib$', 'bin/libclang.dll', clang_lib_path)
+
+ # Path to directory containing clang.
+ clang_lib_dir = os.path.dirname(clang_lib_path)
+
+ # The name of the clang file found by CMake.
+ basename = os.path.basename(clang_lib_path)
+
+ # We want to copy the library and all the symlinks for now, thus the wildcard.
+ clang_filter = basename + "*"
+
+ # Destination is the package folder near the other extension modules.
+ destination_dir = "{}/PySide2".format(os.path.join(self.script_dir, 'pyside_package'))
+ if os.path.exists(clang_lib_path):
+ log.info('Copying libclang shared library to the pyside package.')
+
+ copydir(clang_lib_dir, destination_dir,
+ filter=[clang_filter],
+ recursive=False)
+ else:
+ raise RuntimeError("Error copying libclang library "
+ "from {} to {}. ".format(clang_lib_path, destination_dir))
+
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(