diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 65ef3de7f..124c3fcd5 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -94,9 +94,11 @@ jobs: - name: Test manual makefiles if: ${{ matrix.build == 'make' }} run: | - make -f Makefile.manual FYPPFLAGS="-DMAXRANK=4" -j + make -f Makefile.manual -j make -f Makefile.manual test make -f Makefile.manual clean + env: + FYPPFLAGS: "-DMAXRANK=4" intel-build: runs-on: ${{ matrix.os }} diff --git a/API-doc-FORD-file.md b/API-doc-FORD-file.md index b14bcec2e..b4892ad74 100644 --- a/API-doc-FORD-file.md +++ b/API-doc-FORD-file.md @@ -9,6 +9,9 @@ media_dir: doc/media fpp_extensions: fypp preprocess: true macro: MAXRANK=3 + PROJECT_VERSION_MAJOR=0 + PROJECT_VERSION_MINOR=0 + PROJECT_VERSION_PATCH=0 preprocessor: fypp display: public protected diff --git a/CMakeLists.txt b/CMakeLists.txt index 27c5058c4..ec186fc1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,17 @@ cmake_minimum_required(VERSION 3.14.0) project(fortran_stdlib LANGUAGES Fortran - VERSION 0.1.0 DESCRIPTION "Community driven and agreed upon de facto standard library for Fortran" ) + +# Read version from file +file(STRINGS "${PROJECT_SOURCE_DIR}/VERSION" PROJECT_VERSION) +string(REPLACE "." ";" VERSION_LIST ${PROJECT_VERSION}) +list(GET VERSION_LIST 0 PROJECT_VERSION_MAJOR) +list(GET VERSION_LIST 1 PROJECT_VERSION_MINOR) +list(GET VERSION_LIST 2 PROJECT_VERSION_PATCH) +unset(VERSION_LIST) + enable_testing() # Follow GNU conventions for installation directories diff --git a/Makefile.manual b/Makefile.manual index b7af735b7..c6b437295 100644 --- a/Makefile.manual +++ b/Makefile.manual @@ -4,6 +4,12 @@ FC ?= gfortran FFLAGS ?= -Wall -Wextra -Wimplicit-interface -fPIC -g -fcheck=all FYPPFLAGS ?= +VERSION := $(subst ., ,$(file < VERSION)) +FYPPFLAGS += \ + -DPROJECT_VERSION_MAJOR=$(word 1,$(VERSION)) \ + -DPROJECT_VERSION_MINOR=$(word 2,$(VERSION)) \ + -DPROJECT_VERSION_PATCH=$(word 3,$(VERSION)) + export FC export FFLAGS export FYPPFLAGS diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..6e8bf73aa --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.0 diff --git a/ci/fpm-deployment.sh b/ci/fpm-deployment.sh index 3d9884345..4fc20094c 100644 --- a/ci/fpm-deployment.sh +++ b/ci/fpm-deployment.sh @@ -22,6 +22,7 @@ fi include=( "ci/fpm.toml" "LICENSE" + "VERSION" ) # Files to remove from collection @@ -32,6 +33,11 @@ prune=( "$destdir/src/f18estop.f90" ) +major=$(cut -d. -f1 VERSION) +minor=$(cut -d. -f2 VERSION) +patch=$(cut -d. -f3 VERSION) +fyflags="${fyflags} -DPROJECT_VERSION_MAJOR=${major} -DPROJECT_VERSION_MINOR=${minor} -DPROJECT_VERSION_PATCH=${patch}" + mkdir -p "$destdir/src" "$destdir/test" # Preprocess stdlib sources diff --git a/ci/fpm.toml b/ci/fpm.toml index aeba3087c..e85a54f69 100644 --- a/ci/fpm.toml +++ b/ci/fpm.toml @@ -1,5 +1,5 @@ name = "stdlib" -version = "0.1.0" +version = "VERSION" license = "MIT" author = "stdlib contributors" maintainer = "@fortran-lang/stdlib" diff --git a/doc/specs/index.md b/doc/specs/index.md index a3b0a5def..389fcde0d 100644 --- a/doc/specs/index.md +++ b/doc/specs/index.md @@ -28,6 +28,7 @@ This is and index/directory of the specifications (specs) for each new module/fe - [string\_type](./stdlib_string_type.html) - Basic string support - [strings](./stdlib_strings.html) - String handling and manipulation routines - [stringlist_type](./stdlib_stringlist_type.html) - 1-Dimensional list of strings + - [version](./stdlib_version.html) - Version information ## Released/Stable Features & Modules diff --git a/doc/specs/stdlib_version.md b/doc/specs/stdlib_version.md new file mode 100644 index 000000000..9b3350f28 --- /dev/null +++ b/doc/specs/stdlib_version.md @@ -0,0 +1,64 @@ +--- +title: Version information +--- + +# The `stdlib_version` module + +[TOC] + +## Introduction + +The `stdlib_version` module contains the version of the standard library. +The version information can be used as a compile time constant or retrieved from a getter function at runtime. +In case the standard library is dynamically linked, the version number retrieved from the getter might mismatch the compile time constants provided from the version built against. +Therefore, it is recommended to retrieve the version information always at runtime. + + +## Constants provided by `stdlib_version` + +### `stdlib_version_string` + +String constant representing the version number. + +### `stdlib_version_compact` + +Compact representation of the version string following the scheme: +major * 10000 + minor * 100 + patch. + + +### `get_stdlib_version` + +#### Status + +Experimental + +#### Description + +Getter function to retrieve version information + +#### Syntax + +`res = [[stdlib_version(module):get_stdlib_version(function)]] ([major], [minor], [patch], [string])` + +#### Class + +Pure subroutine. + +#### Argument + +`major`: shall be an intrinsic integer type. It is an optional, `intent(out)` argument. +`minor`: shall be an intrinsic integer type. It is an optional, `intent(out)` argument. +`patch`: shall be an intrinsic integer type. It is an optional, `intent(out)` argument. +`string`: shall be a deferred length character type. It is an optional, `intent(out)` argument. + +#### Example + +```fortran +program demo_version + use stdlib_version, only : get_stdlib_version + implicit none + character(len=:), allocatable :: version + call get_stdlib_version(string=version) + print '(a)', version +end program demo_version +``` diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bcb4931b3..601dac96a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,6 +39,7 @@ set(fppFiles stdlib_string_type_constructor.fypp stdlib_strings_to_string.fypp stdlib_strings.fypp + stdlib_version.fypp ) @@ -55,6 +56,9 @@ list( APPEND fyppFlags "-DWITH_QP=$" "-DWITH_XDP=$" + "-DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}" + "-DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR}" + "-DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}" ) fypp_f90("${fyppFlags}" "${fppFiles}" outFiles) diff --git a/src/Makefile.manual b/src/Makefile.manual index f573fa6cf..57a717d6a 100644 --- a/src/Makefile.manual +++ b/src/Makefile.manual @@ -35,7 +35,8 @@ SRCFYPP = \ stdlib_string_type.fypp \ stdlib_string_type_constructor.fypp \ stdlib_strings.fypp \ - stdlib_strings_to_string.fypp + stdlib_strings_to_string.fypp \ + stdlib_version.fypp SRC = f18estop.f90 \ stdlib_error.f90 \ diff --git a/src/common.fypp b/src/common.fypp index 7ae5f70e1..f94b6ec1a 100644 --- a/src/common.fypp +++ b/src/common.fypp @@ -1,5 +1,8 @@ #:mute +#! Project version number +#:set PROJECT_VERSION = "{}.{}.{}".format(PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR, PROJECT_VERSION_PATCH) + #! Support for quadruple precision floating point numbers #:if not defined("WITH_QP") #:set WITH_QP = False diff --git a/src/stdlib_version.fypp b/src/stdlib_version.fypp new file mode 100644 index 000000000..5be172cdc --- /dev/null +++ b/src/stdlib_version.fypp @@ -0,0 +1,65 @@ +! SPDX-Identifier: MIT + +#:include "common.fypp" + +!> Version information on stdlib +module stdlib_version + implicit none + private + + public :: get_stdlib_version + public :: stdlib_version_string, stdlib_version_compact + + + !> String representation of the standard library version + character(len=*), parameter :: stdlib_version_string = "${PROJECT_VERSION}$" + + !> Major version number of the above standard library version + integer, parameter :: stdlib_major = ${PROJECT_VERSION_MAJOR}$ + + !> Minor version number of the above standard library version + integer, parameter :: stdlib_minor = ${PROJECT_VERSION_MINOR}$ + + !> Patch version number of the above standard library version + integer, parameter :: stdlib_patch = ${PROJECT_VERSION_PATCH}$ + + !> Compact numeric representation of the standard library version + integer, parameter :: stdlib_version_compact = & + & stdlib_major*10000 + stdlib_minor*100 + stdlib_patch + + +contains + + +!> Getter function to retrieve standard library version +pure subroutine get_stdlib_version(major, minor, patch, string) + + !> Major version number of the standard library version + integer, intent(out), optional :: major + + !> Minor version number of the standard library version + integer, intent(out), optional :: minor + + !> Patch version number of the standard library version + integer, intent(out), optional :: patch + + !> String representation of the standard library version + character(len=:), allocatable, intent(out), optional :: string + + if (present(major)) then + major = stdlib_major + end if + if (present(minor)) then + minor = stdlib_minor + end if + if (present(patch)) then + patch = stdlib_patch + end if + if (present(string)) then + string = stdlib_version_string + end if + +end subroutine get_stdlib_version + + +end module stdlib_version