forked from altMITgcm/MITgcm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
genmake2
executable file
·3611 lines (3224 loc) · 106 KB
/
genmake2
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
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#! /usr/bin/env bash
#
# $Header: /u/gcmpack/MITgcm/tools/genmake2,v 1.278 2016/01/15 22:08:17 jmc Exp $
# $Name: $
#
# Makefile generator for MITgcm UV codes
# created by cnh 03/98
# adapted by aja 06/98
# modified by aja 01/00
# rewritten in bash by eh3 08/03
# Explain usage
usage() {
cat <<EOF
Usage: "$0" [OPTIONS]
where [OPTIONS] can be:
-help | --help | -h | --h
Print this help message and exit.
-oad | --oad
Generate a Makefile for an OpenAD built
-nocat4ad | -dog4ad | -ncad | -dad
do not concatenate (cat) source code sent to TAF
resulting in compilation of multiple files
-adoptfile NAME | --adoptfile NAME | -adof NAME | --adof NAME
-adoptfile=NAME | --adoptfile=NAME | -adof=NAME | --adof=NAME
Use "NAME" as the adoptfile. By default, the file at
"tools/adjoint_options/adjoint_oad" (for OpenAD built) or
"tools/adjoint_options/adjoint_default" will be used.
-optfile NAME | --optfile NAME | -of NAME | --of NAME
-optfile=NAME | --optfile=NAME | -of=NAME | --of=NAME
Use "NAME" as the optfile. By default, an attempt will be
made to find an appropriate "standard" optfile in the
tools/build_options/ directory.
-pdepend NAME | --pdepend NAME
-pdepend=NAME | --pdepend=NAME
Get package dependency information from "NAME".
-pgroups NAME | --pgroups NAME
-pgroups=NAME | --pgroups=NAME
Get the package groups information from "NAME".
-bash NAME
Explicitly specify the Bourne or BASH shell to use
-make NAME | -m NAME
--make=NAME | -m=NAME
Use "NAME" for the MAKE program. The default is "make" but
many platforms, "gmake" is the preferred choice.
-makefile NAME | -mf NAME
--makefile=NAME | -mf=NAME
Call the makefile "NAME". The default is "Makefile".
-makedepend NAME | -md NAME
--makedepend=NAME | -md=NAME
Use "NAME" for the MAKEDEPEND program.
-rootdir NAME | --rootdir NAME | -rd NAME | --rd NAME
-rootdir=NAME | --rootdir=NAME | -rd=NAME | --rd=NAME
Specify the location of the MITgcm ROOTDIR as "NAME".
By default, genamke will try to find the location by
looking in parent directories (up to the 5th parent).
-mods NAME | --mods NAME | -mo NAME | --mo NAME
-mods=NAME | --mods=NAME | -mo=NAME | --mo=NAME
Here, "NAME" specifies a list of directories that are
used for additional source code. Files found in the
"mods list" are given preference over files of the same
name found elsewhere.
-disable NAME | --disable NAME
-disable=NAME | --disable=NAME
Here "NAME" specifies a list of packages that we don't
want to use. If this violates package dependencies,
genamke will exit with an error message.
-enable NAME | --enable NAME
-enable=NAME | --enable=NAME
Here "NAME" specifies a list of packages that we wish
to specifically enable. If this violates package
dependencies, genamke will exit with an error message.
-standarddirs NAME | --standarddirs NAME
-standarddirs=NAME | --standarddirs=NAME
Here, "NAME" specifies a list of directories to be
used as the "standard" code.
-fortran NAME | --fortran NAME | -fc NAME | --fc NAME
-fc=NAME | --fc=NAME
Use "NAME" as the fortran compiler. By default, genmake
will search for a working compiler by trying a list of
"usual suspects" such as g77, f77, etc.
-cc NAME | --cc NAME | -cc=NAME | --cc=NAME
Use "NAME" as the C compiler. By default, genmake
will search for a working compiler by trying a list of
"usual suspects" such as gcc, c89, cc, etc.
-use_real4 | -use_r4 | -ur4 | --use_real4 | --use_r4 | --ur4
Use "real*4" type for _RS variable (#undef REAL4_IS_SLOW)
*only* works if CPP_EEOPTIONS.h allows this.
-ignoretime | -ignore_time | --ignoretime | --ignore_time
Ignore all the "wall clock" routines entirely. This will
not in any way hurt the model results -- it simply means
that the code that checks how long the model spends in
various routines will give junk values.
-ts | --ts
Produce timing information per timestep
-papis | --papis
Produce summary MFlop/s (and IPC) with PAPI per timestep
-pcls | --pcls
Produce summary MFlop/s etc. with PCL per timestep
-foolad | --foolad
Fool the AD code generator
-papi | --papi
Performance analysis with PAPI
-pcl | --pcl
Performance analysis with PCL
-hpmt | --hpmt
Performance analysis with the HPM Toolkit
-ieee | --ieee
use IEEE numerics. Note that this option *only* works
if it is supported by the OPTFILE that is being used.
-devel | --devel
Add additional warning and debugging flags for development
(if supported by the OPTFILE); also switch to IEEE numerics.
-gsl | --gsl
Use GSL to control floating point rounding and precision
-mpi | --mpi
Include MPI header files and link to MPI libraries
-mpi=PATH | --mpi=PATH
Include MPI header files and link to MPI libraries using MPI_ROOT
set to PATH. i.e. Include files from \$PATH/include, link to libraries
from \$PATH/lib and use binaries from \$PATH/bin.
-omp | --omp
Activate OpenMP code + use Compiler option OMPFLAG
-omp=OMPFLAG | --omp=OMPFLAG
Activate OpenMP code + use Compiler option OMPFLAG
-es | --es | -embed-source | --embed-source
Embed a tarball containing the full source code
(including the Makefile, etc.) used to build the
executable [off by default]
-ds | --ds
Report genmake internal variables status (DUMPSTATE)
to file "genmake_state" (for debug purpose)
While it is most often a single word, the "NAME" variables specified
above can in many cases be a space-delimited string such as:
--enable pkg1 --enable 'pkg1 pkg2' --enable 'pkg1 pkg2 pkg3'
-mods=dir1 -mods='dir1' -mods='dir1 dir2 dir3'
-foptim='-Mvect=cachesize:512000,transform -xtypemap=real:64,double:64,integer:32'
which, depending upon your shell, may need to be single-quoted.
For more detailed genmake documentation, please see:
http://mitgcm.org/public/devel_HOWTO/
EOF
exit 1
}
# Search for particular CPP #cmds associated with packages
# usage: test_for_package_in_cpp_options CPP_file package_name
test_for_package_in_cpp_options() {
cpp_options=$1
pkg=$2
test_for_string_in_file $cpp_options "^ *# *define *\<ALLOW_$pkg\>"
test_for_string_in_file $cpp_options "^ *# *undef *\<ALLOW_$pkg\>"
test_for_string_in_file $cpp_options "^ *# *define *\<DISABLE_$pkg\>"
test_for_string_in_file $cpp_options "^ *# *undef *\<DISABLE_$pkg\>"
}
# Search for particular CPP #cmds associated with MPI
# usage: test_for_mpi_in_cpp_eeoptions CPP_file
test_for_mpi_in_cpp_eeoptions() {
cpp_options=$1
test_for_string_in_file $cpp_options "^ *# *define *\<ALLOW_USE_MPI\>"
test_for_string_in_file $cpp_options "^ *# *undef *\<ALLOW_USE_MPI\>"
}
# Search for particular string in a file. Return 1 if detected, 0 if not
# usage: test_for_string_in_file file string
test_for_string_in_file() {
file=$1
strng=$2
grep "$strng" $file > /dev/null 2>&1
RETVAL=$?
if test "x${RETVAL}" = x0 ; then
printf "Error: In $file there is an illegal line: "
grep -i "$strng" $file
exit 99
fi
return 0
}
# Read the $ROOTDIR/pkg/pkg_groups file and expand any references to
# the package list.
expand_pkg_groups() {
new_packages=
if test -r $PKG_GROUPS ; then
cat $PKG_GROUPS | sed -e 's/#.*$//g' | sed -e 's/:/ : /g' > $TMP.p1
cat $TMP.p1 | $AWK '(NF>2 && $2==":"){ print $0 }' > $TMP.p2
matched=0
for i in $PACKAGES ; do
line=`grep "^ *$i" $TMP.p2`
RETVAL=$?
if test "x$RETVAL" = x0 ; then
matched=1
replace=`echo $line | $AWK '{ $1=""; $2=""; print $0 }'`
echo " replacing \"$i\" with:$replace"
new_packages="$new_packages $replace"
else
new_packages="$new_packages $i"
fi
done
PACKAGES=$new_packages
rm -f $TMP.p[1,2]
return $matched
else
echo "Warning: can't read package groups definition file: $PKG_GROUPS"
fi
}
# Check for broken environments (eg. cygwin, MacOSX w/HFS+) that
# cannot distinguish [*.F/*.F90] from [*.f/*.f90] files.
check_for_broken_Ff() {
# Do we have defaults for $FS and/or $FS90 ?
tfs=f
tfs9=f90
if test "x$FS" != x ; then
tfs="$FS"
fi
if test "x$FS90" != x ; then
tfs9="$FS90"
fi
# First check the ability to create a *.F/.f pair.
cat <<EOF >> genmake_hello.F
program hello
write(*,*) 'hi'
stop
end
EOF
cp genmake_hello.F "genmake_hello."$tfs > /dev/null 2>&1
RETVAL=$?
if test "x$RETVAL" != x0 ; then
if test "x$FS" = x ; then
FS='for'
FS90='fr9'
check_for_broken_Ff
else
cat <<EOF 2>&1
ERROR: Your file system cannot distinguish between *.F and *.f files
(fails the "cp" test) and this program cannot find a suitable
replacement extension. Please try a different build environment or
contact the <MITgcm-support@mitgcm.org> list for help.
EOF
exit -1
fi
return
fi
rm -f genmake_hello.*
# Check the ability of ${MAKE} and ${LN} to use the current set
# of extensions.
cat <<EOF >> genmake_hello.F
program hello
write(*,*) 'hi'
stop
end
EOF
test -f $MAKEFILE && mv -f $MAKEFILE $MAKEFILE".tst"
cat <<EOF >> $MAKEFILE
.SUFFIXES:
.SUFFIXES: .$tfs .F
.F.$tfs:
$LN \$< \$@
EOF
$MAKE -f $MAKEFILE "genmake_hello."$tfs > /dev/null 2>&1
RETVAL=$?
if test "x$RETVAL" != x0 -o ! -f "genmake_hello."$tfs ; then
if test "x$FS" = x ; then
FS='for'
FS90='fr9'
check_for_broken_Ff
else
echo "ERROR: test: '$MAKE -f $MAKEFILE genmake_hello.$tfs' Failed"
echo " see simple makefile: '$MAKEFILE' (left here)"
echo " Please check (1) your '$MAKE' command, (2) your '$LN' command"
echo " and (3) the allowed sufix '.F' and '.$tfs' in makefile"
echo " or contact the <MITgcm-support@mitgcm.org> list for help."
echo ""
exit -1
return
fi
fi
rm -f genmake_hello.* $MAKEFILE
test -f $MAKEFILE".tst" && mv -f $MAKEFILE".tst" $MAKEFILE
# If we make it here, use the extensions
FS=$tfs
FS90=$tfs9
return
}
look_for_makedepend() {
# The "original" makedepend is part of the Imake system that is
# most often distributed with XFree86 or with an XFree86 source
# package. As a result, many machines (eg. generic Linux) do not
# have a system-default "makedepend" available. For those
# systems, we have two fall-back options:
#
# 1) a makedepend implementation shipped with the cyrus-imapd
# package: ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
# 2) a local tools/xmakedepend shell script
#
# So the choices are, in order:
# 1) use the user-specified program
# 2) use the local xmakedepend script (get all dependencies, but slower)
# 3) use a system-wide default
# 4) locally build and use the cyrus makedepend
# (faster, but can miss some dependencies)
#
echo >> $LOGFILE
echo "running: look_for_makedepend()" >> $LOGFILE
if test "x${MAKEDEPEND}" != x ; then
echo "${MAKEDEPEND}" | grep -i cyrus > /dev/null 2>&1
RETVAL=$?
if test x"$RETVAL" = x0 ; then
build_cyrus_makedepend
RETVAL=$?
if test "x$RETVAL" != x0 ; then
echo "WARNING: unable to build cyrus-makedepend. Try other 'makedepend'"
MAKEDEPEND=
fi
else
echo "${MAKEDEPEND}" | grep 'tools.xmakedepend' > /dev/null 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
MAKEDEPEND='$(TOOLSDIR)/xmakedepend'
fi
echo " --> MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
fi
fi
if test "x${MAKEDEPEND}" = x ; then
test -f $MAKEFILE && mv -f $MAKEFILE $MAKEFILE".tst"
# echo 'MAKEFILE="'$MAKEFILE'"'
cat <<EOF >> $MAKEFILE
# THIS IS A TEST MAKEFILE GENERATED BY "genmake2"
#
# Some "makedepend" implementations will die if they cannot
# find a Makefile -- so this file is here to gives them an
# empty one to find and parse.
EOF
cat <<EOF >> genmake_tc.f
program test
write(*,*) 'test'
stop
end
EOF
$ROOTDIR/tools/xmakedepend -f $MAKEFILE genmake_tc.f > /dev/null 2>&1
RV1=$?
which makedepend > /dev/null 2>&1
RV2=$?
if test "x${RV2}" = x0 ; then
makedepend -f $MAKEFILE genmake_tc.f > /dev/null 2>&1
RV3=$? ; loc_msg='not working.'
else RV3=$RV2 ; loc_msg='not found.'
fi
test -f $MAKEFILE && rm -f $MAKEFILE
test -f $MAKEFILE".tst" && mv -f $MAKEFILE".tst" $MAKEFILE
echo " check makedepend (local: $RV1, system: $RV2, $RV3)"
if test "x${RV1}" = x0 ; then
MAKEDEPEND='$(TOOLSDIR)/xmakedepend'
echo " --> set MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
elif test "x${RV3}" = x0 ; then
echo " local tools/xmakedepend not working. Use system-default makedepend"
MAKEDEPEND=makedepend
echo " --> set MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
else
echo " local tools/xmakedepend not working; system-default makedepend $loc_msg"
echo -n " Try to build cyrus-makedepend ..."
# Try to build the cyrus implementation
build_cyrus_makedepend
RETVAL=$?
if test "x$RETVAL" = x0 ; then
echo " Works"
else
echo " Fails" ; echo "" >> $LOGFILE
echo "ERROR: no working makedepend found ; look_for_makedepend FAILED" | tee -a $LOGFILE
echo ""
exit -1
return
fi
fi
fi
}
build_cyrus_makedepend() {
echo >> $LOGFILE
echo "running: build_cyrus_makedepend()" >> $LOGFILE
rm -f ./genmake_cy_md
(
cd $ROOTDIR/tools/cyrus-imapd-makedepend \
&& ./configure > /dev/null 2>&1 \
&& $MAKE > /dev/null 2>&1
if test -x ./makedepend.exe ; then
$LN ./makedepend.exe ./makedepend
fi
./makedepend ifparser.c > /dev/null 2>&1 \
&& echo "true"
) > ./genmake_cy_md
grep true ./genmake_cy_md > /dev/null 2>&1
RETVAL=$?
rm -f ./genmake_cy_md
if test "x$RETVAL" = x0 ; then
MAKEDEPEND='$(TOOLSDIR)/cyrus-imapd-makedepend/makedepend'
echo " --> set MAKEDEPEND=${MAKEDEPEND}" >> $LOGFILE
return 0
else
echo "WARNING: fail to build cyrus-imapd-makedepend" >> $LOGFILE
return 1
fi
}
build_embed_encode()
{
printf " building the embed-encode utility... "
if test ! -e "$ROOTDIR/tools/embed_encode/encode_files" ; then
if test ! -d "$ROOTDIR/tools/embed_encode" ; then
echo
echo " Error: can't locate \"$ROOTDIR/tools/embed_encode\""
echo
EMBED_SRC=f
return 1
fi
clist="cc gcc c89 $CC"
for ic in $clist ; do
comm="$ic -o encode_files encode_files.c"
( cd $ROOTDIR/tools/embed_encode && $comm ) > /dev/null 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
echo "OK"
return 0
fi
done
echo
echo " Error: unable to build $ROOTDIR/embed_encode/encode_files"
echo " so it has been disabled"
echo
EMBED_SRC=f
return 1
fi
echo "OK"
}
# look for possible C compilers
look_for_C_compilers() {
echo >> $LOGFILE
echo "running: look_for_C_compilers()" >> $LOGFILE
rm -f ./genmake_hello.c ./genmake_hello
cat >> genmake_hello.c << EOF
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello!\n");
return 0;
}
EOF
tmp="$MITGCM_CC $CC gcc c89 cc c99 mpicc icc"
p_CC=
for c in $tmp ; do
COMM="$c $CFLAGS -o genmake_hello genmake_hello.c"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RETVAL=$?
if test "x${RETVAL}" = x0 ; then
echo " $c test successful" >> $LOGFILE
p_CC="$p_CC $c"
fi
done
rm -f ./genmake_hello.c ./genmake_hello
if test "x${p_CC}" = x ; then
cat 1>&2 <<EOF
Error: No C compilers were found in your path. Please specify one using:
1) an "optfile" on (eg. "-optfile=path/to/OPTFILE"),
2) the CC or MITGCM_CC environment variables.
EOF
exit 1
else
echo " The possible C compilers found in your path are: $p_CC" | tee -a $LOGFILE
if test "x$CC" = x ; then
CC=`echo $p_CC | $AWK '{print $1}'`
echo " Setting C compiler to: "$CC
fi
fi
echo " --> set CC='$CC'" >> $LOGFILE
}
# Guess possible config options for this host
find_possible_optfile() {
echo >> $LOGFILE
echo "running: find_possible_optfile()" >> $LOGFILE
tmp1=`uname`"_"`uname -m`
tmp2=`echo $tmp1 | sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
tmp3=`echo $tmp2 | sed -e 's/power macintosh/ppc/'`
tmp1=`echo $tmp3 | sed -e 's|x86_64|amd64|'`
tmp2=`echo $tmp1 | sed -e 's/i[3-6]86/ia32/' | sed -e 's/athlon/ia32/'`
tmp3=`echo $tmp2 | sed -e 's/cray sv1/craysv1/'`
PLATFORM=$tmp3
echo $PLATFORM | grep cygwin > /dev/null 2>&1 && PLATFORM=cygwin_ia32
OFLIST=`(cd $ROOTDIR/tools/build_options; ls | grep "^$PLATFORM")`
echo " The platform appears to be: $PLATFORM" | tee -a $LOGFILE
#================================================================
# look for possible FORTRAN compilers
echo " look for possible FORTRAN compilers" >> $LOGFILE
tmp="$MITGCM_FC $FC efc gfortran g77 f77 pgf77 pgf95 ifc ifort f90 f95 mpif77 mpf77 mpxlf95 g95"
p_FC=
rm -f ./genmake_hello.f
cat >> genmake_hello.f <<EOF
program hello
do i=1,3
print *, 'hello world : ', i
enddo
end
EOF
for f in $tmp ; do
COMM="$f -o genmake_hello genmake_hello.f"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RETVAL=$?
if test "x${RETVAL}" = x0 ; then
echo " $f test successful" >> $LOGFILE
p_FC="$p_FC $f"
fi
done
rm -f ./genmake_hello.f ./genmake_hello
if test "x${p_FC}" = x ; then
cat 1>&2 <<EOF
Error: No Fortran compilers were found in your path. Please specify one using:
1) an "optfile" on (eg. "-optfile=path/to/OPTFILE"),
2) a command-line option (eg. "-fc NAME"), or
3) the FC or MITGCM_FC environment variables.
EOF
exit 1
else
echo " The possible FORTRAN compilers found in your path are: $p_FC" | tee -a $LOGFILE
fi
# Use the first of the compilers found in the current PATH
# that has a correctly-named optfile
if test "x$OPTFILE" = x -a "x$FC" = x ; then
for i in $p_FC ; do
OPTFILE=$ROOTDIR"/tools/build_options/"$PLATFORM"_"$i
if test -r $OPTFILE ; then
echo " Setting OPTFILE to: "$OPTFILE | tee -a $LOGFILE
break
fi
done
fi
if test "x$OPTFILE" = x ; then
OPTFILE=$ROOTDIR"/tools/build_options/"$PLATFORM"_"$FC
if test ! -r $OPTFILE ; then
echo " I looked for the file "$OPTFILE" but did not find it"
fi
fi
if test "x$OPTFILE" = x ; then
cat 1>&2 <<EOF
Error: No options file was found in: $ROOTDIR/tools/build_options/
that matches this platform ("$PLATFORM") and the compilers found in
your path. Please specify an "optfile" using:
1) the command line (eg. "-optfile=path/to/OPTFILE"), or
2) the MITGCM_OF environment variable.
If you need help, please contact the developers at <MITgcm-support@mitgcm.org>.
EOF
exit 1
fi
}
# Do a local copy of MPI headers files (in local dir ./mpi_headers/) after
# checking for additional included headers (in case of chain of included header)
mpi_headers_do_local_copy() {
dBug=0
rm -rf ./mpi_headers
if test -d $MPIINCLUDEDIR ; then
#----- check for additional headers (chain of included headers)
echo -n ' Check MPI headers ... '
listIni=$MPI_HEADER_FILES
echo $listIni | grep "\<mpif.h\>" > /dev/null 2>&1
outp=$?
#- always check mpif.h (the only mpi-header included in standard MITgcm code)
if test $outp != 0 ; then listIni="mpif.h $listIni" ; fi
if test $dBug = 1 ; then echo "listIni='$listIni'" ; fi
doCheck=1 ; list2copy='' ; list2check=$listIni
while test $doCheck = 1 ; do
newList=''
for i in $list2check ; do
if test -f $MPIINCLUDEDIR/$i ; then
newInc=`grep '^ *include ' $MPIINCLUDEDIR/$i | \
sed -e 's/^ *include //' -e 's/\!.*$//' -e "s/'//g" -e 's/\"//g'`
if test $dBug = 1 ; then echo -n "checking $i : newInc='$newInc'" ; fi
for j in $newInc ; do
echo $listIni $list2copy $newList | grep "\<$j\>" > /dev/null 2>&1
outp=$?
if test $outp != 0 ; then
if test $dBug = 1 ; then echo -n " ; adding $j" ; fi
newList="$newList $j"
fi
done
if test $dBug = 1 ; then echo "" ; fi
fi
done
if test "x$newList" = x ; then doCheck=0
else list2check=$newList ; list2copy="$list2copy $newList"
fi
done
list2copy="$MPI_HEADER_FILES $list2copy"
if test $dBug = 1 ; then echo "list2copy='$list2copy'" ; fi
#----- create local mpi_headers dir if we have files to copy
mkListInc=`echo $list2copy | wc -w`
if test $mkListInc != 0 ; then
echo 'create local "./mpi_headers" dir'
mkdir -p ./mpi_headers
INCLUDES="-I./mpi_headers $INCLUDES"
mkListInc=1
fi
if test "x$LOCAL_MPI_HEADERS" != x ; then mkListInc=0 ; fi
#----- make local copy and update LOCAL_MPI_HEADERS (if not already set)
for i in $list2copy ; do
if test -f $MPIINCLUDEDIR/$i ; then
cp -p $MPIINCLUDEDIR/$i ./mpi_headers
if test $i = 'mpif.h' ; then
perl -i -pe 's/MPI_DISPLACEMENT_CURRENT=-1_8/MPI_DISPLACEMENT_CURRENT=-1/g' mpi_headers/mpif.h
fi
if test $mkListInc = 2 ; then
LOCAL_MPI_HEADERS="$LOCAL_MPI_HEADERS ./mpi_headers/$i"
fi
if test $mkListInc = 1 ; then
LOCAL_MPI_HEADERS="./mpi_headers/$i" ; mkListInc=2
fi
fi
done
else
echo "WARNING: MPIINCLUDEDIR='$MPIINCLUDEDIR' is not a directory"
echo "WARNING: => skip checking for MPI headers (no ./mpi_headers dir)"
# exit -1
fi
}
# Parse the package dependency information
get_pdepend_list() {
# strip the comments and then convert the dependency file into
# two arrays: PNAME, DNAME
cat $1 | sed -e 's/#.*$//g' \
| $AWK 'BEGIN{nn=-1;} (NF>0){ for(i=2;i<=NF;i++){nn++; print "PNAME_"nn"="$1"\nDNAME_"nn"="$i}} END{print "nname="nn}' \
> ./.pd_tmp
RETVAL=$?
if test ! "x${RETVAL}" = x0 ; then
echo "Error: unable to parse package dependencies -- please check PKG_DEPEND=\"$1\""
exit 1
fi
. ./.pd_tmp
rm -f ./.pd_tmp
}
# Build a CPP macro to automate calling C routines from FORTRAN
get_fortran_c_namemangling() {
#echo "FC_NAMEMANGLE = \"$FC_NAMEMANGLE\""
if test ! "x$FC_NAMEMANGLE" = x ; then
return 0
fi
echo " running: get_fortran_c_namemangling()" >> $LOGFILE
default_nm="#define FC_NAMEMANGLE(X) X ## _"
cat > genmake_test.c <<EOF
void tcall( char * string ) { tsub( string ); }
EOF
COMM="$CC $CFLAGS -c genmake_test.c"
echo ' '$COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RETVAL=$?
if test "x$RETVAL" != x0 ; then
FC_NAMEMANGLE=$default_nm
cat <<EOF>> $LOGFILE
WARNING: C test compile fails
WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here
EOF
return 1
fi
c_tcall=`nm genmake_test.o 2>/dev/null | grep 'T ' | grep tcall | cut -d ' ' -f 3`
RETVAL=$?
if test "x$RETVAL" != x0 ; then
FC_NAMEMANGLE=$default_nm
cat <<EOF>> $LOGFILE
WARNING: The "nm" command failed.
WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here
EOF
return 1
fi
cat > genmake_tcomp.$FS <<EOF
subroutine tcall( string )
character*(*) string
call tsub( string )
end
EOF
COMM="$FC $FFLAGS -c genmake_tcomp.$FS"
echo ' '$COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RETVAL=$?
if test "x$RETVAL" != x0 ; then
FC_NAMEMANGLE=$default_nm
cat <<EOF>> $LOGFILE
WARNING: FORTRAN test compile fails -- please see '$LOGFILE'
WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here.
EOF
return 1
fi
f_tcall=`nm genmake_tcomp.o 2>/dev/null | grep 'T ' | grep tcall | cut -d ' ' -f 3`
RETVAL=$?
if test "x$RETVAL" != x0 ; then
FC_NAMEMANGLE=$default_nm
cat <<EOF>> $LOGFILE
WARNING: The "nm" command failed.
WARNING: We'll try to use: FC_NAMEMANGLE='$FC_NAMEMANGLE'
WARNING: Please contact <MITgcm-support@mitgcm.org> if you need help here.
EOF
return 1
fi
c_a=`echo $c_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 1 | sed -e 's|Y||'`
f_a=`echo $f_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 1 | sed -e 's|Y||'`
c_b=`echo $c_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 2 | sed -e 's|Y||'`
f_b=`echo $f_tcall | sed -e 's|tcall|Y Y|' | cut -d ' ' -f 2 | sed -e 's|Y||'`
nmangle="X"
if test "x$c_a" != "x$f_a" ; then
comm="echo x$f_a | sed -e 's|x$c_a||'"
a=`eval $comm`
nmangle="$a ## $nmangle"
fi
if test "x$c_b" != "x$f_b" ; then
comm="echo x$f_b | sed -e 's|x$c_b||'"
b=`eval $comm`
nmangle="$nmangle ## $b"
fi
FC_NAMEMANGLE="#define FC_NAMEMANGLE(X) $nmangle"
# cleanup the testing files
rm -f genmake_tcomp.* genmake_test.*
echo " --> set FC_NAMEMANGLE='$FC_NAMEMANGLE'" >> $LOGFILE
}
check_HAVE_CLOC() {
echo >> $LOGFILE
echo "running: check_HAVE_CLOC()" >> $LOGFILE
get_fortran_c_namemangling
cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/time.h>
void FC_NAMEMANGLE(cloc) ( double *curtim )
{
struct timeval tv1;
gettimeofday(&tv1 , (void *)NULL );
*curtim = (double)((tv1.tv_usec)+(tv1.tv_sec)*1.E6);
*curtim = *curtim/1.E6;
}
EOF
COMM="$CC $CFLAGS -c genmake_tc_1.c"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RET_C=$?
cat <<EOF > genmake_tc_2.$FS
program hello
REAL*8 wtime
external cloc
call cloc(wtime)
print *," HELLO WORLD", wtime
end
EOF
COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RET_F=$?
test -x ./genmake_tc && ./genmake_tc >> $LOGFILE 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
HAVE_CLOC=t
fi
rm -f genmake_tc*
echo " --> set HAVE_CLOC='$HAVE_CLOC'" >> $LOGFILE
}
check_HAVE_SIGREG() {
if test ! "x$HAVE_SIGREG" = x ; then
return
fi
echo >> $LOGFILE
echo "running: check_HAVE_SIGREG()" >> $LOGFILE
get_fortran_c_namemangling
cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <ucontext.h>
int * ip;
static void killhandler(
unsigned int sn, siginfo_t si, struct ucontext *sc )
{
*ip = *ip + 1;
return;
}
void FC_NAMEMANGLE(sigreg) (int * aip)
{
struct sigaction s;
ip = aip;
s.sa_flags = SA_SIGINFO;
s.sa_sigaction = (void *)killhandler;
if(sigaction (SIGTERM,&s,(struct sigaction *)NULL)) {
printf("Sigaction returned error = %d\n", errno);
exit(0);
}
return;
}
EOF
COMM="$CC $CFLAGS -c genmake_tc_1.c"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RET_C=$?
cat <<EOF > genmake_tc_2.$FS
program hello
integer anint
common /iv/ anint
external sigreg
call sigreg(anint)
end
EOF
cat genmake_tc_2.$FS >> $LOGFILE
COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
HAVE_SIGREG=t
fi
rm -f genmake_tc*
echo " --> set HAVE_SIGREG='$HAVE_SIGREG'" >> $LOGFILE
}
check_HAVE_SETRLSTK() {
if test ! "x$HAVE_SETRLSTK" = x ; then
return
fi
echo >> $LOGFILE
echo "running: check_HAVE_SETRLSTK()" >> $LOGFILE
get_fortran_c_namemangling
cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
void FC_NAMEMANGLE(setrlstk) ()
{
struct rlimit rls;
rls.rlim_cur = RLIM_INFINITY;
rls.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_STACK, &rls);
return;
}
EOF
COMM="$CC $CFLAGS -c genmake_tc_1.c"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RET_C=$?
cat <<EOF > genmake_tc_2.$FS
program hello
external setrlstk
call setrlstk()
end
EOF
cat genmake_tc_2.$FS >> $LOGFILE
COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
echo $COMM >> $LOGFILE
$COMM >> $LOGFILE 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
HAVE_SETRLSTK=t
fi
rm -f genmake_tc*
echo " --> set HAVE_SETRLSTK='$HAVE_SETRLSTK'" >> $LOGFILE
}
check_HAVE_STAT() {
echo >> $LOGFILE
echo "running: check_HAVE_STAT()" >> $LOGFILE
get_fortran_c_namemangling
cat <<EOF > genmake_tc_1.c
$FC_NAMEMANGLE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
void FC_NAMEMANGLE(tfsize) ( int *nbyte )
{
char name[512];
struct stat astat;
name[0] = 'a'; name[1] = '\0';
if (! stat(name, &astat))
*nbyte = (int)(astat.st_size);
else
*nbyte = -1;
}
EOF
COMM="$CC $CFLAGS -c genmake_tc_1.c"
echo $COMM >> $LOGFILE
$COMM >> genmake_tc.log 2>&1
RET_C=$?
cat <<EOF > genmake_tc_2.$FS
program hello
integer nbyte
call tfsize(nbyte)
print *," HELLO WORLD", nbyte
end
EOF
cat genmake_tc_2.$FS >> $LOGFILE
COMM="$FC $FFLAGS -o genmake_tc genmake_tc_2.$FS genmake_tc_1.o"
echo $COMM >> $LOGFILE
$COMM >> genmake_tc.log 2>&1
RETVAL=$?
if test "x$RETVAL" = x0 ; then
HAVE_STAT=t
fi
rm -f genmake_tc*
echo " --> set HAVE_STAT='$HAVE_STAT'" >> $LOGFILE
}
check_netcdf_libs() {
if test ! "x$SKIP_NETCDF_CHECK" = x ; then
return
fi
echo >> $LOGFILE