diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2018-07-20 18:54:05 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2018-10-12 14:45:35 +0000 |
commit | 43fe3494a9d902034896e3afa7b5158c77163be0 (patch) | |
tree | 07bbd20b8bd322fdf062b87dfade1e1e74d80433 /build_scripts/platforms | |
parent | c6c9f057cddc0e0b885a648489264538eba0a158 (diff) |
Allow building shiboken2 and PySide2 as separate wheels
Actually this creates 3 wheel packages:
- shiboken2 (the python module and libshiboken shared library)
- shiboken2-generator (contains the generator executable, libclang and
dependent Qt libraries)
- PySide2 (the PySide2 modules and Qt shared libraries, and tools like
rcc, uic)
Calling the setup.py script will not do the actual build now (in the
sense of calling CMake, make, etc.). Instead it will spawn new
processes (via subprocess.call) calling the same setup.py script,
but with different arguments. These "sub-invocations" will do the
actual building. Thus, the "top-level invocation" will decide which
packages to build and delegate that to the "sub-invocations" of
setup.py.
A new optional command line argument is introduced called
"--build-type" which defaults to "all", and can also be set to
"shiboken2", "shiboken2-generator" and "pyside2". A user can choose
which packages to build using this option. The "top-level invocation"
uses this option to decide how many "sub-invocations" to execute.
A new command line argument called "--internal-build-type"
takes the same values as the one above. It defines which package
will actually be built in the new spawned "sub-invocation" process.
The "top-level invocation" sets this automatically for each
"sub-invocation" depending on the value of "--build-type".
This option is also useful for developers that may want to debug the
python building code in the "sub-invocation".
Developers can set this manually via the command line, and
thus avoid the process spawning indirection.
A new class Config is introduced to facilitate storage of
the various state needed for building a single package.
A new class SetupRunner is introduced that takes care of the
"--build-type" and "--internal-build-type" argument handling
and delegation of "sub-invocations".
A new class Options is introduced to 'hopefully', in the future, streamline
the mess of option handling that we currently have.
setup.py now is now simplified to mostly just call
SetupRunner.run_setup().
Certain refactorings were done to facilitate further clean-up of the
build code, the current code is definitely not the end all be all.
Various other changes that were needed to implement the wheel
separation:
- a new cmake_helpers directory is added to share common cmake
code between packages.
- the custom popenasync.py file is removed in favor of using
subprocess.call in as many places as possible, and thus
avoid 10 different functions for process creation.
- Manifest.in is removed, because copying to the setuptools
build dir is now done directly by prepare_packages functions.
- because prepare_packages copies directly to the setuptools
build dir, avoiding the pyside_package dir, we do less copying
of big Qt files now.
- versioning of PySide2 and shiboken2 packages is now separate.
shiboken2 and shiboken2-generator share the same versions for
now though.
- shiboken2 is now listed as a required package for PySide2, to
facilitate pip requirements.txt dependencies.
- coin_build_instructions currently needs to install an unreleased
version of wheel, due to a bug that breaks installation of
generated wheel files.
- added separate command line options to pyside2_config.py for
shiboken2-module and shiboken2-generator.
- adapted samplebinding and scriptableapplication projects due to
shiboken being a separate package.
- adapted pyside2-tool and shiboken2-tool python scripts for setup
tools entry points.
- made some optimizations not to invoke cmake for shiboken2-generator
when doing a top-level "all" build.
- fixed unnecessary rpaths not to be included on Linux (mainly the
Qt rpaths).
Task-nubmer: PYSIDE-749
Change-Id: I0336043955624c1d12ed254802c442608cced5fb
Reviewed-by: Christian Tismer <tismer@stackless.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'build_scripts/platforms')
-rw-r--r-- | build_scripts/platforms/linux.py | 136 | ||||
-rw-r--r-- | build_scripts/platforms/macos.py | 119 | ||||
-rw-r--r-- | build_scripts/platforms/unix.py | 261 | ||||
-rw-r--r-- | build_scripts/platforms/windows_desktop.py | 468 |
4 files changed, 577 insertions, 407 deletions
diff --git a/build_scripts/platforms/linux.py b/build_scripts/platforms/linux.py index 4c38fef6c..067179cdc 100644 --- a/build_scripts/platforms/linux.py +++ b/build_scripts/platforms/linux.py @@ -37,76 +37,100 @@ ## ############################################################################# -from ..options import * from ..utils import copydir, copyfile, copy_icu_libs, find_files_using_glob +from ..config import config -def prepare_standalone_package_linux(self, executables, vars): + +def prepare_standalone_package_linux(self, vars): built_modules = vars['built_modules'] - # <qt>/lib/* -> <setup>/PySide2/Qt/lib - destination_lib_dir = "{pyside_package_dir}/PySide2/Qt/lib" + constrain_modules = None + copy_plugins = True + copy_qml = True + copy_translations = True + copy_qt_conf = True + should_copy_icu_libs = True + + if config.is_internal_shiboken_generator_build(): + constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"] + copy_plugins = False + copy_qml = False + copy_translations = False + copy_qt_conf = False + should_copy_icu_libs = False + + # <qt>/lib/* -> <setup>/{st_package_name}/Qt/lib + destination_lib_dir = "{st_build_dir}/{st_package_name}/Qt/lib" + + accepted_modules = ['libQt5*.so.?'] + if constrain_modules: + accepted_modules = ["libQt5" + module + "*.so.?" for module in constrain_modules] + accepted_modules.append("libicu*.so.??") + copydir("{qt_lib_dir}", destination_lib_dir, - filter=[ - "libQt5*.so.?", - "libicu*.so.??", - ], - recursive=False, vars=vars, force_copy_symlinks=True) - - # Check if ICU libraries were copied over to the destination - # Qt libdir. - resolved_destination_lib_dir = destination_lib_dir.format(**vars) - maybe_icu_libs = find_files_using_glob(resolved_destination_lib_dir, - "libicu*") - - # If no ICU libraries are present in the Qt libdir (like when - # Qt is built against system ICU, or in the Coin CI where ICU - # libs are in a different directory) try to find out / resolve - # which ICU libs are used by QtCore (if used at all) using a - # custom written ldd, and copy the ICU libs to the Pyside Qt - # dir if necessary. We choose the QtCore lib to inspect, by - # checking which QtCore library the shiboken2 executable uses. - if not maybe_icu_libs: - copy_icu_libs(self._patchelf_path, resolved_destination_lib_dir) + filter=accepted_modules, + recursive=False, vars=vars, force_copy_symlinks=True) + + if should_copy_icu_libs: + # Check if ICU libraries were copied over to the destination + # Qt libdir. + resolved_destination_lib_dir = destination_lib_dir.format(**vars) + maybe_icu_libs = find_files_using_glob(resolved_destination_lib_dir, + "libicu*") + + # If no ICU libraries are present in the Qt libdir (like when + # Qt is built against system ICU, or in the Coin CI where ICU + # libs are in a different directory) try to find out / resolve + # which ICU libs are used by QtCore (if used at all) using a + # custom written ldd, and copy the ICU libs to the Pyside Qt + # dir if necessary. We choose the QtCore lib to inspect, by + # checking which QtCore library the shiboken2 executable uses. + if not maybe_icu_libs: + copy_icu_libs(self._patchelf_path, resolved_destination_lib_dir) if self.is_webengine_built(built_modules): copydir("{qt_lib_execs_dir}", - "{pyside_package_dir}/PySide2/Qt/libexec", + "{st_build_dir}/{st_package_name}/Qt/libexec", filter=None, recursive=False, vars=vars) copydir("{qt_prefix_dir}/resources", - "{pyside_package_dir}/PySide2/Qt/resources", + "{st_build_dir}/{st_package_name}/Qt/resources", filter=None, recursive=False, vars=vars) - # <qt>/plugins/* -> <setup>/PySide2/Qt/plugins - copydir("{qt_plugins_dir}", - "{pyside_package_dir}/PySide2/Qt/plugins", - filter=["*.so"], - recursive=True, - vars=vars) - - # <qt>/qml/* -> <setup>/PySide2/Qt/qml - copydir("{qt_qml_dir}", - "{pyside_package_dir}/PySide2/Qt/qml", - filter=None, - force=False, - recursive=True, - ignore=["*.so.debug"], - vars=vars) - - # <qt>/translations/* -> <setup>/PySide2/Qt/translations - - copydir("{qt_translations_dir}", - "{pyside_package_dir}/PySide2/Qt/translations", - filter=["*.qm", "*.pak"], - force=False, - vars=vars) - - # Copy the qt.conf file to libexec. - copyfile( - "{build_dir}/pyside2/PySide2/qt.conf", - "{pyside_package_dir}/PySide2/Qt/libexec", - vars=vars) + if copy_plugins: + # <qt>/plugins/* -> <setup>/{st_package_name}/Qt/plugins + copydir("{qt_plugins_dir}", + "{st_build_dir}/{st_package_name}/Qt/plugins", + filter=["*.so"], + recursive=True, + vars=vars) + + if copy_qml: + # <qt>/qml/* -> <setup>/{st_package_name}/Qt/qml + copydir("{qt_qml_dir}", + "{st_build_dir}/{st_package_name}/Qt/qml", + filter=None, + force=False, + recursive=True, + ignore=["*.so.debug"], + vars=vars) + + if copy_translations: + # <qt>/translations/* -> + # <setup>/{st_package_name}/Qt/translations + copydir("{qt_translations_dir}", + "{st_build_dir}/{st_package_name}/Qt/translations", + filter=["*.qm", "*.pak"], + force=False, + vars=vars) + + if copy_qt_conf: + # Copy the qt.conf file to libexec. + copyfile( + "{build_dir}/pyside2/{st_package_name}/qt.conf", + "{st_build_dir}/{st_package_name}/Qt/libexec", + vars=vars) diff --git a/build_scripts/platforms/macos.py b/build_scripts/platforms/macos.py index 936f4ca90..49f02754d 100644 --- a/build_scripts/platforms/macos.py +++ b/build_scripts/platforms/macos.py @@ -37,12 +37,29 @@ ## ############################################################################# -import fnmatch, os +import fnmatch +import os from ..utils import copydir, copyfile, macos_fix_rpaths_for_library +from ..config import config -def prepare_standalone_package_macos(self, executables, vars): + +def prepare_standalone_package_macos(self, vars): built_modules = vars['built_modules'] + constrain_modules = None + copy_plugins = True + copy_qml = True + copy_translations = True + copy_qt_conf = True + + if config.is_internal_shiboken_generator_build(): + constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"] + constrain_frameworks = ['Qt' + name + '.framework' for name in constrain_modules] + copy_plugins = False + copy_qml = False + copy_translations = False + copy_qt_conf = False + # Directory filter for skipping unnecessary files. def general_dir_filter(dir_name, parent_full_path, dir_full_path): if fnmatch.fnmatch(dir_name, "*.dSYM"): @@ -52,6 +69,7 @@ def prepare_standalone_package_macos(self, executables, vars): # Filter out debug plugins and qml plugins in the # debug_and_release config. no_copy_debug = True + def file_variant_filter(file_name, file_full_path): if self.qtinfo.build_type != 'debug_and_release': return True @@ -59,17 +77,16 @@ def prepare_standalone_package_macos(self, executables, vars): return False return True - # <qt>/lib/* -> <setup>/PySide2/Qt/lib + # <qt>/lib/* -> <setup>/{st_package_name}/Qt/lib if self.qt_is_framework_build(): - framework_built_modules = [ - 'Qt' + name + '.framework' for name in built_modules] - - def framework_dir_filter(dir_name, parent_full_path, - dir_full_path): + def framework_dir_filter(dir_name, parent_full_path, dir_full_path): if '.framework' in dir_name: - if dir_name.startswith('QtWebEngine') and not \ - self.is_webengine_built(built_modules): + if (dir_name.startswith('QtWebEngine') and + not self.is_webengine_built(built_modules)): + return False + if constrain_modules and dir_name not in constrain_frameworks: return False + if dir_name in ['Headers', 'fonts']: return False if dir_full_path.endswith('Versions/Current'): @@ -84,6 +101,7 @@ def prepare_standalone_package_macos(self, executables, vars): # Filter out debug frameworks in the # debug_and_release config. no_copy_debug = True + def framework_variant_filter(file_name, file_full_path): if self.qtinfo.build_type != 'debug_and_release': return True @@ -93,7 +111,7 @@ def prepare_standalone_package_macos(self, executables, vars): return False return True - copydir("{qt_lib_dir}", "{pyside_package_dir}/PySide2/Qt/lib", + copydir("{qt_lib_dir}", "{st_build_dir}/{st_package_name}/Qt/lib", recursive=True, vars=vars, ignore=["*.la", "*.a", "*.cmake", "*.pc", "*.prl"], dir_filter_function=framework_dir_filter, @@ -104,7 +122,7 @@ def prepare_standalone_package_macos(self, executables, vars): # from Versions/5/Helpers, thus adding two more levels of # directory hierarchy. if self.is_webengine_built(built_modules): - qt_lib_path = "{pyside_package_dir}/PySide2/Qt/lib".format( + qt_lib_path = "{st_build_dir}/{st_package_name}/Qt/lib".format( **vars) bundle = "QtWebEngineCore.framework/Helpers/" bundle += "QtWebEngineProcess.app" @@ -120,9 +138,11 @@ def prepare_standalone_package_macos(self, executables, vars): if 'WebKit' not in built_modules: ignored_modules.extend(['libQt5WebKit*.dylib']) accepted_modules = ['libQt5*.5.dylib'] + if constrain_modules: + accepted_modules = ["libQt5" + module + "*.5.dylib" for module in constrain_modules] copydir("{qt_lib_dir}", - "{pyside_package_dir}/PySide2/Qt/lib", + "{st_build_dir}/{st_package_name}/Qt/lib", filter=accepted_modules, ignore=ignored_modules, file_filter_function=file_variant_filter, @@ -130,53 +150,58 @@ def prepare_standalone_package_macos(self, executables, vars): if self.is_webengine_built(built_modules): copydir("{qt_lib_execs_dir}", - "{pyside_package_dir}/PySide2/Qt/libexec", + "{st_build_dir}/{st_package_name}/Qt/libexec", filter=None, recursive=False, vars=vars) copydir("{qt_prefix_dir}/resources", - "{pyside_package_dir}/PySide2/Qt/resources", + "{st_build_dir}/{st_package_name}/Qt/resources", filter=None, recursive=False, vars=vars) # Fix rpath for WebEngine process executable. - pyside_package_dir = vars['pyside_package_dir'] - qt_libexec_path = "{}/PySide2/Qt/libexec".format(pyside_package_dir) + qt_libexec_path = "{st_build_dir}/{st_package_name}/Qt/libexec".format(**vars) binary = "QtWebEngineProcess" final_path = os.path.join(qt_libexec_path, binary) rpath = "@loader_path/../lib" macos_fix_rpaths_for_library(final_path, rpath) - # Copy the qt.conf file to libexec. - copyfile( - "{build_dir}/pyside2/PySide2/qt.conf", - "{pyside_package_dir}/PySide2/Qt/libexec", - vars=vars) + if copy_qt_conf: + # Copy the qt.conf file to libexec. + copyfile( + "{build_dir}/pyside2/{st_package_name}/qt.conf", + "{st_build_dir}/{st_package_name}/Qt/libexec", + vars=vars) + + if copy_plugins: + # <qt>/plugins/* -> <setup>/{st_package_name}/Qt/plugins + copydir("{qt_plugins_dir}", + "{st_build_dir}/{st_package_name}/Qt/plugins", + filter=["*.dylib"], + recursive=True, + dir_filter_function=general_dir_filter, + file_filter_function=file_variant_filter, + vars=vars) + - # <qt>/plugins/* -> <setup>/PySide2/Qt/plugins - copydir("{qt_plugins_dir}", - "{pyside_package_dir}/PySide2/Qt/plugins", - filter=["*.dylib"], - recursive=True, - dir_filter_function=general_dir_filter, - file_filter_function=file_variant_filter, - vars=vars) - - # <qt>/qml/* -> <setup>/PySide2/Qt/qml - copydir("{qt_qml_dir}", - "{pyside_package_dir}/PySide2/Qt/qml", - filter=None, - recursive=True, - force=False, - dir_filter_function=general_dir_filter, - file_filter_function=file_variant_filter, - vars=vars) - - # <qt>/translations/* -> <setup>/PySide2/Qt/translations - copydir("{qt_translations_dir}", - "{pyside_package_dir}/PySide2/Qt/translations", - filter=["*.qm", "*.pak"], - force=False, - vars=vars) + if copy_qml: + # <qt>/qml/* -> <setup>/{st_package_name}/Qt/qml + copydir("{qt_qml_dir}", + "{st_build_dir}/{st_package_name}/Qt/qml", + filter=None, + recursive=True, + force=False, + dir_filter_function=general_dir_filter, + file_filter_function=file_variant_filter, + vars=vars) + + if copy_translations: + # <qt>/translations/* -> + # <setup>/{st_package_name}/Qt/translations + copydir("{qt_translations_dir}", + "{st_build_dir}/{st_package_name}/Qt/translations", + filter=["*.qm", "*.pak"], + force=False, + vars=vars) diff --git a/build_scripts/platforms/unix.py b/build_scripts/platforms/unix.py index e7fa92390..7dce11612 100644 --- a/build_scripts/platforms/unix.py +++ b/build_scripts/platforms/unix.py @@ -37,73 +37,31 @@ ## ############################################################################# -import os, re, sys +import os +import sys from .linux import prepare_standalone_package_linux from .macos import prepare_standalone_package_macos + +from ..config import config from ..options import * from ..utils import copydir, copyfile, rmtree, makefile from ..utils import regenerate_qt_resources + def prepare_packages_posix(self, vars): executables = [] - # <build>/shiboken2/doc/html/* -> - # <setup>/PySide2/docs/shiboken2 - copydir( - "{build_dir}/shiboken2/doc/html", - "{pyside_package_dir}/PySide2/docs/shiboken2", - force=False, vars=vars) - # <install>/lib/site-packages/PySide2/* -> <setup>/PySide2 - copydir( - "{site_packages_dir}/PySide2", - "{pyside_package_dir}/PySide2", - vars=vars) - # <install>/lib/site-packages/shiboken2.so -> - # <setup>/PySide2/shiboken2.so - shiboken_module_name = 'shiboken2.so' - shiboken_src_path = "{site_packages_dir}".format(**vars) - maybe_shiboken_names = [f for f in os.listdir(shiboken_src_path) - if re.match(r'shiboken.*\.so', f)] - if maybe_shiboken_names: - shiboken_module_name = maybe_shiboken_names[0] - vars.update({'shiboken_module_name': shiboken_module_name}) - copyfile( - "{site_packages_dir}/{shiboken_module_name}", - "{pyside_package_dir}/PySide2/{shiboken_module_name}", - vars=vars) - # <install>/lib/site-packages/pyside2uic/* -> - # <setup>/pyside2uic + + # <install>/lib/site-packages/{st_package_name}/* -> + # <setup>/{st_package_name} + # This copies the module .so/.dylib files and various .py files + # (__init__, config, git version, etc.) copydir( - "{site_packages_dir}/pyside2uic", - "{pyside_package_dir}/pyside2uic", - force=False, vars=vars) - if sys.version_info[0] > 2: - rmtree("{pyside_package_dir}/pyside2uic/port_v2".format(**vars)) - else: - rmtree("{pyside_package_dir}/pyside2uic/port_v3".format(**vars)) - # <install>/bin/pyside2-uic -> PySide2/scripts/uic.py - makefile( - "{pyside_package_dir}/PySide2/scripts/__init__.py", + "{site_packages_dir}/{st_package_name}", + "{st_build_dir}/{st_package_name}", vars=vars) - copyfile( - "{install_dir}/bin/pyside2-uic", - "{pyside_package_dir}/PySide2/scripts/uic.py", - force=False, vars=vars) - copyfile( - "{install_dir}/bin/pyside_tool.py", - "{pyside_package_dir}/PySide2/scripts/pyside_tool.py", - force=False, vars=vars) - # <install>/bin/* -> PySide2/ - executables.extend(copydir( - "{install_dir}/bin/", - "{pyside_package_dir}/PySide2", - filter=[ - "pyside2-lupdate", - "pyside2-rcc", - "shiboken2", - ], - recursive=False, vars=vars)) - # <install>/lib/lib* -> PySide2/ - config = self.get_built_pyside_config(vars) + + generated_config = self.get_built_pyside_config(vars) + def adjusted_lib_name(name, version): postfix = '' if sys.platform.startswith('linux'): @@ -111,61 +69,144 @@ def prepare_packages_posix(self, vars): elif sys.platform == 'darwin': postfix = '.' + version + '.dylib' return name + postfix - copydir( - "{install_dir}/lib/", - "{pyside_package_dir}/PySide2", - filter=[ - adjusted_lib_name("libpyside*", - config['pyside_library_soversion']), - adjusted_lib_name("libshiboken*", - config['shiboken_library_soversion']), - ], - recursive=False, vars=vars, force_copy_symlinks=True) - # <install>/share/PySide2/typesystems/* -> - # <setup>/PySide2/typesystems - copydir( - "{install_dir}/share/PySide2/typesystems", - "{pyside_package_dir}/PySide2/typesystems", - vars=vars) - # <install>/include/* -> <setup>/PySide2/include - copydir( - "{install_dir}/include", - "{pyside_package_dir}/PySide2/include", - vars=vars) - # <source>/pyside2/PySide2/support/* -> - # <setup>/PySide2/support/* - copydir( - "{build_dir}/pyside2/PySide2/support", - "{pyside_package_dir}/PySide2/support", - vars=vars) - if not OPTION_NOEXAMPLES: - # 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) - pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format( - **vars) - pyside_rcc_options = '-py3' - regenerate_qt_resources(examples_path, pyside_rcc_path, - pyside_rcc_options) + + if config.is_internal_shiboken_module_build(): + # <build>/shiboken2/doc/html/* -> + # <setup>/{st_package_name}/docs/shiboken2 + copydir( + "{build_dir}/shiboken2/doc/html", + "{st_build_dir}/{st_package_name}/docs/shiboken2", + force=False, vars=vars) + + # <install>/lib/lib* -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=[ + adjusted_lib_name("libshiboken*", + generated_config['shiboken_library_soversion']), + ], + recursive=False, vars=vars, force_copy_symlinks=True) + + if config.is_internal_shiboken_generator_build(): + # <install>/bin/* -> {st_package_name}/ + executables.extend(copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=[ + "shiboken2", + ], + recursive=False, vars=vars)) + + # Used to create scripts directory. + makefile( + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + vars=vars) + + # For setting up setuptools entry points. + copyfile( + "{install_dir}/bin/shiboken_tool.py", + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + force=False, vars=vars) + + if config.is_internal_shiboken_generator_build() or config.is_internal_pyside_build(): + # <install>/include/* -> <setup>/{st_package_name}/include + copydir( + "{install_dir}/include/{cmake_package_name}", + "{st_build_dir}/{st_package_name}/include", + vars=vars) + + if config.is_internal_pyside_build(): + # <install>/lib/site-packages/pyside2uic/* -> + # <setup>/pyside2uic + copydir( + "{site_packages_dir}/pyside2uic", + "{st_build_dir}/pyside2uic", + force=False, vars=vars) + if sys.version_info[0] > 2: + rmtree("{st_build_dir}/pyside2uic/port_v2".format(**vars)) + else: + rmtree("{st_build_dir}/pyside2uic/port_v3".format(**vars)) + + # <install>/bin/pyside2-uic -> {st_package_name}/scripts/uic.py + makefile( + "{st_build_dir}/{st_package_name}/scripts/__init__.py", + vars=vars) + copyfile( + "{install_dir}/bin/pyside2-uic", + "{st_build_dir}/{st_package_name}/scripts/uic.py", + force=False, vars=vars) + + # For setting up setuptools entry points + copyfile( + "{install_dir}/bin/pyside_tool.py", + "{st_build_dir}/{st_package_name}/scripts/pyside_tool.py", + force=False, vars=vars) + + # <install>/bin/* -> {st_package_name}/ + executables.extend(copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=[ + "pyside2-lupdate", + "pyside2-rcc", + ], + recursive=False, vars=vars)) + + # <install>/lib/lib* -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=[ + adjusted_lib_name("libpyside*", + generated_config['pyside_library_soversion']), + ], + recursive=False, vars=vars, force_copy_symlinks=True) + + # <install>/share/{st_package_name}/typesystems/* -> + # <setup>/{st_package_name}/typesystems + copydir( + "{install_dir}/share/{st_package_name}/typesystems", + "{st_build_dir}/{st_package_name}/typesystems", + vars=vars) + + # <source>/pyside2/{st_package_name}/support/* -> + # <setup>/{st_package_name}/support/* + copydir( + "{build_dir}/pyside2/{st_package_name}/support", + "{st_build_dir}/{st_package_name}/support", + vars=vars) + + if not OPTION_NOEXAMPLES: + # examples/* -> <setup>/{st_package_name}/examples + copydir(os.path.join(self.script_dir, "examples"), + "{st_build_dir}/{st_package_name}/examples", + force=False, vars=vars) + # Re-generate examples Qt resource files for Python 3 + # compatibility + if sys.version_info[0] == 3: + examples_path = "{st_build_dir}/{st_package_name}/examples".format( + **vars) + pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format( + **vars) + pyside_rcc_options = '-py3' + regenerate_qt_resources(examples_path, pyside_rcc_path, + pyside_rcc_options) + # Copy Qt libs to package if OPTION_STANDALONE: - vars['built_modules'] = config['built_modules'] - if sys.platform == 'darwin': - prepare_standalone_package_macos(self, executables, vars) - else: - prepare_standalone_package_linux(self, executables, vars) + if config.is_internal_pyside_build() or config.is_internal_shiboken_generator_build(): + vars['built_modules'] = generated_config['built_modules'] + if sys.platform == 'darwin': + prepare_standalone_package_macos(self, vars) + else: + prepare_standalone_package_linux(self, vars) - # Copy over clang before rpath patching. - self.prepare_standalone_clang(is_win=False) + if config.is_internal_shiboken_generator_build(): + # 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) + if sys.platform.startswith('linux') or sys.platform.startswith('darwin'): + rpath_path = "{st_build_dir}/{st_package_name}".format(**vars) + self.update_rpath(rpath_path, executables) diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py index aa9487ec6..6307238a1 100644 --- a/build_scripts/platforms/windows_desktop.py +++ b/build_scripts/platforms/windows_desktop.py @@ -38,153 +38,225 @@ ############################################################################# import functools -import os, re, sys +import os +import sys + +from ..config import config from ..options import * from ..utils import copydir, copyfile, rmtree, makefile from ..utils import regenerate_qt_resources, filter_match from ..utils import download_and_extract_7z + def prepare_packages_win32(self, vars): # For now, debug symbols will not be shipped into the package. copy_pdbs = False pdbs = [] if (self.debug or self.build_type == 'RelWithDebInfo') and copy_pdbs: pdbs = ['*.pdb'] - # <install>/lib/site-packages/PySide2/* -> <setup>/PySide2 + + # <install>/lib/site-packages/{st_package_name}/* -> + # <setup>/{st_package_name} + # This copies the module .pyd files and various .py files + # (__init__, config, git version, etc.) copydir( - "{site_packages_dir}/PySide2", - "{pyside_package_dir}/PySide2", + "{site_packages_dir}/{st_package_name}", + "{st_build_dir}/{st_package_name}", vars=vars) - built_modules = self.get_built_pyside_config(vars)['built_modules'] - # <build>/pyside2/PySide2/*.pdb -> <setup>/PySide2 - copydir( - "{build_dir}/pyside2/PySide2", - "{pyside_package_dir}/PySide2", - filter=pdbs, - recursive=False, vars=vars) + if config.is_internal_shiboken_module_build(): + # <build>/shiboken2/doc/html/* -> + # <setup>/{st_package_name}/docs/shiboken2 + copydir( + "{build_dir}/shiboken2/doc/html", + "{st_build_dir}/{st_package_name}/docs/shiboken2", + force=False, vars=vars) + + # <install>/bin/*.dll -> {st_package_name}/ + copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=["shiboken*.dll"], + recursive=False, vars=vars) - # <build>/shiboken2/doc/html/* -> - # <setup>/PySide2/docs/shiboken2 - copydir( - "{build_dir}/shiboken2/doc/html", - "{pyside_package_dir}/PySide2/docs/shiboken2", - force=False, vars=vars) - - # <install>/lib/site-packages/shiboken2.pyd -> - # <setup>/PySide2/shiboken2.pyd - shiboken_module_name = 'shiboken2.pyd' - shiboken_src_path = "{site_packages_dir}".format(**vars) - maybe_shiboken_names = [f for f in os.listdir(shiboken_src_path) - if re.match(r'shiboken.*\.pyd', f)] - if maybe_shiboken_names: - shiboken_module_name = maybe_shiboken_names[0] - vars.update({'shiboken_module_name': shiboken_module_name}) - copyfile( - "{site_packages_dir}/{shiboken_module_name}", - "{pyside_package_dir}/PySide2/{shiboken_module_name}", - vars=vars) - # @TODO: Fix this .pdb file not to overwrite release - # {shibokengenerator}.pdb file. - # Task-number: PYSIDE-615 - copydir( - "{build_dir}/shiboken2/shibokenmodule", - "{pyside_package_dir}/PySide2", - filter=pdbs, - recursive=False, vars=vars) + # <install>/lib/*.lib -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=["shiboken*.lib"], + recursive=False, vars=vars) - # <install>/lib/site-packages/pyside2uic/* -> - # <setup>/pyside2uic - copydir( - "{site_packages_dir}/pyside2uic", - "{pyside_package_dir}/pyside2uic", - force=False, vars=vars) - if sys.version_info[0] > 2: - rmtree("{pyside_package_dir}/pyside2uic/port_v2".format(**vars)) - else: - rmtree("{pyside_package_dir}/pyside2uic/port_v3".format(**vars)) + # @TODO: Fix this .pdb file not to overwrite release + # {shibokengenerator}.pdb file. + # Task-number: PYSIDE-615 + copydir( + "{build_dir}/shiboken2/shibokenmodule", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) - # <install>/bin/pyside2-uic -> PySide2/scripts/uic.py - makefile( - "{pyside_package_dir}/PySide2/scripts/__init__.py", - vars=vars) - copyfile( - "{install_dir}/bin/pyside2-uic", - "{pyside_package_dir}/PySide2/scripts/uic.py", - force=False, vars=vars) - - # For setting up entry points - copyfile( - "{install_dir}/bin/pyside_tool.py", - "{pyside_package_dir}/PySide2/scripts/pyside_tool.py", - force=False, vars=vars) - - # <install>/bin/*.exe,*.dll,*.pdb -> PySide2/ - copydir( - "{install_dir}/bin/", - "{pyside_package_dir}/PySide2", - filter=["*.exe", "*.dll"], - recursive=False, vars=vars) - # @TODO: Fix this .pdb file not to overwrite release - # {shibokenmodule}.pdb file. - # Task-number: PYSIDE-615 - copydir( - "{build_dir}/shiboken2/generator", - "{pyside_package_dir}/PySide2", - filter=pdbs, - recursive=False, vars=vars) + # pdb files for libshiboken and libpyside + copydir( + "{build_dir}/shiboken2/libshiboken", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) - # <install>/lib/*.lib -> PySide2/ - copydir( - "{install_dir}/lib/", - "{pyside_package_dir}/PySide2", - filter=["*.lib"], - recursive=False, vars=vars) + if config.is_internal_shiboken_generator_build(): + # <install>/bin/*.dll -> {st_package_name}/ + copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=["shiboken*.exe"], + recursive=False, vars=vars) - # <install>/share/PySide2/typesystems/* -> - # <setup>/PySide2/typesystems - copydir( - "{install_dir}/share/PySide2/typesystems", - "{pyside_package_dir}/PySide2/typesystems", - vars=vars) + # Used to create scripts directory. + makefile( + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + vars=vars) - # <install>/include/* -> <setup>/PySide2/include - copydir( - "{install_dir}/include", - "{pyside_package_dir}/PySide2/include", - vars=vars) + # For setting up setuptools entry points. + copyfile( + "{install_dir}/bin/shiboken_tool.py", + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + force=False, vars=vars) + + # @TODO: Fix this .pdb file not to overwrite release + # {shibokenmodule}.pdb file. + # Task-number: PYSIDE-615 + copydir( + "{build_dir}/shiboken2/generator", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) - # <source>/pyside2/PySide2/support/* -> - # <setup>/PySide2/support/* - copydir( - "{build_dir}/pyside2/PySide2/support", - "{pyside_package_dir}/PySide2/support", - vars=vars) + if config.is_internal_shiboken_generator_build() or config.is_internal_pyside_build(): + # <install>/include/* -> <setup>/{st_package_name}/include + copydir( + "{install_dir}/include/{cmake_package_name}", + "{st_build_dir}/{st_package_name}/include", + vars=vars) + + if config.is_internal_pyside_build(): + # <build>/pyside2/{st_package_name}/*.pdb -> + # <setup>/{st_package_name} + copydir( + "{build_dir}/pyside2/{st_package_name}", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) + + # <install>/lib/site-packages/pyside2uic/* -> + # <setup>/pyside2uic + copydir( + "{site_packages_dir}/pyside2uic", + "{st_build_dir}/pyside2uic", + force=False, vars=vars) + if sys.version_info[0] > 2: + rmtree("{st_build_dir}/pyside2uic/port_v2".format(**vars)) + else: + rmtree("{st_build_dir}/pyside2uic/port_v3".format(**vars)) + + # <install>/bin/pyside2-uic -> {st_package_name}/scripts/uic.py + makefile( + "{st_build_dir}/{st_package_name}/scripts/__init__.py", + vars=vars) + copyfile( + "{install_dir}/bin/pyside2-uic", + "{st_build_dir}/{st_package_name}/scripts/uic.py", + force=False, vars=vars) + + # For setting up setuptools entry points + copyfile( + "{install_dir}/bin/pyside_tool.py", + "{st_build_dir}/{st_package_name}/scripts/pyside_tool.py", + force=False, vars=vars) + + # <install>/bin/*.exe,*.dll -> {st_package_name}/ + copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=["pyside*.exe", "pyside*.dll"], + recursive=False, vars=vars) + + # <install>/lib/*.lib -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=["pyside*.lib"], + recursive=False, vars=vars) + + # <install>/share/{st_package_name}/typesystems/* -> + # <setup>/{st_package_name}/typesystems + copydir( + "{install_dir}/share/{st_package_name}/typesystems", + "{st_build_dir}/{st_package_name}/typesystems", + vars=vars) + + # <source>/pyside2/{st_package_name}/support/* -> + # <setup>/{st_package_name}/support/* + copydir( + "{build_dir}/pyside2/{st_package_name}/support", + "{st_build_dir}/{st_package_name}/support", + vars=vars) + + copydir( + "{build_dir}/pyside2/libpyside", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) - if not OPTION_NOEXAMPLES: - # examples/* -> <setup>/PySide2/examples - copydir(os.path.join(self.script_dir, "examples"), - "{pyside_package_dir}/PySide2/examples", + if not OPTION_NOEXAMPLES: + # examples/* -> <setup>/{st_package_name}/examples + copydir(os.path.join(self.script_dir, "examples"), + "{st_build_dir}/{st_package_name}/examples", + force=False, vars=vars) + # Re-generate examples Qt resource files for Python 3 + # compatibility + if sys.version_info[0] == 3: + examples_path = "{st_build_dir}/{st_package_name}/examples".format( + **vars) + pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format( + **vars) + pyside_rcc_options = '-py3' + regenerate_qt_resources(examples_path, pyside_rcc_path, + pyside_rcc_options) + + if vars['ssl_libs_dir']: + # <ssl_libs>/* -> <setup>/{st_package_name}/openssl + copydir("{ssl_libs_dir}", "{st_build_dir}/{st_package_name}/openssl", + filter=[ + "libeay32.dll", + "ssleay32.dll"], 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) - pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format( - **vars) - pyside_rcc_options = '-py3' - regenerate_qt_resources(examples_path, pyside_rcc_path, - pyside_rcc_options) - - # <ssl_libs>/* -> <setup>/PySide2/openssl - copydir("{ssl_libs_dir}", "{pyside_package_dir}/PySide2/openssl", - filter=[ - "libeay32.dll", - "ssleay32.dll"], - force=False, vars=vars) - - # <qt>/bin/*.dll and Qt *.exe -> <setup>/PySide2 + + if config.is_internal_pyside_build() or config.is_internal_shiboken_generator_build(): + copy_qt_artifacts(self, copy_pdbs, vars) + + +def copy_qt_artifacts(self, copy_pdbs, vars): + built_modules = self.get_built_pyside_config(vars)['built_modules'] + + constrain_modules = None + copy_plugins = True + copy_qml = True + copy_translations = True + copy_qt_conf = True + copy_qt_permanent_artifacts = True + copy_msvc_redist = False + copy_clang = False + + if config.is_internal_shiboken_generator_build(): + constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"] + copy_plugins = False + copy_qml = False + copy_translations = False + copy_qt_conf = False + copy_qt_permanent_artifacts = False + copy_msvc_redist = True + copy_clang = True + + # <qt>/bin/*.dll and Qt *.exe -> <setup>/{st_package_name} qt_artifacts_permanent = [ "opengl*.dll", "d3d*.dll", @@ -195,6 +267,7 @@ def prepare_packages_win32(self, vars): "lconvert.exe", "qtdiag.exe" ] + # MSVC redistributable msvc_redist = [ "concrt140.dll", @@ -218,8 +291,14 @@ def prepare_packages_win32(self, vars): else: egl_suffix = '' qt_artifacts_egl = [a.format(egl_suffix) for a in qt_artifacts_egl] - qt_artifacts_permanent += qt_artifacts_egl - qt_artifacts_permanent += msvc_redist + + artifacts = [] + if copy_qt_permanent_artifacts: + artifacts += qt_artifacts_permanent + artifacts += qt_artifacts_egl + + if copy_msvc_redist: + artifacts += msvc_redist # Extract Qt dependency dll's when building on Qt CI # There is no proper CI env variable, so using agent launch params @@ -231,15 +310,22 @@ def prepare_packages_win32(self, vars): zip_file = "pyside_qt_deps_32.7z" download_and_extract_7z(redist_url + zip_file, "{qt_bin_dir}".format(**vars)) - copydir("{qt_bin_dir}", "{pyside_package_dir}/PySide2", - filter=qt_artifacts_permanent, - recursive=False, vars=vars) + if artifacts: + copydir("{qt_bin_dir}", + "{st_build_dir}/{st_package_name}", + filter=artifacts, recursive=False, vars=vars) - # <qt>/bin/*.dll and Qt *.pdbs -> <setup>/PySide2 part two + # <qt>/bin/*.dll and Qt *.pdbs -> <setup>/{st_package_name} part two # File filter to copy only debug or only release files. - qt_dll_patterns = ["Qt5*{}.dll", "lib*{}.dll"] - if copy_pdbs: - qt_dll_patterns += ["Qt5*{}.pdb", "lib*{}.pdb"] + if constrain_modules: + qt_dll_patterns = ["Qt5" + x + "{}.dll" for x in constrain_modules] + if copy_pdbs: + qt_dll_patterns += ["Qt5" + x + "{}.pdb" for x in constrain_modules] + else: + qt_dll_patterns = ["Qt5*{}.dll", "lib*{}.dll"] + if copy_pdbs: + qt_dll_patterns += ["Qt5*{}.pdb", "lib*{}.pdb"] + def qt_build_config_filter(patterns, file_name, file_full_path): release = [a.format('') for a in patterns] debug = [a.format('d') for a in patterns] @@ -289,56 +375,60 @@ def prepare_packages_win32(self, vars): return False qt_dll_filter = functools.partial(qt_build_config_filter, - qt_dll_patterns) - copydir("{qt_bin_dir}", "{pyside_package_dir}/PySide2", - file_filter_function=qt_dll_filter, - recursive=False, vars=vars) - - # <qt>/plugins/* -> <setup>/PySide2/plugins - plugin_dll_patterns = ["*{}.dll"] - pdb_pattern = "*{}.pdb" - if copy_pdbs: - plugin_dll_patterns += [pdb_pattern] - plugin_dll_filter = functools.partial(qt_build_config_filter, - plugin_dll_patterns) - copydir("{qt_plugins_dir}", "{pyside_package_dir}/PySide2/plugins", - file_filter_function=plugin_dll_filter, - vars=vars) + qt_dll_patterns) + copydir("{qt_bin_dir}", + "{st_build_dir}/{st_package_name}", + file_filter_function=qt_dll_filter, + recursive=False, vars=vars) - # <qt>/translations/* -> <setup>/PySide2/translations - copydir("{qt_translations_dir}", - "{pyside_package_dir}/PySide2/translations", - filter=["*.qm", "*.pak"], - force=False, - vars=vars) + if copy_plugins: + # <qt>/plugins/* -> <setup>/{st_package_name}/plugins + plugin_dll_patterns = ["*{}.dll"] + pdb_pattern = "*{}.pdb" + if copy_pdbs: + plugin_dll_patterns += [pdb_pattern] + plugin_dll_filter = functools.partial(qt_build_config_filter, + plugin_dll_patterns) + copydir("{qt_plugins_dir}", "{st_build_dir}/{st_package_name}/plugins", + file_filter_function=plugin_dll_filter, + vars=vars) - # <qt>/qml/* -> <setup>/PySide2/qml - qml_dll_patterns = ["*{}.dll"] - qml_ignore_patterns = qml_dll_patterns + [pdb_pattern] - qml_ignore = [a.format('') for a in qml_ignore_patterns] + if copy_translations: + # <qt>/translations/* -> <setup>/{st_package_name}/translations + copydir("{qt_translations_dir}", + "{st_build_dir}/{st_package_name}/translations", + filter=["*.qm", "*.pak"], + force=False, + vars=vars) - # Copy all files that are not dlls and pdbs (.qml, qmldir). - copydir("{qt_qml_dir}", "{pyside_package_dir}/PySide2/qml", - ignore=qml_ignore, - force=False, - recursive=True, - vars=vars) + if copy_qml: + # <qt>/qml/* -> <setup>/{st_package_name}/qml + qml_dll_patterns = ["*{}.dll"] + qml_ignore_patterns = qml_dll_patterns + [pdb_pattern] + qml_ignore = [a.format('') for a in qml_ignore_patterns] + + # Copy all files that are not dlls and pdbs (.qml, qmldir). + copydir("{qt_qml_dir}", "{st_build_dir}/{st_package_name}/qml", + ignore=qml_ignore, + force=False, + recursive=True, + vars=vars) - if copy_pdbs: - qml_dll_patterns += [pdb_pattern] - qml_dll_filter = functools.partial(qt_build_config_filter, - qml_dll_patterns) + if copy_pdbs: + qml_dll_patterns += [pdb_pattern] + qml_dll_filter = functools.partial(qt_build_config_filter, + qml_dll_patterns) - # Copy all dlls (and possibly pdbs). - copydir("{qt_qml_dir}", "{pyside_package_dir}/PySide2/qml", - file_filter_function=qml_dll_filter, - force=False, - recursive=True, - vars=vars) + # Copy all dlls (and possibly pdbs). + copydir("{qt_qml_dir}", "{st_build_dir}/{st_package_name}/qml", + file_filter_function=qml_dll_filter, + force=False, + recursive=True, + vars=vars) if self.is_webengine_built(built_modules): copydir("{qt_prefix_dir}/resources", - "{pyside_package_dir}/PySide2/resources", + "{st_build_dir}/{st_package_name}/resources", filter=None, recursive=False, vars=vars) @@ -346,26 +436,16 @@ def prepare_packages_win32(self, vars): filter = 'QtWebEngineProcess{}.exe'.format( 'd' if self.debug else '') copydir("{qt_bin_dir}", - "{pyside_package_dir}/PySide2", + "{st_build_dir}/{st_package_name}", filter=[filter], recursive=False, vars=vars) - # Copy the qt.conf file to prefix dir. - copyfile( - "{build_dir}/pyside2/PySide2/qt.conf", - "{pyside_package_dir}/PySide2", - vars=vars) - - self.prepare_standalone_clang(is_win=True) + if copy_qt_conf: + # Copy the qt.conf file to prefix dir. + copyfile( + "{build_dir}/pyside2/{st_package_name}/qt.conf", + "{st_build_dir}/{st_package_name}", + vars=vars) - # pdb files for libshiboken and libpyside - copydir( - "{build_dir}/shiboken2/libshiboken", - "{pyside_package_dir}/PySide2", - filter=pdbs, - recursive=False, vars=vars) - copydir( - "{build_dir}/pyside2/libpyside", - "{pyside_package_dir}/PySide2", - filter=pdbs, - recursive=False, vars=vars) + if copy_clang: + self.prepare_standalone_clang(is_win=True) |