aboutsummaryrefslogtreecommitdiffstats
path: root/build_scripts/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'build_scripts/main.py')
-rw-r--r--build_scripts/main.py920
1 files changed, 413 insertions, 507 deletions
diff --git a/build_scripts/main.py b/build_scripts/main.py
index 5f536792a..796ea2040 100644
--- a/build_scripts/main.py
+++ b/build_scripts/main.py
@@ -41,10 +41,17 @@ from __future__ import print_function
from distutils.version import LooseVersion
import os
+import platform
+import re
+import sys
+from textwrap import dedent
import time
from .config import config
-from .utils import memoize, get_python_dict
-from .options import *
+from .utils import get_python_dict
+from .options import DistUtilsCommandMixin, OPTION
+from .wheel_utils import (get_package_version, get_qt_version,
+ get_package_timestamp, macos_plat_name,
+ macos_pyside_min_deployment_target)
setup_script_dir = os.getcwd()
build_scripts_dir = os.path.join(setup_script_dir, 'build_scripts')
@@ -52,35 +59,10 @@ setup_py_path = os.path.join(setup_script_dir, "setup.py")
start_time = int(time.time())
+
def elapsed():
return int(time.time()) - start_time
-@memoize
-def get_package_timestamp():
- """ In a Coin CI build the returned timestamp will be the
- Coin integration id timestamp. For regular builds it's
- just the current timestamp or a user provided one."""
- return OPTION_PACKAGE_TIMESTAMP if OPTION_PACKAGE_TIMESTAMP else start_time
-
-@memoize
-def get_package_version():
- """ Returns the version string for the PySide2 package. """
- pyside_version_py = os.path.join(
- setup_script_dir, "sources", "pyside2", "pyside_version.py")
- d = get_python_dict(pyside_version_py)
-
- final_version = "{}.{}.{}".format(
- d['major_version'], d['minor_version'], d['patch_version'])
- pre_release_version_type = d['pre_release_version_type']
- pre_release_version = d['pre_release_version']
- if pre_release_version and pre_release_version_type:
- final_version += pre_release_version_type + pre_release_version
-
- # Add the current timestamp to the version number, to suggest it
- # is a development snapshot build.
- if OPTION_SNAPSHOT_BUILD:
- final_version += ".dev{}".format(get_package_timestamp())
- return final_version
def get_setuptools_extension_modules():
# Setting py_limited_api on the extension is the "correct" thing
@@ -89,14 +71,163 @@ def get_setuptools_extension_modules():
# future.
extension_args = ('QtCore', [])
extension_kwargs = {}
- if OPTION_LIMITED_API:
+ if OPTION["LIMITED_API"] == 'yes':
extension_kwargs['py_limited_api'] = True
extension_modules = [Extension(*extension_args, **extension_kwargs)]
return extension_modules
-# Git submodules: ["submodule_name",
-# "location_relative_to_sources_folder"]
+def _get_make(platform_arch, build_type):
+ """Helper for retrieving the make command and CMake generator name"""
+ makespec = OPTION["MAKESPEC"]
+ if makespec == "make":
+ return ("make", "Unix Makefiles")
+ if makespec == "msvc":
+ nmake_path = find_executable("nmake")
+ if nmake_path is None or not os.path.exists(nmake_path):
+ log.info("nmake not found. Trying to initialize the MSVC env...")
+ init_msvc_env(platform_arch, build_type)
+ nmake_path = find_executable("nmake")
+ if not nmake_path or not os.path.exists(nmake_path):
+ raise DistutilsSetupError('"nmake" could not be found.')
+ if not OPTION["NO_JOM"]:
+ jom_path = find_executable("jom")
+ if jom_path:
+ log.info("jom was found in {}".format(jom_path))
+ return (jom_path, "NMake Makefiles JOM")
+ log.info("nmake was found in {}".format(nmake_path))
+ if OPTION["JOBS"]:
+ msg = "Option --jobs can only be used with 'jom' on Windows."
+ raise DistutilsSetupError(msg)
+ return (nmake_path, "NMake Makefiles")
+ if makespec == "mingw":
+ return ("mingw32-make", "mingw32-make")
+ if makespec == "ninja":
+ return ("ninja", "Ninja")
+ m = 'Invalid option --make-spec "{}".'.format(makespec)
+ raise DistutilsSetupError(m)
+
+
+def get_make(platform_arch, build_type):
+ """Retrieve the make command and CMake generator name"""
+ (make_path, make_generator) = _get_make(platform_arch, build_type)
+ if not os.path.isabs(make_path):
+ make_path = find_executable(make_path)
+ if not make_path or not os.path.exists(make_path):
+ raise DistutilsSetupError("You need the program '{}' on your system path to "
+ "compile PySide2.".format(make_path))
+ return (make_path, make_generator)
+
+
+def _get_py_library_win(build_type, py_version, py_prefix, py_libdir,
+ py_include_dir):
+ """Helper for finding the Python library on Windows"""
+ if py_include_dir is None or not os.path.exists(py_include_dir):
+ py_include_dir = os.path.join(py_prefix, "include")
+ if py_libdir is None or not os.path.exists(py_libdir):
+ # For virtual environments on Windows, the py_prefix will contain a
+ # path pointing to it, instead of the system Python installation path.
+ # Since INCLUDEPY contains a path to the system location, we use the
+ # same base directory to define the py_libdir variable.
+ py_libdir = os.path.join(os.path.dirname(py_include_dir), "libs")
+ if not os.path.isdir(py_libdir):
+ raise DistutilsSetupError("Failed to locate the 'libs' directory")
+ dbg_postfix = "_d" if build_type == "Debug" else ""
+ if OPTION["MAKESPEC"] == "mingw":
+ static_lib_name = "libpython{}{}.a".format(
+ py_version.replace(".", ""), dbg_postfix)
+ return os.path.join(py_libdir, static_lib_name)
+ v = py_version.replace(".", "")
+ python_lib_name = "python{}{}.lib".format(v, dbg_postfix)
+ return os.path.join(py_libdir, python_lib_name)
+
+
+def _get_py_library_unix(build_type, py_version, py_prefix, py_libdir,
+ py_include_dir):
+ """Helper for finding the Python library on UNIX"""
+ if py_libdir is None or not os.path.exists(py_libdir):
+ py_libdir = os.path.join(py_prefix, "lib")
+ if py_include_dir is None or not os.path.exists(py_include_dir):
+ dir = "include/python{}".format(py_version)
+ py_include_dir = os.path.join(py_prefix, dir)
+ dbg_postfix = "_d" if build_type == "Debug" else ""
+ lib_exts = ['.so']
+ if sys.platform == 'darwin':
+ lib_exts.append('.dylib')
+ if sys.version_info[0] > 2:
+ lib_suff = getattr(sys, 'abiflags', None)
+ else: # Python 2
+ lib_suff = ''
+ lib_exts.append('.so.1')
+ # Suffix for OpenSuSE 13.01
+ lib_exts.append('.so.1.0')
+ # static library as last gasp
+ lib_exts.append('.a')
+
+ if sys.version_info[0] == 2 and dbg_postfix:
+ # For Python2 add a duplicate set of extensions combined with the
+ # dbg_postfix, so we test for both the debug version of the lib
+ # and the normal one. This allows a debug PySide2 to be built with a
+ # non-debug Python.
+ lib_exts = [dbg_postfix + e for e in lib_exts] + lib_exts
+
+ libs_tried = []
+ for lib_ext in lib_exts:
+ lib_name = "libpython{}{}{}".format(py_version, lib_suff, lib_ext)
+ py_library = os.path.join(py_libdir, lib_name)
+ if os.path.exists(py_library):
+ return py_library
+ libs_tried.append(py_library)
+ # At least on macOS 10.11, the system Python 2.6 does not include a
+ # symlink to the framework file disguised as a .dylib file, thus finding
+ # the library would fail. Manually check if a framework file "Python"
+ # exists in the Python framework bundle.
+ if sys.platform == 'darwin' and sys.version_info[:2] == (2, 6):
+ # These manipulations essentially transform
+ # /System/Library/Frameworks/Python.framework/Versions/2.6/lib
+ # to
+ # /System/Library/Frameworks/Python.framework/Versions/2.6/Python
+ possible_framework_path = os.path.realpath(os.path.join(py_libdir, '..'))
+ possible_framework_version = os.path.basename(possible_framework_path)
+ possible_framework_library = os.path.join(possible_framework_path, 'Python')
+
+ if (possible_framework_version == '2.6'
+ and os.path.exists(possible_framework_library)):
+ return possible_framework_library
+ libs_tried.append(possible_framework_library)
+
+ # Try to find shared libraries which have a multi arch
+ # suffix.
+ py_multiarch = get_config_var("MULTIARCH")
+ if py_multiarch:
+ try_py_libdir = os.path.join(py_libdir, py_multiarch)
+ libs_tried = []
+ for lib_ext in lib_exts:
+ lib_name = "libpython{}{}{}".format(py_version, lib_suff, lib_ext)
+ py_library = os.path.join(try_py_libdir, lib_name)
+ if os.path.exists(py_library):
+ return py_library
+ libs_tried.append(py_library)
+
+ m = "Failed to locate the Python library with {}".format(", ".join(libs_tried))
+ raise DistutilsSetupError(m)
+
+
+def get_py_library(build_type, py_version, py_prefix, py_libdir, py_include_dir):
+ """Find the Python library"""
+ if sys.platform == "win32":
+ py_library = _get_py_library_win(build_type, py_version, py_prefix,
+ py_libdir, py_include_dir)
+ else:
+ py_library = _get_py_library_unix(build_type, py_version, py_prefix,
+ py_libdir, py_include_dir)
+ if py_library.endswith('.a'):
+ # Python was compiled as a static library
+ log.error("Failed to locate a dynamic Python library, using {}".format(py_library))
+ return py_library
+
+
+# Git submodules: ["submodule_name", "location_relative_to_sources_folder"]
submodules = [["pyside2-tools"]]
try:
@@ -105,9 +236,12 @@ except ImportError:
from ez_setup import use_setuptools
use_setuptools()
-import sys
-import platform
-import re
+from setuptools import Extension
+from setuptools.command.install import install as _install
+from setuptools.command.install_lib import install_lib as _install_lib
+from setuptools.command.bdist_egg import bdist_egg as _bdist_egg
+from setuptools.command.develop import develop as _develop
+from setuptools.command.build_py import build_py as _build_py
import distutils.log as log
from distutils.errors import DistutilsSetupError
@@ -117,13 +251,7 @@ from distutils.spawn import find_executable
from distutils.command.build import build as _build
from distutils.command.build_ext import build_ext as _build_ext
from distutils.util import get_platform
-
-from setuptools import Extension
-from setuptools.command.install import install as _install
-from setuptools.command.install_lib import install_lib as _install_lib
-from setuptools.command.bdist_egg import bdist_egg as _bdist_egg
-from setuptools.command.develop import develop as _develop
-from setuptools.command.build_py import build_py as _build_py
+from distutils.cmd import Command
from .qtinfo import QtInfo
from .utils import rmtree, detect_clang, copyfile, copydir, run_process_output, run_process
@@ -134,8 +262,6 @@ from .platforms.unix import prepare_packages_posix
from .platforms.windows_desktop import prepare_packages_win32
from .wheel_override import wheel_module_exists, get_bdist_wheel_override
-from textwrap import dedent
-
def check_allowed_python_version():
"""
@@ -151,7 +277,7 @@ def check_allowed_python_version():
if found:
major = int(found.group(1))
minor = int(found.group(2))
- supported.append( (major, minor) )
+ supported.append((major, minor))
this_py = sys.version_info[:2]
if this_py not in supported:
print("Unsupported python version detected. Only these python versions are supported: {}"
@@ -161,70 +287,11 @@ def check_allowed_python_version():
qt_src_dir = ''
-if OPTION_QT_VERSION is None:
- OPTION_QT_VERSION = "5"
-if OPTION_QMAKE is None:
- OPTION_QMAKE = find_executable("qmake-qt5")
-if OPTION_QMAKE is None:
- OPTION_QMAKE = find_executable("qmake")
-
-# make qtinfo.py independent of relative paths.
-if OPTION_QMAKE is not None and os.path.exists(OPTION_QMAKE):
- OPTION_QMAKE = os.path.abspath(OPTION_QMAKE)
-if OPTION_CMAKE is not None and os.path.exists(OPTION_CMAKE):
- OPTION_CMAKE = os.path.abspath(OPTION_CMAKE)
-
-QMAKE_COMMAND = None
-# Checking whether qmake executable exists
-if OPTION_QMAKE is not None and os.path.exists(OPTION_QMAKE):
- # Looking whether qmake path is a link and whether the link exists
- if os.path.islink(OPTION_QMAKE) and os.path.lexists(OPTION_QMAKE):
- # Set -qt=X here.
- if "qtchooser" in os.readlink(OPTION_QMAKE):
- QMAKE_COMMAND = [OPTION_QMAKE, "-qt={}".format(OPTION_QT_VERSION)]
-if not QMAKE_COMMAND:
- QMAKE_COMMAND = [OPTION_QMAKE]
-
-if len(QMAKE_COMMAND) == 0 or QMAKE_COMMAND[0] is None:
- print("qmake could not be found.")
- sys.exit(1)
-if not os.path.exists(QMAKE_COMMAND[0]):
- print("'{}' does not exist.".format(QMAKE_COMMAND[0]))
- sys.exit(1)
-if OPTION_CMAKE is None:
- OPTION_CMAKE = find_executable("cmake")
-
-if OPTION_CMAKE is None:
- print("cmake could not be found.")
- sys.exit(1)
-if not os.path.exists(OPTION_CMAKE):
- print("'{}' does not exist.".format(OPTION_CMAKE))
- sys.exit(1)
-
-# First element is default
-available_mkspecs = ["msvc", "mingw", "ninja"] if sys.platform == "win32" else ["make", "ninja"]
-
-if OPTION_MAKESPEC is None:
- OPTION_MAKESPEC = available_mkspecs[0]
-
-if not OPTION_MAKESPEC in available_mkspecs:
- print('Invalid option --make-spec "{}". Available values are {}'.format(
- OPTION_MAKESPEC, available_mkspecs))
- sys.exit(1)
-
-if OPTION_JOBS:
- if sys.platform == 'win32' and OPTION_NO_JOM:
- print("Option --jobs can only be used with jom on Windows.")
- sys.exit(1)
- else:
- if not OPTION_JOBS.startswith('-j'):
- OPTION_JOBS = '-j' + OPTION_JOBS
-else:
- OPTION_JOBS = ''
def is_debug_python():
return getattr(sys, "gettotalrefcount", None) is not None
+
# Return a prefix suitable for the _install/_build directory
def prefix():
virtual_env_name = os.environ.get('VIRTUAL_ENV', None)
@@ -233,14 +300,15 @@ def prefix():
else:
name = "pyside"
name += str(sys.version_info[0])
- if OPTION_DEBUG:
+ if OPTION["DEBUG"]:
name += "d"
if is_debug_python():
name += "p"
- if OPTION_LIMITED_API == "yes" and sys.version_info[0] == 3:
+ if OPTION["LIMITED_API"] == "yes" and sys.version_info[0] == 3:
name += "a"
return name
+
# Initialize, pull and checkout submodules
def prepare_sub_modules():
print("Initializing submodules for PySide2 version: {}".format(
@@ -263,13 +331,11 @@ def prepare_sub_modules():
if need_init_sub_modules:
git_update_cmd = ["git", "submodule", "update", "--init"]
if run_process(git_update_cmd) != 0:
- m = ("Failed to initialize the git submodules: "
- "update --init failed")
+ m = "Failed to initialize the git submodules: update --init failed"
raise DistutilsSetupError(m)
git_pull_cmd = ["git", "submodule", "foreach", "git", "fetch", "--all"]
if run_process(git_pull_cmd) != 0:
- m = ("Failed to initialize the git submodules: "
- "git fetch --all failed")
+ m = "Failed to initialize the git submodules: git fetch --all failed"
raise DistutilsSetupError(m)
else:
print("All submodules present.")
@@ -279,28 +345,10 @@ def prepare_sub_modules():
m = "Failed to checkout the correct git submodules SHA1s."
raise DistutilsSetupError(m)
-# Single global instance of QtInfo to be used later in multiple code
-# paths.
-qtinfo = QtInfo(QMAKE_COMMAND)
-
-def get_qt_version():
- qt_version = qtinfo.version
-
- if not qt_version:
- log.error("Failed to query the Qt version with qmake {0}".format(qtinfo.qmake_command))
- sys.exit(1)
-
- if LooseVersion(qtinfo.version) < LooseVersion("5.7"):
- log.error("Incompatible Qt version detected: {}. "
- "A Qt version >= 5.7 is required.".format(qt_version))
- sys.exit(1)
-
- return qt_version
-
def prepare_build():
- if (os.path.isdir(".git") and not OPTION_IGNOREGIT and
- not OPTION_ONLYPACKAGE and not OPTION_REUSE_BUILD):
+ if (os.path.isdir(".git") and not OPTION["IGNOREGIT"] and not OPTION["ONLYPACKAGE"]
+ and not OPTION["REUSE_BUILD"]):
prepare_sub_modules()
# Clean up temp build folder.
for n in ["build"]:
@@ -314,22 +362,26 @@ def prepare_build():
print('ignored error: {}'.format(e))
# locate Qt sources for the documentation
- if OPTION_QT_SRC is None:
- install_prefix = qtinfo.prefix_dir
+ if OPTION["QT_SRC"] is None:
+ install_prefix = QtInfo().prefix_dir
if install_prefix:
global qt_src_dir
# In-source, developer build
if install_prefix.endswith("qtbase"):
qt_src_dir = install_prefix
- else: # SDK: Use 'Src' directory
- qt_src_dir = os.path.join(os.path.dirname(install_prefix),
- 'Src', 'qtbase')
+ else: # SDK: Use 'Src' directory
+ qt_src_dir = os.path.join(os.path.dirname(install_prefix), 'Src', 'qtbase')
+
+
+class PysideInstall(_install, DistUtilsCommandMixin):
+
+ user_options = _install.user_options + DistUtilsCommandMixin.mixin_user_options
-class PysideInstall(_install):
def __init__(self, *args, **kwargs):
_install.__init__(self, *args, **kwargs)
+ DistUtilsCommandMixin.__init__(self)
- def initialize_options (self):
+ def initialize_options(self):
_install.initialize_options(self)
if sys.platform == 'darwin':
@@ -346,9 +398,14 @@ class PysideInstall(_install):
# similar cases.
self.warn_dir = False
+ def finalize_options(self):
+ DistUtilsCommandMixin.mixin_finalize_options(self)
+ _install.finalize_options(self)
+
def run(self):
_install.run(self)
- print('*** Install completed ({}s)'.format(elapsed()))
+ print('--- Install completed ({}s)'.format(elapsed()))
+
class PysideDevelop(_develop):
@@ -359,6 +416,7 @@ class PysideDevelop(_develop):
self.run_command("build")
_develop.run(self)
+
class PysideBdistEgg(_bdist_egg):
def __init__(self, *args, **kwargs):
@@ -368,6 +426,7 @@ class PysideBdistEgg(_bdist_egg):
self.run_command("build")
_bdist_egg.run(self)
+
class PysideBuildExt(_build_ext):
def __init__(self, *args, **kwargs):
@@ -399,23 +458,26 @@ class PysideInstallLib(_install_lib):
if os.path.isdir(self.build_dir):
# Using our own copydir makes sure to preserve symlinks.
- outfiles = copydir(os.path.abspath(self.build_dir),
- os.path.abspath(self.install_dir))
+ outfiles = copydir(os.path.abspath(self.build_dir), os.path.abspath(self.install_dir))
else:
- self.warn("'{}' does not exist -- "
- "no Python modules to install".format(self.build_dir))
+ self.warn("'{}' does not exist -- no Python modules to install".format(self.build_dir))
return
return outfiles
-class PysideBuild(_build):
+
+class PysideBuild(_build, DistUtilsCommandMixin):
+
+ user_options = _build.user_options + DistUtilsCommandMixin.mixin_user_options
def __init__(self, *args, **kwargs):
_build.__init__(self, *args, **kwargs)
+ DistUtilsCommandMixin.__init__(self)
def finalize_options(self):
os_name_backup = os.name
+ DistUtilsCommandMixin.mixin_finalize_options(self)
if sys.platform == 'darwin':
- self.plat_name = PysideBuild.macos_plat_name()
+ self.plat_name = macos_plat_name()
# This is a hack to circumvent the dubious check in
# distutils.commands.build -> finalize_options, which only
# allows setting the plat_name for windows NT.
@@ -434,7 +496,6 @@ class PysideBuild(_build):
_build.initialize_options(self)
self.make_path = None
self.make_generator = None
- self.debug = False
self.script_dir = None
self.sources_dir = None
self.build_dir = None
@@ -454,62 +515,15 @@ class PysideBuild(_build):
log.info("Python architecture is {}".format(platform_arch))
self.py_arch = platform_arch[:-3]
- build_type = "Debug" if OPTION_DEBUG else "Release"
- if OPTION_RELWITHDEBINFO:
+ build_type = "Debug" if OPTION["DEBUG"] else "Release"
+ if OPTION["RELWITHDEBINFO"]:
build_type = 'RelWithDebInfo'
# Check env
make_path = None
make_generator = None
- if not OPTION_ONLYPACKAGE:
- if OPTION_MAKESPEC == "make":
- make_name = "make"
- make_generator = "Unix Makefiles"
- elif OPTION_MAKESPEC == "msvc":
- nmake_path = find_executable("nmake")
- if nmake_path is None or not os.path.exists(nmake_path):
- log.info("nmake not found. "
- "Trying to initialize the MSVC env...")
- init_msvc_env(platform_arch, build_type)
- nmake_path = find_executable("nmake")
- assert(nmake_path is not None and
- os.path.exists(nmake_path))
- jom_path = None if OPTION_NO_JOM else find_executable("jom")
- if jom_path is not None and os.path.exists(jom_path):
- log.info("jom was found in {}".format(jom_path))
- make_name = "jom"
- make_generator = "NMake Makefiles JOM"
- else:
- log.info("nmake was found in {}".format(nmake_path))
- make_name = "nmake"
- make_generator = "NMake Makefiles"
- if OPTION_JOBS:
- msg = "Option --jobs can only be used with 'jom' on Windows."
- raise DistutilsSetupError(msg)
- elif OPTION_MAKESPEC == "mingw":
- make_name = "mingw32-make"
- make_generator = "MinGW Makefiles"
- elif OPTION_MAKESPEC == "ninja":
- make_name = "ninja"
- make_generator = "Ninja"
- else:
- raise DistutilsSetupError(
- "Invalid option --make-spec.")
- make_path = find_executable(make_name)
- if make_path is None or not os.path.exists(make_path):
- raise DistutilsSetupError("You need the program '{}' on your "
- "system path to compile PySide2.".format(make_name))
-
- if OPTION_CMAKE is None or not os.path.exists(OPTION_CMAKE):
- raise DistutilsSetupError(
- "Failed to find cmake."
- " Please specify the path to cmake with "
- "--cmake parameter.")
-
- if OPTION_QMAKE is None or not os.path.exists(OPTION_QMAKE):
- raise DistutilsSetupError(
- "Failed to find qmake."
- " Please specify the path to qmake with --qmake parameter.")
+ if not OPTION["ONLYPACKAGE"]:
+ (make_path, make_generator) = get_make(platform_arch, build_type)
# Prepare parameters
py_executable = sys.executable
@@ -525,116 +539,9 @@ class PysideBuild(_build):
else:
py_scripts_dir = os.path.join(py_prefix, "bin")
self.py_scripts_dir = py_scripts_dir
- if py_libdir is None or not os.path.exists(py_libdir):
- if sys.platform == "win32":
- py_libdir = os.path.join(py_prefix, "libs")
- else:
- py_libdir = os.path.join(py_prefix, "lib")
- if py_include_dir is None or not os.path.exists(py_include_dir):
- if sys.platform == "win32":
- py_include_dir = os.path.join(py_prefix, "include")
- else:
- py_include_dir = os.path.join(py_prefix,
- "include/python{}".format(py_version))
- dbg_postfix = ""
- if build_type == "Debug":
- dbg_postfix = "_d"
- if sys.platform == "win32":
- if OPTION_MAKESPEC == "mingw":
- static_lib_name = "libpython{}{}.a".format(
- py_version.replace(".", ""), dbg_postfix)
- py_library = os.path.join(py_libdir, static_lib_name)
- else:
- python_lib_name = "python{}{}.lib".format(
- py_version.replace(".", ""), dbg_postfix)
- py_library = os.path.join(py_libdir, python_lib_name)
- else:
- lib_exts = ['.so']
- if sys.platform == 'darwin':
- lib_exts.append('.dylib')
- if sys.version_info[0] > 2:
- lib_suff = getattr(sys, 'abiflags', None)
- else: # Python 2
- lib_suff = ''
- lib_exts.append('.so.1')
- # Suffix for OpenSuSE 13.01
- lib_exts.append('.so.1.0')
- # static library as last gasp
- lib_exts.append('.a')
-
- if sys.version_info[0] == 2 and dbg_postfix:
- # For Python2 add a duplicate set of extensions
- # combined with the dbg_postfix, so we test for both the
- # debug version of the lib and the normal one.
- # This allows a debug PySide2 to be built with a
- # non-debug Python.
- lib_exts = [dbg_postfix + e for e in lib_exts] + lib_exts
-
- python_library_found = False
- libs_tried = []
- for lib_ext in lib_exts:
- lib_name = "libpython{}{}{}".format(py_version, lib_suff,
- lib_ext)
- py_library = os.path.join(py_libdir, lib_name)
- if os.path.exists(py_library):
- python_library_found = True
- break
- libs_tried.append(py_library)
- else:
- # At least on macOS 10.11, the system Python 2.6 does
- # not include a symlink to the framework file disguised
- # as a .dylib file, thus finding the library would
- # fail.
- # Manually check if a framework file "Python" exists in
- # the Python framework bundle.
- if sys.platform == 'darwin' and sys.version_info[:2] == (2, 6):
- # These manipulations essentially transform
- # /System/Library/Frameworks/Python.framework/Versions/2.6/lib
- # to
- # /System/Library/Frameworks/Python.framework/Versions/2.6/Python
- possible_framework_path = os.path.realpath(
- os.path.join(py_libdir, '..'))
- possible_framework_version = os.path.basename(
- possible_framework_path)
- possible_framework_library = os.path.join(
- possible_framework_path, 'Python')
-
- if (possible_framework_version == '2.6' and
- os.path.exists(possible_framework_library)):
- py_library = possible_framework_library
- python_library_found = True
- else:
- libs_tried.append(possible_framework_library)
-
- # Try to find shared libraries which have a multi arch
- # suffix.
- if not python_library_found:
- py_multiarch = get_config_var("MULTIARCH")
- if py_multiarch and not python_library_found:
- try_py_libdir = os.path.join(py_libdir, py_multiarch)
- libs_tried = []
- for lib_ext in lib_exts:
- lib_name = "libpython{}{}{}".format(
- py_version, lib_suff, lib_ext)
- py_library = os.path.join(try_py_libdir, lib_name)
- if os.path.exists(py_library):
- py_libdir = try_py_libdir
- python_library_found = True
- break
- libs_tried.append(py_library)
-
- if not python_library_found:
- raise DistutilsSetupError(
- "Failed to locate the Python library with {}".format(
- ", ".join(libs_tried)))
-
- if py_library.endswith('.a'):
- # Python was compiled as a static library
- log.error("Failed to locate a dynamic Python library, "
- "using {}".format(py_library))
-
- self.qtinfo = qtinfo
- qt_dir = os.path.dirname(OPTION_QMAKE)
+
+ self.qtinfo = QtInfo()
+ qt_dir = os.path.dirname(OPTION["QMAKE"])
qt_version = get_qt_version()
# Update the PATH environment variable
@@ -642,14 +549,14 @@ class PysideBuild(_build):
# 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")):
+ if (sys.platform == "win32"
+ and LooseVersion(self.qtinfo.version) >= LooseVersion("5.7.0")):
clang_dir = detect_clang()
if clang_dir[0]:
clangBinDir = os.path.join(clang_dir[0], 'bin')
- if not clangBinDir in os.environ.get('PATH'):
- log.info("Adding {} as detected by {} to PATH".format(
- clangBinDir, clang_dir[1]))
+ if clangBinDir not in os.environ.get('PATH'):
+ log.info("Adding {} as detected by {} to PATH".format(clangBinDir,
+ clang_dir[1]))
additional_paths.append(clangBinDir)
else:
raise DistutilsSetupError("Failed to detect Clang when checking "
@@ -659,22 +566,20 @@ class PysideBuild(_build):
# Used for test blacklists and registry test.
self.build_classifiers = "py{}-qt{}-{}-{}".format(py_version, qt_version,
- platform.architecture()[0], build_type.lower())
- if OPTION_SHORTER_PATHS:
+ platform.architecture()[0],
+ build_type.lower())
+ if OPTION["SHORTER_PATHS"]:
build_name = "p{}".format(py_version)
else:
build_name = self.build_classifiers
script_dir = setup_script_dir
sources_dir = os.path.join(script_dir, "sources")
- build_dir = os.path.join(script_dir, prefix() + "_build",
- "{}".format(build_name))
- install_dir = os.path.join(script_dir, prefix() + "_install",
- "{}".format(build_name))
+ build_dir = os.path.join(script_dir, prefix() + "_build", "{}".format(build_name))
+ install_dir = os.path.join(script_dir, prefix() + "_install", "{}".format(build_name))
self.make_path = make_path
self.make_generator = make_generator
- self.debug = OPTION_DEBUG
self.script_dir = script_dir
self.st_build_dir = os.path.join(self.script_dir, self.build_lib)
self.sources_dir = sources_dir
@@ -682,11 +587,12 @@ class PysideBuild(_build):
self.install_dir = install_dir
self.py_executable = py_executable
self.py_include_dir = py_include_dir
- self.py_library = py_library
+ self.py_library = get_py_library(build_type, py_version, py_prefix,
+ py_libdir, py_include_dir)
self.py_version = py_version
self.build_type = build_type
self.site_packages_dir = get_python_lib(1, 0, prefix=install_dir)
- self.build_tests = OPTION_BUILDTESTS
+ self.build_tests = OPTION["BUILDTESTS"]
# Save the shiboken build dir path for clang deployment
# purposes.
@@ -705,13 +611,13 @@ class PysideBuild(_build):
log.info("Creating install folder {}...".format(self.install_dir))
os.makedirs(self.install_dir)
- if (not OPTION_ONLYPACKAGE
+ if (not OPTION["ONLYPACKAGE"]
and not config.is_internal_shiboken_generator_build_and_part_of_top_level_all()):
# Build extensions
for ext in config.get_buildable_extensions():
self.build_extension(ext)
- if OPTION_BUILDTESTS:
+ if OPTION["BUILDTESTS"]:
# we record the latest successful build and note the
# build directory for supporting the tests.
timestamp = time.strftime('%Y-%m-%d_%H%M%S')
@@ -724,7 +630,7 @@ class PysideBuild(_build):
print(self.build_classifiers, file=f)
log.info("Created {}".format(build_history))
- if not OPTION_SKIP_PACKAGING:
+ if not OPTION["SKIP_PACKAGING"]:
# Build patchelf if needed
self.build_patchelf()
@@ -735,27 +641,27 @@ class PysideBuild(_build):
_build.run(self)
else:
log.info("Skipped preparing and building packages.")
- print('*** Build completed ({}s)'.format(elapsed()))
+ print('--- Build completed ({}s)'.format(elapsed()))
def log_pre_build_info(self):
if config.is_internal_shiboken_generator_build_and_part_of_top_level_all():
return
setuptools_install_prefix = get_python_lib(1)
- if OPTION_FINAL_INSTALL_PREFIX:
- setuptools_install_prefix = OPTION_FINAL_INSTALL_PREFIX
+ if OPTION["FINAL_INSTALL_PREFIX"]:
+ setuptools_install_prefix = OPTION["FINAL_INSTALL_PREFIX"]
log.info("=" * 30)
log.info("Package version: {}".format(get_package_version()))
- log.info("Build type: {}".format(self.build_type))
+ log.info("Build type: {}".format(self.build_type))
log.info("Build tests: {}".format(self.build_tests))
log.info("-" * 3)
- log.info("Make path: {}".format(self.make_path))
+ log.info("Make path: {}".format(self.make_path))
log.info("Make generator: {}".format(self.make_generator))
- log.info("Make jobs: {}".format(OPTION_JOBS))
+ log.info("Make jobs: {}".format(OPTION["JOBS"]))
log.info("-" * 3)
- log.info("setup.py directory: {}".format(self.script_dir))
+ log.info("setup.py directory: {}".format(self.script_dir))
log.info("Build scripts directory: {}".format(build_scripts_dir))
- log.info("Sources directory: {}".format(self.sources_dir))
+ log.info("Sources directory: {}".format(self.sources_dir))
log.info(dedent("""
Building {st_package_name} will create and touch directories
in the following order:
@@ -765,9 +671,9 @@ class PysideBuild(_build):
setuptools install directory
(usually path-installed-python/lib/python*/site-packages/*)
""").format(st_package_name=config.package_name()))
- log.info("make build directory: {}".format(self.build_dir))
+ log.info("make build directory: {}".format(self.build_dir))
log.info("make install directory: {}".format(self.install_dir))
- log.info("setuptools build directory: {}".format(self.st_build_dir))
+ log.info("setuptools build directory: {}".format(self.st_build_dir))
log.info("setuptools install directory: {}".format(setuptools_install_prefix))
log.info(dedent("""
make-installed site-packages directory: {}
@@ -777,109 +683,39 @@ class PysideBuild(_build):
self.site_packages_dir))
log.info("-" * 3)
log.info("Python executable: {}".format(self.py_executable))
- log.info("Python includes: {}".format(self.py_include_dir))
- log.info("Python library: {}".format(self.py_library))
- log.info("Python prefix: {}".format(self.py_prefix))
- log.info("Python scripts: {}".format(self.py_scripts_dir))
+ log.info("Python includes: {}".format(self.py_include_dir))
+ log.info("Python library: {}".format(self.py_library))
+ log.info("Python prefix: {}".format(self.py_prefix))
+ log.info("Python scripts: {}".format(self.py_scripts_dir))
log.info("-" * 3)
- log.info("Qt qmake: {}".format(self.qtinfo.qmake_command))
+ log.info("Qt qmake: {}".format(self.qtinfo.qmake_command))
log.info("Qt version: {}".format(self.qtinfo.version))
- log.info("Qt bins: {}".format(self.qtinfo.bins_dir))
- log.info("Qt docs: {}".format(self.qtinfo.docs_dir))
+ log.info("Qt bins: {}".format(self.qtinfo.bins_dir))
+ log.info("Qt docs: {}".format(self.qtinfo.docs_dir))
log.info("Qt plugins: {}".format(self.qtinfo.plugins_dir))
log.info("-" * 3)
if sys.platform == 'win32':
- log.info("OpenSSL dll directory: {}".format(OPTION_OPENSSL))
+ log.info("OpenSSL dll directory: {}".format(OPTION["OPENSSL"]))
if sys.platform == 'darwin':
pyside_macos_deployment_target = (
- PysideBuild.macos_pyside_min_deployment_target()
+ macos_pyside_min_deployment_target()
)
log.info("MACOSX_DEPLOYMENT_TARGET set to: {}".format(
pyside_macos_deployment_target))
log.info("=" * 30)
- @staticmethod
- def macos_qt_min_deployment_target():
- target = qtinfo.macos_min_deployment_target
-
- if not target:
- raise DistutilsSetupError("Failed to query for Qt's "
- "QMAKE_MACOSX_DEPLOYMENT_TARGET.")
- return target
-
- @staticmethod
- @memoize
- def macos_pyside_min_deployment_target():
- """
- Compute and validate PySide2 MACOSX_DEPLOYMENT_TARGET value.
- Candidate sources that are considered:
- - setup.py provided value
- - maximum value between minimum deployment target of the
- Python interpreter and the minimum deployment target of
- the Qt libraries.
- If setup.py value is provided, that takes precedence.
- Otherwise use the maximum of the above mentioned two values.
- """
- python_target = get_config_var('MACOSX_DEPLOYMENT_TARGET') or None
- qt_target = PysideBuild.macos_qt_min_deployment_target()
- setup_target = OPTION_MACOS_DEPLOYMENT_TARGET
-
- qt_target_split = [int(x) for x in qt_target.split('.')]
- if python_target:
- python_target_split = [int(x) for x in python_target.split('.')]
- if setup_target:
- setup_target_split = [int(x) for x in setup_target.split('.')]
-
- message = ("Can't set MACOSX_DEPLOYMENT_TARGET value to {} because "
- "{} was built with minimum deployment target set to {}.")
- # setup.py provided OPTION_MACOS_DEPLOYMENT_TARGET value takes
- # precedence.
- if setup_target:
- if python_target and setup_target_split < python_target_split:
- raise DistutilsSetupError(message.format(setup_target,
- "Python", python_target))
- if setup_target_split < qt_target_split:
- raise DistutilsSetupError(message.format(setup_target,
- "Qt", qt_target))
- # All checks clear, use setup.py provided value.
- return setup_target
-
- # Setup.py value not provided,
- # use same value as provided by Qt.
- if python_target:
- maximum_target = '.'.join([str(e) for e in max(python_target_split,
- qt_target_split)])
- else:
- maximum_target = qt_target
- return maximum_target
-
- @staticmethod
- @memoize
- def macos_plat_name():
- deployment_target = PysideBuild.macos_pyside_min_deployment_target()
- # Example triple "macosx-10.12-x86_64".
- plat = get_platform().split("-")
- plat_name = "{}-{}-{}".format(plat[0], deployment_target, plat[2])
- return plat_name
-
def build_patchelf(self):
if not sys.platform.startswith('linux'):
return
self._patchelf_path = find_executable('patchelf')
if self._patchelf_path:
if not os.path.isabs(self._patchelf_path):
- self._patchelf_path = os.path.join(os.getcwd(),
- self._patchelf_path)
+ self._patchelf_path = os.path.join(os.getcwd(), self._patchelf_path)
log.info("Using {} ...".format(self._patchelf_path))
return
log.info("Building patchelf...")
module_src_dir = os.path.join(self.sources_dir, "patchelf")
- build_cmd = [
- "g++",
- "{}/patchelf.cc".format(module_src_dir),
- "-o",
- "patchelf",
- ]
+ build_cmd = ["g++", "{}/patchelf.cc".format(module_src_dir), "-o", "patchelf"]
if run_process(build_cmd) != 0:
raise DistutilsSetupError("Error building patchelf")
self._patchelf_path = os.path.join(self.script_dir, "patchelf")
@@ -891,38 +727,33 @@ class PysideBuild(_build):
# Prepare folders
os.chdir(self.build_dir)
- module_build_dir = os.path.join(self.build_dir, extension)
- skipflag_file = module_build_dir + '-skip'
+ module_build_dir = os.path.join(self.build_dir, extension)
+ skipflag_file = "{} -skip".format(module_build_dir)
if os.path.exists(skipflag_file):
- log.info("Skipping {} because {} exists".format(extension,
- skipflag_file))
+ log.info("Skipping {} because {} exists".format(extension, skipflag_file))
return
module_build_exists = os.path.exists(module_build_dir)
if module_build_exists:
- if not OPTION_REUSE_BUILD:
- log.info("Deleting module build folder {}...".format(
- module_build_dir))
+ if not OPTION["REUSE_BUILD"]:
+ log.info("Deleting module build folder {}...".format(module_build_dir))
try:
rmtree(module_build_dir)
except Exception as e:
- print('***** problem removing "{}"'.format(
- module_build_dir))
+ print('***** problem removing "{}"'.format(module_build_dir))
print('ignored error: {}'.format(e))
else:
- log.info("Reusing module build folder {}...".format(
- module_build_dir))
+ log.info("Reusing module build folder {}...".format(module_build_dir))
if not os.path.exists(module_build_dir):
- log.info("Creating module build folder {}...".format(
- module_build_dir))
+ log.info("Creating module build folder {}...".format(module_build_dir))
os.makedirs(module_build_dir)
os.chdir(module_build_dir)
module_src_dir = os.path.join(self.sources_dir, extension)
# Build module
- cmake_cmd = [OPTION_CMAKE]
- if OPTION_QUIET:
+ cmake_cmd = [OPTION["CMAKE"]]
+ if OPTION["QUIET"]:
# Pass a special custom option, to allow printing a lot less information when doing
# a quiet build.
cmake_cmd.append('-DQUIET_BUILD=1')
@@ -944,27 +775,27 @@ class PysideBuild(_build):
cmake_cmd.append("-DPYTHON_LIBRARY={}".format(self.py_library))
# If a custom shiboken cmake config directory path was provided, pass it to CMake.
- if OPTION_SHIBOKEN_CONFIG_DIR and config.is_internal_pyside_build():
- if os.path.exists(OPTION_SHIBOKEN_CONFIG_DIR):
+ if OPTION["SHIBOKEN_CONFIG_DIR"] and config.is_internal_pyside_build():
+ if os.path.exists(OPTION["SHIBOKEN_CONFIG_DIR"]):
log.info("Using custom provided shiboken2 installation: {}"
- .format(OPTION_SHIBOKEN_CONFIG_DIR))
- cmake_cmd.append("-DShiboken2_DIR={}".format(OPTION_SHIBOKEN_CONFIG_DIR))
+ .format(OPTION["SHIBOKEN_CONFIG_DIR"]))
+ cmake_cmd.append("-DShiboken2_DIR={}".format(OPTION["SHIBOKEN_CONFIG_DIR"]))
else:
log.info("Custom provided shiboken2 installation not found. Path given: {}"
- .format(OPTION_SHIBOKEN_CONFIG_DIR))
+ .format(OPTION["SHIBOKEN_CONFIG_DIR"]))
- if OPTION_MODULE_SUBSET:
+ if OPTION["MODULE_SUBSET"]:
module_sub_set = ''
- for m in OPTION_MODULE_SUBSET.split(','):
+ for m in OPTION["MODULE_SUBSET"].split(','):
if m.startswith('Qt'):
m = m[2:]
if module_sub_set:
module_sub_set += ';'
module_sub_set += m
cmake_cmd.append("-DMODULES={}".format(module_sub_set))
- if OPTION_SKIP_MODULES:
+ if OPTION["SKIP_MODULES"]:
skip_modules = ''
- for m in OPTION_SKIP_MODULES.split(','):
+ for m in OPTION["SKIP_MODULES"].split(','):
if m.startswith('Qt'):
m = m[2:]
if skip_modules:
@@ -972,7 +803,7 @@ class PysideBuild(_build):
skip_modules += m
cmake_cmd.append("-DSKIP_MODULES={}".format(skip_modules))
# Add source location for generating documentation
- cmake_src_dir = OPTION_QT_SRC if OPTION_QT_SRC else qt_src_dir
+ cmake_src_dir = OPTION["QT_SRC"] if OPTION["QT_SRC"] else qt_src_dir
cmake_cmd.append("-DQT_SRC_DIR={}".format(cmake_src_dir))
log.info("Qt Source dir: {}".format(cmake_src_dir))
@@ -980,34 +811,33 @@ class PysideBuild(_build):
cmake_cmd.append("-DPYTHON_DEBUG_LIBRARY={}".format(
self.py_library))
- if OPTION_LIMITED_API == "yes":
+ if OPTION["LIMITED_API"] == "yes":
cmake_cmd.append("-DFORCE_LIMITED_API=yes")
- elif OPTION_LIMITED_API == "no":
+ elif OPTION["LIMITED_API"] == "no":
cmake_cmd.append("-DFORCE_LIMITED_API=no")
- elif not OPTION_LIMITED_API:
+ elif not OPTION["LIMITED_API"]:
pass
else:
raise DistutilsSetupError("option limited-api must be 'yes' or 'no' "
"(default yes if applicable, i.e. python version >= 3.5)")
- if OPTION_VERBOSE_BUILD:
+ if OPTION["VERBOSE_BUILD"]:
cmake_cmd.append("-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON")
- if OPTION_SANITIZE_ADDRESS:
+ if OPTION["SANITIZE_ADDRESS"]:
# Some simple sanity checking. Only use at your own risk.
- if (sys.platform.startswith('linux') or
- sys.platform.startswith('darwin')):
+ if (sys.platform.startswith('linux')
+ or sys.platform.startswith('darwin')):
cmake_cmd.append("-DSANITIZE_ADDRESS=ON")
else:
- raise DistutilsSetupError("Address sanitizer can only be used "
- "on Linux and macOS.")
+ raise DistutilsSetupError("Address sanitizer can only be used on Linux and macOS.")
if extension.lower() == "pyside2":
pyside_qt_conf_prefix = ''
- if OPTION_QT_CONF_PREFIX:
- pyside_qt_conf_prefix = OPTION_QT_CONF_PREFIX
+ if OPTION["QT_CONF_PREFIX"]:
+ pyside_qt_conf_prefix = OPTION["QT_CONF_PREFIX"]
else:
- if OPTION_STANDALONE:
+ if OPTION["STANDALONE"]:
pyside_qt_conf_prefix = '"Qt"'
if sys.platform == 'win32':
pyside_qt_conf_prefix = '"."'
@@ -1017,17 +847,15 @@ class PysideBuild(_build):
# Pass package version to CMake, so this string can be
# embedded into _config.py file.
package_version = get_package_version()
- cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_VERSION={}".format(
- package_version))
+ cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_VERSION={}".format(package_version))
# In case if this is a snapshot build, also pass the
# timestamp as a separate value, because it is the only
# version component that is actually generated by setup.py.
timestamp = ''
- if OPTION_SNAPSHOT_BUILD:
+ if OPTION["SNAPSHOT_BUILD"]:
timestamp = get_package_timestamp()
- cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_TIMESTAMP={}".format(
- timestamp))
+ cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_TIMESTAMP={}".format(timestamp))
if extension.lower() in ["shiboken2", "pyside2-tools"]:
cmake_cmd.append("-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=yes")
@@ -1035,12 +863,11 @@ class PysideBuild(_build):
cmake_cmd.append("-DUSE_PYTHON_VERSION=3.3")
if sys.platform == 'darwin':
- if OPTION_MACOS_ARCH:
+ if OPTION["MACOS_ARCH"]:
# also tell cmake which architecture to use
- cmake_cmd.append("-DCMAKE_OSX_ARCHITECTURES:STRING={}".format(
- OPTION_MACOS_ARCH))
+ cmake_cmd.append("-DCMAKE_OSX_ARCHITECTURES:STRING={}".format(OPTION["MACOS_ARCH"]))
- if OPTION_MACOS_USE_LIBCPP:
+ if OPTION["MACOS_USE_LIBCPP"]:
# Explicitly link the libc++ standard library (useful
# for macOS deployment targets lower than 10.9).
# This is not on by default, because most libraries and
@@ -1051,12 +878,12 @@ class PysideBuild(_build):
# option is a no-op in those cases.
cmake_cmd.append("-DOSX_USE_LIBCPP=ON")
- if OPTION_MACOS_SYSROOT:
+ if OPTION["MACOS_SYSROOT"]:
cmake_cmd.append("-DCMAKE_OSX_SYSROOT={}".format(
- OPTION_MACOS_SYSROOT))
+ OPTION["MACOS_SYSROOT"]))
else:
- latest_sdk_path = run_process_output(['xcrun',
- '--sdk', 'macosx', '--show-sdk-path'])
+ latest_sdk_path = run_process_output(['xcrun', '--sdk', 'macosx',
+ '--show-sdk-path'])
if latest_sdk_path:
latest_sdk_path = latest_sdk_path[0]
cmake_cmd.append("-DCMAKE_OSX_SYSROOT={}".format(
@@ -1070,30 +897,40 @@ class PysideBuild(_build):
# interpreter sysconfig value.
# Doing so could break the detected clang include paths
# for example.
- deployment_target = \
- PysideBuild.macos_pyside_min_deployment_target()
- cmake_cmd.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(
- deployment_target))
+ deployment_target = macos_pyside_min_deployment_target()
+ cmake_cmd.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target))
os.environ['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
+ elif sys.platform == 'win32':
+ # Prevent cmake from auto-detecting clang if it is in path.
+ cmake_cmd.append("-DCMAKE_C_COMPILER=cl.exe")
+ cmake_cmd.append("-DCMAKE_CXX_COMPILER=cl.exe")
+
+ if OPTION["DOC_BUILD_ONLINE"]:
+ log.info("Output format will be HTML")
+ cmake_cmd.append("-DDOC_OUTPUT_FORMAT=html")
+ else:
+ log.info("Output format will be qthelp")
+ cmake_cmd.append("-DDOC_OUTPUT_FORMAT=qthelp")
+
+ # Build the whole documentation (rst + API) by default
+ cmake_cmd.append("-DFULLDOCSBUILD=1")
- if not OPTION_SKIP_CMAKE:
- log.info("Configuring module {} ({})...".format(extension,
- module_src_dir))
+ if not OPTION["SKIP_CMAKE"]:
+ log.info("Configuring module {} ({})...".format(extension, module_src_dir))
if run_process(cmake_cmd) != 0:
- raise DistutilsSetupError("Error configuring {}".format(
- extension))
+ raise DistutilsSetupError("Error configuring {}".format(extension))
else:
log.info("Reusing old configuration for module {} ({})...".format(
extension, module_src_dir))
- log.info("Compiling module {}...".format(extension))
+ log.info("-- Compiling module {}...".format(extension))
cmd_make = [self.make_path]
- if OPTION_JOBS:
- cmd_make.append(OPTION_JOBS)
+ if OPTION["JOBS"]:
+ cmd_make.append(OPTION["JOBS"])
if run_process(cmd_make) != 0:
raise DistutilsSetupError("Error compiling {}".format(extension))
- if not OPTION_SKIP_DOCS:
+ if not OPTION["SKIP_DOCS"]:
if extension.lower() == "shiboken2":
try:
# Check if sphinx is installed to proceed.
@@ -1101,24 +938,21 @@ class PysideBuild(_build):
log.info("Generating Shiboken documentation")
if run_process([self.make_path, "doc"]) != 0:
- raise DistutilsSetupError(
- "Error generating documentation for {}".format(
- extension))
+ raise DistutilsSetupError("Error generating documentation "
+ "for {}".format(extension))
except ImportError:
log.info("Sphinx not found, skipping documentation build")
else:
log.info("Skipped documentation generation")
-
- if not OPTION_SKIP_MAKE_INSTALL:
+ if not OPTION["SKIP_MAKE_INSTALL"]:
log.info("Installing module {}...".format(extension))
# Need to wait a second, so installed file timestamps are
# older than build file timestamps.
# See https://gitlab.kitware.com/cmake/cmake/issues/16155
# for issue details.
if sys.platform == 'darwin':
- log.info("Waiting 1 second, to ensure installation is "
- "successful...")
+ log.info("Waiting 1 second, to ensure installation is successful...")
time.sleep(1)
# ninja: error: unknown target 'install/fast'
target = 'install/fast' if self.make_generator != 'Ninja' else 'install'
@@ -1149,7 +983,7 @@ class PysideBuild(_build):
"st_build_dir": self.st_build_dir,
"cmake_package_name": config.package_name(),
"st_package_name": config.package_name(),
- "ssl_libs_dir": OPTION_OPENSSL,
+ "ssl_libs_dir": OPTION["OPENSSL"],
"py_version": self.py_version,
"qt_version": self.qtinfo.version,
"qt_bin_dir": self.qtinfo.bins_dir,
@@ -1171,7 +1005,7 @@ class PysideBuild(_build):
os.chdir(self.script_dir)
if sys.platform == "win32":
- vars['dbg_postfix'] = OPTION_DEBUG and "_d" or ""
+ vars['dbg_postfix'] = OPTION["DEBUG"] and "_d" or ""
return prepare_packages_win32(self, vars)
else:
return prepare_packages_posix(self, vars)
@@ -1195,8 +1029,9 @@ class PysideBuild(_build):
return temp_config
def is_webengine_built(self, built_modules):
- return ('WebEngineWidgets' in built_modules or 'WebEngineCore' in built_modules
- or 'WebEngine' in built_modules)
+ return ('WebEngineWidgets' in built_modules
+ or 'WebEngineCore' in built_modules
+ or 'WebEngine' in built_modules)
def prepare_standalone_clang(self, is_win=False):
"""
@@ -1205,7 +1040,7 @@ class PysideBuild(_build):
"""
log.info('Finding path to the libclang shared library.')
cmake_cmd = [
- OPTION_CMAKE,
+ OPTION["CMAKE"],
"-L", # Lists variables
"-N", # Just inspects the cache (faster)
"--build", # Specifies the build dir
@@ -1274,8 +1109,7 @@ class PysideBuild(_build):
make_writable_by_owner=True)
else:
raise RuntimeError("Error copying libclang library "
- "from {} to {}. ".format(
- clang_lib_path, destination_dir))
+ "from {} to {}. ".format(clang_lib_path, destination_dir))
def update_rpath(self, package_path, executables):
if sys.platform.startswith('linux'):
@@ -1286,15 +1120,15 @@ class PysideBuild(_build):
final_rpath = ''
# Command line rpath option takes precedence over
# automatically added one.
- if OPTION_RPATH_VALUES:
- final_rpath = OPTION_RPATH_VALUES
+ if OPTION["RPATH_VALUES"]:
+ final_rpath = OPTION["RPATH_VALUES"]
else:
# Add rpath values pointing to $ORIGIN and the
# installed qt lib directory.
final_rpath = self.qtinfo.libs_dir
- if OPTION_STANDALONE:
+ if OPTION["STANDALONE"]:
final_rpath = "$ORIGIN/Qt/lib"
- override = OPTION_STANDALONE
+ override = OPTION["STANDALONE"]
linux_fix_rpaths_for_library(self._patchelf_path, srcpath, final_rpath,
override=override)
@@ -1306,18 +1140,17 @@ class PysideBuild(_build):
final_rpath = ''
# Command line rpath option takes precedence over
# automatically added one.
- if OPTION_RPATH_VALUES:
- final_rpath = OPTION_RPATH_VALUES
+ if OPTION["RPATH_VALUES"]:
+ final_rpath = OPTION["RPATH_VALUES"]
else:
- if OPTION_STANDALONE:
+ if OPTION["STANDALONE"]:
final_rpath = "@loader_path/Qt/lib"
else:
final_rpath = self.qtinfo.libs_dir
macos_fix_rpaths_for_library(srcpath, final_rpath)
else:
- raise RuntimeError('Not configured for platform ' +
- sys.platform)
+ raise RuntimeError('Not configured for platform {}'.format(sys.platform))
pyside_libs.extend(executables)
@@ -1333,6 +1166,83 @@ class PysideBuild(_build):
"updated rpath (OS/X) in {}.".format(srcpath))
+class PysideRstDocs(Command, DistUtilsCommandMixin):
+ description = "Build .rst documentation only"
+ user_options = DistUtilsCommandMixin.mixin_user_options
+
+ def initialize_options(self):
+ DistUtilsCommandMixin.__init__(self)
+ log.info("-- This build process will not include the API documentation."
+ "API documentation requires a full build of pyside/shiboken.")
+ self.skip = False
+ if config.is_internal_shiboken_generator_build():
+ self.skip = True
+ if not self.skip:
+ self.name = config.package_name().lower()
+ self.doc_dir = os.path.join(config.setup_script_dir, "sources")
+ self.doc_dir = os.path.join(self.doc_dir, self.name)
+ self.doc_dir = os.path.join(self.doc_dir, "doc")
+ try:
+ # Check if sphinx is installed to proceed.
+ import sphinx
+ if self.name == "shiboken2":
+ log.info("-- Generating Shiboken documentation")
+ log.info("-- Documentation directory: 'html/pyside2/shiboken2/'")
+ elif self.name == "pyside2":
+ log.info("-- Generating PySide documentation")
+ log.info("-- Documentation directory: 'html/pyside2/'")
+ except ImportError:
+ raise DistutilsSetupError("Sphinx not found - aborting")
+ self.html_dir = "html"
+
+ # creating directories html/pyside2/shiboken2
+ try:
+ if not os.path.isdir(self.html_dir):
+ os.mkdir(self.html_dir)
+ if self.name == "shiboken2":
+ out_pyside = os.path.join(self.html_dir, "pyside2")
+ if not os.path.isdir(out_pyside):
+ os.mkdir(out_pyside)
+ out_shiboken = os.path.join(out_pyside, "shiboken2")
+ if not os.path.isdir(out_shiboken):
+ os.mkdir(out_shiboken)
+ self.out_dir = out_shiboken
+ # We know that on the shiboken step, we already created the
+ # 'pyside2' directory
+ elif self.name == "pyside2":
+ self.out_dir = os.path.join(self.html_dir, "pyside2")
+ except:
+ raise DistutilsSetupError("Error while creating directories for {}".format(self.doc_dir))
+
+ def run(self):
+ if not self.skip:
+ cmake_cmd = [OPTION["CMAKE"]]
+ cmake_cmd += [
+ "-S", self.doc_dir,
+ "-B", self.out_dir,
+ "-DDOC_OUTPUT_FORMAT=html",
+ "-DFULLDOCSBUILD=0",
+ ]
+ if run_process(cmake_cmd) != 0:
+ raise DistutilsSetupError("Error running CMake for {}".format(self.doc_dir))
+
+ if self.name == "pyside2":
+ self.sphinx_src = os.path.join(self.out_dir, "rst")
+ elif self.name == "shiboken2":
+ self.sphinx_src = self.out_dir
+
+ sphinx_cmd = ["sphinx-build", "-b", "html", "-c", self.sphinx_src,
+ self.doc_dir, self.out_dir]
+ if run_process(sphinx_cmd) != 0:
+ raise DistutilsSetupError("Error running CMake for {}".format(self.doc_dir))
+ # Last message
+ if not self.skip and self.name == "pyside2":
+ log.info("-- The documentation was built. Check html/pyside2/index.html")
+
+ def finalize_options(self):
+ DistUtilsCommandMixin.mixin_finalize_options(self)
+
+
cmd_class_dict = {
'build': PysideBuild,
'build_py': PysideBuildPy,
@@ -1340,14 +1250,10 @@ cmd_class_dict = {
'bdist_egg': PysideBdistEgg,
'develop': PysideDevelop,
'install': PysideInstall,
- 'install_lib': PysideInstallLib
+ 'install_lib': PysideInstallLib,
+ 'build_rst_docs': PysideRstDocs,
}
if wheel_module_exists:
- params = {}
- params['qt_version'] = get_qt_version()
- params['package_version'] = get_package_version()
- if sys.platform == 'darwin':
- params['macos_plat_name'] = PysideBuild.macos_plat_name()
- pyside_bdist_wheel = get_bdist_wheel_override(params)
+ pyside_bdist_wheel = get_bdist_wheel_override()
if pyside_bdist_wheel:
cmd_class_dict['bdist_wheel'] = pyside_bdist_wheel