Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5337a06
fix(amdsmi): restore amd-smi-lib dependency on the tests package
marifamd Jul 22, 2026
d8a2375
test(amdsmi): install disable_system_fallback.py with the tests
marifamd Jul 22, 2026
9b4f4fe
test(amdsmi): run the SONAME conflict check in CI and the build harness
marifamd Jul 22, 2026
e1bf1df
test(amdsmi): guard against drift between the two installed module co…
marifamd Jul 22, 2026
a2557c7
fix(amdsmi): fail the build when the system python3 cannot be detected
marifamd Jul 22, 2026
50ee0a5
test(amdsmi): run the wheel install-location check without a GPU
marifamd Jul 22, 2026
36b6fb1
test(amdsmi): make the older-.so ABI test exercise real behavior
marifamd Jul 22, 2026
087370a
fix(amdsmi): quote the install prefix when writing ld.so.conf.d on RPM
marifamd Jul 22, 2026
6cedf9d
fix(amdsmi): make the operational log group-writable, not world-writable
marifamd Jul 22, 2026
b4a349e
fix(amdsmi): only strip release libraries when a strip tool is available
marifamd Jul 22, 2026
a4ebca5
refactor(amdsmi): share common target setup between the libraries
marifamd Jul 22, 2026
ec8ffc9
fix(amdsmi): remove the unused PY_WRAPPER_INSTALL_DIR cache variable
marifamd Jul 22, 2026
ded24e8
fix(amdsmi): pin permissions on the installed Python module
marifamd Jul 22, 2026
36718e8
docs(amdsmi): document the packaging and install paths
marifamd Jul 22, 2026
b46153f
test(amdsmi): install the dual-copy runner so its guard tests run in CI
marifamd Jul 22, 2026
ddb1139
fix(amdsmi): stop the logger from restoring world-writable log permis…
marifamd Jul 23, 2026
83d20f4
fix(amdsmi): stop the RPM from co-owning system python directories
marifamd Jul 23, 2026
3747053
test(amdsmi): resolve the loader test wrapper deterministically
marifamd Jul 23, 2026
901c64e
fix(amdsmi): skip the system site-packages install for wheel builds
marifamd Jul 23, 2026
3b7e213
fix(amdsmi): reject regenerating the wrapper against the wheel library
marifamd Jul 23, 2026
efe2694
ci(amdsmi): assert the wheel disables system fallback and pin the bui…
marifamd Jul 23, 2026
bdda997
build(amdsmi): build one wheel per platform, not per interpreter
marifamd Jul 23, 2026
7e68fa9
build(amdsmi): tag the python wheel manylinux_2_28 and verify the bun…
marifamd Jul 23, 2026
07d5ab9
fix(amdsmi): fall through to the system library when the TheRock lib …
marifamd Jul 23, 2026
7c4c937
fix(amdsmi): restrict package preun/prerm cleanup to a full erase
marifamd Jul 23, 2026
9c1c087
docs(amdsmi): correct the log-permission comment for root ownership
marifamd Jul 23, 2026
233f03e
build(amdsmi): use a clean PyPI version and expose the commit as meta…
marifamd Jul 23, 2026
0cf0fae
fix(amdsmi): make the wheel fallback-flag staging idempotent
marifamd Jul 23, 2026
6d6ad51
docs(amdsmi): clarify the manylinux wheel build directory
marifamd Jul 24, 2026
a82d947
ci(amdsmi): tighten the manylinux wheel job
marifamd Jul 24, 2026
2e3d5f6
docs(amdsmi): note that PYTHONPATH overrides module precedence
marifamd Jul 24, 2026
862bd84
ci(amdsmi): set PROJECT_DIR as a job-level env var
marifamd Jul 26, 2026
10d1d26
fix(amdsmi): review fixes for the packaging loader and wheel staging
marifamd Jul 29, 2026
8418878
ci(amdsmi): set PROJECT_DIR inside the container, not from github.wor…
marifamd Jul 29, 2026
8237ff3
docs(amdsmi): correct the PyPI wheel CLI support in the packaging matrix
marifamd Jul 29, 2026
705a041
chore(amdsmi): merge develop into packaging follow-up
marifamd Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .github/workflows/amdsmi-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,19 +165,21 @@ jobs:
- name: Mark workspace safe for git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"

- name: Set Project Directory
run: |
set -euo pipefail
# Evaluate inside the container: ${{ github.workspace }} is the host
# runner path, but these steps run in a container where the repo is
# mounted elsewhere. $GITHUB_WORKSPACE is the in-container mount.
echo "PROJECT_DIR=$GITHUB_WORKSPACE/projects/amdsmi" >> $GITHUB_ENV

- name: Set Artifact Metadata
if: github.event_name == 'pull_request'
run: |
set -euo pipefail
echo "PR_NUMBER=PR${{ github.event.pull_request.number }}" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +%m%d%y-%H%M)" >> $GITHUB_ENV

- name: Set Project Directory
run: |
set -euo pipefail
# sparse-checkout places the project at a fixed path.
echo "PROJECT_DIR=$GITHUB_WORKSPACE/projects/amdsmi" >> $GITHUB_ENV

- name: Run AMDSMI Build and Install
run: |
set -euo pipefail
Expand Down
43 changes: 32 additions & 11 deletions .github/workflows/amdsmi-manylinux-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ jobs:
name: ${{matrix.target.name}}
runs-on: ${{matrix.target.runs-on}}
container: ${{matrix.target.container}}
# Build directory for build_wheel.py's CMake tree. This mirrors
# build_wheel.py's own default (/tmp/amdsmi-build); it is set explicitly
# here so the build step and the SONAME conflict check, which reads both
# libraries back from it, stay coupled to one value.
env:
AMDSMI_WHEEL_BUILD_DIR: /tmp/amdsmi-build

strategy:
fail-fast: false
Expand All @@ -49,6 +55,7 @@ jobs:
python-bin: /opt/python/cp310-cp310/bin/python3
os-variant: AlmaLinux8
repair-flag: '--repair'
release-flag: '--release'
artifact-prefix: amdsmi-rpm-wheels
- id: debian
name: Build Debian Wheels (Ubuntu 22.04)
Expand All @@ -57,10 +64,17 @@ jobs:
python-bin: python3
os-variant: Ubuntu22
repair-flag: ''
release-flag: ''
artifact-prefix: amdsmi-debian-wheels

steps:
# rocm-systems is a large monorepo; the wheel build only needs the amdsmi
# project, so sparse-checkout keeps the fetch cheap.
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
sparse-checkout: |
projects/amdsmi
.github/workflows

- name: Install Debian build prerequisites
if: matrix.target.id == 'debian'
Expand All @@ -82,9 +96,10 @@ jobs:
${{matrix.target.python-bin}} \
"$GITHUB_WORKSPACE/projects/amdsmi/tools/build_wheel.py" \
--project-dir "$GITHUB_WORKSPACE/projects/amdsmi" \
--build-dir "$AMDSMI_WHEEL_BUILD_DIR" \
--output-dir "$GITHUB_WORKSPACE/wheels" \
--os-variant ${{matrix.target.os-variant}} \
${{matrix.target.repair-flag}}
${{matrix.target.repair-flag}} ${{matrix.target.release-flag}}

- name: Verify wheels exist
run: |
Expand All @@ -94,24 +109,30 @@ jobs:
exit 1
fi

- name: Verify system/wheel SONAMEs are distinct
run: |
${{matrix.target.python-bin}} \
"$GITHUB_WORKSPACE/projects/amdsmi/tests/run_amdsmi_pkg_conflict_test.py" \
--build-root "$AMDSMI_WHEEL_BUILD_DIR"

- name: Smoke test (install + import)
run: |
${{matrix.target.python-bin}} -m pip install --upgrade pip
${{matrix.target.python-bin}} -m pip install "$GITHUB_WORKSPACE"/wheels/*.whl
${{matrix.target.python-bin}} -c "import amdsmi; print('amdsmi import OK')"
# Prove the installed wheel is what imports (resolves under pip's
# location), not some other amdsmi on the path.
${{matrix.target.python-bin}} -c "import os, subprocess, amdsmi; out = subprocess.check_output(['${{matrix.target.python-bin}}', '-m', 'pip', 'show', 'amdsmi'], text=True); loc = next((l.split(':', 1)[1].strip() for l in out.splitlines() if l.startswith('Location:')), ''); p = os.path.realpath(amdsmi.__file__); print('import from', p, 'pip loc', loc); assert loc and p.startswith(os.path.realpath(loc)), 'wheel is not the imported amdsmi'; print('amdsmi import OK')"
# The wheel must ship with the system-library fallback disabled, so a
# build-step ordering regression that leaves it enabled fails here
# rather than shipping a wheel that can silently load a system .so.
${{matrix.target.python-bin}} -c "import amdsmi.amdsmi_wrapper as w; assert not w._AMDSMI_ALLOW_SYSTEM_FALLBACK, 'wheel shipped with system fallback enabled'; print('fallback disabled OK')"

- name: Upload wheels (by SHA)
# Not consumed by any downstream job; kept so a reviewer can download the
# built wheel from a run. Named by commit SHA for traceability.
- name: Upload wheels
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: ${{matrix.target.artifact-prefix}}-${{github.sha}}
path: ${{github.workspace}}/wheels/*.whl
if-no-files-found: error
retention-days: 30

- name: Upload wheels (downloadable)
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: ${{matrix.target.artifact-prefix}}
path: ${{github.workspace}}/wheels/*.whl
if-no-files-found: warn
retention-days: 90
39 changes: 37 additions & 2 deletions projects/amdsmi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ set(${AMD_SMI_LIBS_TARGET}_VERSION_STRING
"${${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR}.${${AMD_SMI_LIBS_TARGET}_VERSION_MINOR}.${${AMD_SMI_LIBS_TARGET}_VERSION_PATCH}+${${AMD_SMI_LIBS_TARGET}_VERSION_HASH}"
)

# PyPI rejects a PEP 440 local version (the +hash suffix), so a published wheel
# needs a clean MAJOR.MINOR.PATCH. Per-commit CI wheels keep +hash for unique
# filenames; the commit is always recoverable via amdsmi.__commit__.
option(AMDSMI_WHEEL_RELEASE "Use a clean PEP 440 version (no +hash) for the wheel" OFF)
if(AMDSMI_WHEEL_RELEASE)
set(${AMD_SMI_LIBS_TARGET}_WHEEL_VERSION
"${${AMD_SMI_LIBS_TARGET}_VERSION_MAJOR}.${${AMD_SMI_LIBS_TARGET}_VERSION_MINOR}.${${AMD_SMI_LIBS_TARGET}_VERSION_PATCH}"
)
else()
set(${AMD_SMI_LIBS_TARGET}_WHEEL_VERSION "${${AMD_SMI_LIBS_TARGET}_VERSION_STRING}")
endif()

set(DEFAULT_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
update_version_in_file("include/amd_smi/amdsmi.h" ${DEFAULT_VERSION} "#define AMDSMI_LIB_VERSION_" " *" " ")
update_version_in_file("rust-interface/src/amdsmi_wrapper.rs" ${DEFAULT_VERSION} "AMDSMI_LIB_VERSION_" " *: *u32 *= *"
Expand Down Expand Up @@ -481,7 +493,11 @@ set(CPACK_DEBIAN_DEV_PACKAGE_RECOMMENDS ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libdrm-dev, sudo, libc6, python3 (>= 3.6.8)")
set(CPACK_DEBIAN_ASAN_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})
set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})
set(CPACK_DEBIAN_TESTS_PACKAGE_DEPENDS ${CPACK_DEBIAN_PACKAGE_DEPENDS})
# The tests package ships amdsmitst, which dynamically links libamd_smi.so from
# the main package. Keep amd-smi-lib (set by generic_package()) as the first
# dependency and append the runtime deps, so the tests package is never
# installable without the library it links against.
set(CPACK_DEBIAN_TESTS_PACKAGE_DEPENDS "${CPACK_PACKAGE_NAME}, ${CPACK_DEBIAN_PACKAGE_DEPENDS}")

# $CURRENT_YEAR is used by copyright.in
string(TIMESTAMP CURRENT_YEAR "%Y")
Expand Down Expand Up @@ -527,9 +543,25 @@ install(
)

# RPM package specific variables
# The Python module installs under an absolute system site-packages path
# (e.g. /usr/lib64/python3.9/site-packages) that the OS python package already
# owns. Left alone, CPack's RPM generator declares %dir ownership of that
# directory and its parents -- co-owning system directories, with the default
# group-writable (0775) mode. Exclude the sitelib and its ancestors from the
# auto filelist so the RPM owns only its own <sitelib>/amdsmi subtree, not the
# shared /usr python directories.
set(_amdsmi_sitelib_excludes "")
if(AMDSMI_SYSTEM_PYTHON_SITELIB)
set(_amdsmi_walk "${AMDSMI_SYSTEM_PYTHON_SITELIB}")
while(_amdsmi_walk AND NOT _amdsmi_walk STREQUAL "/" AND NOT _amdsmi_walk STREQUAL "/usr")
list(APPEND _amdsmi_sitelib_excludes "${_amdsmi_walk}")
get_filename_component(_amdsmi_walk "${_amdsmi_walk}" DIRECTORY)
endwhile()
endif()
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
"${CPACK_PACKAGING_INSTALL_PREFIX}"
"${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
${_amdsmi_sitelib_excludes}
)
#Set rpm distro
if(CPACK_RPM_PACKAGE_RELEASE)
Expand Down Expand Up @@ -590,7 +622,10 @@ message(STATUS "amdsmi RPM python interpreter dependency: ${_amdsmi_py_req}")
set(CPACK_RPM_PACKAGE_REQUIRES "libdrm-devel, sudo, ${_amdsmi_py_req}")
set(CPACK_RPM_DEV_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})
set(CPACK_RPM_ASAN_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})
set(CPACK_RPM_TESTS_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES})
# amdsmitst dynamically links libamd_smi.so; keep amd-smi-lib (set by
# generic_package()) first and append the runtime requires so the tests RPM
# cannot install without the library it links against.
set(CPACK_RPM_TESTS_PACKAGE_REQUIRES "${CPACK_PACKAGE_NAME}, ${CPACK_RPM_PACKAGE_REQUIRES}")

# don't terminate if bytecompile of python files fails
set(CPACK_RPM_SPEC_MORE_DEFINE "%define _python_bytecompile_errors_terminate_build 0")
Expand Down
12 changes: 6 additions & 6 deletions projects/amdsmi/DEBIAN/postinst.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ do_configureLogrotate() {

mkdir -p "${logPath}"
touch "${logFile}"
# Relax permissions on the operational log file only so non-root
# processes can append to it. Do NOT use chmod -R here: recursing
# would also make the log directory and sibling files (e.g.
# postinst.log) world-writable, which would let a local user create
# or tamper with files under a root-owned log directory (CWE-732).
chmod a+rw "${logFile}"
# Relax permissions on the operational log file only so non-root processes
# in the same group can append to it. 0664 keeps it group-writable but not
# world-writable. Do NOT use chmod -R here: recursing would also make the log
# directory and sibling files (e.g. postinst.log) writable, which would let a
# local user tamper with files under a root-owned log directory (CWE-732).
chmod 0664 "${logFile}"

if ! command -v logrotate &>/dev/null; then
echo "[WARNING] Detected logrotate is not installed."\
Expand Down
24 changes: 12 additions & 12 deletions projects/amdsmi/DEBIAN/prerm.in
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,23 @@ rm_logrotateConfig() {

case "$1" in
( remove | upgrade)
# remove old gpuv-smi symlink
# remove old gpuv-smi symlink on both remove and upgrade
rm -f @CPACK_PACKAGING_INSTALL_PREFIX@/bin/gpuv-smi &> /dev/null
echo "Removing AMDSMI Lib Packages..."
rm_ldconfig
echo "ldconfig removed"
rm_leftovers
echo "leftovers removed"
rm_logFolder
echo "log folder removed"
rm_rocm_tests_dir
echo "rocm tests directory removed"
rm_logrotateConfig
echo "logrotate configuration removed"
;;
( purge )
;;
( * )
exit 0
;;
esac

if [ "$1" = "remove" ]; then
# only on a full remove -- on upgrade these would delete the incoming
# package's ldconfig entry, logs, test dir and logrotate config
echo "Removing AMDSMI Lib Packages..."
rm_ldconfig
rm_leftovers
rm_logFolder
rm_rocm_tests_dir
rm_logrotateConfig
fi
14 changes: 7 additions & 7 deletions projects/amdsmi/RPM/post.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ do_configureLogrotate() {

mkdir -p "${logPath}"
touch "${logFile}"
# Relax permissions on the operational log file only so non-root
# processes can append to it. Do NOT use chmod -R here: recursing
# would also make the log directory and sibling files (e.g.
# postinst.log) world-writable, which would let a local user create
# or tamper with files under a root-owned log directory (CWE-732).
chmod a+rw "${logFile}"
# Relax permissions on the operational log file only so non-root processes
# in the same group can append to it. 0664 keeps it group-writable but not
# world-writable. Do NOT use chmod -R here: recursing would also make the log
# directory and sibling files (e.g. postinst.log) writable, which would let a
# local user tamper with files under a root-owned log directory (CWE-732).
chmod 0664 "${logFile}"

if ! command -v logrotate &>/dev/null; then
echo "[WARNING] Detected logrotate is not installed."\
Expand Down Expand Up @@ -66,7 +66,7 @@ EOF
do_ldconfig() {
# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ "@ENABLE_LDCONFIG@" == "ON" ]; then
echo $RPM_INSTALL_PREFIX0/@CMAKE_INSTALL_LIBDIR@ > /etc/ld.so.conf.d/x86_64-libamd_smi_lib.conf
echo "$RPM_INSTALL_PREFIX0/@CMAKE_INSTALL_LIBDIR@" > /etc/ld.so.conf.d/x86_64-libamd_smi_lib.conf
ldconfig
fi
}
Expand Down
8 changes: 6 additions & 2 deletions projects/amdsmi/RPM/preun.in
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ rm_logrotateConfig() {
}

if [ "$1" -le 1 ]; then
# perform the below actions for rpm remove($1=0) or upgrade($1=1) operations
# remove old gpuv-smi symlink
# remove old gpuv-smi symlink on both remove($1=0) and upgrade($1=1)
rm -f $RPM_INSTALL_PREFIX0/bin/gpuv-smi &> /dev/null
fi

if [ "$1" -eq 0 ]; then
# only on a full erase -- on upgrade($1=1) these would delete the
# incoming package's logs, test dir and logrotate config
rm_leftovers
rm_logFolder
rm_rocm_tests_dir
Expand Down
1 change: 1 addition & 0 deletions projects/amdsmi/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ AMD SMI is the successor to [ROCm SMI](https://github.com/ROCm/rocm-systems/tree
:::{grid-item-card} Install
* [Library and CLI tool installation](./install/install.md)
* [Build from source](./install/build.md)
* [Packaging and install paths](./packaging.md)
:::

:::{grid-item-card} How to
Expand Down
5 changes: 3 additions & 2 deletions projects/amdsmi/docs/install/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,9 @@ install needs to be uninstalled manually.
The wheel ships its own SONAME-renamed `libamd_smi_python.so` next to
the wrapper, so it does not depend on `/opt/rocm` being present.

See `py-interface/README.md` in the source tree for the full
install-paths matrix and the `AMDSMI_LIB_OVERRIDE` override.
See `py-interface/README.md` in the source tree, or
[Packaging and install paths](../packaging.md) for the full install-paths
matrix, coexistence rules, and the `AMDSMI_LIB_OVERRIDE` override.

> **Note:** `sudo` may be required for the system-package path. For pip,
> use `--break-system-packages` only if installing into a non-venv
Expand Down
Loading
Loading