diff options
| author | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2024-07-19 10:24:09 +0200 |
|---|---|---|
| committer | Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> | 2024-07-23 14:29:06 +0200 |
| commit | c1bb2a15556a270181ff6473673080034b4a7f31 (patch) | |
| tree | 386f4faf0aca23064b8c72a62cc00bb1cf088306 /build_scripts/main.py | |
| parent | a92e6c17d5c4da92d0bd95b93ffa65e7245bb847 (diff) | |
Shiboken Build: Deal with libclang having a different SONAME
- In most of the newer prebuild libclang that Qt provides, the
SONAME of the actual libclang library varies from the actual
library. For example, the actual library might be called
libclang.so.14.0.0, but the SONAME might be libclang.so.13.
Normally, we only copy the actual library resulting in shiboken
generator not being able to find the library at runtime.
- During build, this works fine since a symlink already exists in the
libclang directory. However, this symlink is not copied into the
shiboken generator wheel.
- Since symlinks cannot be dealt with using Python setuptools, we
rename the actual library to the SONAME and copy it to
'package_for_wheels'.
Pick-to: 6.7
Task-number: PYSIDE-2819
Change-Id: Ic3703e4887f6c1ba3361ac9097a451fb33d61ed5
Reviewed-by: Adrian Herrmann <adrian.herrmann@qt.io>
Diffstat (limited to 'build_scripts/main.py')
| -rw-r--r-- | build_scripts/main.py | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/build_scripts/main.py b/build_scripts/main.py index 3ad1cb2c5..506a9891f 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -7,6 +7,7 @@ import os import platform import re import sys +import subprocess import sysconfig import time from packaging.version import parse as parse_version @@ -161,6 +162,22 @@ def prepare_build(): qt_src_dir = maybe_qt_src_dir +def get_soname(clang_lib_path: Path) -> str: + """Getting SONAME from a shared library using readelf. Works only on Linux. + """ + clang_lib_path = Path(clang_lib_path) + try: + result = subprocess.run(['readelf', '-d', str(clang_lib_path)], + capture_output=True, text=True, check=True) + for line in result.stdout.split('\n'): + if 'SONAME' in line: + soname = line.split('[')[1].split(']')[0] + return soname + except subprocess.CalledProcessError as e: + print(f"Failed to get SONAME: {e}") + return None + + class PysideInstall(_install, CommandMixin): user_options = _install.user_options + CommandMixin.mixin_user_options @@ -1051,6 +1068,18 @@ class PysideBuild(_build, CommandMixin, BuildInfoCollectorMixin): f"folder as {basename}.") destination_path = destination_dir / basename + # It is possible that the resolved libclang has a different SONAME + # For example the actual libclang might be named libclang.so.14.0.0 and its + # SONAME might be libclang.so.13 + # In this case, the ideal approach is to find the SONAME and create a symlink to the + # actual libclang in the destination directory. But, Python packaging (setuptools) + # does not support symlinks. + # So, we rename the actual libclang to the SONAME and copy it to the destination + if sys.platform == 'linux': + soname = get_soname(clang_lib_path) + if soname and soname != clang_lib_path.name: + destination_path = destination_path.parent / soname + # Need to modify permissions in case file is not writable # (a reinstall would cause a permission denied error). copyfile(clang_lib_path, |
