Skip to content

Commit 93a46d8

Browse files
committed
fix
1 parent 835349d commit 93a46d8

File tree

2 files changed

+75
-108
lines changed

2 files changed

+75
-108
lines changed

.ci/scripts/wheel/pre_build_script.sh

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,27 +57,23 @@ mkdir -p "$PREFIX/lib"
5757
echo ">>> Downloading prebuilt glibc-$GLIBC_VERSION (Fedora 35 RPM)"
5858
RPM_URL="https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/35/Everything/x86_64/os/Packages/g/glibc-2.34-7.fc35.x86_64.rpm"
5959

60-
# Download
6160
curl -fsSL "$RPM_URL" -o /tmp/glibc.rpm
6261

63-
# Extract directly with bsdtar
6462
echo ">>> Extracting RPM with bsdtar"
65-
bsdtar -C /tmp -xf /tmp/glibc.rpm
66-
67-
# Copy needed files from the extracted tree (not host system!)
68-
# Copy all runtime libs from extracted RPM
69-
cp -av /tmp/lib64/libc.so.6 \
70-
/tmp/lib64/ld-linux-x86-64.so.2 \
71-
/tmp/lib64/libdl.so.2 \
72-
/tmp/lib64/libpthread.so.0 \
73-
/tmp/lib64/librt.so.1 \
74-
/tmp/lib64/libm.so.6 \
75-
/tmp/lib64/libutil.so.1 \
63+
WORKDIR=/tmp/glibc-extracted
64+
rm -rf "$WORKDIR"
65+
mkdir -p "$WORKDIR"
66+
bsdtar -C "$WORKDIR" -xf /tmp/glibc.rpm
67+
68+
# Copy the loader and all runtime libs from the SAME glibc
69+
cp -av "$WORKDIR/lib64/ld-linux-x86-64.so.2" \
70+
"$WORKDIR/lib64/libc.so.6" \
71+
"$WORKDIR/lib64/libdl.so.2" \
72+
"$WORKDIR/lib64/libpthread.so.0" \
73+
"$WORKDIR/lib64/librt.so.1" \
74+
"$WORKDIR/lib64/libm.so.6" \
75+
"$WORKDIR/lib64/libutil.so.1" \
7676
"$PREFIX/lib/" || true
7777

78-
# Check what we staged
7978
echo ">>> Contents staged in $PREFIX/lib"
8079
ls -l "$PREFIX/lib"
81-
82-
# Verify version
83-
"$PREFIX/lib/libc.so.6" --version || true

backends/qualcomm/scripts/download_qnn_sdk.py

Lines changed: 62 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -183,114 +183,93 @@ def _extract_tar(archive_path: pathlib.Path, prefix: str, target_dir: pathlib.Pa
183183
####################
184184
# libc management
185185
####################
186-
187-
####################
188-
# libc management
189-
####################
190-
191186
GLIBC_VERSION = "2.34"
192187
GLIBC_ROOT = pathlib.Path(f"/tmp/glibc-install-{GLIBC_VERSION}")
193188
GLIBC_LIBDIR = GLIBC_ROOT / "lib"
194-
195-
# Loader candidates: Fedora RPM may give us either ld-2.34.so or ld-linux-x86-64.so.2
196-
GLIBC_LOADER_CANDIDATES = [
197-
GLIBC_LIBDIR / f"ld-{GLIBC_VERSION}.so",
198-
GLIBC_LIBDIR / "ld-linux-x86-64.so.2",
199-
]
200-
GLIBC_LOADER = next((p for p in GLIBC_LOADER_CANDIDATES if p.exists()), None)
201-
202189
GLIBC_REEXEC_GUARD = "QNN_GLIBC_REEXEC"
203-
MINIMUM_LIBC_VERSION = GLIBC_VERSION
204-
GLIBC_CUSTOM = str(GLIBC_LIBDIR / "libc.so.6")
190+
MINIMUM_LIBC_VERSION = GLIBC_VERSION # string like "2.34"
205191

206192

207193
def _parse_version(v: str) -> tuple[int, int]:
208194
parts = v.split(".")
209195
return int(parts[0]), int(parts[1]) if len(parts) > 1 else 0
210196

211197

212-
def check_glibc_exist_and_validate() -> bool:
213-
"""
214-
Validate glibc in /tmp, fallback to system libc only if custom one not found.
215-
"""
216-
candidates = [GLIBC_CUSTOM]
198+
def _resolve_glibc_loader() -> pathlib.Path | None:
199+
for p in [
200+
GLIBC_LIBDIR / f"ld-{GLIBC_VERSION}.so",
201+
GLIBC_LIBDIR / "ld-linux-x86-64.so.2",
202+
]:
203+
if p.exists():
204+
return p
205+
return None
217206

218-
# Optional: keep fallbacks for debugging (not recommended in CI if you always stage custom)
219-
candidates += [
220-
"/lib64/libc.so.6",
221-
"/lib/x86_64-linux-gnu/libc.so.6",
222-
"/lib/libc.so.6",
223-
]
224207

225-
for path in candidates:
226-
if not pathlib.Path(path).exists():
227-
continue
228-
try:
229-
output = subprocess.check_output(
230-
[path, "--version"], stderr=subprocess.STDOUT
231-
)
232-
first_line = output.decode().split("\n", 1)[0]
233-
logger.debug(f"[QNN] glibc version for path {path} is: {first_line}")
234-
235-
match = re.search(r"version (\d+\.\d+)", first_line)
236-
if match:
237-
version = match.group(1)
238-
if _parse_version(version) >= _parse_version(MINIMUM_LIBC_VERSION):
239-
logger.info(f"[QNN] Using glibc {version} from {path}")
240-
return True
241-
else:
242-
logger.error(
243-
f"[QNN] glibc version {version} too low at {path}. Need >= {MINIMUM_LIBC_VERSION}."
244-
)
245-
else:
246-
logger.error(f"[QNN] Could not parse glibc version from {first_line}")
247-
except Exception as e:
248-
logger.error(f"[QNN] Failed to check {path}: {e}")
208+
def _log_current_loader():
209+
"""Dump the loader and libc mappings from /proc/self/maps for debugging."""
210+
try:
211+
with open("/proc/self/maps") as f:
212+
for line in f:
213+
if "ld-" in line or "libc.so" in line:
214+
logger.info("[glibc] Loader map: %s", line.strip())
215+
except Exception as e:
216+
logger.warning("[glibc] Failed to read /proc/self/maps: %s", e)
249217

250-
logger.error(
251-
f"[QNN] glibc not found or too old. Minimum required: {MINIMUM_LIBC_VERSION}."
252-
)
253-
return False
218+
219+
def _current_glibc_version() -> str:
220+
try:
221+
libc = ctypes.CDLL("libc.so.6")
222+
func = libc.gnu_get_libc_version
223+
func.restype = ctypes.c_char_p
224+
return func().decode()
225+
except Exception as e:
226+
return f"error:{e}"
227+
228+
229+
def _run_under_custom_loader(argv: list[str]) -> bytes:
230+
loader = _resolve_glibc_loader()
231+
if not loader:
232+
raise FileNotFoundError(f"glibc loader not found in {GLIBC_LIBDIR}")
233+
cmd = [str(loader), "--library-path", str(GLIBC_LIBDIR), *argv]
234+
return subprocess.check_output(cmd, stderr=subprocess.STDOUT)
254235

255236

256237
def _check_tmp_glibc() -> bool:
257-
"""Check if staged glibc in /tmp was installed correctly and log its version."""
258238
libc_path = GLIBC_LIBDIR / "libc.so.6"
259239
if not libc_path.exists():
260240
logger.error("[glibc] Expected glibc at %s but file not found", libc_path)
261241
return False
262-
263242
try:
264-
out = subprocess.check_output(
265-
[str(libc_path), "--version"], stderr=subprocess.STDOUT
266-
)
243+
out = _run_under_custom_loader([str(libc_path), "--version"])
267244
first_line = out.decode(errors="ignore").split("\n", 1)[0]
268245
logger.info("[glibc] Found custom glibc at %s: %s", libc_path, first_line)
269246
return True
270247
except Exception as e:
271-
logger.error("[glibc] Failed to run %s --version: %s", libc_path, e)
248+
logger.error("[glibc] Failed to run libc under staged loader: %s", e)
272249
return False
273250

274251

275-
def _current_glibc_version() -> str:
276-
try:
277-
libc = ctypes.CDLL("libc.so.6")
278-
func = libc.gnu_get_libc_version
279-
func.restype = ctypes.c_char_p
280-
return func().decode()
281-
except Exception as e:
282-
return f"error:{e}"
283-
284-
285-
def _log_current_loader():
286-
"""Dump the loader and libc mappings from /proc/self/maps for debugging."""
252+
def check_glibc_exist_and_validate() -> bool:
253+
libc = GLIBC_LIBDIR / "libc.so.6"
254+
if not libc.exists():
255+
logger.error("[QNN] staged libc missing at %s", libc)
256+
return False
287257
try:
288-
with open("/proc/self/maps") as f:
289-
for line in f:
290-
if "ld-" in line or "libc.so" in line:
291-
logger.info("[glibc] Loader map: %s", line.strip())
258+
out = _run_under_custom_loader([str(libc), "--version"])
259+
first = out.decode(errors="ignore").split("\n", 1)[0]
260+
m = re.search(r"version (\d+\.\d+)", first)
261+
if not m:
262+
logger.error("[QNN] could not parse glibc version from: %s", first)
263+
return False
264+
ver = m.group(1)
265+
if _parse_version(ver) >= _parse_version(MINIMUM_LIBC_VERSION):
266+
logger.info("[QNN] Using glibc %s from %s", ver, libc)
267+
return True
268+
logger.error("[QNN] glibc %s < required %s", ver, MINIMUM_LIBC_VERSION)
269+
return False
292270
except Exception as e:
293-
logger.warning("[glibc] Failed to read /proc/self/maps: %s", e)
271+
logger.error("[QNN] failed to validate staged glibc: %s", e)
272+
return False
294273

295274

296275
def _ensure_glibc_minimum(min_version: str = GLIBC_VERSION):
@@ -302,21 +281,18 @@ def _ensure_glibc_minimum(min_version: str = GLIBC_VERSION):
302281
_log_current_loader()
303282
return
304283

305-
if not GLIBC_LOADER or not GLIBC_LOADER.exists():
284+
loader = _resolve_glibc_loader()
285+
if not loader:
306286
logger.error("[glibc] Loader not found in %s", GLIBC_LIBDIR)
307287
return
308288

309289
logger.info(
310-
"[glibc] Forcing re-exec under loader %s with libdir %s",
311-
GLIBC_LOADER,
312-
GLIBC_LIBDIR,
290+
"[glibc] Forcing re-exec under loader %s with libdir %s", loader, GLIBC_LIBDIR
313291
)
314-
315292
os.environ[GLIBC_REEXEC_GUARD] = "1"
316293
os.execv(
317-
str(GLIBC_LOADER),
318-
[str(GLIBC_LOADER), "--library-path", str(GLIBC_LIBDIR), sys.executable]
319-
+ sys.argv,
294+
str(loader),
295+
[str(loader), "--library-path", str(GLIBC_LIBDIR), sys.executable] + sys.argv,
320296
)
321297

322298

@@ -521,13 +497,8 @@ def install_qnn_sdk() -> bool:
521497
True if both steps succeeded (or were already satisfied), else False.
522498
"""
523499
logger.info("[QNN] Starting SDK installation")
524-
525500
_ensure_glibc_minimum(GLIBC_VERSION)
526-
527501
if not _check_tmp_glibc():
528502
logger.error("[glibc] Pre-installed glibc check failed. Exiting early.")
529503
return False
530-
531-
if _ensure_libcxx_stack() and _ensure_qnn_sdk_lib():
532-
return True
533-
return False
504+
return _ensure_libcxx_stack() and _ensure_qnn_sdk_lib()

0 commit comments

Comments
 (0)