-
Notifications
You must be signed in to change notification settings - Fork 0
/
makefile
814 lines (720 loc) · 30.5 KB
/
makefile
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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
# Copyright (c) 2010-2022, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# The current MFEM version as an integer, see also `CMakeLists.txt`.
MFEM_VERSION = 40401
MFEM_VERSION_STRING = $(shell printf "%06d" $(MFEM_VERSION) | \
sed -e 's/^0*\(.*.\)\(..\)\(..\)$$/\1.\2.\3/' -e 's/\.0/./g' -e 's/\.0$$//')
define MFEM_HELP_MSG
MFEM makefile targets:
make config
make
make all
make status/info
make serial
make parallel
make debug
make pdebug
make cuda
make hip
make pcuda
make cudebug
make pcudebug
make test/check
make install
make clean
make distclean
make style
make tags
make hooks
Examples:
make config MFEM_USE_MPI=YES MFEM_DEBUG=YES MPICXX=mpiCC
Configure the make system for subsequent runs (analogous to a configure script).
The available options are documented in the INSTALL file.
make config BUILD_DIR=<dir>
Configure an out-of-source-tree build in the given directory.
make config -f <mfem-dir>/makefile
Configure an out-of-source-tree build in the current directory.
make -j 4
Build the library (in parallel) using the current configuration options.
make all
Build the library, the examples and the miniapps using the current configuration.
make status
Display information about the current configuration.
make serial
A shortcut to configure and build the serial optimized version of the library.
make parallel
A shortcut to configure and build the parallel optimized version of the library.
make debug
A shortcut to configure and build the serial debug version of the library.
make pdebug
A shortcut to configure and build the parallel debug version of the library.
make cuda
A shortcut to configure and build the serial GPU/CUDA optimized version of the library.
make pcuda
A shortcut to configure and build the parallel GPU/CUDA optimized version of the library.
make cudebug
A shortcut to configure and build the serial GPU/CUDA debug version of the library.
make pcudebug
A shortcut to configure and build the parallel GPU/CUDA debug version of the library.
make hip
A shortcut to configure and build the serial GPU/HIP optimized version of the library.
make phip
A shortcut to configure and build the parallel GPU/HIP optimized version of the library.
make hipdebug
A shortcut to configure and build the serial GPU/HIP debug version of the library.
make phipdebug
A shortcut to configure and build the parallel GPU/HIP debug version of the library.
make test
Verify the build by checking the results from running all examples, miniapps,
and tests.
make check
Quick-check the build by compiling and running Example 1/1p.
make unittest
Verify the build against the unit tests.
make install PREFIX=<dir>
Install the library and headers in <dir>/lib and <dir>/include.
make clean
Clean the library and object files, but keep the configuration.
make distclean
In addition to "make clean", clean the configuration and remove the local
installation directory.
make style
Format the MFEM C++ source files using Artistic Style (astyle).
make tags
Generate a vi or Emacs compatible TAGS file in ${MFEM_DIR}/TAGS. Requires
functional "etags" and "egrep" in the user ${PATH}.
make hooks
Creates symlinks to the hooks in the `.git/hooks` directory.
endef
# Save the MAKEOVERRIDES for cases where we explicitly want to pass the command
# line overrides to sub-make:
override MAKEOVERRIDES_SAVE := $(MAKEOVERRIDES)
# Do not pass down variables from the command-line to sub-make:
MAKEOVERRIDES =
# Path to the mfem source directory, defaults to this makefile's directory:
THIS_MK := $(lastword $(MAKEFILE_LIST))
$(if $(wildcard $(THIS_MK)),,$(error Makefile not found "$(THIS_MK)"))
MFEM_DIR ?= $(patsubst %/,%,$(dir $(THIS_MK)))
MFEM_REAL_DIR := $(realpath $(MFEM_DIR))
$(if $(MFEM_REAL_DIR),,$(error Source directory "$(MFEM_DIR)" is not valid))
SRC := $(if $(MFEM_REAL_DIR:$(CURDIR)=),$(MFEM_DIR)/,)
$(if $(word 2,$(SRC)),$(error Spaces in SRC = "$(SRC)" are not supported))
MFEM_GIT_STRING = $(shell [ -d $(MFEM_DIR)/.git ] && git -C $(MFEM_DIR) \
describe --all --long --abbrev=40 --dirty --always 2> /dev/null)
EXAMPLE_SUBDIRS = amgx caliper ginkgo hiop petsc pumi sundials superlu moonolith
EXAMPLE_DIRS := examples $(addprefix examples/,$(EXAMPLE_SUBDIRS))
EXAMPLE_TEST_DIRS := examples
MINIAPP_SUBDIRS = common electromagnetics meshing navier performance tools toys nurbs gslib adjoint solvers shifted mtop parelag autodiff
MINIAPP_DIRS := $(addprefix miniapps/,$(MINIAPP_SUBDIRS))
MINIAPP_TEST_DIRS := $(filter-out %/common,$(MINIAPP_DIRS))
MINIAPP_USE_COMMON := $(addprefix miniapps/,electromagnetics meshing tools toys shifted)
EM_DIRS = $(EXAMPLE_DIRS) $(MINIAPP_DIRS)
TEST_SUBDIRS = unit
TEST_DIRS := $(addprefix tests/,$(TEST_SUBDIRS))
ALL_TEST_DIRS = $(filter-out\
$(SKIP_TEST_DIRS),$(TEST_DIRS) $(EXAMPLE_TEST_DIRS) $(MINIAPP_TEST_DIRS))
# Use BUILD_DIR on the command line; set MFEM_BUILD_DIR before including this
# makefile or config/config.mk from a separate $(BUILD_DIR).
MFEM_BUILD_DIR ?= .
BUILD_DIR := $(MFEM_BUILD_DIR)
BUILD_REAL_DIR := $(abspath $(BUILD_DIR))
ifneq ($(BUILD_REAL_DIR),$(MFEM_REAL_DIR))
BUILD_SUBDIRS = $(DIRS) config $(EM_DIRS) doc $(TEST_DIRS)
CONFIG_FILE_DEF = -DMFEM_CONFIG_FILE='"$(BUILD_REAL_DIR)/config/_config.hpp"'
BLD := $(if $(BUILD_REAL_DIR:$(CURDIR)=),$(BUILD_DIR)/,)
$(if $(word 2,$(BLD)),$(error Spaces in BLD = "$(BLD)" are not supported))
else
BUILD_DIR = $(MFEM_DIR)
BLD := $(SRC)
endif
MFEM_BUILD_DIR := $(BUILD_DIR)
CONFIG_MK = $(BLD)config/config.mk
DEFAULTS_MK = $(SRC)config/defaults.mk
include $(DEFAULTS_MK)
# Optional user config file, see config/defaults.mk
USER_CONFIG = $(BLD)config/user.mk
-include $(USER_CONFIG)
# Helper print-info function
mfem-info = $(if $(filter YES,$(VERBOSE)),$(info *** [info]$(1)),)
export VERBOSE
$(call mfem-info, MAKECMDGOALS = $(MAKECMDGOALS))
$(call mfem-info, MAKEFLAGS = $(MAKEFLAGS))
$(call mfem-info, MFEM_DIR = $(MFEM_DIR))
$(call mfem-info, BUILD_DIR = $(BUILD_DIR))
$(call mfem-info, SRC = $(SRC))
$(call mfem-info, BLD = $(BLD))
# Include $(CONFIG_MK) unless some of the $(SKIP_INCLUDE_TARGETS) are given
SKIP_INCLUDE_TARGETS = help config clean distclean serial parallel debug pdebug\
cuda hip pcuda phip cudebug hipdebug pcudebug phipdebug hpc style
HAVE_SKIP_INCLUDE_TARGET = $(filter $(SKIP_INCLUDE_TARGETS),$(MAKECMDGOALS))
ifeq (,$(HAVE_SKIP_INCLUDE_TARGET))
$(call mfem-info, Including $(CONFIG_MK))
-include $(CONFIG_MK)
else
# Do not allow skip-include targets to be combined with other targets
ifneq (1,$(words $(MAKECMDGOALS)))
$(error Target '$(firstword $(HAVE_SKIP_INCLUDE_TARGET))' can not be\
combined with other targets)
endif
$(call mfem-info, NOT including $(CONFIG_MK))
endif
# Compile flags used by MFEM: CPPFLAGS, CXXFLAGS, plus library flags
INCFLAGS =
# Link flags used by MFEM: library link flags plus LDFLAGS (added last)
ALL_LIBS =
# Building static and/or shared libraries:
MFEM_STATIC ?= $(STATIC)
MFEM_SHARED ?= $(SHARED)
# Internal shortcuts
override static = $(if $(MFEM_STATIC:YES=),,YES)
override shared = $(if $(MFEM_SHARED:YES=),,YES)
# The default value of CXXFLAGS is based on the value of MFEM_DEBUG
ifeq ($(MFEM_DEBUG),YES)
CXXFLAGS ?= $(DEBUG_FLAGS)
endif
CXXFLAGS ?= $(OPTIM_FLAGS)
# MPI configuration
ifneq ($(MFEM_USE_MPI),YES)
HOST_CXX = $(CXX)
PKGS_NEED_MPI = SUPERLU MUMPS STRUMPACK PETSC PUMI SLEPC MKL_CPARDISO
$(foreach mpidep,$(PKGS_NEED_MPI),$(if $(MFEM_USE_$(mpidep):NO=),\
$(warning *** [MPI is OFF] setting MFEM_USE_$(mpidep) = NO)\
$(eval override MFEM_USE_$(mpidep)=NO),))
else
HOST_CXX = $(MPICXX)
INCFLAGS += $(HYPRE_OPT)
ALL_LIBS += $(HYPRE_LIB)
endif
# Default configuration
ifeq ($(MFEM_USE_CUDA)$(MFEM_USE_HIP),NONO)
MFEM_CXX ?= $(HOST_CXX)
MFEM_HOST_CXX ?= $(MFEM_CXX)
XCOMPILER = $(CXX_XCOMPILER)
XLINKER = $(CXX_XLINKER)
endif
ifeq ($(MFEM_USE_CUDA),YES)
MFEM_CXX ?= $(CUDA_CXX)
MFEM_HOST_CXX ?= $(HOST_CXX)
CXXFLAGS += $(CUDA_FLAGS) -ccbin $(MFEM_HOST_CXX)
XCOMPILER = $(CUDA_XCOMPILER)
XLINKER = $(CUDA_XLINKER)
# CUDA_OPT and CUDA_LIB are added below
# Compatibility test against MFEM_USE_HIP
ifeq ($(MFEM_USE_HIP),YES)
$(error Incompatible config: MFEM_USE_CUDA can not be combined with MFEM_USE_HIP)
endif
endif
# HIP configuration
ifeq ($(MFEM_USE_HIP),YES)
ifeq ($(MFEM_USE_MPI),YES)
INCFLAGS += $(MPI_OPT)
ALL_LIBS += $(MPI_LIB)
endif
MFEM_CXX ?= $(HIP_CXX)
MFEM_HOST_CXX ?= $(MFEM_CXX)
CXXFLAGS += $(HIP_FLAGS)
XLINKER = $(HIP_XLINKER)
XCOMPILER = $(HIP_XCOMPILER)
# HIP_OPT and HIP_LIB are added below
# Compatibility test against MFEM_USE_CUDA
ifeq ($(MFEM_USE_CUDA),YES)
$(error Incompatible config: MFEM_USE_HIP can not be combined with MFEM_USE_CUDA)
endif
endif
DEP_CXX ?= $(MFEM_CXX)
# Check legacy OpenMP configuration
ifeq ($(MFEM_USE_LEGACY_OPENMP),YES)
MFEM_THREAD_SAFE ?= YES
ifneq ($(MFEM_THREAD_SAFE),YES)
$(error Incompatible config: MFEM_USE_LEGACY_OPENMP requires MFEM_THREAD_SAFE)
endif
# NOTE: MFEM_USE_LEGACY_OPENMP cannot be combined with any of:
# MFEM_USE_OPENMP, MFEM_USE_CUDA, MFEM_USE_RAJA, MFEM_USE_OCCA
endif
# List of MFEM dependencies, that require the *_LIB variable to be non-empty
MFEM_REQ_LIB_DEPS = SUPERLU MUMPS METIS FMS CONDUIT SIDRE LAPACK SUNDIALS MESQUITE\
SUITESPARSE STRUMPACK GINKGO GNUTLS NETCDF PETSC SLEPC MPFR PUMI HIOP GSLIB\
OCCA CEED RAJA UMPIRE MKL_CPARDISO AMGX CALIPER PARELAG BENCHMARK MOONOLITH
PETSC_ERROR_MSG = $(if $(PETSC_FOUND),,. PETSC config not found: $(PETSC_VARS))
SLEPC_ERROR_MSG = $(if $(SLEPC_FOUND),,. SLEPC config not found: $(SLEPC_VARS))
define mfem_check_dependency
ifeq ($$(MFEM_USE_$(1)),YES)
$$(if $$($(1)_LIB),,$$(error $(1)_LIB is empty$$($(1)_ERROR_MSG)))
endif
endef
# During configuration, check dependencies from MFEM_REQ_LIB_DEPS
ifeq ($(MAKECMDGOALS),config)
$(foreach dep,$(MFEM_REQ_LIB_DEPS),\
$(eval $(call mfem_check_dependency,$(dep))))
endif
# List of MFEM dependencies, processed below
MFEM_DEPENDENCIES = $(MFEM_REQ_LIB_DEPS) LIBUNWIND OPENMP CUDA HIP
# List of deprecated MFEM dependencies, processed below
MFEM_LEGACY_DEPENDENCIES = OPENMP
# Macro for adding dependencies
define mfem_add_dependency
ifeq ($(MFEM_USE_$(1)),YES)
INCFLAGS += $($(1)_OPT)
ALL_LIBS += $($(1)_LIB)
endif
endef
# Macro for adding legacy dependencies
define mfem_add_legacy_dependency
ifeq ($(MFEM_USE_LEGACY_$(1)),YES)
INCFLAGS += $($(1)_OPT)
ALL_LIBS += $($(1)_LIB)
endif
endef
# Process dependencies
$(foreach dep,$(MFEM_DEPENDENCIES),$(eval $(call mfem_add_dependency,$(dep))))
$(foreach dep,$(MFEM_LEGACY_DEPENDENCIES),$(eval $(call \
mfem_add_legacy_dependency,$(dep))))
# Timer option
ifeq ($(MFEM_TIMER_TYPE),2)
ALL_LIBS += $(POSIX_CLOCKS_LIB)
endif
# zlib configuration
ifeq ($(MFEM_USE_ZLIB),YES)
INCFLAGS += $(ZLIB_OPT)
ALL_LIBS += $(ZLIB_LIB)
endif
# List of all defines that may be enabled in config.hpp and config.mk:
MFEM_DEFINES = MFEM_VERSION MFEM_VERSION_STRING MFEM_GIT_STRING MFEM_USE_MPI\
MFEM_USE_METIS MFEM_USE_METIS_5 MFEM_DEBUG MFEM_USE_EXCEPTIONS MFEM_USE_ZLIB\
MFEM_USE_LIBUNWIND MFEM_USE_LAPACK MFEM_THREAD_SAFE MFEM_USE_OPENMP\
MFEM_USE_LEGACY_OPENMP MFEM_USE_MEMALLOC MFEM_TIMER_TYPE MFEM_USE_SUNDIALS\
MFEM_USE_MESQUITE MFEM_USE_SUITESPARSE MFEM_USE_GINKGO MFEM_USE_SUPERLU\
MFEM_USE_STRUMPACK MFEM_USE_GNUTLS MFEM_USE_NETCDF MFEM_USE_PETSC\
MFEM_USE_SLEPC MFEM_USE_MPFR MFEM_USE_SIDRE MFEM_USE_FMS MFEM_USE_CONDUIT\
MFEM_USE_PUMI MFEM_USE_HIOP MFEM_USE_GSLIB MFEM_USE_CUDA MFEM_USE_HIP\
MFEM_USE_OCCA MFEM_USE_MOONOLITH MFEM_USE_CEED MFEM_USE_RAJA MFEM_USE_UMPIRE MFEM_USE_SIMD\
MFEM_USE_ADIOS2 MFEM_USE_MKL_CPARDISO MFEM_USE_AMGX MFEM_USE_MUMPS\
MFEM_USE_ADFORWARD MFEM_USE_CODIPACK MFEM_USE_CALIPER MFEM_USE_BENCHMARK\
MFEM_USE_PARELAG MFEM_SOURCE_DIR MFEM_INSTALL_DIR
# List of makefile variables that will be written to config.mk:
MFEM_CONFIG_VARS = MFEM_CXX MFEM_HOST_CXX MFEM_CPPFLAGS MFEM_CXXFLAGS\
MFEM_INC_DIR MFEM_TPLFLAGS MFEM_INCFLAGS MFEM_PICFLAG MFEM_FLAGS MFEM_LIB_DIR\
MFEM_EXT_LIBS MFEM_LIBS MFEM_LIB_FILE MFEM_STATIC MFEM_SHARED MFEM_BUILD_TAG\
MFEM_PREFIX MFEM_CONFIG_EXTRA MFEM_MPIEXEC MFEM_MPIEXEC_NP MFEM_MPI_NP\
MFEM_TEST_MK
# Config vars: values of the form @VAL@ are replaced by $(VAL) in config.mk
MFEM_CPPFLAGS ?= $(CPPFLAGS)
MFEM_CXXFLAGS ?= $(CXXFLAGS)
MFEM_TPLFLAGS ?= $(INCFLAGS)
MFEM_INCFLAGS ?= -I@MFEM_INC_DIR@ @MFEM_TPLFLAGS@
MFEM_PICFLAG ?= $(if $(shared),$(PICFLAG))
MFEM_FLAGS ?= @MFEM_CPPFLAGS@ @MFEM_CXXFLAGS@ @MFEM_INCFLAGS@
MFEM_EXT_LIBS ?= $(ALL_LIBS) $(LDFLAGS)
MFEM_LIBS ?= $(if $(shared),$(BUILD_RPATH)) -L@MFEM_LIB_DIR@ -lmfem\
@MFEM_EXT_LIBS@
MFEM_LIB_FILE ?= @MFEM_LIB_DIR@/libmfem.$(if $(shared),$(SO_VER),a)
MFEM_BUILD_TAG ?= $(shell uname -snm)
MFEM_PREFIX ?= $(PREFIX)
MFEM_INC_DIR ?= $(if $(CONFIG_FILE_DEF),@MFEM_BUILD_DIR@,@MFEM_DIR@)
MFEM_LIB_DIR ?= $(if $(CONFIG_FILE_DEF),@MFEM_BUILD_DIR@,@MFEM_DIR@)
MFEM_TEST_MK ?= @MFEM_DIR@/config/test.mk
# Use "\n" (interpreted by sed) to add a newline.
MFEM_CONFIG_EXTRA ?= $(if $(CONFIG_FILE_DEF),MFEM_BUILD_DIR ?= @MFEM_DIR@,)
MFEM_SOURCE_DIR = $(MFEM_REAL_DIR)
MFEM_INSTALL_DIR = $(abspath $(MFEM_PREFIX))
# If we have 'config' target, export variables used by config/makefile
ifneq (,$(filter config,$(MAKECMDGOALS)))
export $(MFEM_DEFINES) MFEM_DEFINES $(MFEM_CONFIG_VARS) MFEM_CONFIG_VARS
export VERBOSE HYPRE_OPT PUMI_DIR MUMPS_OPT
endif
# If we have 'install' target, export variables used by config/makefile
ifneq (,$(filter install,$(MAKECMDGOALS)))
ifneq (install,$(MAKECMDGOALS))
$(error Target 'install' can not be combined with other targets)
endif
# Allow changing the PREFIX during install with: make install PREFIX=<dir>
PREFIX := $(MFEM_PREFIX)
PREFIX_INC := $(PREFIX)/include
PREFIX_LIB := $(PREFIX)/lib
PREFIX_SHARE := $(PREFIX)/share/mfem
override MFEM_DIR := $(MFEM_REAL_DIR)
MFEM_INCFLAGS = -I@MFEM_INC_DIR@ @MFEM_TPLFLAGS@
MFEM_FLAGS = @MFEM_CPPFLAGS@ @MFEM_CXXFLAGS@ @MFEM_INCFLAGS@
MFEM_LIBS = $(if $(shared),$(INSTALL_RPATH)) -L@MFEM_LIB_DIR@ -lmfem\
@MFEM_EXT_LIBS@
MFEM_LIB_FILE = @MFEM_LIB_DIR@/libmfem.$(if $(shared),$(SO_VER),a)
ifeq ($(MFEM_USE_OCCA),YES)
ifneq ($(MFEM_INSTALL_DIR),$(abspath $(PREFIX)))
$(error OCCA is enabled: PREFIX must be set during configuration!)
endif
endif
MFEM_PREFIX := $(abspath $(PREFIX))
MFEM_INC_DIR = $(abspath $(PREFIX_INC))
MFEM_LIB_DIR = $(abspath $(PREFIX_LIB))
MFEM_TEST_MK = $(abspath $(PREFIX_SHARE)/test.mk)
MFEM_CONFIG_EXTRA =
export $(MFEM_DEFINES) MFEM_DEFINES $(MFEM_CONFIG_VARS) MFEM_CONFIG_VARS
export VERBOSE
endif
# Source dirs in logical order
DIRS = general linalg linalg/simd mesh fem fem/fe fem/ceed fem/qinterp fem/tmop
ifeq ($(MFEM_USE_MOONOLITH),YES)
MFEM_CXXFLAGS += $(MOONOLITH_CXX_FLAGS)
MFEM_INCFLAGS += -I$(MFEM_DIR)/fem/moonolith $(MOONOLITH_INCLUDES)
MFEM_TPLFLAGS += $(MOONOLITH_INCLUDES)
DIRS += fem/moonolith
endif
SOURCE_FILES = $(foreach dir,$(DIRS),$(wildcard $(SRC)$(dir)/*.cpp))
RELSRC_FILES = $(patsubst $(SRC)%,%,$(SOURCE_FILES))
OBJECT_FILES = $(patsubst $(SRC)%,$(BLD)%,$(SOURCE_FILES:.cpp=.o))
OKL_DIRS = fem
.PHONY: lib all clean distclean install config status info deps serial parallel \
debug pdebug cuda hip pcuda cudebug pcudebug hpc style check test unittest \
deprecation-warnings
.SUFFIXES:
.SUFFIXES: .cpp .o
# Remove some default implicit rules
%: %.o
%.o: %.cpp
%: %.cpp
# Default rule.
lib: $(if $(static),$(BLD)libmfem.a) $(if $(shared),$(BLD)libmfem.$(SO_EXT))
# Flags used for compiling all source files.
MFEM_BUILD_FLAGS = $(MFEM_PICFLAG) $(MFEM_CPPFLAGS) $(MFEM_CXXFLAGS)\
$(MFEM_TPLFLAGS) $(CONFIG_FILE_DEF)
# Rules for compiling all source files.
$(OBJECT_FILES): $(BLD)%.o: $(SRC)%.cpp $(CONFIG_MK)
$(MFEM_CXX) $(MFEM_BUILD_FLAGS) -c $(<) -o $(@)
all: examples miniapps $(TEST_DIRS)
.PHONY: miniapps $(EM_DIRS) $(TEST_DIRS)
miniapps: $(MINIAPP_DIRS)
$(MINIAPP_USE_COMMON): miniapps/common
$(EM_DIRS) $(TEST_DIRS): lib
$(MAKE) -C $(BLD)$(@)
.PHONY: doc
doc:
$(MAKE) -C $(BLD)$(@)
-include $(BLD)deps.mk
$(BLD)libmfem.a: $(OBJECT_FILES)
$(AR) $(ARFLAGS) $(@) $(OBJECT_FILES)
$(RANLIB) $(@)
@$(MAKE) deprecation-warnings
$(BLD)libmfem.$(SO_EXT): $(BLD)libmfem.$(SO_VER)
cd $(@D) && ln -sf $(<F) $(@F)
@$(MAKE) deprecation-warnings
# If some of the external libraries are build without -fPIC, linking shared MFEM
# library may fail. In such cases, one may set EXT_LIBS on the command line.
EXT_LIBS = $(MFEM_EXT_LIBS)
$(BLD)libmfem.$(SO_VER): $(OBJECT_FILES)
$(MFEM_CXX) $(MFEM_LINK_FLAGS) $(BUILD_SOFLAGS) $(OBJECT_FILES) \
$(EXT_LIBS) -o $(@)
# Shortcut targets options
serial debug cuda hip cudebug hipdebug: M_MPI=NO
parallel pdebug pcuda pcudebug phip phipdebug: M_MPI=YES
serial parallel cuda pcuda hip phip: M_DBG=NO
debug pdebug cudebug pcudebug hipdebug phipdebug: M_DBG=YES
cuda pcuda cudebug pcudebug: M_CUDA=YES
hip phip hipdebug phipdebug: M_HIP=YES
serial parallel debug pdebug:
$(MAKE) -f $(THIS_MK) config MFEM_USE_MPI=$(M_MPI) MFEM_DEBUG=$(M_DBG) \
$(MAKEOVERRIDES_SAVE)
$(MAKE) $(MAKEOVERRIDES_SAVE)
cuda pcuda cudebug pcudebug:
$(MAKE) -f $(THIS_MK) config MFEM_USE_MPI=$(M_MPI) MFEM_DEBUG=$(M_DBG) \
MFEM_USE_CUDA=$(M_CUDA) $(MAKEOVERRIDES_SAVE)
$(MAKE) $(MAKEOVERRIDES_SAVE)
hip phip hipdebug phipdebug:
$(MAKE) -f $(THIS_MK) config MFEM_USE_MPI=$(M_MPI) MFEM_DEBUG=$(M_DBG) \
MFEM_USE_HIP=$(M_HIP) $(MAKEOVERRIDES_SAVE)
$(MAKE) $(MAKEOVERRIDES_SAVE)
# Build with MPI and all Device backends enabled (requires OCCA and RAJA)
hpc:
$(MAKE) -f $(THIS_MK) config MFEM_USE_MPI=YES MFEM_USE_CUDA=YES \
MFEM_USE_OPENMP=YES MFEM_USE_OCCA=YES MFEM_USE_RAJA=YES \
$(MAKEOVERRIDES_SAVE)
$(MAKE) $(MAKEOVERRIDES_SAVE)
deps:
rm -f $(BLD)deps.mk
for i in $(RELSRC_FILES:.cpp=); do \
$(DEP_CXX) $(MFEM_BUILD_FLAGS) $(DEP_FLAGS) $(BLD)$${i}.o $(SRC)$${i}.cpp\
>> $(BLD)deps.mk; done
check: lib
@printf "Quick-checking the MFEM library."
@printf " Use 'make test' for more extensive tests.\n"
@$(MAKE) -C $(BLD)examples \
$(if $(findstring YES,$(MFEM_USE_MPI)),ex1p-test-par,ex1-test-seq)
test test-noclean:
@echo "Testing the MFEM library. This may take a while..."
@echo "Building all examples, miniapps, and tests..."
@$(MAKE) $(MAKEOVERRIDES_SAVE) all
@echo "Running tests in: [ $(ALL_TEST_DIRS) ] ..."
@ERR=0; for dir in $(ALL_TEST_DIRS); do \
echo "Running tests in $${dir} ..."; \
if ! $(MAKE) -j1 -C $(BLD)$${dir} $@; then \
ERR=1; fi; done; \
if [ 0 -ne $${ERR} ]; then echo "Some tests failed."; exit 1; \
else echo "All tests passed."; fi
.PHONY: test-miniapps
test-miniapps:
@echo "Building all miniapps ..."
@$(MAKE) $(MAKEOVERRIDES_SAVE) miniapps
@ERR=0; for dir in $(MINIAPP_TEST_DIRS); do \
echo "Running tests in $${dir} ..."; \
if ! $(MAKE) -j1 -C $(BLD)$${dir} test; then \
ERR=1; fi; done; \
if [ 0 -ne $${ERR} ]; then echo "Some miniapp tests failed."; \
exit 1; else echo "All miniapp tests passed."; fi
unittest: lib
$(MAKE) -C $(BLD)tests/unit test
.PHONY: test-print
test-print:
@echo "Printing tests in: [ $(ALL_TEST_DIRS) ] ..."
@for dir in $(ALL_TEST_DIRS); do \
$(MAKE) -j1 -C $(BLD)$${dir} test-print; done
ALL_CLEAN_SUBDIRS = $(addsuffix /clean,config $(EM_DIRS) doc $(TEST_DIRS))
.PHONY: $(ALL_CLEAN_SUBDIRS) miniapps/clean
miniapps/clean: $(addsuffix /clean,$(MINIAPP_DIRS))
$(ALL_CLEAN_SUBDIRS):
$(MAKE) -C $(BLD)$(@D) $(@F)
clean: $(addsuffix /clean,$(EM_DIRS) $(TEST_DIRS))
rm -f $(addprefix $(BLD),$(foreach d,$(DIRS),$(d)/*.o))
rm -f $(addprefix $(BLD),$(foreach d,$(DIRS),$(d)/*~))
rm -rf $(addprefix $(BLD),*~ libmfem.* deps.mk)
distclean: clean config/clean doc/clean
rm -rf mfem/
INSTALL_SHARED_LIB = $(MFEM_CXX) $(MFEM_LINK_FLAGS) $(INSTALL_SOFLAGS)\
$(OBJECT_FILES) $(EXT_LIBS) -o $(PREFIX_LIB)/libmfem.$(SO_VER) && \
cd $(PREFIX_LIB) && ln -sf libmfem.$(SO_VER) libmfem.$(SO_EXT)
install: $(if $(static),$(BLD)libmfem.a) $(if $(shared),$(BLD)libmfem.$(SO_EXT))
mkdir -p $(PREFIX_LIB)
# install static and/or shared library
$(if $(static),$(INSTALL) -m 640 $(BLD)libmfem.a $(PREFIX_LIB))
$(if $(shared),$(INSTALL_SHARED_LIB))
# install top level includes
mkdir -p $(PREFIX_INC)/mfem
$(INSTALL) -m 640 $(SRC)mfem.hpp $(SRC)mfem-performance.hpp \
$(PREFIX_INC)/mfem
for hdr in mfem.hpp mfem-performance.hpp; do \
printf '// Auto-generated file.\n#include "mfem/'$$hdr'"\n' \
> $(PREFIX_INC)/$$hdr && chmod 640 $(PREFIX_INC)/$$hdr; done
# install config include
mkdir -p $(PREFIX_INC)/mfem/config
$(INSTALL) -m 640 $(BLD)config/_config.hpp $(PREFIX_INC)/mfem/config/config.hpp
$(INSTALL) -m 640 $(SRC)config/tconfig.hpp $(PREFIX_INC)/mfem/config
# install remaining includes in each subdirectory
for dir in $(DIRS); do \
mkdir -p $(PREFIX_INC)/mfem/$$dir && \
$(INSTALL) -m 640 $(SRC)$$dir/*.hpp $(PREFIX_INC)/mfem/$$dir; \
done
# install *.okl files
for dir in $(OKL_DIRS); do \
mkdir -p $(PREFIX_INC)/mfem/$$dir && \
$(INSTALL) -m 640 $(SRC)$$dir/*.okl $(PREFIX_INC)/mfem/$$dir; \
done
# install libCEED q-function headers
mkdir -p $(PREFIX_INC)/mfem/fem/ceed
$(INSTALL) -m 640 $(SRC)fem/ceed/*.h $(PREFIX_INC)/mfem/fem/ceed
# install config.mk in $(PREFIX_SHARE)
mkdir -p $(PREFIX_SHARE)
$(MAKE) -C $(BLD)config config-mk CONFIG_MK=config-install.mk
$(INSTALL) -m 640 $(BLD)config/config-install.mk $(PREFIX_SHARE)/config.mk
rm -f $(BLD)config/config-install.mk
# install test.mk in $(PREFIX_SHARE)
$(INSTALL) -m 640 $(SRC)config/test.mk $(PREFIX_SHARE)/test.mk
$(CONFIG_MK):
# Skip the error message when '-B' make flag is used (unconditionally
# make all targets), but still check for the $(CONFIG_MK) file
ifeq (,$(and $(findstring B,$(MAKEFLAGS)),$(wildcard $(CONFIG_MK))))
$(info )
$(info MFEM is not configured.)
$(info Run "make config" first, or see "make help".)
$(info )
$(error )
endif
config: $(if $(CONFIG_FILE_DEF),build-config,local-config)
.PHONY: local-config
local-config:
$(MAKE) -C config all
@printf "\nBuild destination: <source> [$(BUILD_REAL_DIR)]\n\n"
.PHONY: build-config
build-config:
for d in $(BUILD_SUBDIRS); do mkdir -p $(BLD)$${d}; done
for dir in "" $(addsuffix /,config $(EM_DIRS) doc $(TEST_DIRS)); do \
printf "# Auto-generated file.\n%s\n%s\n" \
"MFEM_DIR = $(MFEM_REAL_DIR)" \
"include \$$(MFEM_DIR)/$${dir}makefile" \
> $(BLD)$${dir}GNUmakefile; done
$(MAKE) -C $(BLD)config all
cd "$(BUILD_DIR)" && ln -sf "$(MFEM_REAL_DIR)/data" .
for hdr in mfem.hpp mfem-performance.hpp; do \
printf "// Auto-generated file.\n%s\n%s\n" \
"#define MFEM_CONFIG_FILE \"$(BUILD_REAL_DIR)/config/_config.hpp\"" \
"#include \"$(MFEM_REAL_DIR)/$${hdr}\"" > $(BLD)$${hdr}; done
@printf "\nBuild destination: $(BUILD_DIR) [$(BUILD_REAL_DIR)]\n\n"
help:
$(info $(value MFEM_HELP_MSG))
@true
status info:
$(info MFEM_VERSION = $(MFEM_VERSION) [v$(MFEM_VERSION_STRING)])
$(info MFEM_GIT_STRING = $(MFEM_GIT_STRING))
$(info MFEM_USE_MPI = $(MFEM_USE_MPI))
$(info MFEM_USE_METIS = $(MFEM_USE_METIS))
$(info MFEM_USE_METIS_5 = $(MFEM_USE_METIS_5))
$(info MFEM_DEBUG = $(MFEM_DEBUG))
$(info MFEM_USE_EXCEPTIONS = $(MFEM_USE_EXCEPTIONS))
$(info MFEM_USE_ZLIB = $(MFEM_USE_ZLIB))
$(info MFEM_USE_LIBUNWIND = $(MFEM_USE_LIBUNWIND))
$(info MFEM_USE_LAPACK = $(MFEM_USE_LAPACK))
$(info MFEM_THREAD_SAFE = $(MFEM_THREAD_SAFE))
$(info MFEM_USE_OPENMP = $(MFEM_USE_OPENMP))
$(info MFEM_USE_LEGACY_OPENMP = $(MFEM_USE_LEGACY_OPENMP))
$(info MFEM_USE_MEMALLOC = $(MFEM_USE_MEMALLOC))
$(info MFEM_TIMER_TYPE = $(MFEM_TIMER_TYPE))
$(info MFEM_USE_SUNDIALS = $(MFEM_USE_SUNDIALS))
$(info MFEM_USE_MESQUITE = $(MFEM_USE_MESQUITE))
$(info MFEM_USE_SUITESPARSE = $(MFEM_USE_SUITESPARSE))
$(info MFEM_USE_SUPERLU = $(MFEM_USE_SUPERLU))
$(info MFEM_USE_MUMPS = $(MFEM_USE_MUMPS))
$(info MFEM_USE_STRUMPACK = $(MFEM_USE_STRUMPACK))
$(info MFEM_USE_GINKGO = $(MFEM_USE_GINKGO))
$(info MFEM_USE_AMGX = $(MFEM_USE_AMGX))
$(info MFEM_USE_GNUTLS = $(MFEM_USE_GNUTLS))
$(info MFEM_USE_NETCDF = $(MFEM_USE_NETCDF))
$(info MFEM_USE_PETSC = $(MFEM_USE_PETSC))
$(info MFEM_USE_SLEPC = $(MFEM_USE_SLEPC))
$(info MFEM_USE_MPFR = $(MFEM_USE_MPFR))
$(info MFEM_USE_SIDRE = $(MFEM_USE_SIDRE))
$(info MFEM_USE_FMS = $(MFEM_USE_FMS))
$(info MFEM_USE_CONDUIT = $(MFEM_USE_CONDUIT))
$(info MFEM_USE_PUMI = $(MFEM_USE_PUMI))
$(info MFEM_USE_HIOP = $(MFEM_USE_HIOP))
$(info MFEM_USE_GSLIB = $(MFEM_USE_GSLIB))
$(info MFEM_USE_CUDA = $(MFEM_USE_CUDA))
$(info MFEM_USE_HIP = $(MFEM_USE_HIP))
$(info MFEM_USE_RAJA = $(MFEM_USE_RAJA))
$(info MFEM_USE_OCCA = $(MFEM_USE_OCCA))
$(info MFEM_USE_CALIPER = $(MFEM_USE_CALIPER))
$(info MFEM_USE_CEED = $(MFEM_USE_CEED))
$(info MFEM_USE_UMPIRE = $(MFEM_USE_UMPIRE))
$(info MFEM_USE_SIMD = $(MFEM_USE_SIMD))
$(info MFEM_USE_ADIOS2 = $(MFEM_USE_ADIOS2))
$(info MFEM_USE_MKL_CPARDISO = $(MFEM_USE_MKL_CPARDISO))
$(info MFEM_USE_MOONOLITH = $(MFEM_USE_MOONOLITH))
$(info MFEM_USE_ADFORWARD = $(MFEM_USE_ADFORWARD))
$(info MFEM_USE_CODIPACK = $(MFEM_USE_CODIPACK))
$(info MFEM_USE_BENCHMARK = $(MFEM_USE_BENCHMARK))
$(info MFEM_USE_PARELAG = $(MFEM_USE_PARELAG))
$(info MFEM_CXX = $(value MFEM_CXX))
$(info MFEM_HOST_CXX = $(value MFEM_HOST_CXX))
$(info MFEM_CPPFLAGS = $(value MFEM_CPPFLAGS))
$(info MFEM_CXXFLAGS = $(value MFEM_CXXFLAGS))
$(info MFEM_TPLFLAGS = $(value MFEM_TPLFLAGS))
$(info MFEM_INCFLAGS = $(value MFEM_INCFLAGS))
$(info MFEM_FLAGS = $(value MFEM_FLAGS))
$(info MFEM_LINK_FLAGS = $(value MFEM_LINK_FLAGS))
$(info MFEM_EXT_LIBS = $(value MFEM_EXT_LIBS))
$(info MFEM_LIBS = $(value MFEM_LIBS))
$(info MFEM_LIB_FILE = $(value MFEM_LIB_FILE))
$(info MFEM_BUILD_TAG = $(value MFEM_BUILD_TAG))
$(info MFEM_PREFIX = $(value MFEM_PREFIX))
$(info MFEM_INC_DIR = $(value MFEM_INC_DIR))
$(info MFEM_LIB_DIR = $(value MFEM_LIB_DIR))
$(info MFEM_STATIC = $(MFEM_STATIC))
$(info MFEM_SHARED = $(MFEM_SHARED))
$(info MFEM_BUILD_DIR = $(MFEM_BUILD_DIR))
$(info MFEM_MPIEXEC = $(MFEM_MPIEXEC))
$(info MFEM_MPIEXEC_NP = $(MFEM_MPIEXEC_NP))
$(info MFEM_MPI_NP = $(MFEM_MPI_NP))
@true
ASTYLE_BIN = astyle
ASTYLE = $(ASTYLE_BIN) --options=$(SRC)config/mfem.astylerc
ASTYLE_VER = "Artistic Style Version 3.1"
FORMAT_FILES = $(foreach dir,$(DIRS) $(EM_DIRS) config,$(dir)/*.?pp)
FORMAT_FILES += tests/unit/*.?pp
UNIT_TESTS_SUBDIRS = general linalg mesh fem miniapps ceed
FORMAT_FILES += $(foreach dir,$(UNIT_TESTS_SUBDIRS),tests/unit/$(dir)/*.?pp)
FORMAT_EXCLUDE = general/tinyxml2.cpp tests/unit/catch.hpp
FORMAT_LIST = $(filter-out $(FORMAT_EXCLUDE),$(wildcard $(FORMAT_FILES)))
COUT_CERR_FILES = $(foreach dir,$(DIRS),$(dir)/*.[ch]pp)
COUT_CERR_EXCLUDE = '^general/error\.cpp' '^general/globals\.[ch]pp'
DEPRECATION_WARNING := \
"This feature is planned for removal in the next release."\
"Please open an issue at github.com/mfem/mfem/issues if you depend on it."
deprecation-warnings:
@if [ -t 1 ]; then\
red="\033[0;31m"; yellow="\033[0;33m"; end="\033[0m";\
fi;\
if [ $(MFEM_USE_LEGACY_OPENMP) = YES ]; then\
printf $$red"[MFEM_USE_LEGACY_OPENMP]"$$end": "$$yellow"%s"$$end"\n"\
$(DEPRECATION_WARNING);\
fi
# $(call mfem_check_command, command-to-execute, success_msg, failed_msg)
mfem_check_command = \
if [ -t 1 ]; then red="\033[0;31m"; green="\033[0;32m"; end="\033[0m"; fi;\
if ! $(1); then\
printf $$green"%s"$$end"\n" "[ OK ] "$(strip $(2));\
else\
printf $$red"%s"$$end"\n" "[FAILED] "$(strip $(3)); err_code=1;\
fi
# Verify the C++ code styling in MFEM and check that std::cout and std::cerr are
# not used in the library (use mfem::out and mfem::err instead).
style:
@echo "Applying C++ code style..."
@astyle_version="$$($(ASTYLE_BIN) --version)";\
if [ "$$astyle_version" != $(ASTYLE_VER) ]; then\
printf "%s\n" "Invalid astyle version: '$$astyle_version'"\
"Please use: '"$(ASTYLE_VER)"'";\
exit 1;\
fi
@err_code=0;\
$(call mfem_check_command,\
$(ASTYLE) $(FORMAT_LIST) | grep Formatted,\
"No source files were changed",\
"Please make sure the changes are committed");\
echo "Checking for use of std::cout...";\
$(call mfem_check_command,\
grep cout $(COUT_CERR_FILES) | grep -v $(COUT_CERR_EXCLUDE:%=-e %),\
"No use of std::cout found", "Use mfem::out instead of std::cout");\
echo "Checking for use of std::cerr...";\
$(call mfem_check_command,\
grep cerr $(COUT_CERR_FILES) |\
grep -v $(COUT_CERR_EXCLUDE:%=-e %) -e cerrno,\
"No use of std::cerr found", "Use mfem::err instead of std::cerr");\
exit $$err_code
# Generate a TAGS table in $MFEM_DIR from all the tracked files
.PHONY: tags
tags:
ifndef ETAGS_BIN
$(error Error could not find suitable 'etags', please install one \
using your package manager)
else ifndef EGREP_BIN
$(error Error could not find suitable 'egrep', please install one \
using your package manager)
endif
$(eval MFEM_TRACKED_SOURCE = $(shell git -C $(MFEM_REAL_DIR) ls-files |\
$(EGREP_BIN) '(\.[hc](pp)?)$$'))
@cd $(MFEM_REAL_DIR) && $(ETAGS_BIN) --class-qualify \
--declarations -o $(MFEM_REAL_DIR)/TAGS $(MFEM_TRACKED_SOURCE)
# Creates symlinks to the hooks in the `.git/hooks` directory. Individual
# hooks can be enabled by manually creating symlinks. Hooks can be customized
# using hard copies (trading off with automated updates).
.PHONY: hooks
hooks:
@cd $(MFEM_DIR)/.git/hooks && \
ln -s ../../config/githooks/pre-commit pre-commit; \
ln -s ../../config/githooks/pre-push pre-push;
# Print the contents of a makefile variable, e.g.: 'make print-MFEM_LIBS'.
print-%:
$(info [ variable name]: $*)
$(info [ origin]: $(origin $*))
$(info [ value]: $(value $*))
$(info [expanded value]: $($*))
$(info )
@true
# Print the contents of all makefile variables.
.PHONY: printall
printall: $(subst :,\:,$(foreach var,$(.VARIABLES),print-$(var)))
@true