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 |
---|