#!/opt/local/bin/perl #!/usr/local/bin/perl # # Get list of fortran source and header files: # system("/bin/ls -1 *.f *.F > Srcfiles"); open(SRCFILES,"< Srcfiles") || die "$0: Could not open Srcfiles\n"; while () { chop; push(@srcfiles,$_); } # # Get list of modules contained in each source file: # (modules is assoc array w/ each source file as the # key, and a list of module(s) defined in that source # as the values) # %modules = &find_modules(@srcfiles); # # Open output file: open(DEPENDS,"> Depends") || die "$0: Can't open output file Depends\n"; open(OBJECTS,"> Objects") || die "$0: Can't open output file Objects\n"; print OBJECTS "OBJS = "; # # Loop through each source file, find modules used by each # source, and build file dependencies. # module_deps: list of modules used by current source file # file_deps: list of file dependencies of current source # (i.e., objects (.o) of files containing modules used) # foreach $srcfile (@srcfiles) { open(SRCFILE,"< $srcfile") || die "$0: Error opening file $srcfile.\n"; undef(@module_deps); # module dependencies for each source file undef(@include_deps); # include dependencies for each source file undef(@file_deps); # file dependencies for each source file # # Add dot-o file name to OBJECTS file: $doto = $srcfile; $doto =~ s/\.[fF]$/\.o/; print OBJECTS "$doto\t"; # # Build list of modules used: while () { # # Fixed source style use statement: if (/^ use (\w*)/) { $module = $1; # # Check for "use module,only: xyz": if ($module =~ /(\w*[^,])[,]/) { $module = $1; } if (&findmember($module,@module_deps) < 0) { push(@module_deps,$module); } } # # Check for include statements: # # Fortran style include statement: if ( /^\s+include\s+[<"'](.*)[>"']/ ) { $hdrfile = $1; if (&findmember($hdrfile,@include_deps) < 0) { push(@include_deps,$hdrfile); } } # # cpp style include statement: if ( /^#include\s+[<"'](.*)[>"']/ ) { $hdrfile = $1; if (&findmember($hdrfile,@include_deps) < 0) { push(@include_deps,$hdrfile); } } } # end reading srcfile # # Find file dependencies (i.e., files containing the module(s) # used by the source file): # if (@module_deps) { foreach $module (@module_deps) { # # Find source file that defines $module: undef($filedep); foreach $src (@srcfiles) { @modules_in_src = split(' ',$modules{$src}); if (&findmember($module,@modules_in_src) >= 0) { $filedep = $src; $filedep =~ s/\.[fF]$/\.o/; push(@file_deps,$filedep); } } if (! $filedep) { print "WARNING: could not find module $module (used by source file $srcfile)\n"; } } } # # Add included header files to list of dependencies: # if (@include_deps) { foreach $hdrfile (@include_deps) { if (-e $hdrfile) { push(@file_deps,$hdrfile); } else { # print "WARNING: could not find header file $hdrfile (included by source file $srcfile)\n"; } } } close($srcfile); # # Write file dependencies to output file: # $srcobj = $srcfile; $srcobj =~ s/\.[fF]$/\.o/; print DEPENDS "$srcobj: @file_deps\n"; } # each srcfile print OBJECTS "\n"; close(OBJECTS); close(DEPEND); #------------------------------------------------------------------------- sub find_modules { # # Given list of source files, return associative array with # each source file as the key and the module(s) it contains the # as the values. # local (@srcfiles) = @_; local ($srcfile,*SRCFILE,$modules); # foreach $srcfile (@srcfiles) { open(SRCFILE,"< $srcfile") || die "sub module_files: Error opening file $srcfile.\n"; while () { if (/^ module (.*)/) { $modules{$srcfile} .= $1 . ' '; } } } return %modules; } #------------------------------------------------------------------------- sub findmember { # # Given a string $member, and a list @list, search for $member in @list # and if found return index of $member in @list, otherwise return -1: # # (Note this routine also in $TGCMROOT/bin/util.pl) # local ($member,@list) = @_; local ($offset); $offset = 0; foreach $ele (@list) { if ($ele eq $member) { return $offset } $offset++; } $offset = -1; return $offset; }