aboutsummaryrefslogtreecommitdiffstats
path: root/build_scripts/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'build_scripts/config.py')
-rw-r--r--build_scripts/config.py399
1 files changed, 399 insertions, 0 deletions
diff --git a/build_scripts/config.py b/build_scripts/config.py
new file mode 100644
index 000000000..f47230a6d
--- /dev/null
+++ b/build_scripts/config.py
@@ -0,0 +1,399 @@
+#############################################################################
+##
+## 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$
+##
+#############################################################################
+
+import sys, os
+import distutils.log as log
+
+
+class Config(object):
+ def __init__(self):
+ # Constants
+ self._build_type_all = "all"
+ self._invocation_type_top_level = "top-level"
+ self._invocation_type_internal = "internal"
+
+ # The keyword arguments which will be given to setuptools.setup
+ self.setup_kwargs = {}
+
+ # The setup.py invocation type.
+ # top-level
+ # internal
+ self.invocation_type = None
+
+ # The type of the top-level build.
+ # all - build shiboken2 module, shiboken2-generator and PySide2
+ # modules
+ # shiboken2 - build only shiboken2 module
+ # shiboken2-generator - build only the shiboken2-generator
+ # pyside2 - build only PySide2 modules
+ self.build_type = None
+
+ # The internal build type, used for internal invocations of
+ # setup.py to build a specific module only.
+ self.internal_build_type = None
+
+ # Options that can be given to --build-type and
+ # --internal-build-type
+ self.shiboken_module_option_name = "shiboken2"
+ self.shiboken_generator_option_name = "shiboken2-generator"
+ self.pyside_option_name = "pyside2"
+
+ # Names to be passed to setuptools.setup() name key,
+ # so not package name, but rather project name as it appears
+ # in the wheel name and on PyPi.
+ self.shiboken_module_st_name = "shiboken2"
+ self.shiboken_generator_st_name = "shiboken2-generator"
+ self.pyside_st_name = "PySide2"
+
+ # Used by check_allowed_python_version to validate the
+ # interpreter version.
+ self.python_version_classifiers = [
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ ]
+
+ self.setup_script_dir = None
+
+ def init_config(self, build_type=None, internal_build_type=None,
+ cmd_class_dict=None, package_version=None,
+ ext_modules=None, setup_script_dir=None,
+ quiet=False):
+ """
+ Sets up the global singleton config which is used in many parts
+ of the setup process.
+ """
+
+ # if --internal-build-type was passed, it means that this is a
+ # sub-invocation to build a specific package.
+ if internal_build_type:
+ self.set_is_internal_invocation()
+ self.set_internal_build_type(internal_build_type)
+ else:
+ self.set_is_top_level_invocation()
+
+ # --build-type was specified explicitly, so set it. Otherwise
+ # default to all.
+ if build_type:
+ self.build_type = build_type
+ else:
+ self.build_type = self._build_type_all
+
+ self.setup_script_dir = setup_script_dir
+
+ setup_kwargs = {}
+ setup_kwargs['long_description'] = self.get_long_description()
+ setup_kwargs['long_description_content_type'] = 'text/markdown',
+ setup_kwargs['keywords'] = 'Qt'
+ setup_kwargs['author'] = 'Qt for Python Team'
+ setup_kwargs['author_email'] = 'pyside@qt-project.org'
+ setup_kwargs['url'] = 'https://www.pyside.org'
+ setup_kwargs['download_url'] = 'https://download.qt.io/official_releases/QtForPython'
+ setup_kwargs['license'] = 'LGPL'
+ setup_kwargs['zip_safe'] = False
+ setup_kwargs['cmdclass'] = cmd_class_dict
+ setup_kwargs['version'] = package_version
+
+ if quiet:
+ # Tells distutils / setuptools to be quiet, and only print warnings or errors.
+ # Makes way less noise in the terminal when building.
+ setup_kwargs['verbose'] = 0
+
+ # Setting these two keys is still a bit of a discussion point.
+ # In general not setting them will allow using "build" and
+ # "bdist_wheel" just fine. What they do, is they specify to the
+ # setuptools.command.build_py command that certain pure python
+ # modules (.py files) exist in the specified package location,
+ # and that they should be copied over to the setuptools build
+ # dir.
+ # But it doesn't really make sense for us, because we copy all
+ # the necessary files to the build dir via prepare_packages()
+ # function anyway.
+ # If we don't set them, the build_py sub-command will be
+ # skipped, but the build command will still be executed, which
+ # is where we run cmake / make.
+ # The only plausible usage of it, is if we will implement a
+ # correctly functioning setup.py develop command (or bdist_egg).
+ # But currently that doesn't seem to work.
+ setup_kwargs['packages'] = self.get_setup_tools_packages_for_current_build()
+ setup_kwargs['package_dir'] = self.get_package_name_to_dir_path_mapping()
+
+ # Add a bogus extension module (will never be built here since
+ # we are overriding the build command to do it using cmake) so
+ # things like bdist_egg will know that there are extension
+ # modules and will name the dist with the full platform info.
+ setup_kwargs['ext_modules'] = ext_modules
+
+ common_classifiers = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Console',
+ 'Environment :: MacOS X',
+ 'Environment :: X11 Applications :: Qt',
+ 'Environment :: Win32 (MS Windows)',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
+ 'Operating System :: MacOS :: MacOS X',
+ 'Operating System :: POSIX',
+ 'Operating System :: POSIX :: Linux',
+ 'Operating System :: Microsoft',
+ 'Operating System :: Microsoft :: Windows',
+ 'Programming Language :: C++']
+ common_classifiers.extend(self.python_version_classifiers)
+ common_classifiers.extend([
+ 'Topic :: Database',
+ 'Topic :: Software Development',
+ 'Topic :: Software Development :: Code Generators',
+ 'Topic :: Software Development :: Libraries :: Application Frameworks',
+ 'Topic :: Software Development :: User Interfaces',
+ 'Topic :: Software Development :: Widget Sets'])
+ setup_kwargs['classifiers'] = common_classifiers
+
+ if self.internal_build_type == self.shiboken_module_option_name:
+ setup_kwargs['name'] = self.shiboken_module_st_name
+ setup_kwargs['description'] = "Python / C++ bindings helper module",
+ setup_kwargs['entry_points'] = {}
+
+ elif self.internal_build_type == self.shiboken_generator_option_name:
+ setup_kwargs['name'] = self.shiboken_generator_st_name
+ setup_kwargs['description'] = "Python / C++ bindings generator",
+ setup_kwargs['install_requires'] = [self.shiboken_module_st_name]
+ setup_kwargs['entry_points'] = {
+ 'console_scripts': [
+ 'shiboken2 = {}.scripts.shiboken_tool:main'.format(self.package_name()),
+ ]
+ }
+
+ elif self.internal_build_type == self.pyside_option_name:
+ setup_kwargs['name'] = self.pyside_st_name
+ setup_kwargs['description'] = ("Python bindings for the Qt cross-platform application"
+ " and UI framework"),
+ setup_kwargs['install_requires'] = [self.shiboken_module_st_name]
+ setup_kwargs['entry_points'] = {
+ 'console_scripts': [
+ 'pyside2-uic = {}.scripts.uic:main'.format(self.package_name()),
+ 'pyside2-rcc = {}.scripts.pyside_tool:main'.format(self.package_name()),
+ 'pyside2-lupdate = {}.scripts.pyside_tool:main'.format(self.package_name()),
+ ]
+ }
+ self.setup_kwargs = setup_kwargs
+
+ def get_long_description(self):
+ readme_filename = 'README.md'
+ changes_filename = 'CHANGES.rst'
+
+ if self.is_internal_shiboken_module_build():
+ readme_filename = 'README.shiboken2.md'
+ elif self.is_internal_shiboken_generator_build():
+ readme_filename = 'README.shiboken2-generator.md'
+ elif self.is_internal_pyside_build():
+ readme_filename = 'README.pyside2.md'
+
+ content = ''
+ changes = ''
+ try:
+ with open(os.path.join(self.setup_script_dir, readme_filename)) as f:
+ readme = f.read()
+ except Exception as e:
+ log.error("Couldn't read contents of {}.".format(readme_filename))
+ raise
+
+ # Don't include CHANGES.rst for now, because we have not decided
+ # how to handle change files yet.
+ include_changes = False
+ if include_changes:
+ try:
+ with open(os.path.join(self.setup_script_dir, changes_filename)) as f:
+ changes = f.read()
+ except Exception as e:
+ log.error("Couldn't read contents of {}".format(changes_filename))
+ raise
+ content += readme
+
+ if changes:
+ content += "\n\n" + changes
+
+ return content
+
+ def package_name(self):
+ """
+ Returns package name as it appears in Python's site-packages
+ directory.
+
+ Package names can only be delimited by underscores, and not by
+ dashes.
+ """
+ if self.is_internal_shiboken_module_build():
+ return "shiboken2"
+ elif self.is_internal_shiboken_generator_build():
+ return "shiboken2_generator"
+ elif self.is_internal_pyside_build():
+ return "PySide2"
+ else:
+ return None
+
+ def get_setup_tools_packages_for_current_build(self):
+ """
+ Returns a list of packages for setup tools to consider in the
+ build_py command, so that it can copy the pure python files.
+ Not really necessary because it's done in prepare_packages()
+ anyway.
+
+ This is really just to satisfy some checks in setuptools
+ build_py command, and if we ever properly implement the develop
+ command.
+ """
+ if self.internal_build_type == self.pyside_option_name:
+ return [
+ config.package_name(),
+ 'pyside2uic',
+ 'pyside2uic.Compiler',
+ 'pyside2uic.port_v{}'.format(sys.version_info[0])
+ ]
+ elif self.internal_build_type == self.shiboken_module_option_name:
+ return [self.package_name()]
+ else:
+ return []
+
+ def get_package_name_to_dir_path_mapping(self):
+ """
+ Used in setuptools.setup 'package_dir' argument to specify where
+ the actual module packages are located.
+
+ For example when building the shiboken module, setuptools will
+ expect to find the "shiboken2" module sources under
+ "sources/shiboken2/shibokenmodule".
+
+ This is really just to satisfy some checks in setuptools
+ build_py command, and if we ever properly implement the develop
+ command.
+ """
+ if self.is_internal_shiboken_module_build():
+ return {
+ self.package_name(): "sources/shiboken2/shibokenmodule"
+ }
+ elif self.is_internal_shiboken_generator_build():
+ # This is left empty on purpose, because the shiboken
+ # generator doesn't have a python module for now.
+ return {}
+ elif self.is_internal_pyside_build():
+ return {
+ self.package_name(): "sources/pyside2/PySide2",
+ "pyside2uic": "sources/pyside2-tools/pyside2uic"
+ }
+ else:
+ return {}
+
+ def get_buildable_extensions(self):
+ """
+ Used by PysideBuild.run to build the CMake projects.
+ :return: A list of directory names under the sources directory.
+ """
+ if self.is_internal_shiboken_module_build() or self.is_internal_shiboken_generator_build():
+ return ['shiboken2']
+ elif self.is_internal_pyside_build():
+ return ['pyside2', 'pyside2-tools']
+ return None
+
+ def set_is_top_level_invocation(self):
+ self.invocation_type = self._invocation_type_top_level
+
+ def set_is_internal_invocation(self):
+ self.invocation_type = self._invocation_type_internal
+
+ def is_top_level_invocation(self):
+ return self.invocation_type == self._invocation_type_top_level
+
+ def is_internal_invocation(self):
+ return self.invocation_type == self._invocation_type_internal
+
+ def is_top_level_build_all(self):
+ return self.build_type == self._build_type_all
+
+ def is_top_level_build_shiboken_module(self):
+ return self.build_type == self.shiboken_module_option_name
+
+ def is_top_level_build_shiboken_generator(self):
+ return self.build_type == self.shiboken_generator_option_name
+
+ def is_top_level_build_pyside(self):
+ return self.build_type == self.pyside_option_name
+
+ def set_internal_build_type(self, internal_build_type):
+ self.internal_build_type = internal_build_type
+
+ def is_internal_shiboken_module_build(self):
+ return self.internal_build_type == self.shiboken_module_option_name
+
+ def is_internal_shiboken_generator_build(self):
+ return self.internal_build_type == self.shiboken_generator_option_name
+
+ def is_internal_pyside_build(self):
+ return self.internal_build_type == self.pyside_option_name
+
+ def is_internal_shiboken_generator_build_and_part_of_top_level_all(self):
+ """
+ Used to skip certain build rules and output, when we know that
+ the CMake build of shiboken was already done as part of the
+ top-level "all" build when shiboken2-module was built.
+ """
+ return self.is_internal_shiboken_generator_build() and self.is_top_level_build_all()
+
+ def get_allowed_top_level_build_values(self):
+ return [
+ self._build_type_all,
+ self.shiboken_module_option_name,
+ self.shiboken_generator_option_name,
+ self.pyside_option_name
+ ]
+
+ def get_allowed_internal_build_values(self):
+ return [
+ self.shiboken_module_option_name,
+ self.shiboken_generator_option_name,
+ self.pyside_option_name
+ ]
+
+
+config = Config()