Skip to content

Commit 722d908

Browse files
authoredJan 22, 2021
Merge pull request fortran-lang#17 from Jim-215-Fisher/master
merge
2 parents 200b307 + 349d0eb commit 722d908

11 files changed

+240
-59
lines changed
 

‎.github/workflows/CI.yml

+19-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ jobs:
5959
brew link gcc@${GCC_V}
6060
6161
- name: Configure with CMake
62-
run: cmake -Wdev -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAXIMUM_RANK=4 -S . -B build
62+
run: >-
63+
cmake -Wdev
64+
-DCMAKE_BUILD_TYPE=Release
65+
-DCMAKE_MAXIMUM_RANK=4
66+
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
67+
-S . -B build
6368
6469
- name: Build and compile
6570
run: cmake --build build
@@ -72,6 +77,9 @@ jobs:
7277
run: ctest --parallel --output-on-failure
7378
working-directory: build
7479

80+
- name: Install project
81+
run: cmake --install build
82+
7583
- name: Test in-tree builds
7684
if: contains( matrix.gcc_v, '10') # Only test one compiler on each platform
7785
run: |
@@ -82,7 +90,7 @@ jobs:
8290
- name: Test manual makefiles
8391
if: contains(matrix.os, 'ubuntu') && contains(matrix.gcc_v, '10')
8492
run: |
85-
make -f Makefile.manual FYPPFLAGS="-DMAXRANK=4"
93+
make -f Makefile.manual FYPPFLAGS="-DMAXRANK=4" -j
8694
make -f Makefile.manual test
8795
make -f Makefile.manual clean
8896
@@ -129,7 +137,12 @@ jobs:
129137
run: pip install --upgrade fypp
130138

131139
- name: Configure with CMake
132-
run: cmake -Wdev -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAXIMUM_RANK=4 -S . -B build
140+
run: >-
141+
cmake -Wdev
142+
-DCMAKE_BUILD_TYPE=Release
143+
-DCMAKE_MAXIMUM_RANK=4
144+
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
145+
-S . -B build
133146
134147
- name: Build and compile
135148
run: cmake --build build
@@ -141,3 +154,6 @@ jobs:
141154
- name: test
142155
run: ctest --parallel --output-on-failure
143156
working-directory: build
157+
158+
- name: Install project
159+
run: cmake --install build

‎.github/workflows/ci_windows.yml

+4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ jobs:
9999
-DCMAKE_BUILD_TYPE=Debug
100100
-DCMAKE_Fortran_FLAGS_DEBUG="-Wall -Wextra -Wimplicit-interface -fPIC -g -fcheck=all -fbacktrace"
101101
-DCMAKE_MAXIMUM_RANK=4
102+
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
102103
env:
103104
FC: gfortran
104105
CC: gcc
@@ -120,3 +121,6 @@ jobs:
120121
with:
121122
name: WindowsCMakeTestlog
122123
path: build/Testing/Temporary/LastTest.log
124+
125+
- name: Install project
126+
run: cmake --install build

‎CMakeLists.txt

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
cmake_minimum_required(VERSION 3.14.0)
2-
project(stdlib Fortran)
2+
project(fortran_stdlib
3+
LANGUAGES Fortran
4+
VERSION 0
5+
DESCRIPTION "Community driven and agreed upon de facto standard library for Fortran"
6+
)
37
enable_testing()
48

5-
include(${CMAKE_SOURCE_DIR}/cmake/stdlib.cmake)
9+
# Follow GNU conventions for installation directories
10+
include(GNUInstallDirs)
11+
12+
include(${PROJECT_SOURCE_DIR}/cmake/stdlib.cmake)
13+
14+
# --- CMake specific configuration and package data export
15+
add_subdirectory(config)
616

717
# --- compiler options
818
if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
@@ -52,3 +62,8 @@ if(NOT FYPP)
5262
endif()
5363

5464
add_subdirectory(src)
65+
66+
install(EXPORT ${PROJECT_NAME}-targets
67+
NAMESPACE ${PROJECT_NAME}::
68+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
69+
)

‎README.md

+121-18
Original file line numberDiff line numberDiff line change
@@ -40,54 +40,157 @@ git clone https://github.com/fortran-lang/stdlib
4040
cd stdlib
4141
```
4242

43+
4344
### Requirements
4445

45-
The preprocessor ```fypp``` (https://github.com/aradi/fypp) is needed because metaprogramming is used.
46-
It can be installed using the command line installer ```pip```.
46+
To build the Fortran standard library you need
47+
48+
- a Fortran 2008 compliant compiler, or better, a Fortran 2018 compliant compiler
49+
(GCC Fortran and Intel Fortran compilers are known to work for stdlib)
50+
- CMake version 3.14 or newer (alternatively Make can be used)
51+
- a build backend for CMake, like Make or Ninja (the latter is recommended on Windows)
52+
- the [fypp](https://github.com/aradi/fypp) preprocessor (used as meta-programming tool)
53+
54+
If your system package manager does not provide the required build tools, all build dependencies can be installed with the Python command line installer ``pip``:
55+
56+
```sh
57+
pip install --user fypp cmake ninja
58+
```
59+
60+
Alternatively, you can install the build tools from the conda-forge channel with the conda package manager:
61+
4762
```sh
48-
pip install fypp
63+
conda config --add channels conda-forge
64+
conda create -n stdlib-tools fypp cmake ninja
65+
conda activate stdlib-tools
4966
```
5067

68+
You can install conda using the [miniforge installer](https://github.com/conda-forge/miniforge/releases).
69+
Also, you can install a Fortran compiler from conda-forge by installing the ``fortran-compiler`` package, which installs GFortran.
70+
71+
72+
### Supported Compilers
73+
74+
The following combinations are tested on the default branch of stdlib:
75+
76+
Name | Version | Platform | Architecture
77+
--- | --- | --- | ---
78+
GCC Fortran | 7, 8, 9, 10 | Ubuntu 18.04 | x86_64
79+
GCC Fortran | 7, 8, 9, 10 | MacOS Catalina 10.15 | x86_64
80+
GCC Fortran | 8 | Windows Server 2019 | x86_64
81+
GCC Fortran (MSYS) | 10 | Windows Server 2019 | x86_64
82+
GCC Fortran (MinGW) | 10 | Windows Server 2019 | x86_64, i686
83+
Intel oneAPI classic | 2021.1 | Ubuntu 20.04 | x86_64
84+
85+
We try to test as many available compilers and platforms as possible.
86+
A list of tested compilers which are currently not working and the respective issue are listed below.
87+
88+
Name | Version | Platform | Architecture | Status
89+
--- | --- | --- | --- | ---
90+
GCC Fortran | 7.4 | Windows 10 | i686 | [#296](https://github.com/fortran-lang/stdlib/issues/296)
91+
NVIDIA HPC SDK | 20.7, 20.9, 20.11 | Manjaro Linux 20 | x86_64 | [#107](https://github.com/fortran-lang/stdlib/issues/107)
92+
NAG | 7.0 | RHEL | x86_64 | [#108](https://github.com/fortran-lang/stdlib/issues/108)
93+
Intel Parallel Studio XE | 16, 17, 18 | OpenSUSE | x86_64 | failed to compile
94+
95+
Please share your experience with successful and failing builds for compiler/platform/architecture combinations not covered above.
96+
97+
5198
### Build with CMake
5299

100+
Configure the build with
101+
53102
```sh
54103
cmake -B build
104+
```
105+
106+
You can pass additional options to CMake to customize the build.
107+
Important options are
108+
109+
- `-G Ninja` to use the Ninja backend instead of the default Make backend. Other build backends are available with a similar syntax.
110+
- `-DCMAKE_INSTALL_PREFIX` is used to provide the install location for the library.
111+
- `-DCMAKE_MAXIMUM_RANK` the maximum array rank procedures should be generated for.
112+
The default is 15 for Fortran 2003 compliant compilers, otherwise 7 for compilers not supporting Fortran 2003 completely yet.
113+
The minimum required rank to compile this project is 4.
114+
Compiling with maximum rank 15 can be resource intensive and requires at least 16 GB of memory to allow parallel compilation or 4 GB memory for sequential compilation.
115+
- `-DBUILD_SHARED_LIBS` set to `on` in case you want link your application dynamically against the standard library (default: `off`).
55116

117+
For example, to configure a build using the Ninja backend and generating procedures up to rank 7, which is installed to your home directory use
118+
119+
```sh
120+
cmake -B build -G Ninja -DCMAKE_MAXIMUM_RANK=7 -DCMAKE_INSTALL_PREFIX=$HOME/.local
121+
```
122+
123+
To build the standard library run
124+
125+
```sh
56126
cmake --build build
127+
```
128+
129+
To test your build, run the test suite after the build has finished with
57130

131+
```sh
58132
cmake --build build --target test
59133
```
60134

61-
### Build with make
135+
Please report failing tests on our [issue tracker](https://github.com/fortran-lang/stdlib/issues/new/choose) including details on the compiler used, the operating system and platform architecture.
62136

63-
Alternatively, you can build using provided Makefiles:
137+
To install the project to the declared prefix run
64138

139+
```sh
140+
cmake --install build
65141
```
66-
make -f Makefile.manual
67-
```
68142

69-
## Limiting the maximum rank of generated procedures
143+
Now you have a working version of stdlib you can use for your project.
144+
145+
146+
### Build with make
70147

71-
Stdlib's preprocessor (fypp) by default generates specific procedures for arrays of all ranks, up to rank 15.
72-
This can result in long compilation times and, on some computers, exceeding available memory.
73-
If you know that you won't need all 15 ranks, you can specify the maximum rank for which the specific procedures will be generated.
74-
For example, with CMake:
148+
Alternatively, you can build using provided Makefiles:
75149

76150
```sh
77-
cmake -B build -DCMAKE_MAXIMUM_RANK=4
78-
cmake --build build
79-
cmake --build build --target test
151+
make -f Makefile.manual
80152
```
81-
or as follows with `make`:
153+
154+
You can limit the maximum rank by setting ``-DMAXRANK=<num>`` in the ``FYPPFLAGS`` environment variable:
82155

83156
```sh
84157
make -f Makefile.manual FYPPFLAGS=-DMAXRANK=4
85158
```
86-
Note that currently the minimum value for maximum rank is 4.
159+
160+
161+
162+
## Using stdlib in your project
163+
164+
The stdlib project exports CMake package files and pkg-config files to make stdlib usable for other projects.
165+
The package files are located in the library directory in the installation prefix.
166+
167+
For CMake builds of stdlib you can find a local installation with
168+
169+
```cmake
170+
find_package(fortran_stdlib REQUIRED)
171+
...
172+
target_link_libraries(
173+
${PROJECT_NAME}
174+
PRIVATE
175+
fortran_stdlib::fortran_stdlib
176+
)
177+
```
178+
179+
To make the installed stdlib project discoverable add the stdlib directory to the ``CMAKE_PREFIX_PATH``.
180+
The usual install localtion of the package files is ``$PREFIX/lib/cmake/fortran_stdlib``.
181+
182+
For non-CMake build systems (like make) you can use the exported pkg-config file by setting ``PKG_CONFIG_PATH`` to include the directory containing the exported pc-file.
183+
The usual install location of the pc-file is ``$PREFIX/lib/pkgconfig``.
184+
In make you can obtain the required compile and link arguments with
185+
186+
```make
187+
STDLIB_CFLAGS := $(shell pkg-config --cflags fortran_stdlib)
188+
STDLIB_LIBS := $(shell pkg-config --libs fortran_stdlib)
189+
```
87190

88191
## Documentation
89192

90-
Documentation is a work in progress (see issue #4) but is currently available at https://stdlib.fortran-lang.org.
193+
Documentation is a work in progress (see issue [#4](https://github.com/fortran-lang/stdlib/issues/4)) but already available at [stdlib.fortran-lang.org](https://stdlib.fortran-lang.org).
91194
This includes API documentation automatically generated from static analysis and markup comments in the source files
92195
using the [FORD](https://github.com/Fortran-FOSS-programmers/ford/wiki) tool,
93196
as well as a specification document or ["spec"](https://stdlib.fortran-lang.org/page/specs/index.html) for each proposed feature.

‎config/CMakeLists.txt

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# SPDX-Identifier: MIT
2+
3+
# Export a pkg-config file
4+
configure_file(
5+
"${CMAKE_CURRENT_SOURCE_DIR}/template.pc"
6+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
7+
@ONLY
8+
)
9+
install(
10+
FILES
11+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
12+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
13+
)
14+
15+
# Export CMake package file
16+
include(CMakePackageConfigHelpers)
17+
configure_package_config_file(
18+
"${CMAKE_CURRENT_SOURCE_DIR}/template.cmake"
19+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
20+
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
21+
)
22+
if(BUILD_SHARED_LIBS OR PROJECT_VERSION_MAJOR EQUAL 0)
23+
# Due to the uncertain ABI compatibility of Fortran shared libraries
24+
# limit compatibility for dynamic linking to same minor version.
25+
set(COMPATIBILITY SameMinorVersion)
26+
else()
27+
# Require API compatibility via semantic versioning for static linking.
28+
set(COMPATIBILITY SameMajorVersion)
29+
endif()
30+
write_basic_package_version_file(
31+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
32+
VERSION "${PROJECT_VERSION}"
33+
COMPATIBILITY ${COMPATIBILITY}
34+
)
35+
install(
36+
FILES
37+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
38+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
39+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
40+
)

‎config/template.cmake

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@PACKAGE_INIT@
2+
3+
if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@")
4+
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
5+
endif()

‎config/template.pc

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
prefix=@CMAKE_INSTALL_PREFIX@
2+
libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@
3+
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
4+
5+
Name: @PROJECT_NAME@
6+
Description: @PROJECT_DESCRIPTION@
7+
Version: @PROJECT_VERSION@
8+
Libs: -L${libdir} -l@PROJECT_NAME@
9+
Cflags: -I${includedir}

‎src/CMakeLists.txt

+12-11
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,28 @@ set(SRC
4545
${outFiles}
4646
)
4747

48-
add_library(fortran_stdlib ${SRC})
48+
add_library(${PROJECT_NAME} ${SRC})
4949

5050
set(LIB_MOD_DIR ${CMAKE_CURRENT_BINARY_DIR}/mod_files/)
51-
set_target_properties(fortran_stdlib PROPERTIES
51+
set_target_properties(${PROJECT_NAME} PROPERTIES
5252
Fortran_MODULE_DIRECTORY ${LIB_MOD_DIR})
53-
target_include_directories(fortran_stdlib PUBLIC
53+
target_include_directories(${PROJECT_NAME} PUBLIC
5454
$<BUILD_INTERFACE:${LIB_MOD_DIR}>
5555
$<INSTALL_INTERFACE:include>
5656
)
5757

5858
if(f18errorstop)
59-
target_sources(fortran_stdlib PRIVATE f18estop.f90)
59+
target_sources(${PROJECT_NAME} PRIVATE f18estop.f90)
6060
else()
61-
target_sources(fortran_stdlib PRIVATE f08estop.f90)
61+
target_sources(${PROJECT_NAME} PRIVATE f08estop.f90)
6262
endif()
6363

6464
add_subdirectory(tests)
6565

66-
install(TARGETS fortran_stdlib
67-
RUNTIME DESTINATION bin
68-
ARCHIVE DESTINATION lib
69-
LIBRARY DESTINATION lib
70-
)
71-
install(DIRECTORY ${LIB_MOD_DIR} DESTINATION include)
66+
install(TARGETS ${PROJECT_NAME}
67+
EXPORT ${PROJECT_NAME}-targets
68+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
69+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
70+
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
71+
)
72+
install(DIRECTORY ${LIB_MOD_DIR} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

‎src/stdlib_ascii.f90

+10-22
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,14 @@ module stdlib_ascii
6868
!> Checks whether `c` is an ASCII letter (A .. Z, a .. z).
6969
pure logical function is_alpha(c)
7070
character(len=1), intent(in) :: c !! The character to test.
71-
integer :: ic
72-
ic = iachar(c)
73-
is_alpha = (ic >= iachar('A') .and. ic <= iachar('Z')) .or. (ic >= iachar('a') .and. ic <= iachar('z'))
71+
is_alpha = (c >= 'A' .and. c <= 'Z') .or. (c >= 'a' .and. c <= 'z')
7472
end function
7573

7674
!> Checks whether `c` is a letter or a number (0 .. 9, a .. z, A .. Z).
7775
pure logical function is_alphanum(c)
7876
character(len=1), intent(in) :: c !! The character to test.
79-
integer :: ic
80-
ic = iachar(c)
81-
is_alphanum = (ic >= iachar('0') .and. ic <= iachar('9')) .or. (ic >= iachar('a') .and. ic <= iachar('z')) &
82-
.or. (ic >= iachar('A') .and. ic <= iachar('Z'))
77+
is_alphanum = (c >= '0' .and. c <= '9') .or. (c >= 'a' .and. c <= 'z') &
78+
.or. (c >= 'A' .and. c <= 'Z')
8379
end function
8480

8581
!> Checks whether or not `c` is in the ASCII character set -
@@ -100,26 +96,20 @@ pure logical function is_control(c)
10096
!> Checks whether `c` is a digit (0 .. 9).
10197
pure logical function is_digit(c)
10298
character(len=1), intent(in) :: c !! The character to test.
103-
integer :: ic
104-
ic = iachar(c)
105-
is_digit = (iachar('0') <= ic) .and. (ic <= iachar('9'))
99+
is_digit = ('0' <= c) .and. (c <= '9')
106100
end function
107101

108102
!> Checks whether `c` is a digit in base 8 (0 .. 7).
109103
pure logical function is_octal_digit(c)
110104
character(len=1), intent(in) :: c !! The character to test.
111-
integer :: ic
112-
ic = iachar(c)
113-
is_octal_digit = (ic >= iachar('0')) .and. (ic <= iachar('7'))
105+
is_octal_digit = (c >= '0') .and. (c <= '7');
114106
end function
115107

116108
!> Checks whether `c` is a digit in base 16 (0 .. 9, A .. F, a .. f).
117109
pure logical function is_hex_digit(c)
118110
character(len=1), intent(in) :: c !! The character to test.
119-
integer :: ic
120-
ic = iachar(c)
121-
is_hex_digit = (ic >= iachar('0') .and. ic <= iachar('9')) .or. (ic >= iachar('a') .and. ic <= iachar('f')) &
122-
.or. (ic >= iachar('A') .and. ic <= iachar('F')) .or. (ic >= iachar('a') .and. ic <= iachar('f'))
111+
is_hex_digit = (c >= '0' .and. c <= '9') .or. (c >= 'a' .and. c <= 'f') &
112+
.or. (c >= 'A' .and. c <= 'F')
123113
end function
124114

125115
!> Checks whether or not `c` is a punctuation character. That includes
@@ -165,9 +155,7 @@ pure logical function is_lower(c)
165155
!> Checks whether `c` is an uppercase ASCII letter (A .. Z).
166156
pure logical function is_upper(c)
167157
character(len=1), intent(in) :: c !! The character to test.
168-
integer :: ic
169-
ic = iachar(c)
170-
is_upper = ic >= iachar('A') .and. ic <= iachar('Z')
158+
is_upper = (c >= 'A') .and. (c <= 'Z')
171159
end function
172160

173161
!> Checks whether or not `c` is a whitespace character. That includes the
@@ -177,7 +165,7 @@ pure logical function is_white(c)
177165
character(len=1), intent(in) :: c !! The character to test.
178166
integer :: ic
179167
ic = iachar(c) ! TAB, LF, VT, FF, CR
180-
is_white = ic == iachar(' ') .or. (ic >= int(z'09') .and. ic <= int(z'0D'))
168+
is_white = (c == ' ') .or. (ic >= int(z'09') .and. ic <= int(z'0D'));
181169
end function
182170

183171
!> Checks whether or not `c` is a blank character. That includes the
@@ -186,7 +174,7 @@ pure logical function is_blank(c)
186174
character(len=1), intent(in) :: c !! The character to test.
187175
integer :: ic
188176
ic = iachar(c) ! TAB
189-
is_blank = ic == iachar(' ') .or. ic == int(z'09')
177+
is_blank = (c == ' ') .or. (ic == int(z'09'));
190178
end function
191179

192180
!> Returns the corresponding lowercase letter, if `c` is an uppercase

‎src/tests/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro(ADDTEST name)
22
add_executable(test_${name} test_${name}.f90)
3-
target_link_libraries(test_${name} fortran_stdlib)
3+
target_link_libraries(test_${name} ${PROJECT_NAME})
44
add_test(NAME ${name}
55
COMMAND $<TARGET_FILE:test_${name}> ${CMAKE_CURRENT_BINARY_DIR}
66
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

‎src/tests/system/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
add_executable(test_sleep test_sleep.f90)
2-
target_link_libraries(test_sleep fortran_stdlib)
2+
target_link_libraries(test_sleep ${PROJECT_NAME})
33

44
add_test(NAME Sleep COMMAND $<TARGET_FILE:test_sleep> 350)
5-
set_tests_properties(Sleep PROPERTIES TIMEOUT 1)
5+
set_tests_properties(Sleep PROPERTIES TIMEOUT 1)

0 commit comments

Comments
 (0)
Please sign in to comment.