diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-06-01 13:23:44 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-06-01 13:23:48 +0200 |
commit | e4e72eae189e57c255193aa8ee556a3d9936d110 (patch) | |
tree | 56c79d8d75479d71d341f5682531fdbd11f6ec95 /build_scripts | |
parent | 6383820c4b32395fe6dfead79f38ff93b7a0e686 (diff) | |
parent | ae0aa898a3bc1701499ff7993c8d31bc86eb1675 (diff) |
Merge remote-tracking branch 'origin/5.9' into 5.11
Change-Id: I31a0ff26bc02e6cc2ec2a816c16d170fc334f800
Diffstat (limited to 'build_scripts')
-rw-r--r-- | build_scripts/main.py | 72 | ||||
-rw-r--r-- | build_scripts/options.py | 2 | ||||
-rw-r--r-- | build_scripts/wheel_override.py | 200 |
3 files changed, 234 insertions, 40 deletions
diff --git a/build_scripts/main.py b/build_scripts/main.py index 26fc191c5..f288756c1 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -64,7 +64,7 @@ def get_package_version(): 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: + 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 @@ -73,6 +73,18 @@ def get_package_version(): 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 + # to do, but it doesn't actually do anything, because we + # override build_ext. So this is just foolproofing for the + # future. + extension_args = ('QtCore', []) + extension_kwargs = {} + if OPTION_LIMITED_API: + extension_kwargs['py_limited_api'] = True + extension_modules = [Extension(*extension_args, **extension_kwargs)] + return extension_modules + # Buildable extensions. contained_modules = ['shiboken2', 'pyside2', 'pyside2-tools'] @@ -113,19 +125,12 @@ 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 -wheel_module_exists = False -try: - from wheel.bdist_wheel import bdist_wheel as _bdist_wheel - from wheel.bdist_wheel import safer_name as _safer_name - wheel_module_exists = True -except ImportError: - pass - from .qtinfo import QtInfo from .utils import rmtree, detect_clang, copyfile, copydir, run_process_output, run_process from .utils import update_env_path, init_msvc_env, filter_match, macos_fix_rpaths_for_library 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 @@ -378,35 +383,7 @@ class PysideBuildExt(_build_ext): def run(self): pass -if wheel_module_exists: - class PysideBuildWheel(_bdist_wheel): - def __init__(self, *args, **kwargs): - _bdist_wheel.__init__(self, *args, **kwargs) - - @property - def wheel_dist_name(self): - # Slightly modified version of wheel's wheel_dist_name - # method, to add the Qt version as well. - # Example: - # PySide2-5.6-5.6.4-cp27-cp27m-macosx_10_10_intel.whl - # The PySide2 version is "5.6". - # The Qt version built against is "5.6.4". - qt_version = get_qt_version() - package_version = get_package_version() - wheel_version = "{}-{}".format(package_version, qt_version) - components = (_safer_name(self.distribution.get_name()), - wheel_version) - if self.build_number: - components += (self.build_number,) - return '-'.join(components) - - def finalize_options(self): - if sys.platform == 'darwin': - # Override the platform name to contain the correct - # minimum deployment target. - # This is used in the final wheel name. - self.plat_name = PysideBuild.macos_plat_name() - _bdist_wheel.finalize_options(self) + # pyside_build_py and pyside_install_lib are reimplemented to preserve # symlinks when distutils / setuptools copy files to various @@ -985,6 +962,16 @@ class PysideBuild(_build): cmake_cmd.append("-DPYTHON_DEBUG_LIBRARY={}".format( self.py_library)) + if OPTION_LIMITED_API == "yes": + cmake_cmd.append("-DFORCE_LIMITED_API=yes") + elif OPTION_LIMITED_API == "no": + cmake_cmd.append("-DFORCE_LIMITED_API=no") + 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: cmake_cmd.append("-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON") @@ -1309,4 +1296,11 @@ cmd_class_dict = { 'install_lib': PysideInstallLib } if wheel_module_exists: - cmd_class_dict['bdist_wheel'] = PysideBuildWheel + 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) + if pyside_bdist_wheel: + cmd_class_dict['bdist_wheel'] = pyside_bdist_wheel diff --git a/build_scripts/options.py b/build_scripts/options.py index 80c9041e4..d7174feff 100644 --- a/build_scripts/options.py +++ b/build_scripts/options.py @@ -80,4 +80,4 @@ OPTION_QT_SRC = option_value("qt-src-dir") OPTION_VERBOSE_BUILD = has_option("verbose-build") OPTION_SANITIZE_ADDRESS = has_option("sanitize-address") OPTION_SNAPSHOT_BUILD = has_option("snapshot-build") - +OPTION_LIMITED_API = option_value("limited-api") diff --git a/build_scripts/wheel_override.py b/build_scripts/wheel_override.py new file mode 100644 index 000000000..ee8bd8382 --- /dev/null +++ b/build_scripts/wheel_override.py @@ -0,0 +1,200 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + + +wheel_module_exists = False + +try: + import os, sys + + from distutils import log + from wheel import pep425tags + from wheel.bdist_wheel import bdist_wheel as _bdist_wheel + from wheel.bdist_wheel import safer_name as _safer_name + from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag + from wheel.pep425tags import get_platform as wheel_get_platform + from email.generator import Generator + from wheel import __version__ as wheel_version + + from .options import * + + wheel_module_exists = True +except Exception as e: + print('***** Exception while trying to prepare bdist_wheel override class: {}. Skipping wheel overriding.'.format(e)) + +def get_bdist_wheel_override(params): + if wheel_module_exists: + class PysideBuildWheelDecorated(PysideBuildWheel): + def __init__(self, *args, **kwargs): + self.params = params + PysideBuildWheel.__init__(self, *args, **kwargs) + return PysideBuildWheelDecorated + else: + return None + +if wheel_module_exists: + class PysideBuildWheel(_bdist_wheel): + def __init__(self, *args, **kwargs): + self.pyside_params = None + _bdist_wheel.__init__(self, *args, **kwargs) + + @property + def wheel_dist_name(self): + # Slightly modified version of wheel's wheel_dist_name + # method, to add the Qt version as well. + # Example: + # PySide2-5.6-5.6.4-cp27-cp27m-macosx_10_10_intel.whl + # The PySide2 version is "5.6". + # The Qt version built against is "5.6.4". + qt_version = self.params['qt_version'] + package_version = self.params['package_version'] + wheel_version = "{}-{}".format(package_version, qt_version) + components = (_safer_name(self.distribution.get_name()), + wheel_version) + if self.build_number: + components += (self.build_number,) + return '-'.join(components) + + # Copy of get_tag from bdist_wheel.py, to allow setting a + # multi-python impl tag, by removing an assert. Otherwise we + # would have to rename wheels manually for limited api + # packages. Also we set "none" abi tag on Windows, because + # pip does not yet support "abi3" tag, leading to + # installation failure when tried. + def get_tag(self): + # bdist sets self.plat_name if unset, we should only use + # it for purepy wheels if the user supplied it. + if self.plat_name_supplied: + plat_name = self.plat_name + elif self.root_is_pure: + plat_name = 'any' + else: + plat_name = self.plat_name or wheel_get_platform() + if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize == 2147483647: + plat_name = 'linux_i686' + + # To allow uploading to pypi, we need the wheel name + # to contain 'manylinux1'. + # The wheel which will be uploaded to pypi will be + # built on RHEL7, so it doesn't completely qualify for + # manylinux1 support, but it's the minimum requirement + # for building Qt. We only enable this for x64 limited + # api builds (which are the only ones uploaded to + # pypi). + # TODO: Add actual distro detection, instead of + # relying on limited_api option. + if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize > 2147483647 \ + and self.py_limited_api: + plat_name = 'manylinux1_x86_64' + plat_name = plat_name.replace('-', '_').replace('.', '_') + + if self.root_is_pure: + if self.universal: + impl = 'py2.py3' + else: + impl = self.python_tag + tag = (impl, 'none', plat_name) + else: + impl_name = get_abbr_impl() + impl_ver = get_impl_ver() + impl = impl_name + impl_ver + # We don't work on CPython 3.1, 3.0. + if self.py_limited_api and (impl_name + impl_ver).startswith('cp3'): + impl = self.py_limited_api + if sys.platform == "win32": + abi_tag = 'none' + else: + abi_tag = 'abi3' + else: + abi_tag = str(get_abi_tag()).lower() + tag = (impl, abi_tag, plat_name) + supported_tags = pep425tags.get_supported( + supplied_platform=plat_name if self.plat_name_supplied else None) + # XXX switch to this alternate implementation for + # non-pure: + if not self.py_limited_api: + assert tag == supported_tags[0], "%s != %s" % (tag, supported_tags[0]) + assert tag in supported_tags, \ + "would build wheel with unsupported tag {}".format(tag) + return tag + + # Copy of get_tag from bdist_wheel.py, to write a triplet Tag + # only once for the limited_api case. + def write_wheelfile(self, wheelfile_base, generator='bdist_wheel (' + wheel_version + ')'): + from email.message import Message + msg = Message() + msg['Wheel-Version'] = '1.0' # of the spec + msg['Generator'] = generator + msg['Root-Is-Purelib'] = str(self.root_is_pure).lower() + if self.build_number is not None: + msg['Build'] = self.build_number + + # Doesn't work for bdist_wininst + impl_tag, abi_tag, plat_tag = self.get_tag() + limited_api_enabled = OPTION_LIMITED_API and sys.version_info[0] >= 3 + + def writeTag(impl): + for abi in abi_tag.split('.'): + for plat in plat_tag.split('.'): + msg['Tag'] = '-'.join((impl, abi, plat)) + if limited_api_enabled: + writeTag(impl_tag) + else: + for impl in impl_tag.split('.'): + writeTag(impl) + + wheelfile_path = os.path.join(wheelfile_base, 'WHEEL') + log.info('creating %s', wheelfile_path) + with open(wheelfile_path, 'w') as f: + Generator(f, maxheaderlen=0).flatten(msg) + + def finalize_options(self): + if sys.platform == 'darwin': + # Override the platform name to contain the correct + # minimum deployment target. + # This is used in the final wheel name. + self.plat_name = self.params['macos_plat_name'] + + # When limited API is requested, notify bdist_wheel to + # create a properly named package. + limited_api_enabled = OPTION_LIMITED_API and sys.version_info[0] >= 3 + if limited_api_enabled: + self.py_limited_api = "cp35.cp36.cp37.cp38" + + _bdist_wheel.finalize_options(self) |