Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

198 lines
6.3 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Copyright Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT
from pathlib import Path
import os
import platform
import shutil
import subprocess
import sys
repo_root = Path(__file__).resolve().parents[4]
build_tools_path = repo_root / "build_tools"
sys.path.insert(0, str(build_tools_path))
from patch_linux_so import relativize_pc_file
def rename_pc_files(pc_file: Path) -> None:
"""Rename a .pc file by removing the 'rocm_sysdeps_' prefix if present.
This function is used when ROCm‑patched pkg‑config files need to be
restored to their original upstream names. If the filename begins with the
prefix 'rocm_sysdeps_', the prefix is stripped and the file is renamed in place.
Parameters
----------
pc_file : Path Path object pointing to the .pc file to be examined and possibly renamed.
Returns
-------
None The function performs an in‑place rename and does not return a value.
"""
prefix = "rocm_sysdeps_"
if pc_file.name.startswith(prefix):
new_name = pc_file.name[len(prefix) :]
new_path = pc_file.with_name(new_name)
pc_file.rename(new_path)
def symlink_or_copy(existing_path, new_link):
"""Create symlink if the destination filesystem supports it. Create a copy otherwise.
Exists to support Windows, where only modern systems might support symlinks.
"""
existing_path = Path(existing_path)
new_link = Path(new_link)
new_link.parent.mkdir(parents=True, exist_ok=True)
if new_link.exists() or new_link.is_symlink():
if new_link.is_dir() and not new_link.is_symlink():
shutil.rmtree(new_link)
else:
new_link.unlink()
try:
rel_target = os.path.relpath(existing_path, start=new_link.parent)
new_link.symlink_to(rel_target, target_is_directory=existing_path.is_dir())
return
except OSError:
pass
if existing_path.is_dir():
shutil.copytree(existing_path, new_link)
else:
shutil.copy2(existing_path, new_link)
def update_library_links(libfile: Path) -> None:
"""
Normalize a shared library so that its real file is named exactly as its ELF SONAME,
and ensure a canonical linker-visible symlink exists.
This function is used when a library has been installed under a prefixed or
non-standard filename (e.g., librocm_sysdeps_ncursesw.so).
It performs the following operations:
- Extracts the library's SONAME using `patchelf --print-soname`.
- Resolves the underlying real file (following symlinks).
- Renames the real file to match its SONAME if it does not already.
- Creates or updates a symlink named `linker_name` pointing to the SONAME file.
- Removes or renames the original file or symlink as appropriate.
Parameters ----------
libfile : Path
Path to the library file or symlink to normalize.
Example: /prefix/lib/librocm_sysdeps_ncursesw.so
"""
# Ensure file exists
if not libfile.exists():
raise FileNotFoundError(f"File '{libfile}' not found")
dir_path = libfile.parent
# Get SONAME
try:
lib_soname = subprocess.check_output(
[patchelf_exe, "--print-soname", str(libfile)],
stderr=subprocess.DEVNULL,
text=True,
).strip()
except subprocess.CalledProcessError:
print(f"Error: No SONAME found in '{libfile}'", flush=True)
sys.exit(1)
# Resolve real file path
try:
realname = libfile.resolve(strict=True)
except FileNotFoundError:
print(f"Error: resolve() failed for '{libfile}'", flush=True)
sys.exit(1)
linker_name = libfile.name.replace("librocm_sysdeps_", "lib")
target_real = dir_path / lib_soname
symlink_path = dir_path / linker_name
if realname != target_real:
# Move real file to $dir/$soname
shutil.move(str(realname), str(target_real))
# Create/update symlink
if symlink_path.exists() or symlink_path.is_symlink():
symlink_path.unlink()
symlink_path.symlink_to(lib_soname)
# Remove the original symlink or file
if libfile.is_symlink() or libfile.exists():
libfile.unlink()
else:
# Rename symlink in the same directory
if symlink_path.exists():
symlink_path.unlink()
libfile.rename(symlink_path)
def link_header_files_under_dir(source_dir, dest_dir):
"""Support applications referencing ncurses header through
both `<ncurses.h>` and `<ncursesw/ncurses.h>` by making
"""
source_dir = Path(source_dir)
dest_dir = Path(dest_dir)
if not source_dir.exists():
return
dest_dir.mkdir(parents=True, exist_ok=True)
for header_path in source_dir.iterdir():
if header_path.is_file() and header_path.suffix == ".h":
symlink_or_copy(header_path, dest_dir / header_path.name)
# Fetch an environment variable or exit if it is not found.
def get_env_or_exit(var_name):
value = os.environ.get(var_name)
if value is None:
print(f"Error: {var_name} not defined")
sys.exit(1)
return value
# Validate the install prefix argument.
if len(sys.argv) < 2:
print("Error: Expected install prefix argument")
sys.exit(1)
# 1st argument is the installation prefix.
install_prefix = Path(sys.argv[1])
# Required environment variables.
patchelf_exe = get_env_or_exit("PATCHELF")
# Make headers available under <ncursesw/> e.g.
# `<ncurses.h>` and `<ncursesw/ncurses.h>`
# This follows Ubuntu and Fedora packaging
include_dir = Path(install_prefix) / "include"
ncursesw_dir = include_dir / "ncursesw"
link_header_files_under_dir(include_dir, ncursesw_dir)
if platform.system() == "Linux":
# Specify the directory
lib_dir = Path(install_prefix) / "lib"
# Remove static libs (*.a) and descriptors (*.la).
for file_path in lib_dir.iterdir():
if file_path.suffix in (".a", ".la"):
file_path.unlink(missing_ok=True)
# Update library linking
for so_file in lib_dir.glob("librocm_sysdeps_*.so"):
update_library_links(so_file)
# Fix .pc files to use relocatable paths.
pkgconfig_dir = lib_dir / "pkgconfig"
if pkgconfig_dir.exists():
for pc_file in pkgconfig_dir.glob("*.pc"):
relativize_pc_file(pc_file)
rename_pc_files(pc_file)
elif platform.system() == "Windows":
# Do nothing for now.
sys.exit(0)