diff options
author | Alexandru Croitor <alexandru.croitor@qt.io> | 2017-11-03 16:46:17 +0100 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@qt.io> | 2017-11-15 15:47:06 +0000 |
commit | f970327f8d40a81d4801918d3e6cb1fc44ff2292 (patch) | |
tree | c9bf7e2a9b177b41f7443d07fe3de508fa29dfb7 | |
parent | a7f3f7d3e711520a32f87aace8df265589a649e7 (diff) |
Make standalone option work on Linux
Changes were made to copy the correct Qt shared libraries into the
package (updated to Qt5 naming).
A new rpath value will be inserted alongside $ORIGIN, to point to
the copied over libraries.
Also because symlinks are not supported by wheels, the actual Qt
libraries have to be copied instead of the symlinks.
Change-Id: I656a89a0b0136a290752bca141125bdeb5bb44d5
Task-number: PYSIDE-558
Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r-- | setup.py | 99 | ||||
-rw-r--r-- | utils.py | 10 |
2 files changed, 69 insertions, 40 deletions
@@ -953,6 +953,21 @@ class pyside_build(_build): print('setup.py/prepare_packages: ', e) raise + def get_built_pyside_modules(self, vars): + # Get list of built modules, so that we copy only required Qt libraries. + pyside_package_dir = vars['dist_dir'] + built_modules_path = os.path.join(pyside_package_dir, "PySide2", "_built_modules.py") + + try: + with open(built_modules_path) as f: + scoped_locals = {} + code = compile(f.read(), built_modules_path, 'exec') + exec(code, scoped_locals, scoped_locals) + return scoped_locals['built_modules'] + except IOError as e: + print("get_built_pyside_modules: Couldn't find file: {}.".format(built_modules_path)) + raise + def prepare_packages_posix(self, vars): executables = [] if sys.platform.startswith('linux'): @@ -1050,34 +1065,12 @@ class pyside_build(_build): pyside_rcc_options) # Copy Qt libs to package if OPTION_STANDALONE: + vars['built_modules'] = self.get_built_pyside_modules(vars) if sys.platform == 'darwin': self.prepare_standalone_package_osx(executables, vars) else: - # <qt>/bin/* -> <setup>/PySide2 - executables.extend(copydir("{qt_bin_dir}", "{dist_dir}/PySide2", - filter=[ - "designer", - "linguist", - "lrelease", - "lupdate", - "lconvert", - ], - recursive=False, vars=vars)) - # <qt>/lib/* -> <setup>/PySide2 - copydir("{qt_lib_dir}", "{dist_dir}/PySide2", - filter=[ - "libQt*.so.?", - "libphonon.so.?", - ], - recursive=False, vars=vars) - # <qt>/plugins/* -> <setup>/PySide2/plugins - copydir("{qt_plugins_dir}", "{dist_dir}/PySide2/plugins", - filter=["*.so"], - vars=vars) - # <qt>/translations/* -> <setup>/PySide2/translations - copydir("{qt_translations_dir}", "{dist_dir}/PySide2/translations", - filter=["*.qm"], - vars=vars) + self.prepare_standalone_package_linux(executables, vars) + # Update rpath to $ORIGIN if sys.platform.startswith('linux') or sys.platform.startswith('darwin'): self.update_rpath("{dist_dir}/PySide2".format(**vars), executables) @@ -1087,16 +1080,50 @@ class pyside_build(_build): return True return False - def prepare_standalone_package_osx(self, executables, vars): - # Get list of built modules, so that we copy only required Qt libraries. - pyside_package_dir = vars['dist_dir'] - built_modules_path = os.path.join(pyside_package_dir, "PySide2", "_built_modules.py") + def prepare_standalone_package_linux(self, executables, vars): + built_modules = vars['built_modules'] + + # <qt>/lib/* -> <setup>/PySide2/Qt/lib + copydir("{qt_lib_dir}", "{dist_dir}/PySide2/Qt/lib", + filter=[ + "libQt5*.so.?", + "libicu*.so.??", + ], + recursive=False, vars=vars, force_copy_symlinks=True) + + if 'WebEngineWidgets' in built_modules: + copydir("{qt_lib_execs_dir}", "{dist_dir}/PySide2/Qt/libexec", + filter=None, + recursive=False, + vars=vars) + + copydir("{qt_prefix_dir}/resources", "{dist_dir}/PySide2/Qt/resources", + filter=None, + recursive=False, + vars=vars) - with open(built_modules_path) as f: - scoped_locals = {} - code = compile(f.read(), built_modules_path, 'exec') - exec(code, scoped_locals, scoped_locals) - built_modules = scoped_locals['built_modules'] + # <qt>/plugins/* -> <setup>/PySide2/Qt/plugins + copydir("{qt_plugins_dir}", "{dist_dir}/PySide2/Qt/plugins", + filter=["*.so"], + recursive=True, + vars=vars) + + # <qt>/qml/* -> <setup>/PySide2/Qt/qml + copydir("{qt_qml_dir}", "{dist_dir}/PySide2/Qt/qml", + filter=None, + force=False, + recursive=True, + vars=vars) + + # <qt>/translations/* -> <setup>/PySide2/Qt/translations + + copydir("{qt_translations_dir}", "{dist_dir}/PySide2/Qt/translations", + filter=["*.qm"], + force=False, + vars=vars) + + def prepare_standalone_package_osx(self, executables, vars): + built_modules = vars['built_modules'] # Directory filter for skipping unnecessary files. def general_dir_filter(dir_name, parent_full_path, dir_full_path): @@ -1363,7 +1390,9 @@ class pyside_build(_build): # Add rpath values pointing to $ORIGIN and the installed qt lib directory. local_rpath = '$ORIGIN/' qt_lib_dir = self.qtinfo.libs_dir - final_rpath = local_rpath + ':' + qt_lib_dir + if OPTION_STANDALONE: + qt_lib_dir = "$ORIGIN/Qt/lib" + final_rpath = local_rpath + ':' + qt_lib_dir cmd = [patchelf_path, '--set-rpath', final_rpath, srcpath] if run_process(cmd) != 0: raise RuntimeError("Error patching rpath in " + srcpath) @@ -222,7 +222,7 @@ def init_msvc_env(platform_arch, build_type): log.info("Done initializing MSVC env") -def copyfile(src, dst, force=True, vars=None): +def copyfile(src, dst, force=True, vars=None, force_copy_symlink=False): if vars is not None: src = src.format(**vars) dst = dst.format(**vars) @@ -231,7 +231,7 @@ def copyfile(src, dst, force=True, vars=None): log.info("**Skiping copy file %s to %s. Source does not exists." % (src, dst)) return - if not os.path.islink(src): + if not os.path.islink(src) or force_copy_symlink: log.info("Copying file %s to %s." % (src, dst)) shutil.copy2(src, dst) else: @@ -276,7 +276,7 @@ def makefile(dst, content=None, vars=None): def copydir(src, dst, filter=None, ignore=None, force=True, recursive=True, vars=None, - dir_filter_function=None): + dir_filter_function=None, force_copy_symlinks=False): if vars is not None: src = src.format(**vars) @@ -310,14 +310,14 @@ def copydir(src, dst, filter=None, ignore=None, force=True, recursive=True, vars if recursive: results.extend( copydir(srcname, dstname, filter, ignore, force, recursive, - vars, dir_filter_function)) + vars, dir_filter_function, force_copy_symlinks)) else: if (filter is not None and not filter_match(name, filter)) or \ (ignore is not None and filter_match(name, ignore)): continue if not os.path.exists(dst): os.makedirs(dst) - results.append(copyfile(srcname, dstname, True, vars)) + results.append(copyfile(srcname, dstname, True, vars, force_copy_symlinks)) # catch the Error from the recursive copytree so that we can # continue with other files except shutil.Error as err: |