Skip to content

Commit 5d572e7

Browse files
committed
Initial version of CMake example for stdlib
0 parents  commit 5d572e7

File tree

12 files changed

+486
-0
lines changed

12 files changed

+486
-0
lines changed

.github/workflows/build.yml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: CI
2+
on: [push, pull_request]
3+
4+
env:
5+
CI: "ON"
6+
HOMEBREW_NO_ANALYTICS: "ON"
7+
HOMEBREW_NO_AUTO_UPDATE: "ON"
8+
HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: "ON"
9+
HOMEBREW_NO_GITHUB_API: "ON"
10+
HOMEBREW_NO_INSTALL_CLEANUP: "ON"
11+
BUILD_DIR: _build
12+
CMAKE_OPTIONS: >-
13+
-DCMAKE_BUILD_TYPE=Debug
14+
15+
jobs:
16+
gcc-build:
17+
runs-on: ${{ matrix.os }}
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
os: [ubuntu-latest, macos-latest]
22+
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v2
26+
27+
- uses: actions/setup-python@v1
28+
with:
29+
python-version: '3.x'
30+
31+
- name: Set Compiler (Linux)
32+
if: contains(matrix.os, 'ubuntu')
33+
run: |
34+
echo "FC=gfortran" >> $GITHUB_ENV
35+
echo "CC=gcc" >> $GITHUB_ENV
36+
37+
- name: Set Compiler (OSX)
38+
if: contains(matrix.os, 'macos')
39+
run: |
40+
echo "FC=gfortran-9" >> $GITHUB_ENV
41+
echo "CC=gcc-9" >> $GITHUB_ENV
42+
43+
- name: Install cmake
44+
run: pip3 install cmake ninja fypp
45+
46+
- name: Configure build
47+
run: >-
48+
cmake -B ${BUILD_DIR} -G Ninja
49+
-DCMAKE_INSTALL_PREFIX=${PWD}/_install
50+
${CMAKE_OPTIONS}
51+
52+
- name: Build project
53+
run: cmake --build ${BUILD_DIR}
54+
55+
- name: Run regression tests
56+
run: |
57+
pushd ${BUILD_DIR}
58+
ctest -j 2 --output-on-failure
59+
popd
60+
61+
- name: Install project
62+
run: |
63+
cmake --install ${BUILD_DIR}
64+
65+
# Test MinGW native compilation
66+
mingw-build:
67+
runs-on: windows-latest
68+
strategy:
69+
fail-fast: false
70+
matrix:
71+
include: [
72+
{ msystem: MINGW64, arch: x86_64 },
73+
{ msystem: MINGW32, arch: i686 }
74+
]
75+
defaults:
76+
run:
77+
shell: msys2 {0}
78+
steps:
79+
- uses: actions/checkout@v2
80+
81+
- uses: msys2/setup-msys2@v2
82+
with:
83+
msystem: ${{ matrix.msystem }}
84+
update: false
85+
install: >-
86+
git
87+
mingw-w64-${{ matrix.arch }}-gcc-fortran
88+
mingw-w64-${{ matrix.arch }}-python
89+
mingw-w64-${{ matrix.arch }}-python-pip
90+
mingw-w64-${{ matrix.arch }}-cmake
91+
mingw-w64-${{ matrix.arch }}-ninja
92+
93+
- name: Install fypp
94+
run: pip install fypp
95+
96+
- name: Configure build
97+
run: >-
98+
cmake -B ${BUILD_DIR} -G Ninja
99+
-DCMAKE_INSTALL_PREFIX=${PWD}/_install
100+
${CMAKE_OPTIONS}
101+
env:
102+
FC: gfortran
103+
CC: gcc
104+
105+
- name: Build project
106+
run: cmake --build ${BUILD_DIR}
107+
108+
- name: Run regression tests
109+
run: |
110+
pushd ${BUILD_DIR}
111+
ctest -j 2 --output-on-failure
112+
popd
113+
114+
- name: Install project
115+
run: |
116+
cmake --install ${BUILD_DIR}

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Prerequisites
2+
*.d
3+
4+
# Compiled Object files
5+
*.slo
6+
*.lo
7+
*.o
8+
*.obj
9+
10+
# Precompiled Headers
11+
*.gch
12+
*.pch
13+
14+
# Compiled Dynamic libraries
15+
*.so
16+
*.dylib
17+
*.dll
18+
19+
# Fortran module files
20+
*.mod
21+
*.smod
22+
23+
# Compiled Static libraries
24+
*.lai
25+
*.la
26+
*.a
27+
*.lib
28+
29+
# Executables
30+
*.exe
31+
*.out
32+
*.app
33+
34+
# Directories
35+
/build*/
36+
/_*/

CMakeLists.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# SPDX-Identifier: MIT
2+
cmake_minimum_required(VERSION 3.14)
3+
4+
project(
5+
"stdlib-example"
6+
LANGUAGES "Fortran"
7+
VERSION "0.1"
8+
)
9+
10+
# Follow GNU conventions for installing directories
11+
include(GNUInstallDirs)
12+
13+
# General configuration information
14+
add_subdirectory("config")
15+
16+
# Get the stdlib subproject
17+
set(lib-deps)
18+
add_subdirectory("subprojects")
19+
20+
# Collect source of the project
21+
add_subdirectory("src")
22+
23+
24+
# Collect source of the application
25+
add_subdirectory("app")
26+
27+
# Export targets for other projects
28+
add_library("${PROJECT_NAME}" INTERFACE)
29+
target_link_libraries("${PROJECT_NAME}" INTERFACE "${PROJECT_NAME}-lib")
30+
install(
31+
TARGETS
32+
"${PROJECT_NAME}"
33+
EXPORT
34+
"${PROJECT_NAME}-targets"
35+
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
36+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
37+
)
38+
39+
# Install exported targets
40+
install(
41+
EXPORT "${PROJECT_NAME}-targets"
42+
NAMESPACE
43+
"${PROJECT_NAME}::"
44+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
45+
)
46+
47+
# Package license files
48+
install(
49+
FILES
50+
"LICENSE"
51+
DESTINATION "${CMAKE_INSTALL_DATADIR}/licenses/${PROJECT_NAME}"
52+
)

LICENSE

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright 2020 Sebastian Ehlert
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<!-- Remove this introduction after creating a new project from this template -->
2+
# Using stdlib in your project
3+
4+
The Fortran standard library ([stdlib](https://github.com/fortran-lang/stdlib)) is developed by the [Fortran-lang community](https://github.com/fortran-lang).
5+
This projects shows how to integrate stdlib in your CMake project.
6+
7+
For a quick start you can include stdlib as git submodule in your projects by
8+
9+
```
10+
git submodule https://github.com/fortran-lang/stdlib subprojects/stdlib
11+
```
12+
13+
Users must initialize the submodule themselves when building your project, unless you let CMake perform this operation on demand.
14+
15+
Alternatively, you can use the `FetchContent` module of CMake to retrieve the git repository while configuring the project.
16+
A CMake snippet supporting both approaches is given here
17+
18+
```cmake
19+
# Include the stdlib project
20+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/stdlib/CMakeLists.txt)
21+
add_subdirectory("stdlib")
22+
else()
23+
set("stdlib-url" "https://github.com/fortran-lang/stdlib")
24+
message(STATUS "Retrieving stdlib from ${stdlib-url}")
25+
include(FetchContent)
26+
FetchContent_Declare(
27+
"stdlib"
28+
GIT_REPOSITORY "${stdlib-url}"
29+
GIT_TAG "HEAD"
30+
)
31+
FetchContent_MakeAvailable("stdlib")
32+
endif()
33+
```
34+
35+
You can configure stdlib by setting the appropriate options before including the subproject.
36+
Important options are
37+
38+
- `BUILD_SHARED_LIBS` should be set to off if you want to link statically against stdlib
39+
- `CMAKE_MAXIMUM_RANK` determines the maximum rank of arrays supported in stdlib, the default value is 15.
40+
To save compile time you can reduce this value to the maximum rank needed in your application.
41+
42+
This project offers a ready to use integration of stdlib for CMake, including an exported library and a binary application.
43+
Additionally, some boilerplate text in the README is available below as well as a testing setup with GitHub actions for GCC.
44+
The general CMake style should allow you to reuse most of the CMake build files *without* modification, just change the project name, add your source files and you are ready to go.
45+
46+
You can [just *use this template* to create new project](https://github.com/awvwgk/stdlib-cmake-example/generate).
47+
Remove this introduction from the README afterwards and fill in your project details.
48+
49+
For more information on stdlib visit its [documentation](https://stdlib.fortran-lang.org).
50+
51+
52+
<!-- Boilerplate README starting after this line -->
53+
## Installation
54+
55+
To build this project you need
56+
57+
- A Fortran compiler supporting Fortran 2008 or later (`gfortran` or `ifort`)
58+
- CMake version 3.14 or later
59+
- The [fypp](https://github.com/aradi/fypp) preprocessor
60+
- A build backend, ninja (version 1.10 or newer) or make
61+
<!-- Add other prerequisites from your project to this list -->
62+
63+
Configure the build with (set the `CMAKE_INSTALL_PREFIX` to your preferred install location)
64+
65+
```
66+
cmake -B _build -G Ninja -DCMAKE_INSTALL_PREFIX=$HOME/.local
67+
```
68+
69+
To build the project run
70+
71+
```
72+
cmake --build _build
73+
```
74+
75+
Finally, you can install the project with
76+
77+
```
78+
cmake --install _build
79+
```
80+
81+
82+
<!-- Do not forget to update the LICENSE file with your name! -->
83+
## License
84+
85+
This project is free software: you can redistribute it and/or modify it under the terms of the [MIT license](LICENSE).

app/CMakeLists.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# SPDX-Identifier: MIT
2+
set(dir "${CMAKE_CURRENT_SOURCE_DIR}")
3+
4+
set(
5+
prog
6+
"${dir}/main.f90"
7+
)
8+
9+
# Example application target
10+
add_executable(
11+
"${PROJECT_NAME}-exe"
12+
"${prog}"
13+
)
14+
set_target_properties(
15+
"${PROJECT_NAME}-exe"
16+
PROPERTIES
17+
OUTPUT_NAME "${PROJECT_NAME}"
18+
)
19+
target_link_libraries(
20+
"${PROJECT_NAME}-exe"
21+
PRIVATE
22+
"${PROJECT_NAME}-lib"
23+
)
24+
25+
# Only install executable in main project
26+
if(NOT is-subprojects)
27+
install(
28+
TARGETS
29+
"${PROJECT_NAME}-exe"
30+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
31+
)
32+
endif()

app/main.f90

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
! SPDX-Identifier: MIT
2+
3+
!> Example application
4+
program app
5+
use example
6+
implicit none
7+
8+
call hello_stdlib
9+
10+
end program app

config/CMakeLists.txt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# SPDX-Identifier: MIT
2+
3+
option(BUILD_SHARED_LIBS "Whether the libraries built should be shared" OFF)
4+
5+
# Set build type as CMake does not provide defaults
6+
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
7+
set(
8+
CMAKE_BUILD_TYPE "RelWithDebInfo"
9+
CACHE STRING "Build type to be used."
10+
FORCE
11+
)
12+
message(
13+
STATUS
14+
"Setting build type to '${CMAKE_BUILD_TYPE}' as none was specified."
15+
)
16+
endif()
17+
18+
# Include local CMake modules
19+
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
20+
21+
if(WIN32)
22+
list(
23+
APPEND CMAKE_EXE_LINKER_FLAGS
24+
"-Wl,--allow-multiple-definition"
25+
)
26+
endif()
27+
28+
include(CMakePackageConfigHelpers)
29+
configure_package_config_file(
30+
"${CMAKE_CURRENT_SOURCE_DIR}/template.cmake"
31+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
32+
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
33+
)
34+
write_basic_package_version_file(
35+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
36+
VERSION "${PROJECT_VERSION}"
37+
COMPATIBILITY SameMinorVersion
38+
)
39+
install(
40+
FILES
41+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
42+
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
43+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
44+
)

config/template.cmake

Lines changed: 5 additions & 0 deletions
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()

0 commit comments

Comments
 (0)