1 #-------------------------------------------------------------------------------
3 # $Id: Makefile 11235 2021-06-08 12:38:54Z sbu062 $
4 # Build model automatically generating include files for PRNG and IEEE
5 # author Sergey Budaev <sbudaev@gmail.com>
6 #-------------------------------------------------------------------------------
7 ##//! @file Makefile GNU Make build configuration.
8 ##//! @brief Makefile to build the model executable from the source code.
9 ##//! @details This is a standard GNU Make "Makefile" to build the model from
10 ##//! the sources. It also automatically generates some platform and
11 ##//! compiler specific include files for the `BASE_RANDOM` and the
12 ##//! IEEE math modules. See @ref intro_main "Working with the model"
13 ##//! section and the @ref README.md for details.
15 ##//! ### Dependencies ###
16 ##//! In addition to the GNU Make, this Makefile also depends on the
17 ##//! `grep`, `cut`, `sed` and `awk` utilities that are installed on any
18 ##//! Unix/Linux system, but usually absent on Windows. For Windows
19 ##//! they can be obtained from several locations on the web, e.g.
20 ##//! Cygwin or GnuWin32. See http://ahamodel.uib.no/doc/ar01s01.html for
21 ##//! more information.
23 ##//! ### Main adjustable parameters ###
24 ##//! @param FC sets the default compiler type from the above. Normally GNU
26 ##//! @param HOST_HPC_ROOT is the hostname to run the model executable in the
27 ##//! HPC batch mode. If the hostname the Makefile is called in is this
28 ##//! system, `make run` starts a new batch task. Otherwise, the model
29 ##//! executable is just started normally.
30 ##//! @param SRC is the name of the main source code (can be several files).
31 ##//! @param DRV is the source code of the model "driver", that is the main
32 ##//! Fortran program that produces the executable. It should be very
33 ##//! very small. The "driver" is a separate file from the AHA Model
35 ##//! @param OUT is the executable file name that is actually run, on the
36 ##//! Windows platform must have the `.exe` suffix. By default, the
37 ##//! executable name is set to `MODEL.exe` for maximum portability.
38 ##//! @param DOXYCFG the Doxygen documentation system configuration file name.
39 ##//! @param DOXYPATH defines the Doxygen output directory where the
40 ##//! documentation is generated. This could be set manually or parsed
41 ##//! automatically using the `grep` command. Note that the output
42 ##//! directory is set in the `Doxyfile` as:
43 ##//! `OUTPUT_DIRECTORY = ./model_docs`.
44 ##//! @param HEDTOOLS is the list of HEDTOOLS Fortran source files that are
45 ##//! used in the AHA Model. Note that `BASE_STRINGS` in the list must
46 ##//! go before `BASE_CSV_IO` because `BASE_CSV_IO` depends on
47 ##//! procedures from `BASE_STRINGS`.
48 ##//! @param HEDTOOLSDIR defines the path to the HEDTOOLS source code.
49 ##//! @param IEEEPATH defines the path to the IEEE non-intrinsic math modules
50 ##//! (part of HEDTOOLS).
51 ##//! @param WINRM defines the command that is used to delete files and
52 ##//! directories on the Windows platform; can be set either `del` or
54 ##//! @note The native file delete command on the Windows platform is 'del' or
55 ##//! 'erase'. However, if Cygwin is used, this native file removal
56 ##//! command may not call with a "command not found" error. In such a
57 ##//! case, use the Unix 'rm' tool provided by Cygwin.
59 ##//! The source code of the @ref Makefile contains many other parameters and
60 ##//! is well documented throughout.
62 # Doxygen note: block marked with cond .. endcond is excluded from Doxygen
63 # processing. Therefore, everything below to the end of the
64 # Makefile is not parsed. Makefile is not normally supported
67 #===============================================================================
69 # Supported Fortran compiler types
74 # Choose the default compiler type
77 # Graphics library to use, for example:
78 # PGPLOT, if installed by the system:
80 # If PGPLOT is manually installed by the user into /usr/local/pgplot with
81 # X11 development libraries in /usr/lib/x86_64-linux-gnu (as in a
82 # Debian system), use this value for GRAPHLIB:
83 # -L/usr/local/pgplot -L/usr/lib/x86_64-linux-gnu -lpgplot -lX11
84 # --------------------------------------
86 # -lplplotf95d -lplplotf95cd -lplf95demolibd -I/usr/lib/fortran/modules/plplot
89 # Root of the host name to run in HPC cluster / batch mode, not directly
92 # Define what version control system is used, This is a default value used if
93 # VCS_TYPE is not set from command line of environment variable.
96 #===============================================================================
97 # Main building blocks, define the main program source, executable name (-o)
98 # and possible module (.mod) names.
100 # These names should be set for particular project,
101 # Most probably they should be edited manually for each specific project
102 # SRC is the name of the main source code (can be several files). Note that
103 # Intel fortran doesn't like f95 file extension, use f90
104 # DRV is the source code of the model "driver", that is the main Fortran
105 # program that produces the executable. It should be very very small.
106 # The "driver" is a separate file from the modules.
107 # OUT is the executable file, on the Windows platform has the .exe suffix.
109 SRC = m_common.f90 m_fileio.f90 m_env.f90 m_genome.f90 m_hormon.f90 \
110 m_body.f90 m_neuro.f90 m_behav.f90 m_indiv.f90 m_popul.f90 m_evolut.f90
116 # Doxygen configuration file within the same directory.
119 # Doxygen output directory, can be grepped from Configuration file.
120 # OUTPUT_DIRECTORY = ./model_docs
121 # DOXYPATH = model_docs
122 DOXYPATH = $(shell $(GREP) ^OUTPUT_DIRECTORY Doxyfile | $(CUT) -d '=' -f 2)
124 #===============================================================================
125 # HEDTOOLS sources and module files:
126 # Warning: BASE_STRINGS must go before BASE_CSV_IO because BASE_CSV_IO now
127 # depends on procedures from BASE_STRINGS.
129 HEDTOOLS = BASE_UTILS.f90 BASE_STRINGS.f90 BASE_CSV_IO.f90 BASE_LOGGER.f90 \
132 # Path to HEDTOOLS and IEEE non-intrinsic libs (part of HEDTOOLS).
133 HEDTOOLSDIR = ../HEDTOOLS
134 IEEEPATH = $(HEDTOOLSDIR)/IEEE
136 # Path to the unit tests using pfUnit framework.
139 #===============================================================================
140 # The name of the network server, where the data zip file is pushed by scp
141 # on `make zipsend` command. The server string must contain the complete
142 # destination in the scp notation (see `man scp`): [user@]host:]path
143 # e.g. budaev@bio0215550.klient.uib.no:/cygdrive/d/
144 # @note Note that the zip file as well as all files having the same root
145 # names (including zip extension) are transferred, e.g. `model_1.zip`
146 # along with `model_1.zip.md5` `model_1.zip.notes` `model_1.zip.txt`.
148 AHA_STORAGE_SERVER_STR = budaev@bio0215550.klient.uib.no:/cygdrive/d/AHA-ZDATA/
150 #===============================================================================
151 # Notification command for execution termination
153 AHA_NOTIFY_CMD_WIN = c:\python27\python.exe o:\bin\xsendnc.py sbu062@tegsvn.uib.no 'Model run terminated'
154 AHA_NOTIFY_CMD_UNIX = xsendnc.py sbu062@tegsvn.uib.no "Model run terminated on `hostname`"
156 #===============================================================================
157 # Accessory settings for the build environment
159 # The native file delete command on the Windows platform is 'del' or 'erase'.
160 # However, if Cygwin is used, this native file removal command may not call
161 # with a "command not found" error. In such a case, use the Unix 'rm' tool
162 # provided by Cygwin.
165 #===============================================================================
166 # Define compiler options
168 # #### Options for GNU Fortran
169 # Note: link-time optimisations -flto do not work on Windows, falls with the
170 # segmentation fault. On Linux, it builds without any problem, but seems
171 # to break the LOGGER module output, it loses the logger unit and log
172 # data go to fort.1. More testing is needed, -flto disabled so far.
173 GF_STATIC = -static-libgfortran -static -static-libgcc
174 GF_TRAPS = -ffpe-trap=
175 GF_RCHECKS = -Wall -fbounds-check
176 # Memory leaks sanitize checks for GCC using libasan, work on Linux and OSX
177 GF_MEMCHECK = -fsanitize=address -static-libasan
178 #GF_FFLAGS = $(GF_STATIC) $(GF_TRAPS) $(GF_RCHECKS) -O3
179 GF_FFLAGS = -O3 -march=native -funroll-loops -fforce-addr $(GF_STATIC)
180 GF_FFLAGS_WINDOWS = -O3 -funroll-loops -fforce-addr $(GF_STATIC)
181 #-ffpe-trap=zero,invalid,overflow,underflow
182 # GC_FFLAGS are for gcc C compiler (C may be used for IEEEs)
184 # On Windows might need -mwindows
186 # #### Options for Intel Fortran
187 IF_ANNOTATE = -qopt-report-phase=vec -qopt-report-annotate=html
188 IF_REPORT_OPT = -qopt-report=3
191 IF_RCHECKS = -gen-interfaces -warn -check bounds,pointers,format,uninit
192 # Intel Fortran compiler options maximizing speed for the whole program: -fast
193 # Linux: -ipo, -O3, -no-prec-div, -static, -fp-model fast=2, and -xHost
194 # Note: Build with -ipo crashes on building the the $(OBJ) main model target
195 # with "Segmentation violation signal raised" (ifort 17.0.4 and earlier,
196 # starting at SVN rev. 5010). For this reason, -ipo option is disabled here
197 # (therefore -fast would not work either). When only the latest $(OUT)
198 # target includes -ipo option, a warning appears
199 # ipo: warning #11003: no IR in object file xxx
200 # and IPO optimisation should not probably be there either.
201 # Update: As to ifort 19.0.4.243 20190416, `IPO` works without `parallel`
202 # Base option: IF_FFLAGS = -sox -parallel -O3 -ipo
203 IF_FFLAGS = -sox -O3 -ipo $(IF_STATIC) -heap-arrays -fp-model fast=2 \
204 -xHost -finline-functions $(IF_REPORT_OPT) $(IF_ANNOTATE)
205 # For Intel Fortran, options are somewhat different on Windows platform.
206 # Note: Windows stack size is insufficient for the large number of concurrent
207 # threads and huge arrays used in the model. Therefore, stack overflow
208 # error is issued (ifort 17) with the default build options. Stack size
209 # available for the program is controlled by the /Fn option (n is in
210 # bytes). Setting a huge value resolves the stack overflow issue on the
211 # Windows platform. This can sometimes occur on the Linux and Mac OS X
212 # platforms too. To fix it on Linux, issue this command:
213 # ulimit -s unlimited
214 # Increasing stack size on Mac OS X is described here:
215 # https://developer.apple.com/library/content/qa/qa1419/_index.html.
216 # Base option: /Qsox /Qparallel
218 # Note: The following worked on W7 but O2 optimization resulted
219 # in access violation crash on W10, O1 seems to work on W10
220 # IF_FFLAGS_WINDOWS = /Qsox /Qparallel /Ot /static /heap-arrays /fp:fast=2 \
221 # /QxHost /Ob2 /warn /fpe:0 /F100000000
222 IF_FFLAGS_WINDOWS = /Qsox /O1 /static /heap-arrays /warn /fpe:0 /F100000000
224 #IF_FFLAGS = -sox -fast -parallel $(IF_STATIC) $(IF_TRAPS)
225 # -fpe3 no traps; -fpe0 all traps
227 # Aggressive optimizations: -fast = -O3 –ipo –static
229 # #### Options for Sun/Oracle Solaris Studio
230 SF_STATIC = -Bstatic -dn
231 SF_TRAPS = -ftrap=%none
233 SF_FFLAGS = -O1 -depend=yes
234 # NOTE: optimisations exceeding -O1 might not work with all CSV_IO routines
235 # SF_FFLAGS = -fast -autopar -depend=yes
237 # -ftrap=common is a macro for -ftrap=invalid,overflow,division.
238 # -ftrap=%all, %none, common
240 #-------------------------------------------------------------------------------
242 # DEBUG turns off all optimisations and keeps debug symbols. Note that
243 # SNaNs are initialising all values in case of intel Fortran (-init=snan).
245 GF_FFLAGS = -O0 -g -ffpe-trap=zero,invalid,overflow,underflow \
246 -Warray-temporaries $(GF_RCHECKS)
247 GF_FFLAGS_WINDOWS = $(GF_FFLAGS)
248 IF_FFLAGS = -O0 -heap-arrays -gen-interfaces -g -debug all -fpe0 -traceback \
249 -init=snan $(IF_RCHECKS)
250 SF_FFLAGS = -O0 -g -ftrap=common
251 IF_FFLAGS_WINDOWS = /Qsox /optimize:0 /fpe:0 /heap-arrays /debug:all \
252 /traceback /Qinit:snan /gen-interfaces /check /warn \
257 # PROFILE adds profiling options (-pg on GNU). Then running the program provides
258 # a profiling report: gmon.out. It can be read with: gprof MODEL.exe
263 #-------------------------------------------------------------------------------
264 # Set other build options depending on the specific compiler
266 ifeq ($(FC),$(GF_FC))
267 FFLAGS = $(GF_FFLAGS)
268 STATIC = $(GF_STATIC)
270 RCHECKS = $(GF_RCHECKS)
274 ifeq ($(FC),$(IF_FC))
275 FFLAGS = $(IF_FFLAGS)
276 STATIC = $(IF_STATIC)
278 RCHECKS = $(IF_RCHECKS)
281 ifeq ($(FC),$(SF_FC))
282 FFLAGS = $(SF_FFLAGS)
283 STATIC = $(SF_STATIC)
285 RCHECKS = $(SF_RCHECKS)
288 #===============================================================================
289 # Determine what is the build platform, Windows / non-Windows
291 # Use uname -- but it may not be installed on Windows. Probably the method
292 # based on ComSpec is safer. Note that the -c switch on grep suppresses normal
293 # output and just prints count.
294 ##PLATFORM = $(shell uname)
295 ##IS_WINDOWS = $(shell uname | grep -ci windows)
297 # A safer way to check platform if uname is not available, ComSpec on Windows
298 # Note that ComSpec is (may be?) case-sensitive, check with env.exe
299 # Quirk: - Microsoft Windows echo does not require escaping quotes parentheses
300 # and other symbols and outputrs them as is into redirected shell
301 # output, e.g. in $(shell echo "bla bla bla" >> file.txt), i.e
302 # file.txt gets "bla bla bla". Linux echo, in contrast deletes the
303 # quites, which can create portability problems if a piece of code
304 # (e.g. include file) is auto-generated in such a way.
305 # One way to ensure identical behaviour on all platforms is to use
306 # a third-party echo.exe program from Cygwin, GnuWin32 of Linux
307 # subsystem on Windows 10 (WSL).
308 # - Windows 10 does not seem to use third-party `echo.exe` (e.g. from
309 # GNUwin32 or Linux subsystem if simple echo is referred under shell.
310 # This requires redefining ECHO to refer to a specific `exe`
313 PLATFORM_TYPE=Windows
322 ECHO := "$(shell $(WHICH_CMD) echo.exe)"
336 # Check if certain required executables exist and are callable in path. This is
337 # important on the Windows platform because such GNU command line utilities as
338 # uname and zip are not installed by default.
339 REQUIRED_EXECS = zip a2x md5sum ifort f95 gfortran svn $(CUT) $(GREP)
340 K := $(foreach exec,$(REQUIRED_EXECS),\
341 $(if $(shell $(WHICH_CMD) $(exec) ),check executables,\
342 $(warning ============ $(exec) unavailable in PATH ============)))
344 # Check if we build on Windows platform with GNU gfortran Compiler. Compiler
345 # may differ in this case. Notably, GCC -flto option crashes compiler.
346 # also, memory sanitizer GF_MEMCHECK is disabled on Windows
347 ifeq ($(PLATFORM_TYPE)$(FC),Windowsgfortran)
348 GF_FFLAGS:=$(GF_FFLAGS_WINDOWS)
350 GF_RCHECKS := $(GF_RCHECKS) $(GF_MEMCHECK)
353 # Check if we build on Windows platform with Intel Compiler. It is specific in
354 # two ways: (1) build options are different, start with slash and often have Q
355 # and (2) .obj is used as the extension for object files rather than .o
356 # here we check if with an emulated AND condition. Do this by simply
357 # concatenating two things into Windowsifort.
358 ifeq ($(PLATFORM_TYPE)$(FC),Windowsifort)
360 OBJ = $(addsuffix .$(OBJEXT), $(basename $(SRC)))
361 IF_FFLAGS:=$(IF_FFLAGS_WINDOWS)
364 OBJ = $(addsuffix .$(OBJEXT), $(basename $(SRC)))
367 #===============================================================================
368 # HEDTOOLS object files:
369 # Warning: BASE_STRINGS must go before BASE_CSV_IO because BASE_CSV_IO now
370 # depends on procedures from BASE_STRINGS. This should be set by
371 # correct ordering of components in the HEDTOOLS variable.
373 HTOOLOBJ = $(addsuffix .$(OBJEXT), $(basename $(HEDTOOLS)))
375 #===============================================================================
376 # Generate the list of modules used in the source.
377 # First, get the list of module calls from the 'use' statements within the
379 # NOTE: Make turns $$ into $ in awk call, otherwise it goes empty.
380 # The sort GNU make function produces a sorted list deleting duplicates.
381 MOD_LIST = $(sort $(shell $(GREP) -i "^ *use " $(SRC) | sed -e 's/,//g' | awk '{printf(" %s ",$$2) }'))
383 # Second, produce the final list of all .mod files that are to be generated.
384 # MOD_ALL is a list of Fortran modules generated by the main program as well
385 # as HEDTOOLS. So far MOD_ALL is not used for anything very important, only in
386 # cleaning temporary files, so can be set to .mod files remaining after make
387 # clean/distclean. Modules can be included into prerequisites?
388 # NOTE: The code automatically generating the list of modules uses the MOD_LIST
389 # variable that gets the list of modules by applying Unix 'grep' to the
390 # source code files; extracts basename (just in case) and adds the
391 # '.mod' suffix to each file.
392 MOD_ALL = $(addsuffix .mod, $(basename $(call lowercase, $(MOD_LIST))))
394 #===============================================================================
395 # Auto-generated include file setting compiler/platform specific code for PRNG
396 # The module BASE_RANDOM includes some non-portable header code that
397 # depends on the compiler type. It is auto-generated here. The Fortran Module
398 # code contains INCLUDE statement. The appropriate include file is then
399 # auto-generated during the build process.
400 # The strategy of the build is two-step:
401 # (1) Provide comment macro for the include file as well as the code adapted
402 # for the specific compiler type and platform
403 # (2) Select macro from the above list specific for the
405 # (3) build the BASE_RANDOM.o, the first statement is the include
406 # auto-generation macro, then follow the compile instructions.
408 # Header file setting compiler/platform specific code for PRNG module
409 AUTOGEN_HEADER_RAND = $(HEDTOOLSDIR)/BASE_RANDOM.inc
411 # Auto-generated include files, note that the first two lines do doxygen
413 define AUTOGEN_COMMENT_RANDOM
414 $(shell $(ECHO) "!> @file $(AUTOGEN_HEADER_RAND)" > $(AUTOGEN_HEADER_RAND))
415 $(shell $(ECHO) "!! Autogenerated header for module RANDOM built with $(FC)" >> $(AUTOGEN_HEADER_RAND))
416 $(shell $(ECHO) "!! Sets compiler-specific code for random number generator" >> $(AUTOGEN_HEADER_RAND))
417 $(shell $(ECHO) "!+---------------------------------------------------------+" >> $(AUTOGEN_HEADER_RAND))
418 $(shell $(ECHO) "!| WARNING: auto-generated file, do NOT edit |" >> $(AUTOGEN_HEADER_RAND))
419 $(shell $(ECHO) "!| Sets compiler-specific code for random number generator |" >> $(AUTOGEN_HEADER_RAND))
420 $(shell $(ECHO) "!+---------------------------------------------------------+" >> $(AUTOGEN_HEADER_RAND))
423 # Include file code for GNU
424 define AUTOGEN_CODE_GF
425 $(shell $(ECHO) "! GNU Fortran compiler:" >> $(AUTOGEN_HEADER_RAND))
426 $(shell $(ECHO) "use ISO_FORTRAN_ENV, only: int64" >> $(AUTOGEN_HEADER_RAND))
427 $(shell $(ECHO) "implicit none" >> $(AUTOGEN_HEADER_RAND))
428 $(shell $(ECHO) "integer, allocatable :: seed(:)" >> $(AUTOGEN_HEADER_RAND))
429 $(shell $(ECHO) "integer :: i, n, un, istat, dt(8), pid" >> $(AUTOGEN_HEADER_RAND))
430 $(shell $(ECHO) "integer(int64) :: t">> $(AUTOGEN_HEADER_RAND))
433 # Include file code for Intel
434 define AUTOGEN_CODE_IF
435 $(shell $(ECHO) "! Intel Fortran compiler:" >> $(AUTOGEN_HEADER_RAND))
436 $(shell $(ECHO) "use ISO_FORTRAN_ENV, only: int64 " >> $(AUTOGEN_HEADER_RAND))
437 $(shell $(ECHO) "use IFPORT, only : getpid" >> $(AUTOGEN_HEADER_RAND))
438 $(shell $(ECHO) "implicit none" >> $(AUTOGEN_HEADER_RAND))
439 $(shell $(ECHO) "integer, allocatable :: seed(:)" >> $(AUTOGEN_HEADER_RAND))
440 $(shell $(ECHO) "integer :: i, n, un, istat, dt(8), pid" >> $(AUTOGEN_HEADER_RAND))
441 $(shell $(ECHO) "integer(int64) :: t" >> $(AUTOGEN_HEADER_RAND))
444 # Include file code for Oracle
445 define AUTOGEN_CODE_SF
446 $(shell $(ECHO) "! Intel Oracle compiler:" >> $(AUTOGEN_HEADER_RAND))
447 $(shell $(ECHO) "implicit none" >> $(AUTOGEN_HEADER_RAND))
448 $(shell $(ECHO) "integer, allocatable :: seed(:)" >> $(AUTOGEN_HEADER_RAND))
449 $(shell $(ECHO) "integer :: i, n, un, istat, dt(8), pid" >> $(AUTOGEN_HEADER_RAND))
450 $(shell $(ECHO) "integer, parameter :: int64 = selected_int_kind(18)" >> $(AUTOGEN_HEADER_RAND))
451 $(shell $(ECHO) "integer(int64) :: t" >> $(AUTOGEN_HEADER_RAND))
452 $(shell $(ECHO) "include \"system.inc\"" >> $(AUTOGEN_HEADER_RAND))
455 # Select autogeneration of include file for the specific compiler type
456 ifeq ($(FC),$(GF_FC))
457 AUTOGEN_CODE_RANDOM=$(AUTOGEN_CODE_GF)
460 ifeq ($(FC),$(IF_FC))
461 AUTOGEN_CODE_RANDOM=$(AUTOGEN_CODE_IF)
464 ifeq ($(FC),$(SF_FC))
465 AUTOGEN_CODE_RANDOM=$(AUTOGEN_CODE_SF)
468 #===============================================================================
469 # Determine compiler versions, we may need GCC version > 5 to use
470 # non-intrinsic IEEE math modules for gfortran < 5, GCC > 5 fully
471 # supports intrinsic IEEE math.
472 # IEEE should work with recent versions
474 # Check GCC version and need for non-intrinsic modules
475 GFORTVERSION = $(shell $(GF_FC) -dumpversion)
476 GFORT_LESS_5 = $(shell expr `echo $(GFORTVERSION) | $(CUT) -d. -f1` < 5)
477 ifeq ($(GFORT_LESS_5),1)
478 COMPILE_NONINTRINSIC_IEEE=YES
480 COMPILE_NONINTRINSIC_IEEE=NO
483 # IEEE non-intrinsic modules, list of sources
484 IEEE_NON_INTRINSIC_SRC = precision_m.f90 IEEE_FEATURES.f90 IEEE_EXCEPTIONS.f90 \
485 IEEE_ARITHMETIC.f90 c_control.c
487 IEEEMOD = ieee_arithmetic.mod ieee_exceptions.mod ieee_features.mod \
490 # IEEE non-intrinsic objects
491 IEEEOBJ = precision_m.$(OBJEXT) c_control.$(OBJEXT) IEEE_FEATURES.$(OBJEXT) \
492 IEEE_EXCEPTIONS.$(OBJEXT) IEEE_ARITHMETIC.$(OBJEXT)
494 # Macros to auto-generate F90 headers for IEEE modules -- AUTOGEN_HEADER_FILE
495 AUTOGEN_HEADER_IEEE = IEEE_wrap.inc
497 # Check if the source does include IEEE calls at all, disable non-intrinsic IEEE
498 # if the Fortran source does never refer to them
499 IEEE_GREPPED_SRC = $(shell $(GREP) -ci $(AUTOGEN_HEADER_IEEE) $(SRC))
500 ifeq ($(IEEE_GREPPED_SRC),0)
501 COMPILE_NONINTRINSIC_IEEE=NO
504 ifneq ($(FC),gfortran)
505 COMPILE_NONINTRINSIC_IEEE=NO
508 # Autogenerated include files
509 define AUTOGEN_COMMENT_HEADER_F90
510 $(shell $(ECHO) "!> @file $(AUTOGEN_HEADER_IEEE)" > $(AUTOGEN_HEADER_IEEE))
511 $(shell $(ECHO) "!! Autogenerated header for IEEE math modules built with $(FC)" >> $(AUTOGEN_HEADER_IEEE))
512 $(shell $(ECHO) "!! Calls intrinsic or non-intrinsic IEEE math modules" >> $(AUTOGEN_HEADER_IEEE))
513 $(shell $(ECHO) "!+-----------------------------------------------------+" >> $(AUTOGEN_HEADER_IEEE))
514 $(shell $(ECHO) "!| WARNING: auto-generated file, do NOT edit |" >> $(AUTOGEN_HEADER_IEEE))
515 $(shell $(ECHO) "!| Calls intrinsic or non-intrinsic IEEE math modules |" >> $(AUTOGEN_HEADER_IEEE))
516 $(shell $(ECHO) "!+-----------------------------------------------------+" >> $(AUTOGEN_HEADER_IEEE))
519 # Now only use IEEE_EXCEPTIONS are managed. Other modules may be added:
520 # IEEE_FEATURES IEEE_ARITHMETIC IEEE_EXCEPTIONS
521 define AUTOGEN_INTRINSIC
522 $(AUTOGEN_COMMENT_HEADER_F90)
523 $(shell $(ECHO) "use, intrinsic :: IEEE_ARITHMETIC" >> $(AUTOGEN_HEADER_IEEE))
524 $(shell $(ECHO) "use, intrinsic :: IEEE_EXCEPTIONS" >> $(AUTOGEN_HEADER_IEEE))
527 # Now only use IEEE_EXCEPTIONS are managed. Other modules may be added:
528 # IEEE_FEATURES IEEE_ARITHMETIC IEEE_EXCEPTIONS
529 define AUTOGEN_NON_INTRINSIC
530 $(AUTOGEN_COMMENT_HEADER_F90)
531 $(shell $(ECHO) "use, non_intrinsic :: IEEE_ARITHMETIC" >> $(AUTOGEN_HEADER_IEEE))
532 $(shell $(ECHO) "use, non_intrinsic :: IEEE_EXCEPTIONS" >> $(AUTOGEN_HEADER_IEEE))
535 #-------------------------------------------------------------------------------
537 # Function to convert UPPERCASE to lowercase by Eric Melski, taken from
538 # https://stackoverflow.com/questions/664601/in-gnu-make-how-do-i-convert-a-variable-to-lower-case
539 # It looks a little clunky, but it gets the job done...
540 lowercase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
542 #-------------------------------------------------------------------------------
544 # Determine this makefile's path. Be sure to place this BEFORE `include`s
545 THIS_FILE := $(lastword $(MAKEFILE_LIST))
547 # This is the search paths for looking for components, separated by blanks
548 VPATH = $(HEDTOOLSDIR) $(IEEEPATH)
550 # Determine if we are running on HPC cluster
551 RUNHOST_HPC = $(shell hostname | $(GREP) -c $(HOST_HPC_ROOT))
553 # Determine current SVN version of the code
554 ifeq ($(VCS_TYPE),SVN)
555 SVN_VER = $(shell svn info --show-item last-changed-revision)
557 ifeq ($(VCS_TYPE),HG)
558 SVN_VER = $(shell hg summary | $(GREP) parent: | $(CUT) -d " " -f 2 | $(CUT) -d ":" -f 2 )
564 # Build the data zip file name: data are compressed for make zipdata
565 ZIPDATA_NAME = model_data_rev$(SVN_VER)_$(shell hostname).zip
567 #===============================================================================
569 #===============================================================================
571 # Default build target = executable
577 # Short help on the options
578 # For Intel Fortran compiler on Windows, we have to call the batch file to setup
579 # the build environment. This command is taken from the Command Prompt
580 # shortcut in the Intel Parallel Studio menu:
581 #C:\Windows\SysWOW64\cmd.exe /E:ON /V:ON /K ""C:\Program Files (x86)\Intel\Composer XE 2013\bin\ipsxe-comp-vars.bat" intel64 vs2010"
582 # This mitght be different on different systems, depending on the
583 # installation options for Intel Parallel Studio and the Windows platform
584 # type (e.g. 32 vs. 64 bit)
587 @echo ------------------------------------------------------------------------
588 @echo "Building model $(SRC) ------ via $(THIS_FILE)"
589 @echo ------------------------------------------------------------------------
592 @echo "Normal build: make (uses $(FC) by default)"
594 @echo "Main (re)build (for different compiler type targets):"
595 @echo " make gnu, make intel, make sun"
597 @echo "Compile HEDTOOLS modelling tools: make tools"
599 @echo "Autogenerate documentation with Doxygen (config: $(DOXYCFG))"
602 @echo "Produce system-specific include headers (PRNG and IEEE): make inc"
604 @echo "Produce debug symbols: define DEBUG, e.g.: make DEBUG=1"
605 @echo " profiling output (GNU): define PROFILE, e.g.: make PROFILE=1"
609 @echo "Run model: make run (make run_local to force local run)"
613 @echo "Compress output data: make zipdata (compress CSV: make gzipcsv)"
614 @echo "Check zip file and produce md5 checksum: make zipcheck"
615 @echo "Send zip data (and others) to the remote server AHA_STORAGE_SERVER_STR"
616 @echo " = $(AHA_STORAGE_SERVER_STR): make zipsend"
620 @echo "Run unit tests using pfunt test framework: make tests"
624 @echo "Cleaning: make clean, make cleandata (model data only),"
625 @echo " make distclean (everything, leaving the distro state!)"
626 @echo ------------------------------------------------------------------------
628 @echo " 1. IEEE non-intrinsic modules: make ieee, needed only for GCC < 5"
629 @echo " 2. Intel Fortran compiler under Windows: set up environment for "
630 @echo " Microsoft Visual Studio 2010 x64 tools before calling make."
631 @echo " Call to the shortcuts from the Command Prompt menu under Intel "
632 @echo " Parallel Studio XE"
633 @echo ------------------------------------------------------------------------
634 @echo PROJECT: Rev: $(SVN_VER) \($(VCS_TYPE)\), $(PLATFORM_TYPE), HPC \($(HOST_HPC_ROOT)\) $(RUNHOST_HPC)
635 @echo Source: $(SRC) -- $(OUT) -- $(OBJ)
636 @echo ------------------------------------------------------------------------
638 # shortcut to build for GNU Fortran
641 @$(MAKE) -f $(THIS_FILE) FC=gfortran
643 # shortcut to build for Intel Fortran
646 @$(MAKE) -f $(THIS_FILE) FC=ifort
648 # shortcut to build for Solaris Studio Fortran
651 @$(MAKE) -f $(THIS_FILE) FC=f95
653 # Run through PBS job script on HPC, check if we are on cluster RUNHOST_HPC
654 #run: $(OUT) $(JOB) $(SRC)
656 ifeq ($(RUNHOST_HPC),1)
658 @echo "NOTE: fimm job created"
659 @echo "Batch commands:"
660 @echo " showq -u USER = show user's jobs'"
661 @echo " qstat = display all jobs"
662 @echo " qdel jobid = delete job"
663 @echo " qhold = pause job"
664 @echo " qrls = resume job"
665 @echo "https://docs.hpc.uib.no/wiki/Job_execution_(Fimm)"
667 @$(MAKE) -f $(THIS_FILE) run_local
670 # Note -- this is local start/run on all supported systems.
671 # If the DEBUG flag was set when starting make, the executable also
672 # starts in the DEBUG mode (command line DEBUG flag).
673 run_local: $(OUT) $(SRC)
674 $(info ====================================================================)
675 $(info Executing model $(OUT) now)
676 $(info ====================================================================)
677 ifeq ($(IS_WINDOWS),1)
679 $(AHA_NOTIFY_CMD_WIN)
681 ./$(OUT) $(RUNFLAG) ; $(AHA_NOTIFY_CMD_UNIX)
684 # Main build the executable
687 # Build object files only without the final executable
688 objects: $(OBJ) $(HTOOLOBJ)
690 # Produce include file for PRNG module
691 inc: $(AUTOGEN_HEADER_RAND) $(AUTOGEN_HEADER_IEEE)
693 # Compile the HEDTOOLS modelling tools
696 # Compile the HEDTOOLS modelling tools
697 headtools: $(HTOOLOBJ)
699 # Run unit tests. Note that pFunit is non-essential and any build errors are
700 # ignored in this main Makefile.
703 @echo Running unit tests in $(PFUNIT_PATH). Warning: Any errors IGNORED.
704 -$(MAKE) -C $(PFUNIT_PATH)
706 # Cleanup data files, quotes needed on Windows if file starts from blank
708 -$(RM) HED*.txt ?HED*.txt HED18*.log behaviour gene*
709 -$(RM) debug* *.csv *.ps *.png *.svg *gz
710 ifeq ($(IS_WINDOWS),1)
711 -$(RM) "?HED*.txt" "HED*.txt"
714 # Return to default state, delete all generated files.
715 distclean: clean cleandata cleanzip
716 -$(RM) $(AUTOGEN_HEADER_RAND) $(AUTOGEN_HEADER_IEEE) $(HTOOLOBJ) $(MOD_ALL) \
717 $(IEEEOBJ) $(IEEEMOD) gmon.out *.mod *.log *.o *.obj *.pdb *.patch \
720 @echo Cleaning unit tests in $(PFUNIT_PATH).
721 @echo NOTE: Any errors IGNORED.
722 -$(MAKE) -C $(PFUNIT_PATH) distclean
724 # Clean obj etc for new build of the model, but we don't clean HEDTOOLS and
727 -$(RM) $(OBJ) $(OUT) *.csv *.ps *.png
729 # Cean temporary files and conflict that remain from syncthing synchronisation.
731 -$(RM) *conflict* .syncthing* ~syncthing* fort.* *.tmp *.orig *.lock \
732 *.annot.html *.annot *.optrpt
734 # Compress all generation-based CSV data using gzip. This should
735 # normally be done automatically at run time if the environment variable
738 gzip agents*csv behaviours*csv food_*csv genomes*csv memory*csv \
739 movements*csv timesteps*csv
741 # Compress all output data from the latest model run. This is a shortcut
742 # calling the actual zip target.
743 zipdata: $(ZIPDATA_NAME)
745 # Compress all output data from the latest model run. This is the actual zipper.
747 @echo Producing zipfile: $(ZIPDATA_NAME)
748 -zip $(ZIPDATA_NAME) *.csv *.log *.ps *.gz *.patch
749 @echo "NOTE: If the $(OUT) target is rebuilt at this stage, re-run model!"
750 @echo " To check zip run make zipcheck"
751 @echo " Produced $(ZIPDATA_NAME)"
753 # Check the integrity of the compressed data zip file and produce the md5
755 zipcheck: $(ZIPDATA_NAME)
756 @echo Check zip and produce MD5 checksum file.
757 @echo NOTE: Any errors are IGNORED.
758 -zip -T $(ZIPDATA_NAME)
759 -md5sum $(ZIPDATA_NAME) > $(ZIPDATA_NAME).md5
761 # Sending the data zip file to an external server for storage or data analysis.
762 # The data file is sent using scp command. Note that the zip file as well as
763 # all files having the same root names are transferred, e.g..
764 # model_1.zip along with model_1.zip.md5 model_1.zip.notes model_1.zip.txt
765 zipsend: $(ZIPDATA_NAME)
766 @echo Sending $(ZIPDATA_NAME) to $(AHA_STORAGE_SERVER_STR)
767 @echo NOTE: Any errors are IGNORED. Data transfer may take a long time!
768 -scp $(ZIPDATA_NAME)* $(AHA_STORAGE_SERVER_STR)
770 # Clean any compressed data.
774 #-------------------------------------------------------------------------------
775 #-------------------------------------------------------------------------------
776 # Automatic build follows, usually there is no need to edit the code below...
778 $(OUT): $(DRV) $(OBJ) $(HTOOLOBJ)
779 @$(MAKE) -f $(THIS_FILE) inc
780 ifeq ($(COMPILE_NONINTRINSIC_IEEE),YES)
781 $(FC) $(FFLAGS) -o $(OUT) $^ $(IEEEOBJ) $(GRAPHLIB)
783 $(FC) $(FFLAGS) -o $(OUT) $^ $(GRAPHLIB)
786 $(OBJ): $(SRC) $(HTOOLOBJ)
787 ifeq ($(COMPILE_NONINTRINSIC_IEEE),YES)
788 @$(MAKE) -f $(THIS_FILE) ieee_need
790 @$(MAKE) -f $(THIS_FILE) ieee_not_need
792 $(FC) $(FFLAGS) -c $^ $(GRAPHLIB)
794 #-------------------------------------------------------------------------------
797 # Produce tweaked include file for PRNG
798 $(AUTOGEN_HEADER_RAND): $(BASE_RANDOM.f90) $(THIS_FILE)
799 $(AUTOGEN_COMMENT_RANDOM)
800 $(AUTOGEN_CODE_RANDOM)
801 @echo Generated include: $(AUTOGEN_HEADER_RAND) for $(FC) using $(ECHO)
803 # Compile HEDTOOLS modules. Note that the extension (.o or .obj)
804 # is set via $(OBJEXT). .obj is used on Intel Fortran on Windows.
805 # Also note that generic pattern rules are used here, with the
806 # include files as additional prerequisites.
807 # NOTE: generic pattern with include as prerequisite is disabled
808 # here because it does not work for some reason from within
809 # Code:Blocks, even though works on raw terminal
810 # --- GENERIC UNUSED ---
811 ##%.$(OBJEXT) : %.f90 $(AUTOGEN_HEADER_RAND) $(AUTOGEN_HEADER_IEEE) $(THIS_FILE)
812 ## $(FC) $(FFLAGS) -c $<
813 # --- GENERIC UNUSED ---
814 # So far, use individual builds for each of the HEDTOOLS source files:
815 BASE_UTILS.$(OBJEXT): BASE_UTILS.f90
816 $(FC) $(FFLAGS) -c $<
817 BASE_CSV_IO.$(OBJEXT): BASE_CSV_IO.f90
818 $(FC) $(FFLAGS) -c $<
819 BASE_LOGGER.$(OBJEXT): BASE_LOGGER.f90
820 $(FC) $(FFLAGS) -c $<
821 BASE_RANDOM.$(OBJEXT): BASE_RANDOM.f90 $(THIS_FILE)
822 @$(MAKE) -f $(THIS_FILE) inc
823 $(FC) $(FFLAGS) -c $<
824 BASE_STRINGS.$(OBJEXT): BASE_STRINGS.f90
825 $(FC) $(FFLAGS) -c $<
827 #-------------------------------------------------------------------------------
828 # Build IEEE non-intrinsic modules for GNU Fortran if needed
830 # Generate IEEE include file
831 $(AUTOGEN_HEADER_IEEE): $(THIS_FILE)
832 ifeq ($(COMPILE_NONINTRINSIC_IEEE),YES)
833 $(AUTOGEN_NON_INTRINSIC)
834 @echo Generated include: $(AUTOGEN_HEADER_IEEE) for $(FC) v. $(GFORTVERSION) using $(ECHO)
837 @echo Generated include: $(AUTOGEN_HEADER_IEEE) for $(FC) using $(ECHO)
840 #-------------------------------------------------------------------------------
841 # Compile all IEEE non-intrinsic math modules if needed
843 ifeq ($(COMPILE_NONINTRINSIC_IEEE),YES)
844 @$(MAKE) -f $(THIS_FILE) ieee_need
846 @$(MAKE) -f $(THIS_FILE) ieee_not_need
849 # just issue note that we do not need IEEEs
851 @echo ------------------------------------------------------------------------
852 @echo We do not need non-intrinsic IEEE modules: $(FC), $(GREP) test $(IEEE_GREPPED_SRC)
853 @echo ------------------------------------------------------------------------
855 # build IEEEs assuming we do need them (GNU)
856 ieee_need: $(IEEEOBJ)
857 @echo ------------------------------------------------------------------------
858 @echo GNU Fortran version: $(GFORTVERSION). We NEED NON-INTRINSIC IEEE MODULES.
859 @echo ------------------------------------------------------------------------
861 # specific components of IEEE modules are below
862 precision_m.$(OBJEXT): precision_m.f90
863 $(FC) -c $(FFLAGS) $<
864 c_control.$(OBJEXT): c_control.c
865 $(CC) -c $(GC_FFLAGS) $<
866 IEEE_FEATURES.$(OBJEXT): IEEE_FEATURES.f90
867 $(FC) -c -fno-range-check $(FFLAGS) $<
868 IEEE_EXCEPTIONS.$(OBJEXT): IEEE_EXCEPTIONS.f90
869 $(FC) -c -fno-range-check $(FFLAGS) $<
870 IEEE_ARITHMETIC.$(OBJEXT): IEEE_ARITHMETIC.f90
871 $(FC) -c -fno-range-check $(FFLAGS) $<