diff --git a/cmake/CgvFindVersion.cmake b/cmake/CgvFindVersion.cmake index 8764ca4c..1a59cc8c 100644 --- a/cmake/CgvFindVersion.cmake +++ b/cmake/CgvFindVersion.cmake @@ -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 @@ -31,13 +31,15 @@ CgvFindVersion ```` 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 @@ -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 @@ -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 diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index b15db271..b4a6adcd 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -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/" diff --git a/doc/conf.py b/doc/conf.py index c54c33dd..ec90de7e 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,25 +1,10 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# -# ForTrilinos documentation build configuration file, created by -# sphinx-quickstart on Thu Feb 23 20:41:01 2017. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) +import os +import json +import sys +from pathlib import Path # -- General configuration ------------------------------------------------ @@ -49,38 +34,31 @@ # General information about the project. project = 'ForTrilinos' -copyright = '2017–2020, Oak Ridge National Laboratory, UT-Battelle, LLC' +copyright = '2017–2023, Oak Ridge National Laboratory, UT-Battelle, LLC' all_authors = [ "Seth R. Johnson", "Andrey Prokopenko" ] author = " and ".join(all_authors) -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -# TODO: import from git/cmake-generated version -version = '' -# The full version, including alpha/beta/rc tags. -release = '' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# -# today = '' -# -# Else, today_fmt is used as the format for a strftime call. -# -# today_fmt = '%B %d, %Y' +try: + build_dir = Path(os.environ['CMAKE_CURRENT_BINARY_DIR']) + with open(build_dir / 'config.json', 'r') as f: + cmake_config = json.load(f) +except (KeyError, IOError) as e: + print("Failed to load cmake config data:", e) + build_dir = '.' + + cmake_config = { + "version": "*unknown version*", + "release": "*unknown release*", + "options": {} + } + tags.add('noconfig') + +version = cmake_config['version'] +release = cmake_config['release'] +html_title = f"{project} {version} documentation" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -235,21 +213,6 @@ # -- Options for LaTeX output --------------------------------------------- latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples @@ -260,39 +223,6 @@ r' \and '.join(all_authors), 'manual'), ] -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# -# latex_use_parts = False - -# If true, show page references after internal links. -# -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# -# latex_appendices = [] - -# It false, will not define \strong, \code, itleref, \crossref ... but only -# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added -# packages. -# -# latex_keep_old_macro_names = True - -# If false, no module index is generated. -# -# latex_domain_indices = True - - # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples @@ -302,11 +232,6 @@ [author], 1) ] -# If true, show URL addresses after external links. -# -# man_show_urls = False - - # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples @@ -317,104 +242,4 @@ author, 'ForTrilinos', 'One line description of project.', 'Miscellaneous'), ] - -# Documents to append as an appendix to all manuals. -# -# texinfo_appendices = [] - -# If false, no module index is generated. -# -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# -# texinfo_no_detailmenu = False - - -# -- Options for Epub output ---------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project -epub_author = author -epub_publisher = author -epub_copyright = copyright - -# The basename for the epub file. It defaults to the project name. -# epub_basename = project - -# The HTML theme for the epub output. Since the default themes are not -# optimized for small screen space, using the same theme for HTML and epub -# output is usually not wise. This defaults to 'epub', a theme designed to save -# visual space. -# -# epub_theme = 'epub' - -# The language of the text. It defaults to the language option -# or 'en' if the language is not set. -# -# epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -# epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -# -# epub_cover = () - -# A sequence of (type, uri, title) tuples for the guide element of content.opf. -# -# epub_guide = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_pre_files = [] - -# HTML files that should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_post_files = [] - -# A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] - -# The depth of the table of contents in toc.ncx. -# -# epub_tocdepth = 3 - -# Allow duplicate toc entries. -# -# epub_tocdup = True - -# Choose between 'default' and 'includehidden'. -# -# epub_tocscope = 'default' - -# Fix unsupported image types using the Pillow. -# -# epub_fix_images = False - -# Scale large images. -# -# epub_max_image_width = 0 - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# epub_show_urls = 'inline' - -# If false, no index is generated. -# -# epub_use_index = True diff --git a/doc/config.json.in b/doc/config.json.in new file mode 100644 index 00000000..4152ebb7 --- /dev/null +++ b/doc/config.json.in @@ -0,0 +1,5 @@ +{ + "version": "@ForTrilinos_SHORT_VERSION@", + "release": "@ForTrilinos_VERSION_STRING@", + "options": {} +} diff --git a/doc/index.rst b/doc/index.rst index f63c2bf0..4f6d0403 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -2,6 +2,11 @@ ForTrilinos =========== +.. only:: html + + :Release: |release| + :Date: |today| + .. toctree:: :maxdepth: 2 :caption: Contents diff --git a/doc/install.rst b/doc/install.rst index 48d7d074..a4a990f7 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -22,6 +22,7 @@ the version here simply denotes the version used to generate the included wrappers.) The version scheme is based on semantic versioning: + - Major version numbers with Trilinos and minor versions of SWIG-Fortran (since it's still not officially upstreamed) can result in major version number changes for ForTrilinos. @@ -55,7 +56,7 @@ in the committed version of the generated wrappers. =========== ============== ====================== In :ref:`the version table above `, the ``+fortran`` suffix for -SWIG indicates `the SWIG-Fortran fork `. +SWIG indicates the `SWIG-Fortran fork `_. ``+sha`` refers to a specific Git commit that comes after the given version. Basically, the versioning will be driven by what the Fortran-only users see in the committed version of the generated wrappers. @@ -69,7 +70,7 @@ E4S --- As of this writing, ForTrilinos is distributed as part of the `E4S Project -` and should be available as a +`_ and should be available as a pre-built binary on a variety of user and HPC systems. Spack