Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
DLR-AMR
GitHub Repository: DLR-AMR/t8code
Path: blob/main/CMakeLists.txt
898 views
1
# This file is part of t8code.
2
# t8code is a C library to manage a collection (a forest) of multiple
3
# connected adaptive space-trees of general element types in parallel.
4
#
5
# Copyright (C) 2025 the developers
6
#
7
# t8code is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
11
#
12
# t8code is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with t8code; if not, write to the Free Software Foundation, Inc.,
19
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21
cmake_minimum_required( VERSION 3.16 )
22
23
include( cmake/GitProjectVersion.cmake )
24
include( FetchContent )
25
26
project(
27
T8CODE
28
DESCRIPTION "Parallel algorithms and data structures for tree-based AMR with arbitrary element shapes."
29
LANGUAGES C CXX
30
VERSION "${T8CODE_VERSION_MAJOR}.${T8CODE_VERSION_MINOR}.${T8CODE_VERSION_PATCH}"
31
)
32
33
include( GNUInstallDirs)
34
include( CTest )
35
include( CMakeDependentOption )
36
37
FetchContent_Declare(
38
googletest
39
GIT_REPOSITORY "https://github.com/DLR-SC/googletest_mpi.git"
40
GIT_TAG 98bfff426b057400268a00f97677d749a9e25096 #v1.17.0_mpi
41
GIT_PROGRESS TRUE
42
)
43
44
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
45
mark_as_advanced( FORCE gtest_force_shared_crt)
46
47
48
option( T8CODE_BUILD_AS_SHARED_LIBRARY "Whether t8code should be built as a shared or a static library" ON )
49
option( T8CODE_BUILD_PEDANTIC "Compile t8code with `-pedantic` as done in the Github CI." OFF )
50
option( T8CODE_BUILD_WALL "Compile t8code with `-Wall` as done in the Github CI." OFF )
51
option( T8CODE_BUILD_WERROR "Compile t8code with `-Werror` as done in the Github CI." OFF )
52
option( T8CODE_BUILD_WEXTRA "Compile t8code with extra warnings as done in the Github CI." OFF )
53
option( T8CODE_EXPORT_COMPILE_COMMANDS "Export the compile commands as json. Can be used by IDEs for code completion (e.g. intellisense, clangd)" OFF )
54
55
option( T8CODE_BUILD_TESTS "Build t8code's automated tests" ON )
56
cmake_dependent_option( T8CODE_BUILD_TPL_TESTS "Build the tests from libsc and p4est" OFF "T8CODE_BUILD_TESTS" OFF )
57
58
option( T8CODE_BUILD_EXAMPLES "Build t8code's examples" ON )
59
cmake_dependent_option( T8CODE_BUILD_TPL_EXAMPLES "Build the examples from libsc and p4est" OFF "T8CODE_BUILD_EXAMPLES" OFF )
60
61
option( T8CODE_BUILD_TUTORIALS "Build t8code's tutorials" ON )
62
option( T8CODE_BUILD_BENCHMARKS "Build t8code's benchmarks" ON )
63
option( T8CODE_BUILD_MESH_HANDLE "Build t8code's mesh handle" OFF )
64
option( T8CODE_BUILD_FORTRAN_INTERFACE "Build t8code's Fortran interface" OFF )
65
66
option( T8CODE_ENABLE_MPI "Enable t8code's features which rely on MPI" ON )
67
option( T8CODE_ENABLE_VTK "Enable t8code's features which rely on VTK" OFF )
68
option( T8CODE_ENABLE_OCC "Enable t8code's features which rely on OpenCASCADE" OFF )
69
70
option( T8CODE_USE_SYSTEM_SC "Use system-installed sc library" OFF )
71
option( T8CODE_USE_SYSTEM_P4EST "Use system-installed p4est library" OFF )
72
73
option( T8CODE_BUILD_DOCUMENTATION "Build t8code's documentation" OFF )
74
cmake_dependent_option( T8CODE_BUILD_DOCUMENTATION_SPHINX "Build t8code's documentation using sphinx" OFF "T8CODE_BUILD_DOCUMENTATION" OFF )
75
76
set(T8CODE_CUSTOM_PARALLEL_TEST_COMMAND "" CACHE STRING "Define a custom command for parallel tests , e.g.: mpirun -np 8 (overwrites standard mpirun -np 4 if build with mpi)")
77
set(T8CODE_CUSTOM_SERIAL_TEST_COMMAND "" CACHE STRING "Define a custom command for serial tests.")
78
79
# Reading the option T8CODE_TEST_LEVEL: Possible choices are T8_TEST_LEVEL_FULL, T8_TEST_LEVEL_MEDIUM, or T8_TEST_LEVEL_BASIC. Default is T8_TEST_LEVEL_FULL.
80
set(T8CODE_TEST_LEVEL "T8_TEST_LEVEL_FULL" CACHE STRING "Test level: T8_TEST_LEVEL_FULL for full tests, T8_TEST_LEVEL_MEDIUM for less thorough tests, T8_TEST_LEVEL_BASIC for minimal tests. (WARNING: Use with care.)")
81
set_property(CACHE T8CODE_TEST_LEVEL PROPERTY STRINGS "T8_TEST_LEVEL_FULL" "T8_TEST_LEVEL_MEDIUM" "T8_TEST_LEVEL_BASIC")
82
83
# Parse string T8CODE_TEST_LEVEL into integer T8_TEST_LEVEL_INT for easier usage within the code.
84
if(T8CODE_TEST_LEVEL STREQUAL "T8_TEST_LEVEL_BASIC" )
85
set(T8_TEST_LEVEL_INT 2)
86
elseif(T8CODE_TEST_LEVEL STREQUAL "T8_TEST_LEVEL_MEDIUM" )
87
set(T8_TEST_LEVEL_INT 1)
88
elseif(T8CODE_TEST_LEVEL STREQUAL "T8_TEST_LEVEL_FULL" )
89
set(T8_TEST_LEVEL_INT 0)
90
else()
91
message( FATAL_ERROR "Invalid string for T8CODE_TEST_LEVEL: ${T8CODE_TEST_LEVEL}. Valid options are T8_TEST_LEVEL_FULL, T8_TEST_LEVEL_MEDIUM, or T8_TEST_LEVEL_BASIC.")
92
endif()
93
94
# Set a default build type if none was specified
95
set(default_build_type "Release")
96
97
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
98
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
99
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
100
STRING "Choose the type of build. Build types available: Release Debug RelWithDebInfo" FORCE)
101
# Set the possible values of build type for cmake-gui
102
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
103
"Debug" "Release" "RelWithDebInfo")
104
endif()
105
106
if( CMAKE_BUILD_TYPE STREQUAL "Debug" )
107
# Option to generate code coverage target.
108
option( T8CODE_CODE_COVERAGE "Enable code coverage reporting" OFF)
109
if(T8CODE_CODE_COVERAGE)
110
include(./cmake/CodeCoverage.cmake)
111
endif()
112
endif()
113
114
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
115
116
if( T8CODE_BUILD_FORTRAN_INTERFACE )
117
enable_language( Fortran )
118
endif()
119
120
if( T8CODE_ENABLE_MPI )
121
if( T8CODE_BUILD_FORTRAN_INTERFACE )
122
find_package( MPI 3.0 COMPONENTS C Fortran REQUIRED )
123
else()
124
find_package( MPI 3.0 COMPONENTS C REQUIRED )
125
endif()
126
set (gtest_disable_mpi OFF CACHE BOOL "disable gtest mpi support" FORCE)
127
128
if( NOT MPIEXEC_EXECUTABLE )
129
message( FATAL_ERROR "MPIEXEC was not found" )
130
endif()
131
set( SC_ENABLE_MPI ON )
132
else()
133
set( gtest_disable_mpi ON CACHE BOOL "disable gtest mpi support" FORCE)
134
endif()
135
136
mark_as_advanced( FORCE gtest_disable_mpi)
137
138
139
if( T8CODE_ENABLE_VTK )
140
find_package( VTK REQUIRED COMPONENTS
141
IOXML CommonExecutionModel CommonDataModel
142
IOGeometry IOXMLParser IOParallelXML IOPLY
143
ParallelMPI FiltersCore vtksys CommonCore zlib IOLegacy)
144
if(VTK_FOUND)
145
message("Found VTK")
146
endif (VTK_FOUND)
147
endif( T8CODE_ENABLE_VTK )
148
149
if( T8CODE_ENABLE_OCC )
150
find_package( OpenCASCADE REQUIRED COMPONENTS
151
TKBO TKPrim TKTopAlgo
152
TKGeomAlgo TKBRep
153
TKG3d TKG2d TKMath TKernel )
154
if(OpenCASCADE_FOUND)
155
message("Found OpenCASCADE")
156
endif (OpenCASCADE_FOUND)
157
endif( T8CODE_ENABLE_OCC )
158
159
# Override default for this libsc option
160
set( BUILD_SHARED_LIBS ON CACHE BOOL "Build libsc as a shared library" )
161
162
# Prevent `libsc` and `p4est` from overwriting the default install prefix.
163
set(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT FALSE)
164
165
# Rpath options necessary for shared library install to work correctly in user projects.
166
# Compute the relative Rpath for proper library installation
167
set(libPath ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) # Library directory)
168
cmake_path(RELATIVE_PATH libPath
169
BASE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} # Binary directory
170
OUTPUT_VARIABLE relativeRpath
171
)
172
set(CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/${relativeRpath})
173
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH true)
174
175
if ( T8CODE_USE_SYSTEM_SC )
176
find_package( SC REQUIRED )
177
else()
178
set( SC_BUILD_EXAMPLES ${T8CODE_BUILD_TPL_EXAMPLES} )
179
set( SC_BUILD_TESTING ${T8CODE_BUILD_TPL_TESTS} )
180
181
# When executing CMake tests for libsc, i.e. check_c_source_compiles/check_cxx_source_compiles and others
182
# we need to ignore the -Werror option, since these tests often produce warnings (see check_mpicommshared.cmake for example).
183
# If theses warnings are interpreted as errors, the test fails even though we want it to pass.
184
# This behaviour caused a serious bug and did not initialize our shared memory. See https://github.com/DLR-AMR/t8code/issues/1985.
185
set( T8CODE_OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}" )
186
if (WIN32 AND NOT MINGW)
187
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /w" )
188
else()
189
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -w" )
190
endif()
191
192
# Capture the list of variables before adding the subdirectory to mark the added ones as advanced.
193
get_cmake_property(_vars_before_sc VARIABLES )
194
list( APPEND CMAKE_MESSAGE_CONTEXT "sc" )
195
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/sc )
196
list( POP_BACK CMAKE_MESSAGE_CONTEXT )
197
add_library(SC INTERFACE)
198
# Capture the list of variables after adding the subdirectory
199
get_cmake_property(_vars_after_sc VARIABLES )
200
# Compute the difference (new variables added by the subdirectory)
201
set( _new_sc_vars)
202
foreach( _var IN LISTS _vars_after_sc )
203
if( NOT _var IN_LIST _vars_before_sc )
204
list( APPEND _new_sc_vars ${_var} )
205
endif()
206
endforeach()
207
208
# Mark the new variables as advanced
209
mark_as_advanced( FORCE ${_new_sc_vars} )
210
211
########################## Fix for OpenMPI ############################################
212
# OpenMPI sometimes has a mismatch between their C and CXX interface which produces a warning in SC.
213
# The warning makes t8codes build fail when Werror is activated. This fix checks if t8code
214
# is linked against OpenMPI and then suppresses that Werror treats this warning as error.
215
# The warning is still displayed while compiling.
216
# We compile a test program mich checks if a OpenMPI specific macro is defined and then apply the fix.
217
218
include(CheckIncludeFile)
219
220
# Check if mpi.h is available
221
check_include_file("mpi.h" MPI_HEADER_FOUND)
222
223
if(MPI_HEADER_FOUND)
224
# Create a temporary C++ source file to check for OpenMPI-specific macros
225
include(CheckCXXSourceCompiles)
226
check_cxx_source_compiles("
227
#include <mpi.h>
228
#ifndef OPEN_MPI
229
#error 'Not OpenMPI'
230
#endif
231
int main() { return 0; }" HAS_OPENMPI)
232
233
if(HAS_OPENMPI)
234
message(STATUS "OpenMPI detected via mpi.h")
235
# Suppress warning
236
target_compile_options(SC::SC INTERFACE -Wno-error=cast-function-type)
237
endif()
238
else()
239
message(WARNING "mpi.h not found!")
240
endif()
241
########################## End of fix for OpenMPI ############################################
242
243
# Reactivate previous CMAKE_REQUIRED_FLAGS
244
set( CMAKE_REQUIRED_FLAGS "${T8CODE_OLD_CMAKE_REQUIRED_FLAGS}" )
245
unset( T8CODE_OLD_CMAKE_REQUIRED_FLAGS )
246
endif()
247
248
if ( T8CODE_USE_SYSTEM_P4EST )
249
find_package( P4EST REQUIRED )
250
else()
251
set( P4EST_BUILD_EXAMPLES ${T8CODE_BUILD_TPL_EXAMPLES} )
252
set( P4EST_BUILD_TESTING ${T8CODE_BUILD_TPL_TESTS} )
253
254
# Capture the list of variables before adding the subdirectory to mark the added ones as advanced.
255
get_cmake_property( _vars_before_p4est VARIABLES )
256
list( APPEND CMAKE_MESSAGE_CONTEXT "p4est" )
257
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/p4est )
258
list( POP_BACK CMAKE_MESSAGE_CONTEXT )
259
# Capture the list of variables after adding the subdirectory
260
get_cmake_property( _vars_after_p4est VARIABLES )
261
# Compute the difference (new variables added by the subdirectory)
262
set( _new_p4est_vars )
263
foreach( _var IN LISTS _vars_after_p4est )
264
if( NOT _var IN_LIST _vars_before_p4est )
265
list( APPEND _new_p4est_vars ${_var} )
266
endif()
267
endforeach()
268
269
# Mark the new variables as advanced
270
mark_as_advanced( FORCE ${_new_p4est_vars} )
271
endif()
272
273
# Workaround: Suppress warnings for googletests, so it does not compromise the usage of -WError for t8code.
274
# -----------
275
# 1. Save original flags
276
set(ORIGINAL_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
277
set(ORIGINAL_C_FLAGS "${CMAKE_C_FLAGS}")
278
279
# 2. Suppress warnings for GoogleTest build
280
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w" CACHE STRING "" FORCE)
281
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w" CACHE STRING "" FORCE)
282
283
FetchContent_MakeAvailable( googletest )
284
285
# 3. Restore original flags
286
set(CMAKE_CXX_FLAGS "${ORIGINAL_CXX_FLAGS}" CACHE STRING "" FORCE)
287
set(CMAKE_C_FLAGS "${ORIGINAL_C_FLAGS}" CACHE STRING "" FORCE)
288
289
# End of workaround
290
291
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/src )
292
293
if( T8CODE_BUILD_MESH_HANDLE )
294
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/mesh_handle )
295
endif()
296
297
if ( T8CODE_BUILD_TESTS )
298
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/test )
299
endif()
300
301
if ( T8CODE_BUILD_TUTORIALS )
302
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/tutorials )
303
endif()
304
305
if ( T8CODE_BUILD_EXAMPLES )
306
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/example )
307
endif()
308
309
if ( T8CODE_BUILD_BENCHMARKS )
310
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/benchmarks )
311
endif()
312
313
if ( T8CODE_BUILD_DOCUMENTATION )
314
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/doc )
315
endif()
316
317
if( T8CODE_BUILD_FORTRAN_INTERFACE )
318
add_subdirectory( ${CMAKE_CURRENT_LIST_DIR}/api/t8_fortran_interface )
319
320
if( NOT T8CODE_ENABLE_MPI )
321
message( FATAL_ERROR "Fortran API only available when MPI is enabled." )
322
endif()
323
endif()
324
325
include (cmake/CPackConfig.cmake)
326
327