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