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

Annotation 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 - (hide annotations) (download)
Tue Oct 10 18:17:27 2006 UTC (18 years, 9 months ago) by cnh
Branch point for: Initial, MAIN
File MIME type: text/plain
Initial revision

1 cnh 1.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