aboutsummaryrefslogtreecommitdiffstats
path: root/build_scripts/main.py
diff options
context:
space:
mode:
authorShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2024-07-19 10:24:09 +0200
committerShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2024-07-23 14:29:06 +0200
commitc1bb2a15556a270181ff6473673080034b4a7f31 (patch)
tree386f4faf0aca23064b8c72a62cc00bb1cf088306 /build_scripts/main.py
parenta92e6c17d5c4da92d0bd95b93ffa65e7245bb847 (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.py29
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,