Skip to content

Commit 61e5fb0

Browse files
authored
Add example integration with test-drive (#3)
- use CMake modules for making subprojects available - automatically make test-drive available
1 parent 6a67d6e commit 61e5fb0

File tree

10 files changed

+1155
-34
lines changed

10 files changed

+1155
-34
lines changed

CMakeLists.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ include(GNUInstallDirs)
1313
# General configuration information
1414
add_subdirectory("config")
1515

16-
# Get the stdlib subproject
17-
set(lib-deps)
18-
add_subdirectory("subprojects")
16+
if(NOT TARGET "fortran_stdlib::fortran_stdlib")
17+
find_package("fortran_stdlib" REQUIRED)
18+
endif()
1919

2020
# Collect source of the project
2121
add_subdirectory("src")
2222

23-
2423
# Collect source of the application
2524
add_subdirectory("app")
2625

@@ -50,3 +49,7 @@ install(
5049
"LICENSE"
5150
DESTINATION "${CMAKE_INSTALL_DATADIR}/licenses/${PROJECT_NAME}"
5251
)
52+
53+
# Include test suite
54+
enable_testing()
55+
add_subdirectory("test")

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ else()
3232
endif()
3333
```
3434

35+
A more elaborated CMake module for making stdlib available can be found [here](config/cmake/Findfortran_stdlib.cmake).
36+
This module makes sure the ``fortran_stdlib::fortran_stdlib`` target is always generated regardless of how the stdlib is included in the project.
37+
3538
You can configure stdlib by setting the appropriate options before including the subproject.
3639
Important options are
3740

config/CMakeLists.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,21 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
1515
)
1616
endif()
1717

18-
# Include local CMake modules
19-
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
20-
2118
if(WIN32)
2219
list(
2320
APPEND CMAKE_EXE_LINKER_FLAGS
2421
"-Wl,--allow-multiple-definition"
2522
)
2623
endif()
2724

25+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
26+
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
27+
install(
28+
DIRECTORY
29+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/"
30+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
31+
)
32+
2833
include(CMakePackageConfigHelpers)
2934
configure_package_config_file(
3035
"${CMAKE_CURRENT_SOURCE_DIR}/template.cmake"
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# SPDX-Identifier: MIT
2+
3+
#[[.rst:
4+
Find fortran_stdlib
5+
-------------------
6+
7+
Makes the Fortran standard library (stdlib) project available.
8+
9+
Imported Targets
10+
^^^^^^^^^^^^^^^^
11+
12+
This module provides the following imported target, if found:
13+
14+
``fortran_stdlib::fortran_stdlib``
15+
The Fortran standard library
16+
17+
18+
Result Variables
19+
^^^^^^^^^^^^^^^^
20+
21+
This module will define the following variables:
22+
23+
``FORTRAN_STDLIB_FOUND``
24+
True if the Fortran standard library is available
25+
26+
``FORTRAN_STDLIB_SOURCE_DIR``
27+
Path to the source directory of the Fortran standard library project,
28+
only set if the project is included as source.
29+
30+
``FORTRAN_STDLIB_BINARY_DIR``
31+
Path to the binary directory of the Fortran standard library project,
32+
only set if the project is included as source.
33+
34+
Cache variables
35+
^^^^^^^^^^^^^^^
36+
37+
The following cache variables may be set to influence the library detection:
38+
39+
``FORTRAN_STDLIB_FIND_METHOD``
40+
Methods to find or make the project available. Available methods are
41+
- ``cmake``: Try to find via CMake config file
42+
- ``pkgconf``: Try to find via pkg-config file
43+
- ``subproject``: Use source in subprojects directory
44+
- ``fetch``: Fetch the source from upstream
45+
46+
``FORTRAN_STDLIB_DIR``
47+
Used for searching the CMake config file
48+
49+
``FORTRAN_STDLIB_SUBPROJECT``
50+
Directory to find the Fortran standard library subproject, relative to the project root
51+
52+
#]]
53+
54+
set(_lib "fortran_stdlib")
55+
set(_pkg "FORTRAN_STDLIB")
56+
set(_url "https://github.com/fortran-lang/stdlib")
57+
58+
if(NOT DEFINED "${_pkg}_FIND_METHOD")
59+
if(DEFINED "${PROJECT_NAME}-dependency-method")
60+
set("${_pkg}_FIND_METHOD" "${${PROJECT_NAME}-dependency-method}")
61+
else()
62+
set("${_pkg}_FIND_METHOD" "cmake" "pkgconf" "subproject" "fetch")
63+
endif()
64+
set("_${_pkg}_FIND_METHOD")
65+
endif()
66+
67+
foreach(method ${${_pkg}_FIND_METHOD})
68+
if(TARGET "${_lib}::${_lib}")
69+
break()
70+
endif()
71+
72+
if("${method}" STREQUAL "cmake")
73+
message(STATUS "${_lib}: Find installed package")
74+
if(DEFINED "${_pkg}_DIR")
75+
set("_${_pkg}_DIR")
76+
set("${_lib}_DIR" "${_pkg}_DIR")
77+
endif()
78+
find_package("${_lib}" CONFIG)
79+
if("${_lib}_FOUND")
80+
message(STATUS "${_lib}: Found installed package")
81+
break()
82+
endif()
83+
endif()
84+
85+
if("${method}" STREQUAL "pkgconf")
86+
find_package(PkgConfig QUIET)
87+
pkg_check_modules("${_pkg}" QUIET "${_lib}")
88+
if("${_pkg}_FOUND")
89+
message(STATUS "Found ${_lib} via pkg-config")
90+
91+
add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
92+
target_link_libraries(
93+
"${_lib}::${_lib}"
94+
INTERFACE
95+
"${${_pkg}_LINK_LIBRARIES}"
96+
)
97+
target_include_directories(
98+
"${_lib}::${_lib}"
99+
INTERFACE
100+
"${${_pkg}_INCLUDE_DIRS}"
101+
)
102+
103+
break()
104+
endif()
105+
endif()
106+
107+
if("${method}" STREQUAL "subproject")
108+
if(NOT DEFINED "${_pkg}_SUBPROJECT")
109+
set("_${_pkg}_SUBPROJECT")
110+
set("${_pkg}_SUBPROJECT" "subprojects/${_lib}")
111+
endif()
112+
set("${_pkg}_SOURCE_DIR" "${PROJECT_SOURCE_DIR}/${${_pkg}_SUBPROJECT}")
113+
set("${_pkg}_BINARY_DIR" "${PROJECT_BINARY_DIR}/${${_pkg}_SUBPROJECT}")
114+
if(EXISTS "${${_pkg}_SOURCE_DIR}/CMakeLists.txt")
115+
message(STATUS "Include ${_lib} from ${${_pkg}_SUBPROJECT}")
116+
add_subdirectory(
117+
"${${_pkg}_SOURCE_DIR}"
118+
"${${_pkg}_BINARY_DIR}"
119+
)
120+
121+
add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
122+
target_link_libraries("${_lib}::${_lib}" INTERFACE "${_lib}")
123+
124+
# We need the module directory in the subproject before we finish the configure stage
125+
if(NOT EXISTS "${${_pkg}_BINARY_DIR}/mod_files")
126+
make_directory("${${_pkg}_BINARY_DIR}/mod_files")
127+
endif()
128+
129+
break()
130+
endif()
131+
endif()
132+
133+
if("${method}" STREQUAL "fetch")
134+
message(STATUS "Retrieving ${_lib} from ${_url}")
135+
include(FetchContent)
136+
FetchContent_Declare(
137+
"${_lib}"
138+
GIT_REPOSITORY "${_url}"
139+
GIT_TAG "HEAD"
140+
)
141+
FetchContent_MakeAvailable("${_lib}")
142+
143+
add_library("${_lib}::${_lib}" INTERFACE IMPORTED)
144+
target_link_libraries("${_lib}::${_lib}" INTERFACE "${_lib}")
145+
146+
# We need the module directory in the subproject before we finish the configure stage
147+
FetchContent_GetProperties("${_lib}" SOURCE_DIR "${_pkg}_SOURCE_DIR")
148+
FetchContent_GetProperties("${_lib}" BINARY_DIR "${_pkg}_BINARY_DIR")
149+
if(NOT EXISTS "${${_pkg}_BINARY_DIR}/mod_files")
150+
make_directory("${${_pkg}_BINARY_DIR}/mod_files")
151+
endif()
152+
153+
break()
154+
endif()
155+
156+
endforeach()
157+
158+
if(TARGET "${_lib}::${_lib}")
159+
set("${_pkg}_FOUND" TRUE)
160+
else()
161+
set("${_pkg}_FOUND" FALSE)
162+
endif()
163+
164+
if(DEFINED "_${_pkg}_SUBPROJECT")
165+
unset("${_pkg}_SUBPROJECT")
166+
unset("_${_pkg}_SUBPROJECT")
167+
endif()
168+
if(DEFINED "_${_pkg}_DIR")
169+
unset("${_lib}_DIR")
170+
unset("_${_pkg}_DIR")
171+
endif()
172+
if(DEFINED "_${_pkg}_FIND_METHOD")
173+
unset("${_pkg}_FIND_METHOD")
174+
unset("_${_pkg}_FIND_METHOD")
175+
endif()
176+
unset(_lib)
177+
unset(_pkg)
178+
unset(_url)

0 commit comments

Comments
 (0)