/[MITgcm]/MITgcm_contrib/PRM/multi_comp_setup/multi_code/fmkmf.pl
ViewVC logotype

Contents of /MITgcm_contrib/PRM/multi_comp_setup/multi_code/fmkmf.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1.1.1 - (show annotations) (download) (vendor branch)
Tue Oct 10 18:17:27 2006 UTC (18 years, 9 months ago) by cnh
Branch: Initial, MAIN
CVS Tags: checkpoint63m, checkpoint63n, baseline, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/plain
Initial test

1 #!/usr/bin/perl -w
2 # Copyright (c) The University of Edinburgh
3 # This is a utility to generate make files
4 # for Fortran 90. It was originally in shell script and was re-written
5 # in perl for greater speed and (hopefully) portability.
6 # Initial tests suggest speed is 10x better than the sh version.
7
8 # A basic makefile entry for bork.f90 would be
9 # bork.o:bork.f90
10 # <-tab->$(F90) -c bork.f90
11 #
12 # however if bork.f90 contains the line "use gunge" then
13 # (A)
14 # the entry has to be
15 # bork.o:bork.f90 garple.o <-- Forces bork to be recompiled if a module it
16 # <-tab->$(F90) -c bork.f90 uses is changed
17 # where garple.f90 is the program containing the line "module gunge
18 # (B)
19 # The same type of entry has to be done for garple.f90
20 #
21 # We also need to generate an entry for the link step. If the main program
22 # was in baz.f90 then this should be
23 # baz:baz.o bork.o.........
24 # <-tab->$(F90) -o baz baz.o bork.o .....
25 # The list of object files to be linked should have foo.o in it once
26 # and only once for each foo.f90 that was compiled
27
28 #-------------------------------------------------
29 # First check if the luser has any relevent environment vars set
30 #--------------------------------------------
31 if ( $ENV{FMKMF_F90} ) {
32 print "\# FMKMF_F90 set to $ENV{FMKMF_F90}\n";
33 $f90=$ENV{FMKMF_F90};
34 }
35 else {
36 print "\# FMKMF_F90 not set: using f90\n";
37 $f90="f90";
38 }
39
40
41 if ( $ENV{FMKMF_SFTAG} ) {
42 print "\# FMKMF_SFTAG set to $ENV{FMKMF_SFTAG}\n";
43 $sftag=$ENV{FMKMF_SFTAG};
44 }
45 else {
46 print "\# FMKMF_SFTAG not set: using f90\n";
47 $sftag="f90";
48 }
49
50 if ( $ENV{FMKMF_SPATH} ) {
51 print "\# FMKMF_SPATH set to $ENV{FMKMF_SPATH}\n";
52 $spath=$ENV{FMKMF_SPATH};
53 }
54 else {
55 print "\# FMKMF_SPATH not set: using . \n";
56 $spath=".";
57 }
58
59 if ( $ENV{FMKMF_LINKOPTS} ) {
60 print "\# FMKMF_LINKOPTS set to $ENV{FMKMF_LINKOPTS}\n";
61 $linkopts=$ENV{FMKMF_LINKOPTS};
62 }
63 else {
64 print "\# FMKMF_LINKOPTS not set: using no link options \n";
65 $linkopts=" ";
66 }
67
68 #------------------------------
69 # Done with environment variables. Now we need to process commandline args
70 # These supersede anything supplied via environment variables.
71 #------------------------------
72
73
74 while (@ARGV){
75
76 $arg=shift;
77 if ($arg =~ /^-p$/){
78 $spath=shift;
79 print "# Using search path $spath from cmd line\n";
80 }
81 if ($arg =~ /^-f90$/){
82 $f90=shift;
83 print "# Using compile cmd $f90 from cmd line\n";
84 }
85 if ($arg =~ /^-tag$/){
86 $sftag=shift;
87 print "# Using source file tag $sftag from cmd line\n";
88 }
89 if ($arg =~ /^-l$/){
90 $linkopts=shift;
91 print "# Using Link options $linkopts from cmd line\n";
92 }
93
94 }
95
96
97 #-------------------------------------------
98 # Done processing command line args
99 #-------------------------------------------
100
101
102 @spath=split(/:/,$spath);
103
104
105 @global_outlines=();
106 @global_objlist=();
107 @global_modfiles=();
108
109 $mainprogfile=$arg;
110
111 print "# Main program is $mainprogfile \n" ;
112
113
114
115 # this subroutine (def below) does most of the work.
116 process_fsource($mainprogfile);
117
118 # set some makefile .
119
120 print "\n# ------------------Macro-Defs---------------------\n";
121
122 print "F90=$f90 \n";
123
124 print "\n# -------------------End-macro-Defs---------------------------\n";
125
126 # Generate a name for the executable file
127 $execfile=$mainprogfile;
128 $execfile=~s/\.${sftag}//;
129 $execfile=~s|.*/||;
130
131 # Generate makefile entry for the Link step
132 print "\n# Here is the link step \n";
133
134 print "$execfile:@global_objlist \n";
135 print "\t \$(F90) -o $execfile @global_objlist $linkopts \n";
136
137 print "\n# Here are the compile steps\n ";
138 print STDOUT @global_outlines;
139
140 # Add an entry for make clean at the end of the make file. this
141 # removes most of the gubbage left around by most of the Unix Fortran
142 # 90 compilers I have tried.
143
144 print "# This entry allows you to type \" make clean \" to get rid of\n";
145 print "# all object and module files \n";
146
147 print "clean:\n";
148 print "\trm -f -r f_{files,modd}* *.o *.mod *.M *.d V*.inc *.vo \\\n";
149 print "\tV*.f *.dbg album F.err";
150 print "\n \n";
151
152 # End of main program
153
154 ##############################################
155 # Here is the subroutine that generates the compile entries in the makefile
156 # These end up in the global array @global_outlines. The magic part is
157 # that this subroutine calls itself recursively.
158 ##############################################
159 sub process_fsource {
160
161 my $mainprogfile=$_[0];
162 print"# process_fsource called with arg $mainprogfile \n";
163 open( MAINPROG, $mainprogfile) or
164 die "Can't find main program file $mainprogfile: $! \n";
165
166 # Read through Fortran source looking for USE statements
167 # There should be nothing but whitespace before the USE. Sloppily,
168 # we allow tabs, although the standard (IIRC) does not
169 my @modulelist=();
170 while ($line=<MAINPROG>) {
171 if ($line =~ /^[ \t]*use (\w+)/i ) { # line matches regexp between / /
172 print "# $mainprogfile Uses Module $1\n";
173 @modulelist=(@modulelist,$1);
174 }
175 }
176
177 close(MAINPROG);
178
179 #print "# Full list of modules in $mainprogfile: @modulelist \n";
180
181 print "# Full list of modules in $mainprogfile: @modulelist \n";
182 # Find which file each module is in.
183
184
185
186 my @modfiles=();
187 MODLOOP:foreach $module (@modulelist){
188 foreach $directory (@spath){
189 # print "# Looking in directory $directory\n";
190 opendir( DIRHANDLE, $directory) or die
191 "Can't open directory $directory : $! \n";
192 @sourcefiles=grep /\.${sftag}\Z/, sort(readdir(DIRHANDLE));
193 foreach $sourcefile (@sourcefiles){
194 $pathsourcefile="$directory/$sourcefile";
195 #print "\# Checking $pathsourcefile\n";
196 open( SOURCEFILE, "$pathsourcefile") or
197 die "Can't find source file $pathsourcefile: $! \n";
198 while ($line=<SOURCEFILE>){
199 if ($line =~ /^ *module (\w+)/i ){
200 if($1 =~ /^$module$/i){
201 print "# Uses $module which is in $pathsourcefile\n";
202 @modfiles=(@modfiles,$pathsourcefile);
203
204 if (grep (/$pathsourcefile/,@global_modfiles )){
205 print "# $pathsourcefile already in list\n";
206 }
207 else {
208 @global_modfiles=(@global_modfiles,$pathsourcefile);
209 process_fsource($pathsourcefile);
210
211 }
212 # We found this module -- go on to the next one
213 close (SOURCEFILE);
214 next MODLOOP;
215 }
216 }
217 }
218 close( SOURCEFILE );
219 }
220 }
221 # exhausted source files
222 print STDERR "Couldn't find source file for module $module\n";
223 }
224
225 # name of file we want to make
226 $objfile=$mainprogfile;
227 # replace source file name with .o
228 $objfile=~s/\.${sftag}/\.o/;
229 # strip path so object files go in current dir
230 $objfile=~s|.*/||;
231 @global_objlist=(@global_objlist,$objfile);
232 # list of dependencies
233 @objlist=();
234 foreach $mf (@modfiles) {
235 $obj=$mf;
236 # replace source file name with .o
237 $obj=~s/\.${sftag}/\.o/;
238 # strip path so object files go in current dir
239 $obj=~s|.*/||;
240 @objlist=(@objlist,$obj);
241 }
242
243 @global_outlines=(@global_outlines,"\n$objfile:$mainprogfile @objlist \n");
244 @global_outlines=(@global_outlines,"\t \$(F90) -c $mainprogfile \n");
245
246 }
247
248

  ViewVC Help
Powered by ViewVC 1.1.22