summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <me@the-compiler.org>2020-11-25 09:05:27 +0100
committerFlorian Bruhin <me@the-compiler.org>2020-11-25 09:28:28 +0100
commit80646f9152e292f8c528ed69bad2116d3e54f3ef (patch)
treedd4f775d106df673dd98a98c2114be29343087bc
parent7e1c4dc1cee8aa94c0faed6c59c5b5caf4791e3b (diff)
downloadqutebrowser-80646f9152e292f8c528ed69bad2116d3e54f3ef.tar.gz
qutebrowser-80646f9152e292f8c528ed69bad2116d3e54f3ef.zip
scripts: Add libxcb-util workaround to mkvenv.py
Closes #5905 (cherry picked from commit ba152cbe4ab3c97110a21df02ee858dcc8c8f14b)
-rw-r--r--scripts/mkvenv.py88
1 files changed, 85 insertions, 3 deletions
diff --git a/scripts/mkvenv.py b/scripts/mkvenv.py
index 5eeb90640..da86e7f49 100644
--- a/scripts/mkvenv.py
+++ b/scripts/mkvenv.py
@@ -93,13 +93,22 @@ def pyqt_versions() -> typing.List[str]:
return versions + ['auto']
-def run_venv(venv_dir: pathlib.Path, executable, *args: str) -> None:
+def run_venv(
+ venv_dir: pathlib.Path,
+ executable,
+ *args: str,
+ capture_output=False,
+) -> subprocess.CompletedProcess:
"""Run the given command inside the virtualenv."""
subdir = 'Scripts' if os.name == 'nt' else 'bin'
try:
- subprocess.run([str(venv_dir / subdir / executable)] +
- [str(arg) for arg in args], check=True)
+ return subprocess.run(
+ [str(venv_dir / subdir / executable)] + [str(arg) for arg in args],
+ check=True,
+ universal_newlines=capture_output,
+ stdout=subprocess.PIPE if capture_output else None,
+ )
except subprocess.CalledProcessError as e:
utils.print_error("Subprocess failed, exiting")
sys.exit(e.returncode)
@@ -202,6 +211,77 @@ def install_pyqt_wheels(venv_dir: pathlib.Path,
pip_install(venv_dir, *wheels)
+def apply_xcb_util_workaround(
+ venv_dir: pathlib.Path,
+ pyqt_type: str,
+ pyqt_version: str,
+) -> None:
+ """If needed (Debian Stable), symlink libxcb-util.so.0 -> .1.
+
+ WORKAROUND for https://bugreports.qt.io/browse/QTBUG-88688
+ """
+ utils.print_title("Running xcb-util workaround")
+
+ if not sys.platform.startswith('linux'):
+ print("Workaround not needed: Not on Linux.")
+ return
+ if pyqt_type != 'binary':
+ print("Workaround not needed: Not installing from PyQt binaries.")
+ return
+ if pyqt_version not in ['auto', '5.15']:
+ print("Workaround not needed: Not installing Qt 5.15.")
+ return
+
+ libs = _find_libs()
+ if 'libxcb-util.so.1' in libs:
+ print("Workaround not needed: libxcb-util.so.1 found.")
+ return
+
+ try:
+ libxcb_util_path = pathlib.Path(libs['libxcb-util.so.0'])
+ except KeyError:
+ utils.print_col('Workaround failed: libxcb-util.so.0 not found.', 'red')
+ return
+
+ code = [
+ 'from PyQt5.QtCore import QLibraryInfo',
+ 'print(QLibraryInfo.location(QLibraryInfo.LibrariesPath))',
+ ]
+ proc = run_venv(venv_dir, 'python', '-c', '; '.join(code), capture_output=True)
+ venv_lib_path = pathlib.Path(proc.stdout.strip())
+
+ link_path = venv_lib_path / libxcb_util_path.with_suffix('.1').name
+
+ # This gives us a nicer path to print, and also conveniently makes sure we
+ # didn't accidentally end up with a path outside the venv.
+ rel_link_path = venv_dir / link_path.relative_to(venv_dir.resolve())
+ utils.print_col(f'$ ln -s {libxcb_util_path} {rel_link_path}', 'blue')
+
+ link_path.symlink_to(libxcb_util_path)
+
+
+def _find_libs() -> typing.Dict[str, str]:
+ """Find all system-wide .so libraries."""
+ all_libs = {} # type: typing.Dict[str, str]
+ ldconfig_proc = subprocess.run(
+ ['ldconfig', '-p'],
+ check=True,
+ stdout=subprocess.PIPE,
+ encoding=sys.getfilesystemencoding(),
+ )
+ for line in ldconfig_proc.stdout.splitlines():
+ if ' => ' not in line:
+ continue
+ line = line.strip()
+ name, path = line.split(' => ')
+ name = name.split(' (')[0]
+ if name in all_libs:
+ raise ValueError(f'Found duplicate {name} ({all_libs[name]}; {path})')
+ all_libs[name] = path
+
+ return all_libs
+
+
def install_requirements(venv_dir: pathlib.Path) -> None:
"""Install qutebrowser's requirement.txt."""
utils.print_title("Installing other qutebrowser dependencies")
@@ -275,6 +355,8 @@ def main() -> None:
else:
raise AssertionError
+ apply_xcb_util_workaround(venv_dir, args.pyqt_type, args.pyqt_version)
+
install_requirements(venv_dir)
install_qutebrowser(venv_dir)
if args.dev: