#!/usr/bin/perl -w # cycle through fortran files, determine which headers are included; # the "used" array eliminates duplicate enties # for LES and PUPIL copies, add these dependencies as well to the list # Be sure do to a "make clean" before running this script! printf < ){ next if $file =~ /^_/; ($fileroot) = $file =~ /(.+)\.F90$/; $optimized{$fileroot} = 0; open( F, "$file" ) || die "unable to open $file\n"; while( ){ if( /^ *module /i ){ ($head,$modulename) = /( *[Mm][Oo][Dd][Uu][Ll][Ee]) +(\w*)/; $modulefile{$modulename} = $fileroot; # printf STDERR "modulefile: $modulename $fileroot\n"; } if( /compile=optimized/ ){ $optimized{$fileroot} = 1; } } close( F ); } # Now, cycle over all source files to create the compilation rules and # dependencies. Check for "compile=optimized" comments and do the right # thing: foreach $file ( <*.F90> ){ next if $file =~ /^_/; next if defined($special{$file}); # $deps = ""; ($fileroot) = $file =~ /(.+)\.F90$/; # construct the header and module dependency rules: open( F, "$file" ) || die "unable to open $file\n"; while( ){ if( /^ *use / ){ ($head,$usee) = /( *use) +(\w*)/; # printf STDERR " usee: $usee; modulefile is $modulefile{$usee}\n"; if( !defined $modulefile{$usee} && !defined $ignore{$usee}){ printf STDERR "No file name associated with module $usee\n"; exit(1); } if( !defined $ignore{$usee} && !defined $used{ $fileroot,$modulefile{$usee} } ){ # remove any circular references: next if $fileroot eq $modulefile{$usee}; $deps .= "\\\n " . $modulefile{$usee} . ".o" ; $used{ $fileroot,$modulefile{$usee} } = 1; } } if (/^# *include/) { ($head,$included) = /(# *include) +"(.*)"/; next if $included eq "mpif.h"; if( !defined $used{ $fileroot,$included } ){ $deps .= "\\\n " . $included ; $used{ $fileroot,$included } = 1; } } } printDep($fileroot, "", "",""); printDep($fileroot, ".NAB", "","[ -n \"\$(RISMSFF)\" ]") if defined $nab{$fileroot}; printDep($fileroot, ".SANDER", "-DSANDER -DRISM_CRDINTERP","[ -n \"\$(RISMSANDER)\" ]") if defined $sander{$fileroot}; } #template for dependencies and build target. Automatically applies #optimization flags, if requested. Also allows an optional suffix and #preprocessor flags. This can be used to create different object #files from the same source. #$_[0] : Root name of the source file (no suffix) #$_[1] : Extra suffix for the object file name. An empty string is # fine. Gives $fileroot${suffix}.o #$_[2] : Additional preprocessor flags #$_[3] : Conditional for empty object file. This is the conditional # for a shell if statement. If true, the source is compiled, # otherwise an empty object file is created instead. If this # string is empty, no conditional is built. sub printDep { my $fileroot = shift; my $suffix = shift; my $flags = shift; my $condition = shift; printf "$fileroot${suffix}.o: $deps\n\n" unless $deps eq ""; # construct the compilation rules: printf "\n$fileroot${suffix}.o: $fileroot.F90\n"; if($condition){ printf "\tif $condition; then \\\n\t"; } printf "\t\$(FC) -c \$(FPPFLAGS) \$(AMBERFPPFLAGS) \\\n" ."\t\t$flags \\\n" ."\t\t%s \$(FFLAGS) \$(AMBERFFLAGS) \\\n" ."\t\t-o \$@ $fileroot.F90", ( $optimized{$fileroot}?"\$(FOPTFLAGS)":"\$(FNOOPTFLAGS)"); if($condition){ printf "; \\\n" ."\telse \\\n" ."\t\ttest -e $fileroot${suffix}.o || touch $fileroot${suffix}.o; \\\n" ."\tfi\n\n"; }else{ printf "\n\n"; } }