Skip to content

Add module for handling version information of stdlib #579

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

Merged
merged 8 commits into from
Nov 27, 2021
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
4 changes: 3 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
3 changes: 3 additions & 0 deletions API-doc-FORD-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines +12 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PROJECT_VERSION_MAJOR=0
PROJECT_VERSION_MINOR=0
PROJECT_VERSION_PATCH=0
PROJECT_VERSION_MAJOR=0
PROJECT_VERSION_MINOR=1
PROJECT_VERSION_PATCH=0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or is this overridden during the fypp processing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to be a stub, similar like the MAXRANK=3 argument above, which would would not allow to actually compile stdlib.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't these macros get applied when FORD runs fypp to preprocess the sources for the documentation? At least that's what I understand from here: https://github.com/Fortran-FOSS-Programmers/ford/wiki/Project-File-Options

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does show up in the final docs for the compile time constant:

image

Otherwise the value set won't affect the output of the documentation. I would prefer to leave this as a stub, so we don't have to worry about it becoming outdated when we release a new version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments are not allowed in the FORD meta-data section. Is there somewhere we could document these values are stubs, and don't reflect the actual library?

preprocessor: fypp
display: public
protected
Expand Down
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down
6 changes: 6 additions & 0 deletions Makefile.manual
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
6 changes: 6 additions & 0 deletions ci/fpm-deployment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fi
include=(
"ci/fpm.toml"
"LICENSE"
"VERSION"
)

# Files to remove from collection
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion ci/fpm.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name = "stdlib"
version = "0.1.0"
version = "VERSION"
license = "MIT"
author = "stdlib contributors"
maintainer = "@fortran-lang/stdlib"
Expand Down
1 change: 1 addition & 0 deletions doc/specs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
64 changes: 64 additions & 0 deletions doc/specs/stdlib_version.md
Original file line number Diff line number Diff line change
@@ -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.
Comment on lines +13 to +14
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not only allow the correct approach to do it?

Copy link
Member Author

@awvwgk awvwgk Nov 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the compact version I can see an application to verify the compatibility of API and/or ABI at runtime by a construct like:

use stdlib_version, only : stdlib_version_compact, get_stdlib_version
implicit none
integer :: major
call get_stdlib_version(major=major)
if (major > stdlib_version_compact / 10000) then
  error stop "Incompatible version of stdlib used"
end if
end

Similarly, stdlib_version_string and get_stdlib_version(string=string) can be used to provide a printout to inform about the stdlib versions used at build time and run time.

Not sure whether this is a realistic application of this information, usually this kind of verification happens at build time and constraints in package managers can ensure compatible version, but not everybody is using those.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Thank you for the explanation. You can merge this PR from my point-of-view.



## 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering if a fixed-length string can also be used to collect the output?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dummy argument is currently character(len=:), allocatable, intent(out), optional, since we are using a subroutine rather than a function. The rationale is that we want a stable API and ABI for this procedure, we could also go for multiple functions for getting the individual values, to make use of it in a more functional way.


#### 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
```
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ set(fppFiles
stdlib_string_type_constructor.fypp
stdlib_strings_to_string.fypp
stdlib_strings.fypp
stdlib_version.fypp
)


Expand All @@ -55,6 +56,9 @@ list(
APPEND fyppFlags
"-DWITH_QP=$<BOOL:${WITH_QP}>"
"-DWITH_XDP=$<BOOL:${WITH_XDP}>"
"-DPROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}"
"-DPROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR}"
"-DPROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}"
)

fypp_f90("${fyppFlags}" "${fppFiles}" outFiles)
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.manual
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
3 changes: 3 additions & 0 deletions src/common.fypp
Original file line number Diff line number Diff line change
@@ -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
Expand Down
65 changes: 65 additions & 0 deletions src/stdlib_version.fypp
Original file line number Diff line number Diff line change
@@ -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