Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation infrastructure #293

Merged
merged 2 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
279 changes: 187 additions & 92 deletions cmake/CgvFindVersion.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
#
# https://github.com/sethrj/cmake-git-version
#
# Copyright 2021 UT-Battelle, LLC and Seth R Johnson
# Copyright 2021-2023 UT-Battelle, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#[=======================================================================[.rst:

CgvFindVersion
Expand All @@ -31,13 +31,15 @@ CgvFindVersion
``<projname>``
Name of the project.

This command sets the following variables in the parent package::
This command sets the numeric (usable in CMake version comparisons) and
extended (useful for exact versioning) version variables in the parent
package::

${projname}_VERSION
${projname}_VERSION_STRING

It takes the project name and version file path as optional arguments to
support using it before the CMake ``project`` command.
It takes the project name as an optional argument so that it may be used
*before* calling the CMake ``project`` command.

The project version string uses an approximation to SemVer strings, appearing
as v0.1.2 if the version is actually a tagged release, or v0.1.3+abcdef if
Expand All @@ -47,10 +49,13 @@ CgvFindVersion
it's impossible to determine the version from the tag, so a warning will be
issued and the version will be set to 0.0.0.

The exact regex used to match the version tag is::
The default regex used to match the numeric version and full version string
from the git tag is::

v([0-9.]+)(-dev[0-9.]+)?

but you can override the regex by setting the ``CGV_TAG_REGEX`` variable
before calling ``cgv_find_version``.

.. note:: In order for this script to work properly with archived git
repositories (generated with ``git-archive`` or GitHub's release tarball
Expand All @@ -64,108 +69,198 @@ if(CMAKE_SCRIPT_MODE_FILE)
cmake_minimum_required(VERSION 3.8)
endif()

function(cgv_find_version)
set(projname "${ARGV0}")
if(NOT projname)
set(projname "${CMAKE_PROJECT_NAME}")
if(NOT projname)
message(FATAL_ERROR "Project name is not defined")
endif()
#-----------------------------------------------------------------------------#

function(_cgv_store_version string suffix hash)
if(NOT string)
message(WARNING "The version metadata for ${CGV_PROJECT} could not "
"be determined: installed version number may be incorrect")
endif()
set(_CACHED_VERSION "${string}" "${suffix}" "${hash}")
# Note: extra 'unset' is necessary if using CMake presets with
# ${CGV_PROJECT}_GIT_DESCRIBE="", even with INTERNAL/FORCE
unset(${CGV_CACHE_VAR} CACHE)
set(${CGV_CACHE_VAR} "${_CACHED_VERSION}" CACHE INTERNAL
"Version string and hash for ${CGV_PROJECT}")
endfunction()

#-----------------------------------------------------------------------------#

function(_cgv_try_archive_md)
# Get a possible Git version generated using git-archive (see the
# .gitattributes file)
set(_ARCHIVE_DESCR "$Format:%$")
set(_ARCHIVE_TAG "$Format:%D$")
set(_ARCHIVE_HASH "$Format:%h$")
if(_ARCHIVE_HASH MATCHES "Format:%h")
# Not a git archive
return()
endif()

set(_TAG_REGEX "v([0-9.]+)(-dev[0-9.]+)?")
set(_HASH_REGEX "([0-9a-f]+)")

if(_ARCHIVE_HASH MATCHES "%h")
# Not a "git archive": use live git information
set(_CACHE_VAR "${projname}_GIT_DESCRIBE")
set(_CACHED_VERSION "${${_CACHE_VAR}}")
if(NOT _CACHED_VERSION)
# Building from a git checkout rather than a distribution
if(NOT GIT_EXECUTABLE)
find_package(Git QUIET REQUIRED)
endif()
execute_process(
COMMAND "${GIT_EXECUTABLE}" "describe" "--tags" "--match" "v*"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
ERROR_VARIABLE _GIT_ERR
OUTPUT_VARIABLE _VERSION_STRING
RESULT_VARIABLE _GIT_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(_GIT_RESULT)
message(AUTHOR_WARNING "No git tags in ${projname} matched 'v*': "
"${_GIT_ERR}")
elseif(NOT _VERSION_STRING)
message(WARNING "Failed to get ${projname} version from git: "
"git describe returned an empty string")
else()
# Process description tag: e.g. v0.4.0-2-gc4af497 or v0.4.0
# or v2.0.0-dev2
string(REGEX MATCH "^${_TAG_REGEX}(-[0-9]+-g${_HASH_REGEX})?" _MATCH
"${_VERSION_STRING}"
)
if(_MATCH)
set(_VERSION_STRING "${CMAKE_MATCH_1}")
set(_VERSION_STRING_SUFFIX "${CMAKE_MATCH_2}")
if(CMAKE_MATCH_3)
# *not* a tagged release
set(_VERSION_HASH "${CMAKE_MATCH_4}")
endif()
endif()
endif()
if(NOT _VERSION_STRING)
execute_process(
COMMAND "${GIT_EXECUTABLE}" "log" "-1" "--format=%h" "HEAD"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
OUTPUT_VARIABLE _VERSION_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
set(_CACHED_VERSION "${_VERSION_STRING}" "${_VERSION_STRING_SUFFIX}" "${_VERSION_HASH}")
set("${_CACHE_VAR}" "${_CACHED_VERSION}" CACHE INTERNAL
"Version string and hash for ${projname}")
endif()
list(GET _CACHED_VERSION 0 _VERSION_STRING)
list(GET _CACHED_VERSION 1 _VERSION_STRING_SUFFIX)
list(GET _CACHED_VERSION 2 _VERSION_HASH)
string(REGEX MATCH "tag: *${CGV_TAG_REGEX}" _MATCH "${_ARCHIVE_TAG}")
if(_MATCH)
_cgv_store_version("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" "")
else()
string(REGEX MATCH "tag: *${_TAG_REGEX}" _MATCH "${_ARCHIVE_TAG}")
message(WARNING "Could not match a version tag for "
"git description '${_ARCHIVE_TAG}': perhaps this archive was not "
"exported from a tagged commit?")
string(REGEX MATCH " *([0-9a-f]+)" _MATCH "${_ARCHIVE_HASH}")
if(_MATCH)
set(_VERSION_STRING "${CMAKE_MATCH_1}")
set(_VERSION_STRING_SUFFIX "${CMAKE_MATCH_2}")
_cgv_store_version("" "" "${CMAKE_MATCH_1}")
endif()
endif()
endfunction()

#-----------------------------------------------------------------------------#

function(_cgv_try_git_describe)
# First time calling "git describe"
if(NOT Git_FOUND)
find_package(Git QUIET)
if(NOT Git_FOUND)
message(WARNING "Could not find Git, needed to find the version tag")
return()
endif()
endif()

# Load git description
execute_process(
COMMAND "${GIT_EXECUTABLE}" "describe" "--tags" "--match" "v*"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
ERROR_VARIABLE _GIT_ERR
OUTPUT_VARIABLE _VERSION_STRING
RESULT_VARIABLE _GIT_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(_GIT_RESULT)
message(WARNING "No git tags in ${CGV_PROJECT} matched 'v*': "
"${_GIT_ERR}")
return()
elseif(NOT _VERSION_STRING)
message(WARNING "Failed to get ${CGV_PROJECT} version from git: "
"git describe returned an empty string")
return()
endif()

# Process description tag: e.g. v0.4.0-2-gc4af497 or v0.4.0
# or v2.0.0-dev2
set(_DESCR_REGEX "^${CGV_TAG_REGEX}(-([0-9]+)-g([0-9a-f]+))?")
string(REGEX MATCH "${_DESCR_REGEX}" _MATCH "${_VERSION_STRING}")
if(NOT _MATCH)
message(WARNING "Failed to parse description '${_VERSION_STRING}' "
"with regex '${_DESCR_REGEX}'"
)
return()
endif()

if(NOT CMAKE_MATCH_3)
# This is a tagged release!
_cgv_store_version("${CMAKE_MATCH_1}" "${CMAKE_MATCH_2}" "")
else()
if(CMAKE_MATCH_2)
set(_suffix ${CMAKE_MATCH_2}.${CMAKE_MATCH_4})
else()
message(AUTHOR_WARNING "Could not match a version tag for "
"git description '${_ARCHIVE_TAG}': perhaps this archive was not "
"exported from a tagged commit?")
string(REGEX MATCH " *${_HASH_REGEX}" _MATCH "${_ARCHIVE_HASH}")
if(_MATCH)
set(_VERSION_HASH "${CMAKE_MATCH_1}")
set(_suffix -${CMAKE_MATCH_4})
endif()
# Qualify the version number and save the hash
_cgv_store_version(
"${CMAKE_MATCH_1}" # [0-9.]+
"${_suffix}" # (-dev[0-9.]*)? \. ([0-9]+)
"${CMAKE_MATCH_5}" ([0-9a-f]+)
)
endif()
endfunction()

#-----------------------------------------------------------------------------#

function(_cgv_try_git_hash)
if(NOT GIT_EXECUTABLE)
return()
endif()
# Fall back to just getting the hash
execute_process(
COMMAND "${GIT_EXECUTABLE}" "log" "-1" "--format=%h" "HEAD"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
OUTPUT_VARIABLE _VERSION_HASH
RESULT_VARIABLE _GIT_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(_GIT_RESULT)
message(WARNING "Failed to get current commit hash from git: "
"${_GIT_ERR}")
return()
endif()
_cgv_store_version("" "" "${_VERSION_HASH}")
endfunction()

#-----------------------------------------------------------------------------#

function(cgv_find_version)
# Set CGV_ variables that are used in embedded macros/functions
if(ARGC GREATER 0)
set(CGV_PROJECT "${ARGV0}")
elseif(NOT CGV_PROJECT)
if(NOT CMAKE_PROJECT_NAME)
message(FATAL_ERROR "Project name is not defined")
endif()
set(CGV_PROJECT "${CMAKE_PROJECT_NAME}")
endif()

if(NOT CGV_TAG_REGEX)
set(CGV_TAG_REGEX "v([0-9.]+)(-[a-z]+[0-9.]*)?")
endif()

set(CGV_CACHE_VAR "${CGV_PROJECT}_GIT_DESCRIBE")

# Successively try archive metadata, git description, or just git hash
if(NOT ${CGV_CACHE_VAR})
_cgv_try_archive_md()
if(NOT ${CGV_CACHE_VAR})
_cgv_try_git_describe()
if(NOT ${CGV_CACHE_VAR})
_cgv_try_git_hash()
if(NOT ${CGV_CACHE_VAR})
set(${CGV_CACHE_VAR} "" "-unknown" "")
endif()
endif()
endif()
endif()

# Unpack stored version
set(_CACHED_VERSION "${${CGV_CACHE_VAR}}")
list(GET _CACHED_VERSION 0 _VERSION_STRING)
list(GET _CACHED_VERSION 1 _VERSION_STRING_SUFFIX)
list(GET _CACHED_VERSION 2 _VERSION_HASH)

if(NOT _VERSION_STRING)
set(_VERSION_STRING "0.0.0")
endif()

if(_VERSION_HASH)
set(_FULL_VERSION_STRING "v${_VERSION_STRING}${_VERSION_STRING_SUFFIX}+${_VERSION_HASH}")
set(_FULL_VERSION_STRING "${_VERSION_STRING}${_VERSION_STRING_SUFFIX}+${_VERSION_HASH}")
else()
set(_FULL_VERSION_STRING "v${_VERSION_STRING}${_VERSION_STRING_SUFFIX}")
set(_FULL_VERSION_STRING "${_VERSION_STRING}${_VERSION_STRING_SUFFIX}")
endif()

set(${projname}_VERSION "${_VERSION_STRING}" PARENT_SCOPE)
set(${projname}_VERSION_STRING "${_FULL_VERSION_STRING}" PARENT_SCOPE)
# Set version number and descriptive version in parent scope
set(${CGV_PROJECT}_VERSION "${_VERSION_STRING}" PARENT_SCOPE)
set(${CGV_PROJECT}_VERSION_STRING "${_FULL_VERSION_STRING}" PARENT_SCOPE)
endfunction()

#-----------------------------------------------------------------------------#

if(CMAKE_SCRIPT_MODE_FILE)
cgv_find_version(TEMP)
message("VERSION=\"${TEMP_VERSION}\"")
message("VERSION_STRING=\"${TEMP_VERSION_STRING}\"")
if(DEFINED ONLY)
# Print only the given variable, presumably VERSION or VERSION_STRING
# (will print to stderr)
set(VERSION "${TEMP_VERSION}")
set(VERSION_STRING "${TEMP_VERSION_STRING}")
message("${${ONLY}}")
else()
message("VERSION=\"${TEMP_VERSION}\"")
message("VERSION_STRING=\"${TEMP_VERSION_STRING}\"")
endif()
endif()

# cmake-git-version 1.1.1
31 changes: 29 additions & 2 deletions doc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,44 @@
## License-Filename: LICENSE
find_package(Sphinx REQUIRED)

#-----------------------------------------------------------------------------#

# Define a configure file with version and configuration info
if(ForTrilinos_VERSION STREQUAL ForTrilinos_VERSION_STRING)
set(ForTrilinos_SHORT_VERSION "${ForTrilinos_VERSION}")
elseif("${ForTrilinos_VERSION_STRING}" MATCHES
"^(.*-rc[.-][0-9]+)(\\.[0-9]+\\+[0-9a-f]+)$")
# Use release candidate, stripping off stuff since the tag
set(ForTrilinos_SHORT_VERSION "${CMAKE_MATCH_1}")
else()
# Development version
set(_patch "${PROJECT_VERSION_PATCH}")
if(NOT ForTrilinos_VERSION_STRING MATCHES "-dev")
# Before the next release
math(EXPR _patch "${PROJECT_VERSION_PATCH} + 1")
endif()
set(ForTrilinos_SHORT_VERSION
"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${_patch}-dev"
)
endif()
configure_file("config.json.in" "config.json" @ONLY)

#-----------------------------------------------------------------------------#
add_custom_target(doc)
add_custom_command(TARGET doc
COMMAND "${SPHINX_EXECUTABLE}" -q
VERBATIM COMMAND
"${CMAKE_COMMAND}" -E env
"CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}"
"${SPHINX_EXECUTABLE}" -q
-d "${CMAKE_CURRENT_BINARY_DIR}/doctrees"
-b html
"${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_BINARY_DIR}/html"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Building HTML documentation with Sphinx"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/conf.py"
BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/html/index.html"
)
)


install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html/"
Expand Down
Loading