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
155 lines
5.6 KiB
Python
155 lines
5.6 KiB
Python
#!/usr/bin/env python3
|
|
|
|
##Copyright © Advanced Micro Devices, Inc., or its affiliates.
|
|
##SPDX-License-Identifier: MIT
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def _get_rpath(filepath: Path):
|
|
"""Read DT_RPATH or DT_RUNPATH from an ELF binary via readelf.
|
|
|
|
patchelf --print-rpath only reads DT_RPATH, not DT_RUNPATH, so using it
|
|
directly on a binary that has only DT_RUNPATH returns an empty string and
|
|
would cause --set-rpath to wipe the rpath. readelf reads both tags.
|
|
"""
|
|
try:
|
|
out = subprocess.check_output(
|
|
["readelf", "-d", str(filepath)],
|
|
stderr=subprocess.DEVNULL,
|
|
).decode()
|
|
except subprocess.CalledProcessError:
|
|
return None
|
|
m = re.search(r"\(R(?:UN)?PATH\)\s+Library r(?:un)?path: \[(.+)\]", out)
|
|
return m.group(1) if m else None
|
|
|
|
|
|
def update_rpath(search_path: Path, excludes):
|
|
"""Change DT_RUNPATH to DT_RPATH in all ELF files under search_path.
|
|
|
|
Uses patchelf --force-rpath --set-rpath, which is the same mechanism used
|
|
by the Python wheel packaging path. readelf is used to read the existing
|
|
rpath value because patchelf --print-rpath only reads DT_RPATH, not
|
|
DT_RUNPATH, and would return empty for binaries that only have DT_RUNPATH.
|
|
"""
|
|
for path, dirs, files in os.walk(search_path, topdown=True, followlinks=True):
|
|
dirs[:] = [d for d in dirs if d not in excludes]
|
|
for filename in files:
|
|
filepath = Path(path) / filename
|
|
if filepath.is_symlink():
|
|
continue
|
|
# Quick ELF magic check before invoking readelf/patchelf
|
|
try:
|
|
if filepath.read_bytes()[:4] != b"\x7fELF":
|
|
continue
|
|
except OSError:
|
|
continue
|
|
rpath = _get_rpath(filepath)
|
|
if not rpath:
|
|
continue
|
|
# Write the rpath back, forcing DT_RPATH tag instead of DT_RUNPATH
|
|
try:
|
|
subprocess.check_call(
|
|
[
|
|
"patchelf",
|
|
"--force-rpath",
|
|
"--set-rpath",
|
|
rpath,
|
|
str(filepath),
|
|
]
|
|
)
|
|
print(f"DT_RUNPATH changed to DT_RPATH: {filepath}")
|
|
except subprocess.CalledProcessError as ex:
|
|
print(f"patchelf failed for {filepath}: {ex}")
|
|
|
|
|
|
def update_config_file(cfg_path: Path):
|
|
"""Update rocm llvm config file to default to DT_RPATH."""
|
|
print("Updating cfg file in", cfg_path)
|
|
if cfg_path.exists():
|
|
print("cfg file exist in path, going ahead with update ")
|
|
try:
|
|
file_string = cfg_path.read_text(encoding="utf-8")
|
|
file_string = re.sub("enable-new-dtags", "disable-new-dtags", file_string)
|
|
cfg_path.write_text(file_string, encoding="utf-8")
|
|
except Exception as ex:
|
|
print("Couldnt update rocm.cfg file. ", ex)
|
|
else:
|
|
print("Config path doesnt exist", cfg_path)
|
|
|
|
|
|
def update_compiler_config(search_path: Path):
|
|
"""Search for rocm.cfg in search_path and update it to default to DT_RPATH."""
|
|
cfg_file_name = "rocm.cfg"
|
|
found_cfg = False
|
|
print("Searching for ", cfg_file_name)
|
|
for path, _, files in os.walk(search_path):
|
|
if cfg_file_name in files:
|
|
cfg_path = Path(path) / cfg_file_name
|
|
print(" Found cfg file cfg_path")
|
|
found_cfg = True
|
|
update_config_file(cfg_path)
|
|
# Continue with the search as there could be cfg files in llvm and llvm/alt
|
|
if found_cfg:
|
|
return
|
|
# rocm.cfg config file not found in search path. Search in the ROCM_PATH.
|
|
print(cfg_file_name, " not found in search_path. Trying to search in ROCM_PATH")
|
|
try:
|
|
rocm_path = Path(os.environ["ROCM_PATH"])
|
|
print(" Found ROCM_PATH trying for rocm.cfg")
|
|
# There are multiple possible paths for cfg file.
|
|
# ROCM_PATH/llvm/bin and ROCM_PATH/lib/llvm/bin. Also alt location
|
|
update_config_file(rocm_path / "llvm" / "bin" / cfg_file_name)
|
|
update_config_file(rocm_path / "llvm" / "alt" / "bin" / cfg_file_name)
|
|
update_config_file(rocm_path / "lib" / "llvm" / "bin" / cfg_file_name)
|
|
update_config_file(rocm_path / "lib" / "llvm" / "alt" / "bin" / cfg_file_name)
|
|
except Exception as ex:
|
|
print("ROCM_PATH not found ", ex)
|
|
|
|
|
|
def main():
|
|
# The script expect a search folder as parameter. It finds all ELF files and updates RPATH
|
|
argparser = argparse.ArgumentParser(
|
|
usage="usage: %(prog)s <folder-to-search>",
|
|
description="Find the ELF files in the specified folder and convert the RUNPATH to RPATH. \n",
|
|
add_help=False,
|
|
prog="runpath_to_rpath.py",
|
|
)
|
|
|
|
argparser.add_argument(
|
|
"searchdir",
|
|
nargs="?",
|
|
type=Path,
|
|
default=None,
|
|
help="Folder to search for ELF file. \nPlease note: Any folder with name llvm in that path will be discarded",
|
|
)
|
|
argparser.add_argument(
|
|
"-h",
|
|
"--help",
|
|
action="store_true",
|
|
dest="help",
|
|
help="Display this information",
|
|
)
|
|
|
|
args = argparser.parse_args()
|
|
if args.help or not args.searchdir:
|
|
argparser.print_help()
|
|
sys.exit(0)
|
|
|
|
# Find the elf files in the search path and update DT_RUNPATH to DT_RPATH
|
|
# SWDEV-467155 : remove the exclusion of llvm folder
|
|
excludes = []
|
|
update_rpath(args.searchdir, excludes)
|
|
# Update rocm clang configs to default to DT_RPATH
|
|
update_compiler_config(args.searchdir)
|
|
print("Done with rpath update")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|