diff --git a/.github/workflows/hipobject-documentation-check.yml b/.github/workflows/hipobject-documentation-check.yml index 722616b6..dd271839 100644 --- a/.github/workflows/hipobject-documentation-check.yml +++ b/.github/workflows/hipobject-documentation-check.yml @@ -3,12 +3,10 @@ name: hipObject - Documentation Check on: pull_request: branches: [develop] - # docs/conf.py reads the version from the top-level CMakeLists.txt. paths: &paths - 'docs/**' - 'include/**/*.h' - 'README.md' - - 'CMakeLists.txt' - 'cmake/HIPOBJDocumentation.cmake' - '.github/workflows/hipobject-documentation-check.yml' push: diff --git a/.github/workflows/hipobject-documentation-deploy.yml b/.github/workflows/hipobject-documentation-deploy.yml index b88f0720..1cb18043 100644 --- a/.github/workflows/hipobject-documentation-deploy.yml +++ b/.github/workflows/hipobject-documentation-deploy.yml @@ -10,11 +10,9 @@ name: hipObject - Documentation Deploy on: push: branches: [develop] - # docs/conf.py reads the version from the top-level CMakeLists.txt. paths: - 'docs/**' - 'include/**/*.h' - - 'CMakeLists.txt' - 'cmake/HIPOBJDocumentation.cmake' - '.github/workflows/hipobject-documentation-deploy.yml' workflow_dispatch: diff --git a/AGENTS.md b/AGENTS.md index c8d404c9..a68b7d5d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -159,6 +159,10 @@ Notes: change what callers can rely on or have to do**, so both need a [changelog](#changelog) entry. Fixing a typo or rewording without changing the meaning doesn't. +- **The version is set only in the public header**, by the + `HIPOBJ_VERSION_MAJOR`, `HIPOBJ_VERSION_MINOR`, and `HIPOBJ_VERSION_PATCH` + macros. The top-level `CMakeLists.txt` and `docs/conf.py` read it from + those lines, so keep each one a plain `#define` of a number. - **The public header is C**, and C11 and C++11 consumers both have to be able to include it. Keep it free of C++-isms and of anything newer than C11 or C++11. Every build with `BUILD_TESTING=ON`, including CI's, compiles it as @@ -758,9 +762,8 @@ Python code must run on **Python 3.10**. Don't use anything newer, such as CI: [hipobject-documentation-check.yml](.github/workflows/hipobject-documentation-check.yml), when the documentation (including `docs/sphinx/requirements.txt`), the - public header, `README.md`, the top-level `CMakeLists.txt` (which - `docs/conf.py` reads the version from), the documentation's build files, - or the workflow file change. + public header (which `docs/conf.py` reads the version from), `README.md`, + the documentation's build files, or the workflow file change. - **The documentation has to build without CMake too.** After the move to rocm-systems, Read the Docs will run doxygen in `docs/doxygen` and Sphinx on `docs/conf.py` directly, so keep CMake's `@VARIABLE@` substitutions diff --git a/CMakeLists.txt b/CMakeLists.txt index 989e8586..4a684ec5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,14 +7,29 @@ # value, which breaks the download. cmake_minimum_required(VERSION 3.25.2) -# The version is here and in the HIPOBJ_VERSION_* macros in -# include/hipobj.h, and they must match. The hipobj-install test fails if -# they don't: the installed library reports the header's version, and -# the test expects this one. It isn't a cache variable, so changing it -# here takes effect when an existing build directory is reconfigured. -set(HIPOBJ_VERSION_MAJOR 0) -set(HIPOBJ_VERSION_MINOR 1) -set(HIPOBJ_VERSION_PATCH 0) +# The version is set only in include/hipobj.h, by the HIPOBJ_VERSION_* +# macros, and read from there. The installed library reports the +# header's version too, and the hipobj-install test checks that it's +# this one. docs/conf.py reads the same lines. +set(HIPOBJ_VERSION_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/include/hipobj.h") +file(STRINGS "${HIPOBJ_VERSION_HEADER}" HIPOBJ_VERSION_LINES + REGEX "^#define[ \t]+HIPOBJ_VERSION_(MAJOR|MINOR|PATCH)[ \t]") +foreach(part IN ITEMS MAJOR MINOR PATCH) + string(REGEX MATCH + "#define[ \t]+HIPOBJ_VERSION_${part}[ \t]+([0-9]+)[ \t]*(;|$)" + match "${HIPOBJ_VERSION_LINES}") + # Not if(NOT CMAKE_MATCH_1): CMake treats a version number of 0 as false + if(match STREQUAL "") + message(FATAL_ERROR + "HIPOBJ_VERSION_${part} isn't defined as a number in " + "${HIPOBJ_VERSION_HEADER}") + endif() + set(HIPOBJ_VERSION_${part} "${CMAKE_MATCH_1}") +endforeach() +# Reconfigure when the header changes, so that a new version takes +# effect without anyone having to rerun CMake +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + "${HIPOBJ_VERSION_HEADER}") set(HIPOBJ_LIBRARY_VERSION "${HIPOBJ_VERSION_MAJOR}.${HIPOBJ_VERSION_MINOR}.${HIPOBJ_VERSION_PATCH}") diff --git a/docs/conf.py b/docs/conf.py index e9052915..4d4dfbd7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,22 +21,29 @@ # pylint: enable=redefined-builtin -def _cmake_version(): - """Return the version that the top-level CMakeLists.txt sets.""" - cmake = (Path(__file__).resolve().parent.parent / "CMakeLists.txt").read_text( - encoding="utf-8" - ) +def _header_version(): + """Return the version that the HIPOBJ_VERSION_* macros in hipobj.h set.""" + header = ( + Path(__file__).resolve().parent.parent / "include" / "hipobj.h" + ).read_text(encoding="utf-8") parts = [] for part in ("MAJOR", "MINOR", "PATCH"): - match = re.search(rf"^set\(HIPOBJ_VERSION_{part} (\d+)\)$", cmake, re.MULTILINE) + match = re.search( + rf"^#define[ \t]+HIPOBJ_VERSION_{part}[ \t]+(\d+)[ \t]*$", + header, + re.MULTILINE, + ) if not match: - raise ValueError(f"HIPOBJ_VERSION_{part} not found in CMakeLists.txt") + raise ValueError( + f"HIPOBJ_VERSION_{part} isn't defined as a number in hipobj.h" + ) parts.append(match.group(1)) return ".".join(parts) -# The project's version, from CMakeLists.txt -version = _cmake_version() +# The project's version, from the public header, which is the only +# place it's set +version = _header_version() release = version # -- Extensions ---------------------------------------------- diff --git a/include/hipobj.h b/include/hipobj.h index 27c56d46..9415541b 100644 --- a/include/hipobj.h +++ b/include/hipobj.h @@ -103,6 +103,10 @@ extern "C" { * LIBRARY VERSION NUMBERS * ------------------------------------------------------- */ +/* This is the only place the version is set. CMakeLists.txt and + * docs/conf.py read it from these lines, so keep each one in the form + * #define HIPOBJ_VERSION_ . */ + /*! @brief hipObject major version number @ingroup core */ #define HIPOBJ_VERSION_MAJOR 0 /*! @brief hipObject minor version number @ingroup core */