[10727] | 1 | #!/usr/bin/env perl |
---|
| 2 | # |
---|
| 3 | # svn $Id: sfmakedepend 751 2015-01-07 22:56:36Z arango $ |
---|
| 4 | ####################################################################### |
---|
| 5 | # Copyright (c) 2002-2015 The ROMS/TOMS Group # |
---|
| 6 | # Licensed under a MIT/X style license # |
---|
| 7 | # See License_ROMS.txt # |
---|
| 8 | ##################################################### Kate Hedstrom ### |
---|
| 9 | # # |
---|
| 10 | # Fortran 90/77 dependency checker, version 2007b. # |
---|
| 11 | # # |
---|
| 12 | ####################################################################### |
---|
| 13 | |
---|
| 14 | use 5.6.0; |
---|
| 15 | use strict; |
---|
| 16 | use File::Basename; |
---|
| 17 | use Getopt::Long; |
---|
| 18 | use Pod::Usage; |
---|
| 19 | use Getopt::Long; |
---|
| 20 | use File::Copy; |
---|
| 21 | |
---|
| 22 | my ($opt_help, $opt_man, $opt_file, @incdirs, @srcdirs, @defines, |
---|
| 23 | $opt_modext, $opt_case, $compiler, $opt_depend, $drop_circ); |
---|
| 24 | our ($cpp, $add_ext, $mod_dir, $libdeps, $longpath, $obj_dir, %defines, |
---|
| 25 | $silent); |
---|
| 26 | our $obj_ext = 'o'; |
---|
| 27 | our $ext = 'f'; |
---|
| 28 | |
---|
| 29 | # Parse the arguments, do the right thing for --help, --man. |
---|
| 30 | Getopt::Long::Configure( "bundling" ); |
---|
| 31 | GetOptions("help" => \$opt_help, "man" => \$opt_man, |
---|
| 32 | "file=s" => \$opt_file, "I=s@" => \@incdirs, |
---|
| 33 | "srcdir=s@" => \@srcdirs, "moddir=s" => \$mod_dir, |
---|
| 34 | "fext=s" => \$ext, "objext=s" => \$obj_ext, |
---|
| 35 | "modext=s" => \$opt_modext, "addext=s" => \$add_ext, |
---|
| 36 | "case=s" => \$opt_case, "compiler=s" => \$compiler, |
---|
| 37 | "depend=s" => \$opt_depend, "cpp" => \$cpp, |
---|
| 38 | "libdeps" => \$libdeps, "drop" => \$drop_circ, |
---|
| 39 | "longpath" => \$longpath, "objdir=s" => \$obj_dir, |
---|
| 40 | "D=s@" => \@defines, "silent" => \$silent ) |
---|
| 41 | or pod2usage("Try '$0 --help' for more information"); |
---|
| 42 | pod2usage(-verbose => 1) if $opt_help; |
---|
| 43 | pod2usage(-verbose => 2) if $opt_man; |
---|
| 44 | |
---|
| 45 | our @suffixes = qw( .c .C .cc .cxx .cpp .f .F .f90 .F90 .f95 .F95 .for); |
---|
| 46 | our @mod_files = (); |
---|
| 47 | |
---|
| 48 | my $mf = 'Makefile'; |
---|
| 49 | if ($opt_file) { |
---|
| 50 | $mf = $opt_file; |
---|
| 51 | } elsif (-f "makefile") { |
---|
| 52 | $mf = 'makefile'; |
---|
| 53 | } |
---|
| 54 | if ( !(-f $mf) && ($mf ne '-')) { |
---|
| 55 | system "touch $mf"; |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | if (@defines) { |
---|
| 59 | my $foo; |
---|
| 60 | foreach $foo (@defines) { |
---|
| 61 | my($before, $after) = split /=/, $foo; |
---|
| 62 | $defines{$before} = $after; |
---|
| 63 | } |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | # extension used for compiler's private module information |
---|
| 67 | our $mod_ext = "mod"; |
---|
| 68 | our $depend = "obj"; |
---|
| 69 | our $case = "lower"; |
---|
| 70 | our $obj_dep_flag; |
---|
| 71 | my $ll = 79; # maximum line length in Makefile |
---|
| 72 | my $cray; |
---|
| 73 | my $parasoft; |
---|
| 74 | my $nothing = "\n"; |
---|
| 75 | |
---|
| 76 | # Check the compiler first, then override the compiler-specific defaults |
---|
| 77 | if ($compiler) { |
---|
| 78 | if ($compiler eq "crayold") { |
---|
| 79 | $cray = 1; |
---|
| 80 | $case = "lower"; |
---|
| 81 | $depend = "obj"; |
---|
| 82 | $obj_dep_flag = "-p"; |
---|
| 83 | } elsif ($compiler eq "cray") { |
---|
| 84 | $case = "upper"; |
---|
| 85 | } elsif ($compiler eq "parasoft") { |
---|
| 86 | $parasoft = 1; |
---|
| 87 | $case = "lower"; |
---|
| 88 | $depend = "obj"; |
---|
| 89 | $obj_dep_flag = "-module"; |
---|
| 90 | } elsif ($compiler eq "sgiold") { |
---|
| 91 | $mod_ext = "kmo"; |
---|
| 92 | $case = "upper"; |
---|
| 93 | } elsif ($compiler eq "sgi" or $compiler eq "hp" or |
---|
| 94 | $compiler eq "absoft") { |
---|
| 95 | $case = "upper"; |
---|
| 96 | } elsif ($compiler eq "nag" or $compiler eq "ibm" or |
---|
| 97 | $compiler eq "sun") { |
---|
| 98 | $case = "lower"; |
---|
| 99 | } else { |
---|
| 100 | warn "Unknown compiler: $compiler\n"; |
---|
| 101 | } |
---|
| 102 | } |
---|
| 103 | |
---|
| 104 | $depend = $opt_depend if defined($opt_depend); |
---|
| 105 | if ($depend eq "obj") { |
---|
| 106 | $drop_circ = 1; |
---|
| 107 | } |
---|
| 108 | |
---|
| 109 | $case = $opt_case if defined($opt_case); |
---|
| 110 | |
---|
| 111 | # extension used for compiler's private module information |
---|
| 112 | if ($opt_modext) { |
---|
| 113 | $mod_ext = $opt_modext; |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | # need to add some more dependencies so the .f file gets created |
---|
| 117 | our $need_f; |
---|
| 118 | if ($cpp and $depend eq "obj") { |
---|
| 119 | $need_f = 1; |
---|
| 120 | } |
---|
| 121 | |
---|
| 122 | my $mystring = '# DO NOT DELETE THIS LINE - used by make depend'; |
---|
| 123 | |
---|
| 124 | # Search for the includes in all the files |
---|
| 125 | my $file; |
---|
| 126 | my %sources; |
---|
| 127 | foreach $file (@ARGV) { |
---|
| 128 | my $filesrc = findsrc($file); |
---|
| 129 | $sources{$file} = new Source_File($file, $filesrc, $filesrc); |
---|
| 130 | $sources{$file}->find_includes(); |
---|
| 131 | } |
---|
| 132 | |
---|
| 133 | # Create new Makefile with new dependencies. |
---|
| 134 | |
---|
| 135 | if ($mf ne "-") { |
---|
| 136 | copy( "$mf", "$mf.old"); |
---|
| 137 | open(MFILE, "$mf.old") || die "can't read Makefile $mf.old: $!\n"; |
---|
| 138 | open(NMFILE, "> $mf") || die "can't write $mf: $!\n"; |
---|
| 139 | select(NMFILE); |
---|
| 140 | |
---|
| 141 | while (<MFILE>) { |
---|
| 142 | if (!/$mystring/) { |
---|
| 143 | print; |
---|
| 144 | } else { |
---|
| 145 | last; |
---|
| 146 | } |
---|
| 147 | } |
---|
| 148 | print $mystring, "\n"; |
---|
| 149 | } |
---|
| 150 | |
---|
| 151 | # Now print out include and use dependencies in sorted order. |
---|
| 152 | my $target; |
---|
| 153 | foreach $target (sort keys(%sources)) { |
---|
| 154 | $sources{$target}->print(); |
---|
| 155 | # Hernan hack |
---|
| 156 | print $nothing; |
---|
| 157 | } |
---|
| 158 | |
---|
| 159 | # print out module dependencies |
---|
| 160 | if ( !( $cray || $parasoft) ) { |
---|
| 161 | my $modname; |
---|
| 162 | foreach $modname (sort keys(%main::mod_files)) { |
---|
| 163 | my ($name, $path, $suffix) = fileparse( |
---|
| 164 | $sources{$main::mod_files{$modname}}->{'filepath'}, @suffixes); |
---|
| 165 | my $object = $name . "." . $obj_ext; |
---|
| 166 | if (!( $drop_circ && lc($modname) eq lc($name)) ) { |
---|
| 167 | $object =~ s#^\./##; |
---|
| 168 | my $modfile = "$modname.$mod_ext"; |
---|
| 169 | my $objfile = $object; |
---|
| 170 | $modfile = $mod_dir . '/' . $modfile if $mod_dir; |
---|
| 171 | $objfile = $obj_dir . '/' . $objfile if $obj_dir; |
---|
| 172 | print "$modfile: $objfile\n"; |
---|
| 173 | } |
---|
| 174 | } |
---|
| 175 | } |
---|
| 176 | |
---|
| 177 | # |
---|
| 178 | # End of main |
---|
| 179 | # |
---|
| 180 | |
---|
| 181 | sub findfile { |
---|
| 182 | # Let's see if we can find the included file. Look in current |
---|
| 183 | # directory first, then in directories from -I arguments. |
---|
| 184 | my $file = shift; |
---|
| 185 | my ($found, $i, $filepath); |
---|
| 186 | |
---|
| 187 | $found = 0; |
---|
| 188 | |
---|
| 189 | if ( -f $file ) { |
---|
| 190 | $found = 1; |
---|
| 191 | $file =~ s#^\./##; # convert ./foo.h to foo.h |
---|
| 192 | return $file; |
---|
| 193 | } |
---|
| 194 | foreach $i (0 .. $#incdirs) { |
---|
| 195 | $filepath = $incdirs[$i]."/".$file; |
---|
| 196 | if ( -f $filepath ) { |
---|
| 197 | $found = 1; |
---|
| 198 | $filepath =~ s#^\./##; # convert ./foo.h to foo.h |
---|
| 199 | return $filepath; |
---|
| 200 | } |
---|
| 201 | } |
---|
| 202 | if ( ! $found ) { |
---|
| 203 | $filepath = ""; |
---|
| 204 | } |
---|
| 205 | $filepath; |
---|
| 206 | } |
---|
| 207 | #----------------------------------------------------------------------- |
---|
| 208 | sub findsrc { |
---|
| 209 | # Let's see if we can find the source-file. Look in current |
---|
| 210 | # directory first, then in directories from --srcdir arguments. |
---|
| 211 | my $src = shift; |
---|
| 212 | my($found, $i, $srcpath); |
---|
| 213 | |
---|
| 214 | $found = 0; |
---|
| 215 | |
---|
| 216 | if ( -f $src ) { |
---|
| 217 | $found = 1; |
---|
| 218 | $src =~ s#^\./##; # convert ./foo.h to foo.h |
---|
| 219 | return $src; |
---|
| 220 | } |
---|
| 221 | foreach $i (0 .. $#srcdirs) { |
---|
| 222 | $srcpath = $srcdirs[$i]."/".$src; |
---|
| 223 | if ( -f $srcpath ) { |
---|
| 224 | $found = 1; |
---|
| 225 | $srcpath =~ s#^\./##; # convert ./foo.h to foo.h |
---|
| 226 | return $srcpath; |
---|
| 227 | } |
---|
| 228 | } |
---|
| 229 | if ( ! $found ) { |
---|
| 230 | $srcpath = ""; |
---|
| 231 | } |
---|
| 232 | $srcpath; |
---|
| 233 | } |
---|
| 234 | |
---|
| 235 | ################################################################# |
---|
| 236 | package Source_File; |
---|
| 237 | |
---|
| 238 | # hash containing names of included files |
---|
| 239 | my %inc_files = (); |
---|
| 240 | my %flist; |
---|
| 241 | |
---|
| 242 | # Constructor |
---|
| 243 | sub new { |
---|
| 244 | my $type = shift; |
---|
| 245 | my $filename = shift; |
---|
| 246 | my $path = shift; |
---|
| 247 | my $parent = shift; |
---|
| 248 | my $self = {}; |
---|
| 249 | $self->{'Source_File'} = $filename; |
---|
| 250 | $self->{'filepath'} = $path; |
---|
| 251 | $self->{'parent'} = $parent; |
---|
| 252 | $self->{'includes'} = {}; |
---|
| 253 | $self->{'uses'} = {}; |
---|
| 254 | $self->{'modules'} = {}; |
---|
| 255 | bless $self; |
---|
| 256 | } |
---|
| 257 | |
---|
| 258 | sub find_includes { |
---|
| 259 | my $self = shift; |
---|
| 260 | my $file = $self->{'filepath'}; |
---|
| 261 | my $parent = $self->{'parent'}; |
---|
| 262 | my($after, $filepath, $ref, $included, $use, $modname); |
---|
| 263 | local(*FILE); |
---|
| 264 | local($_); |
---|
| 265 | |
---|
| 266 | if (-f $file) { |
---|
| 267 | open(FILE, $file) || $silent || warn "Can't open $file: $!\n"; |
---|
| 268 | } else { |
---|
| 269 | return; |
---|
| 270 | } |
---|
| 271 | while (<FILE>) { |
---|
| 272 | $included = ""; |
---|
| 273 | $use = ""; |
---|
| 274 | # look for Fortran style includes |
---|
| 275 | if (/^\s*include\s*['"]([^"']*)["']/i) { |
---|
| 276 | $included = $1; |
---|
| 277 | $after = $'; |
---|
| 278 | # C preprocessor style includes |
---|
| 279 | } elsif (/^#\s*include\s*["<]([^">]*)[">]/) { |
---|
| 280 | $included = $1; |
---|
| 281 | $after = $'; |
---|
| 282 | # Fortran 90 "use" |
---|
| 283 | } elsif (/^\s*use\s+(\w+)/i) { |
---|
| 284 | # Gavin Salam attempt at dealing with multiple uses on one line |
---|
| 285 | # remove trailing comments (do not take uses after a comment!) |
---|
| 286 | s/\!.*//; |
---|
| 287 | # try and get multiple use commands |
---|
| 288 | my @commands = split(';',$_); |
---|
| 289 | while (my $command = shift @commands) { |
---|
| 290 | if ($command =~ /^\s*use\s+(\w+)/i) { |
---|
| 291 | $use = $1; |
---|
| 292 | # Change the case as needed - compiler dependent. |
---|
| 293 | if ($main::case eq "upper") { |
---|
| 294 | $use = uc($use); |
---|
| 295 | } elsif ($main::case eq "lower") { |
---|
| 296 | $use = lc($use); |
---|
| 297 | } |
---|
| 298 | $self->{'uses'}{$use} = 1; |
---|
| 299 | } |
---|
| 300 | } |
---|
| 301 | # Fortran 90 module |
---|
| 302 | } elsif (/^\s*module\s+(\w+)/i) { |
---|
| 303 | $modname = $1; |
---|
| 304 | if ($main::case eq "upper") { |
---|
| 305 | $modname = uc($modname); |
---|
| 306 | } elsif ($main::case eq "lower") { |
---|
| 307 | $modname = lc($modname); |
---|
| 308 | } |
---|
| 309 | # Skip "module procedure" in interface blocks |
---|
| 310 | next if (lc($modname) eq "procedure"); |
---|
| 311 | |
---|
| 312 | $main::mod_files{$modname} = $parent; |
---|
| 313 | $self->{'modules'}{$modname} = 1; |
---|
| 314 | } |
---|
| 315 | # C preprocessor style includes of a -DROMS_HEADER sort |
---|
| 316 | my $key; |
---|
| 317 | foreach $key (keys(%defines)) { |
---|
| 318 | if (/^#\s*include\s*($key)/) { |
---|
| 319 | $included = $defines{$key}; |
---|
| 320 | $after = $'; |
---|
| 321 | } |
---|
| 322 | } |
---|
| 323 | if ($included) { |
---|
| 324 | # See if we've already searched this file |
---|
| 325 | if ( $inc_files{$included} ) { |
---|
| 326 | $filepath = $inc_files{$included}{'filepath'}; |
---|
| 327 | } else { |
---|
| 328 | $filepath = main::findfile($included); |
---|
| 329 | $ref = new Source_File($included, $filepath, $parent); |
---|
| 330 | $inc_files{$included} = $ref; |
---|
| 331 | # Search included file for includes |
---|
| 332 | $ref->find_includes(); |
---|
| 333 | } |
---|
| 334 | if ( $filepath ) { |
---|
| 335 | $self->{'includes'}{$included} = 1; |
---|
| 336 | } else { |
---|
| 337 | if ($after !~ /bogus/i) { |
---|
| 338 | $silent || warn "Can't find file: $included\n"; |
---|
| 339 | } |
---|
| 340 | } |
---|
| 341 | } |
---|
| 342 | } |
---|
| 343 | close FILE; |
---|
| 344 | } |
---|
| 345 | |
---|
| 346 | sub print_includes { |
---|
| 347 | my $self = shift; |
---|
| 348 | my $target = shift; |
---|
| 349 | my $len_sum = shift; |
---|
| 350 | my $file; |
---|
| 351 | my $len; |
---|
| 352 | |
---|
| 353 | foreach $file (keys %{$self->{'includes'}}) { |
---|
| 354 | if (!$flist{$file}) { |
---|
| 355 | $flist{$file} = 1; |
---|
| 356 | my $ref = $inc_files{$file}; |
---|
| 357 | if ($longpath) { |
---|
| 358 | $len = length($ref->{'filepath'}) + 1; |
---|
| 359 | } else { |
---|
| 360 | $len = length($ref->{'Source_File'}) + 1; |
---|
| 361 | } |
---|
| 362 | if (($len_sum + $len > $ll) && |
---|
| 363 | (length($target) + 1 < $len_sum)) { |
---|
| 364 | print "\n$target:"; |
---|
| 365 | $len_sum = length($target) + 1; |
---|
| 366 | } |
---|
| 367 | if ($longpath) { |
---|
| 368 | print " " . $ref->{'filepath'}; |
---|
| 369 | } else { |
---|
| 370 | print " " . $ref->{'Source_File'}; |
---|
| 371 | } |
---|
| 372 | $len_sum += $len; |
---|
| 373 | $len_sum = $ref->print_includes($target, $len_sum); |
---|
| 374 | } |
---|
| 375 | } |
---|
| 376 | $len_sum; |
---|
| 377 | } |
---|
| 378 | |
---|
| 379 | # return list of modules used by included files |
---|
| 380 | sub inc_mods { |
---|
| 381 | my $self = shift; |
---|
| 382 | my($file, $ref, $mod, @sub_list); |
---|
| 383 | my @list = (); |
---|
| 384 | |
---|
| 385 | foreach $mod (keys %{$self->{'uses'}}) { |
---|
| 386 | push(@list, $mod); |
---|
| 387 | } |
---|
| 388 | |
---|
| 389 | foreach $file (keys %{$self->{'includes'}}) { |
---|
| 390 | $ref = $inc_files{$file}; |
---|
| 391 | @sub_list = $ref->inc_mods(); |
---|
| 392 | @list = (@list, @sub_list); |
---|
| 393 | } |
---|
| 394 | @list; |
---|
| 395 | } |
---|
| 396 | |
---|
| 397 | # filenames containing the modules used by file and all its includes |
---|
| 398 | sub find_mods { |
---|
| 399 | my $self = shift; |
---|
| 400 | my($modname, $file); |
---|
| 401 | my @module_files = (); |
---|
| 402 | my @mod_list = (); |
---|
| 403 | |
---|
| 404 | # find modules used by include files |
---|
| 405 | if (%{$self->{'includes'}}) { |
---|
| 406 | foreach $file (keys %{$self->{'includes'}}) { |
---|
| 407 | my $ref = $inc_files{$file}; |
---|
| 408 | my @list = $ref->inc_mods(); |
---|
| 409 | @mod_list = (@mod_list, @list); |
---|
| 410 | } |
---|
| 411 | } |
---|
| 412 | |
---|
| 413 | # add them to the uses list (hash ensures uniqueness) |
---|
| 414 | foreach $modname (@mod_list) { |
---|
| 415 | $self->{'uses'}{$modname} = 1; |
---|
| 416 | } |
---|
| 417 | |
---|
| 418 | # now find the filename that contains the module information |
---|
| 419 | foreach $modname (keys %{$self->{'uses'}}) { |
---|
| 420 | if ($main::depend eq "obj") { |
---|
| 421 | if ($file = $main::mod_files{$modname}) { |
---|
| 422 | my $base = main::basename($file, @main::suffixes); |
---|
| 423 | $file = $base . "." . $main::obj_ext; |
---|
| 424 | push(@module_files, $file); |
---|
| 425 | } elsif ( !$silent ) { |
---|
| 426 | warn "Don't know where module $modname lives.\n"; |
---|
| 427 | } |
---|
| 428 | } else { |
---|
| 429 | if ($main::libdeps or defined($main::mod_files{$modname})) { |
---|
| 430 | $modname .= "." . $main::mod_ext; |
---|
| 431 | push(@module_files, $modname); |
---|
| 432 | } elsif ( !$silent ) { |
---|
| 433 | warn "Couldn't locate source for module $modname\n"; |
---|
| 434 | } |
---|
| 435 | } |
---|
| 436 | } |
---|
| 437 | sort(@module_files); |
---|
| 438 | } |
---|
| 439 | |
---|
| 440 | sub print { |
---|
| 441 | my $self = shift; |
---|
| 442 | my $source = $self->{'Source_File'}; |
---|
| 443 | my $compile_string = "\t" . '$(F90) $(F90FLAGS) -c'; |
---|
| 444 | my($len_sum, $len); |
---|
| 445 | my($base, $object, $modname, $flag, $target, $ftarget); |
---|
| 446 | |
---|
| 447 | $base = main::basename($source, @main::suffixes); |
---|
| 448 | $base = $main::obj_dir . '/' . $base if $main::obj_dir; |
---|
| 449 | $target = $base . "." . $main::obj_ext; |
---|
| 450 | if ($main::cpp) { |
---|
| 451 | $ftarget = $base . "." . $main::ext; |
---|
| 452 | } |
---|
| 453 | |
---|
| 454 | $flag = $main::obj_dep_flag; |
---|
| 455 | |
---|
| 456 | # print out "include" dependencies |
---|
| 457 | %flist = (); |
---|
| 458 | if (%{$self->{'includes'}}) { |
---|
| 459 | $len_sum = length($target) + 1; |
---|
| 460 | if ($main::add_ext) { |
---|
| 461 | print "$base.$main::add_ext "; |
---|
| 462 | $len_sum += length($base) + length($main::add_ext) + 2; |
---|
| 463 | } |
---|
| 464 | print "$target:"; |
---|
| 465 | $self->print_includes($target, $len_sum); |
---|
| 466 | print "\n"; |
---|
| 467 | if ($main::cpp) { |
---|
| 468 | %flist = (); |
---|
| 469 | $len_sum = length($ftarget) + 1; |
---|
| 470 | print "$ftarget:"; |
---|
| 471 | $self->print_includes($ftarget, $len_sum); |
---|
| 472 | print "\n"; |
---|
| 473 | } |
---|
| 474 | } |
---|
| 475 | |
---|
| 476 | # clean out "use" of modules in own file |
---|
| 477 | my $mod; |
---|
| 478 | foreach $mod ( keys %{$self->{'uses'}} ) { |
---|
| 479 | if ( ${$self->{'modules'}}{$mod} ) { |
---|
| 480 | delete ${$self->{'uses'}}{$mod}; |
---|
| 481 | } |
---|
| 482 | } |
---|
| 483 | |
---|
| 484 | # print out "use" dependencies |
---|
| 485 | if (%{$self->{'uses'}} || %{$self->{'includes'}}) { |
---|
| 486 | my @module_files = $self->find_mods(); |
---|
| 487 | $len_sum = 0; |
---|
| 488 | my $file; |
---|
| 489 | foreach $file (@module_files) { |
---|
| 490 | $file = $main::mod_dir . '/' . $file if $main::mod_dir; |
---|
| 491 | if( $len_sum < 1 ) { |
---|
| 492 | $len_sum = length($target) + 1; |
---|
| 493 | print "$target:"; |
---|
| 494 | } |
---|
| 495 | $len = length($file) + 1; |
---|
| 496 | if (($len_sum + $len > $ll) && |
---|
| 497 | (length($target) + 1 < $len_sum)) { |
---|
| 498 | print "\n$target:"; |
---|
| 499 | $len_sum = length($target) + 1; |
---|
| 500 | } |
---|
| 501 | $len_sum += $len; |
---|
| 502 | print " " . $file; |
---|
| 503 | } |
---|
| 504 | if ($main::need_f) { |
---|
| 505 | $len = length($ftarget) + 1; |
---|
| 506 | if (($len_sum + $len > $ll) && |
---|
| 507 | (length($target) + 1 < $len_sum)) { |
---|
| 508 | print "\n$target:"; |
---|
| 509 | $len_sum = length($target) + 1; |
---|
| 510 | } |
---|
| 511 | print " " . $ftarget if $len_sum; |
---|
| 512 | } |
---|
| 513 | print "\n" if $len_sum; |
---|
| 514 | # extra Cray / Parasoft stuff |
---|
| 515 | if ($flag) { |
---|
| 516 | print $compile_string; |
---|
| 517 | foreach $file (@module_files) { |
---|
| 518 | print $flag . $file; |
---|
| 519 | } |
---|
| 520 | if ($main::cpp) { |
---|
| 521 | print " " . $ftarget . "\n"; |
---|
| 522 | } else { |
---|
| 523 | print " " . $source . "\n"; |
---|
| 524 | } |
---|
| 525 | } |
---|
| 526 | } |
---|
| 527 | } |
---|
| 528 | |
---|
| 529 | __END__ |
---|
| 530 | |
---|
| 531 | sfmakedepend - Fortran Dependency Checker |
---|
| 532 | |
---|
| 533 | =head1 SYNOPSIS |
---|
| 534 | |
---|
| 535 | sfmakedepend [--help] [--man] [--file=file] [-I dir] |
---|
| 536 | [--srcdir dir] [--objdir dir] [--moddir dir] |
---|
| 537 | [--fext ext] [--objext ext] [--modext ext] |
---|
| 538 | [-D TAG=file] [--addext ext] [--case=up|down|asis] |
---|
| 539 | [--compiler=crayold|cray|sgiold|sgi|nag|ibm| |
---|
| 540 | parasoft|hp|absoft|sun] |
---|
| 541 | [--depend=mod|obj] [--cpp] [--libdeps] [--drop] |
---|
| 542 | [--silent] file ... |
---|
| 543 | |
---|
| 544 | =head1 DESCRIPTION |
---|
| 545 | |
---|
| 546 | This is a makedepend script for Fortran, including Fortran 90. |
---|
| 547 | It searches for Fortran style includes, C preprocessor includes, |
---|
| 548 | and module dependencies to the extent that I understand them. |
---|
| 549 | |
---|
| 550 | Your files must have an extension listed in the @suffixes list |
---|
| 551 | in the code. You might also want to modify $compile_string; |
---|
| 552 | the compiler is called $(F90). |
---|
| 553 | |
---|
| 554 | =head1 OPTIONS AND ARGUMENTS |
---|
| 555 | |
---|
| 556 | =over 4 |
---|
| 557 | |
---|
| 558 | =item I<--help> |
---|
| 559 | |
---|
| 560 | Print more details about the arguments. |
---|
| 561 | |
---|
| 562 | =item I<--man> |
---|
| 563 | |
---|
| 564 | Print a full man page. |
---|
| 565 | |
---|
| 566 | =item I<--file file> |
---|
| 567 | |
---|
| 568 | Change the name of the current Makefile (default is Makefile). |
---|
| 569 | Use "--file -" to write to stdout. |
---|
| 570 | |
---|
| 571 | =item I<-I dir> |
---|
| 572 | |
---|
| 573 | Look in alternate directories for the include files. There can be |
---|
| 574 | several "-I dir" options used at once. The current directory is |
---|
| 575 | still searched first. |
---|
| 576 | |
---|
| 577 | =item I<--srcdir dir> |
---|
| 578 | |
---|
| 579 | Look in alternate directories for the source files, much like VPATH. |
---|
| 580 | It can be used multiple times to search in more than one directory. |
---|
| 581 | |
---|
| 582 | =item I<--objdir dir> |
---|
| 583 | |
---|
| 584 | Tells sfmakedepend to prepend objdir to all object references (and |
---|
| 585 | cpp output files if used). This is required if you use a build |
---|
| 586 | directory that isn't your current directory. |
---|
| 587 | |
---|
| 588 | =item I<--moddir dir> |
---|
| 589 | |
---|
| 590 | Tells sfmakedepend to prepend moddir to all module references. This |
---|
| 591 | is required if you use a common module library directory for a |
---|
| 592 | multi-directory project (+moddir= .. option on HP, eg.). |
---|
| 593 | |
---|
| 594 | =item I<--fext> |
---|
| 595 | |
---|
| 596 | This is used with the --cpp switch for compilers |
---|
| 597 | which expect an extension other than .f on source files. For |
---|
| 598 | instance, one might choose to use "--fext f90". |
---|
| 599 | |
---|
| 600 | =item I<--objext ext> |
---|
| 601 | |
---|
| 602 | Tells sfmakedepend what extension to use for object files. The |
---|
| 603 | default is "o", but "obj", for instance, is |
---|
| 604 | appropriate on MS-DOG etc. |
---|
| 605 | |
---|
| 606 | =item I<--modext ext> |
---|
| 607 | |
---|
| 608 | Specifies the extension to use for Fortran 90 module files. The default |
---|
| 609 | extension is "mod" since this seems to be an emerging standard. Let |
---|
| 610 | me know if other compilers use a different filename for the module |
---|
| 611 | information (keep that --compiler option up to date). |
---|
| 612 | |
---|
| 613 | =item I<--D tag=file> |
---|
| 614 | |
---|
| 615 | Tells sfmakedepend to search the source files for lines such as: |
---|
| 616 | |
---|
| 617 | #include MY_CHEESE |
---|
| 618 | |
---|
| 619 | Where MY_CHEESE is set with a -DMY_CHEESE="wensleydale.h". |
---|
| 620 | |
---|
| 621 | =item I<--addext ext> |
---|
| 622 | |
---|
| 623 | Tells sfmakedepend to add targets with extension add_ext to the rules |
---|
| 624 | for object files. For instance, to operate with (f77) ftnchek .prj |
---|
| 625 | files, you could use |
---|
| 626 | |
---|
| 627 | `--addext prj' to get rules like: |
---|
| 628 | foo.prj foo.o: ... |
---|
| 629 | |
---|
| 630 | =item I<--case up|down|asis> |
---|
| 631 | |
---|
| 632 | Controls case of module names when generating module file names. Only |
---|
| 633 | relevant where the module file name is named after the module rather |
---|
| 634 | than after the source file. |
---|
| 635 | |
---|
| 636 | =item I<--compiler=crayold|cray|sgiold|sgi|nag|ibm|parasoft|hp|absoft|sun> |
---|
| 637 | |
---|
| 638 | Controls the type of target compiler, setting the module name and other |
---|
| 639 | options appropriately. The cray option assumes that FFLAGS includes |
---|
| 640 | -e m for creating the .mod file, while crayold refers to the default of |
---|
| 641 | including that information in the object file. |
---|
| 642 | |
---|
| 643 | =item I<--depend=mod|obj> |
---|
| 644 | |
---|
| 645 | Whether to use the module information file or the module object file |
---|
| 646 | in dependencies. |
---|
| 647 | |
---|
| 648 | =item I<--cpp> |
---|
| 649 | |
---|
| 650 | There are times when one might choose to run .F files through cpp and |
---|
| 651 | to keep the .f files (for the debugger or for a custom preprocessor). |
---|
| 652 | In that case, make must be told about the cpp include dependencies of |
---|
| 653 | the .f files. This option will provide those dependencies. |
---|
| 654 | |
---|
| 655 | =item I<--libdeps> |
---|
| 656 | |
---|
| 657 | Generate dependencies on modules for which source code is not |
---|
| 658 | available. Otherwise a warning is issued, but the dependency is not |
---|
| 659 | listed. |
---|
| 660 | |
---|
| 661 | =item I<--longpath> |
---|
| 662 | |
---|
| 663 | Keep the full path to the include files in the dependency. Otherwise, |
---|
| 664 | just print the filename and use VPATH to provide the directory |
---|
| 665 | information. |
---|
| 666 | |
---|
| 667 | =item I<--drop> |
---|
| 668 | |
---|
| 669 | Drop module dependencies (my_mod.mod: my_mod.o). This is also done when |
---|
| 670 | --depend=obj. |
---|
| 671 | |
---|
| 672 | =item I<--silent> |
---|
| 673 | |
---|
| 674 | The default is to warn about unfound files. This option causes those |
---|
| 675 | warnings to not be printed. |
---|
| 676 | |
---|
| 677 | =item I<[file ...]> |
---|
| 678 | |
---|
| 679 | The list of source files to search for dependencies. |
---|
| 680 | |
---|
| 681 | =back |
---|
| 682 | |
---|
| 683 | =head1 EXAMPLE |
---|
| 684 | |
---|
| 685 | Search for include files in /usr/local/include: |
---|
| 686 | |
---|
| 687 | sfmakedepend --cpp --fext=f90 -I /usr/local/include *.F |
---|
| 688 | |
---|
| 689 | Example usage in gnuMakefile: |
---|
| 690 | |
---|
| 691 | SRCDIRS= srcdir1 srcdir2 srcdir3 ... |
---|
| 692 | FSRCS0 := $(foreach DIR, . $(SRCDIRSH),$(wildcard $(DIR)/*.f)) |
---|
| 693 | FSRCS := $(sort $(notdir $(FSRCS0))) |
---|
| 694 | |
---|
| 695 | F_makedepend=sfmakedepend --file - $(addprefix --srcdir ,$(SRCDIRSH)) \ |
---|
| 696 | $(subst -I,-I ,$(Includes)) |
---|
| 697 | depend $(MAKEFILE_INC): |
---|
| 698 | $(F_makedepend) $(FSRCS) >> $(MAKEFILE_INC) |
---|
| 699 | |
---|
| 700 | include $(MAKEFILE_INC) |
---|
| 701 | |
---|
| 702 | =head1 AUTHOR |
---|
| 703 | |
---|
| 704 | Kate Hedstrom (kate@arsc.edu) |
---|
| 705 | First Perl 5 Fortran 90 version November 1994. |
---|
| 706 | |
---|
| 707 | =head1 CONTRIBUTORS |
---|
| 708 | |
---|
| 709 | Dave Love (d.love@dl.ac.uk) |
---|
| 710 | Added the --objext and --addext options (1996). |
---|
| 711 | |
---|
| 712 | Patrick Jessee |
---|
| 713 | Added hp support (1997, now in --compiler option). |
---|
| 714 | |
---|
| 715 | Sergio Gelato (gelato@tac.dk) |
---|
| 716 | Added the --compiler, --depend, --case options, and |
---|
| 717 | --(no)libdeps (1998). |
---|
| 718 | |
---|
| 719 | Tobias Buchal (buchal@ifh.bau-verm.uni-karlsruhe.de) |
---|
| 720 | Added the --srcdir and --file - options (1999). |
---|
| 721 | |
---|
| 722 | Klaus Ramstock (klaus@tdm234.el.utwente.nl) |
---|
| 723 | Added the --moddir option (1999). |
---|
| 724 | |
---|
| 725 | Sandra Schroedter (sandra@fsg-ship.de) |
---|
| 726 | Fix to preserve Makefile links (1999). |
---|
| 727 | |
---|
| 728 | Holger Bauer (bauer@itsm.uni-stuttgart.de) |
---|
| 729 | Added the --drop option (2000). |
---|
| 730 | |
---|
| 731 | Gavin Salam (salam@lpthe.jussieu.fr) |
---|
| 732 | Made it recognize multiple "use"s on one line (2005). |
---|
| 733 | |
---|
| 734 | Others I've doubtless forgotten. |
---|
| 735 | |
---|
| 736 | =cut |
---|
| 737 | # |
---|
| 738 | # NOTES |
---|
| 739 | # This makedepend script is my first attempt at using perl 5 |
---|
| 740 | # objects. Therefore, it may not be the best example of how |
---|
| 741 | # to do this. Also, it requires perl 5 and will die if you |
---|
| 742 | # to use it with an older perl. The latest version is |
---|
| 743 | # available from: |
---|
| 744 | # |
---|
| 745 | # http://www.arsc.edu/~kate/Perl/ |
---|
| 746 | # ftp://ahab.rutgers.edu/pub/perl/sfmakedepend |
---|
| 747 | # |
---|
| 748 | # Fortran 90 introduces some interesting dependencies. Two |
---|
| 749 | # compilers I have access to (NAG f90 and IBM xlf) produce a |
---|
| 750 | # private "mod_name.mod" file if you define "module mod_name" |
---|
| 751 | # in your code. This file is used by the compiler when you |
---|
| 752 | # use the module as a consistency check (type-safe). On the |
---|
| 753 | # other hand, the Cray and Parasoft compilers store the module |
---|
| 754 | # information in the object file and then files which use the |
---|
| 755 | # modules need to be compiled with extra flags pointing to the |
---|
| 756 | # module object files. |
---|
| 757 | # |
---|
| 758 | # This script assumes that all the files using and defining |
---|
| 759 | # modules are in the same directory and are all in the list of |
---|
| 760 | # files to be searched. It seems that the industry has not |
---|
| 761 | # settled on a practical way to deal with a separate modules |
---|
| 762 | # directory, anyway. |
---|
| 763 | # |
---|
| 764 | # I sometimes include non-existent files as a compile time |
---|
| 765 | # consistency check: |
---|
| 766 | # |
---|
| 767 | # #ifndef PLOTS |
---|
| 768 | # #include "must_define_PLOTS" /* bogus include */ |
---|
| 769 | # #endif |
---|
| 770 | # |
---|
| 771 | # This program warns about include files it can't find, but |
---|
| 772 | # not if there is a "bogus" on the same line. |
---|
| 773 | # |
---|
| 774 | # * The f90 module dependencies can confuse some versions of |
---|
| 775 | # make, especially of the System V variety. We use gnu |
---|
| 776 | # make because it has no problems with these dependencies. |
---|
| 777 | # |
---|
| 778 | # BUGS |
---|
| 779 | # It can sometimes produce duplicate dependencies. |
---|
| 780 | # |
---|
| 781 | # It treats C preprocessor includes the same as Fortran |
---|
| 782 | # includes. This can add unnecessary dependencies if you |
---|
| 783 | # use the -s flag and both kinds of includes. |
---|
| 784 | # |
---|
| 785 | # Please let me know if you find any others. |
---|
| 786 | # Kate Hedstrom |
---|
| 787 | # kate@arsc.edu |
---|