root/mpich2/branches/dev/kumudb/maint/simplemake.in @ 4870

Revision 4870, 172.8 KB (checked in by kumudb, 5 months ago)

Merge from trunk to kumudb r4748:r4869

Line 
1#! @PERL@ -w
2# -*- Mode: perl; -*-
3$abs_mpich2srcdir = "@abs_mpich2srcdir@";
4#
5# (C) 2006 by Argonne National Laboratory.
6#     See COPYRIGHT in top-level directory.
7#
8#
9# Set some defaults
10$includedir = ".";
11$skipAction = 0;
12$makefilebase = "Makefile.base";
13$ranliblib    = 1;   # only set to 0 on systems where ar
14                     # computes a symbol table index.  Also see RANLIBNEEDED
15                     # environment variable
16$useinclude = 0;     # set to 1 to make the Makefiles refer to a single
17                     # base makefile.
18$include_list = "";
19$vpath_config = 0;   # set to 1 for @VPATH@
20$nocomments = 0;     # set to 1 to exclude comments from the source file
21$commonmake = "";    # Common entries for each generated Makefile
22$maint_targets = 1;  # set to 0 for distribution versions
23$maint_perf_targets = 0; # set to 1 to get extra targets to aid in
24                         # performance tuning.  These may cause problems
25                         # if the generated files are sometimes used
26                         # in preference to the original source files,
27                         # so this is not the default
28$verbose = 0;        # set to 1 to get more information
29$am_a = "";          # set to _a for automake style input
30$do_dependencies = "dynamic"; # set to no, static, or dynamic to attempt
31                              # to generate dependency information
32                              # use "ignore" to produce a target (for
33                              # recursive ops) but no actions
34$dependenciesDummy = "no";    # set to yes to create a dummy target for
35                              # dependencies
36$makeInclude = "include";     # set to the include command to use.
37                              # This is more robust if it ignores missing files
38                              # (e.g., the gnumake "-include")
39$gCheckForTargets = 0;        # Set to 1 to look for files not included
40                              # in the Makefile.sm
41$gSubdirSMVarsSeen = "";      # Set to contain the names of variables in
42                              # Makefile.sm that override variables for
43                              # a subdirectory
44@subdirsSMVars = ();          # Stack used with gSubdirSMVarsSeen
45
46$smrootdir = "";              # Location of simplemake - this will override
47                              # the automatic setting if used.
48
49# makeBlockSep is used to deliniate blocks of code in the generated makefile
50# to enhance readability
51$makeBlockSep =
52"# --------------------------------------------------------------------------\n";
53
54# Set the names for the autoconf and autoheader program, along with
55# the optional args and the argument used to specify the include dir for
56# autoconf/autoheader (autoconf 2.57 changed the command-line interface
57# without maintaining backward compatibility)
58if (defined($ENV{"AUTOCONF"})) {
59    $autoconf_prog = $ENV{"AUTOCONF"};
60}
61else {
62    $autoconf_prog = "autoconf";
63}
64if (defined($ENV{"AUTOHEADER"})) {
65    $autoheader_prog = $ENV{"AUTOHEADER"};
66}
67else {
68    $autoheader_prog = "autoheader";
69}
70if (defined($ENV{"CHECKTARGETS"})) {
71    $gCheckForTargets = 1;
72}
73$autoconf_args = ""; # Extra arguments for autoconf
74$acincdir_arg = "-l";
75
76$do_sharedlibs  = 1; # set to 1 the generate targets for shared libraries
77$found_sharedlib = 0;# set to 1 if a specific shared library target is found
78
79$root_tags = 1;      # set to 1 to create a tags file in the root dir
80$local_tags = 0;     # set to 1 to create a tags file in the local dir
81#$do_libmember = 0;   # set to 1 to generate library member rules in makefiles
82$do_docs = 1;        # set to 1 to generate documentation
83
84$convert_Ldir_to_relative = 1; # set to 1 to convert -Ldir to ../../lib
85                     # relative to the rootdir
86#
87# The following two symbols are defined for future use in generating
88# the dependency information for programs that are created.  This
89# allows us to ensure that test programs are rebuilt if we rebuild the
90# libraries
91#$project_libs = "";  # name of the libraries that are created by
92#                     # this project
93#$project_libdir = "";# name of the directory (may contain ROOTDIR) in which
94#                     # the libraries are created                   
95#
96# Perhaps a better approach is to provide
97# <program>_DEPS = other program dependencies
98# DEPSALL = dependencies for *all* programs
99
100$make_depend = "gcc -MM -MT '_$$*.o $$*.o'"; 
101           # Set to command to create dependency list.  Include the
102           # Profiling objects (_xxx.o).  If gcc includes -MF, we can
103           # output directly: -MF '.deps/$*.d'
104$fixup_autoconf_cd = 0; # set to 1 to (partially) fixup configure for
105                        # pathnames that contain blanks
106$autoconf = "autoconf"; # Name of autoconf program to use
107$autoconf_version = ""; # Require a specific version
108$configure_has_config_headers = "no";
109#
110$quietmake = "@";       # set to "" for echo commands, @ to suppress them
111$quietLine = "@";       # set to "" to make the clean targets echo commands
112#
113# Defaults for building MPICH
114$doc_heading = "MPI";
115#%doc_extra   = ();  # for kinds html, man, latex
116#
117# Set to 1 if make doesn't handle time stamps properly (some makes, including
118# some versions of gnumake, improperly and inconsistently
119# handle comparisons of less than a second
120$fixup_for_timestamps = 0;
121# Set a default sleepTime.
122$sleepTime = 1;
123$useSleepFast = 1;
124# The sleep amount should be parameterized.  One developer at IBM
125# needed 10 seconds, not 1, because of the variation in file system times
126# between the local machine and the file server. The environment
127# variable INTERDIR_SLEEP , for inter-directory sleep, sets both the
128# time and selects the use of slow sleep
129
130if (defined($ENV{'INTERDIR_SLEEP'})) {
131    $sleepTime = $ENV{'INTERDIR_SLEEP'};
132    $useSleepFast = 0;
133    $fixup_for_timestamps = 1;
134}
135
136$SleepSlow = "sleep $sleepTime";
137$SleepFast = "perl -e \'\$\$now=time;\$\$now-=10;utime \$\$now, \$\$now, \"LIB\";\'";
138
139# Set the default (it can be overridden by the command line)
140if ($useSleepFast) {
141    $Sleep = $SleepFast;
142}
143else {
144    $Sleep = $SleepSlow;
145}
146
147# Check environment variable to see if ranlib is needed.
148if (defined($ENV{"RANLIBNEEDED"})) {
149    my $val = $ENV{"RANLIBNEEDED"};
150    if ($val eq "YES" || $val eq "yes" || $val == 1) {
151        $ranliblib = 1;
152    }
153    elsif ($val eq "NO" || $val eq "no" || $val == 0) {
154        $ranliblib = 0;
155    }
156}
157
158#
159# Output File end-of-line character
160$newline = "\n";
161
162$create_configure_input = 1;  # Changes file.sm to file.in .  Set to 0
163                              # for file.sm to file .
164$smdir=$0;         # directory containing simplemake
165if ($smdir =~/^[^\/]/) {
166    $curpwd = $ENV{'PWD'};
167    #chomp($curpwd = `pwd`);
168    #print "curdir = $curpwd\n";
169    #print "\$0 = $0\n";
170    $smdir = $curpwd . "/$0";
171}
172$smdir =~ s/\/?simplemake$//;
173#print "smdir = $smdir\n";
174
175$debug = 0;                 # General debugging
176$debug_dirs = 0;            # Debug the choice of directories
177$debug_confdir = 0;         # Track the directory containing the controlling
178                            # configure.in
179$gDebugWhy = 0;             # Provide an explanation of why certain
180                            # targets are created
181$gDebugSubdirVar = 0;       # Track changes to internal variables that
182                            # apply to a subdirectory
183$debugConfigHeaderDepend = 0;    # Print the config header targets added to
184                                 # makefile.in's
185# Allow us to set the debug variables from the environment:
186if (defined($ENV{"DEBUG"})) { $debug = 1; }
187if (defined($ENV{"DEBUG_DIRS"})) { $debug_dirs = 1; }
188if (defined($ENV{"DEBUG_CONFDIR"})) { $debug_confdir = 1; }
189if (defined($ENV{"DEBUG_SUBDIRVAR"})) { $gDebugSubdirVar = 1; }
190
191# Initialize global variables used in informal modules
192&printInit();
193
194$quiet = 0;
195
196%libdir = ();
197#
198# While simplemake doesn't support ext->other (e.g., .c to .s),
199# the rules have been added.
200%extrules = ( 'c:o' => '$(C_COMPILE) -c $<',
201              'f:o' => '$(F77_COMPILE) -c $<',
202              'cxx:o' => '$(CXX_COMPILE) -c $<',
203              'cpp:o' => '$(CXX_COMPILE) -c $<',
204              's:o' => '$(AS_COMPILE) $<',
205              'f90:o' => '$(F90_COMPILE) -c $<',
206# Assembler *output* definitions
207              'c:s' => '$(C_COMPILE) -S $<',
208              'f:s' => '$(F77_COMPILE) -S $<',
209# C preprocessor *output* definitions.  We don't use cpp as the
210# output suffix to avoid conflicts with C++
211              'c:txt' => '$(CPP) $(INCLUDES) $(CPPFLAGS) $< >$*.txt',
212              'F:txt' => '$(CPP) $(INCLUDES) $(CPPFLAGS) $<  >$*.txt',
213              'cxx:txt' => '$(CXXCPP) $(INCLUDES) $(CPPFLAGS) $< >$*.txt',
214# Program from source rules
215              'c:' => '$(C_COMPILE) -o $* $< $(LDFLAGS) $(LIBS)',
216              'f:' => '$(F77_COMPILE) -o $* $< $(LDFLAGS) $(LIBS)',
217              'f90:' => '$(F90_COMPILE) -o $* $< $(LDFLAGS) $(LIBS)',
218              'cxx:' => '$(CXX_COMPILE) -o $* $< $(LDFLAGS) $(LIBS)',
219# LaTeX definitions
220              'tex:dvi' => 'latex $<',
221              'dvi:ps' => 'dvips $<',
222              'dvi:pdf' => 'dvipdfm $<',
223# Shared object definitions           
224# To avoid overwritting the .o file, we use a specific output file name
225# Note that many compilers insist that that file have a .o extension,
226# so we change the *name*.  We us _s for the shared lib intermediates
227              'c:lo' => '$(C_COMPILE_SHL) -c $< -o _s$*.o
228        @mv -f _s$*.o $*.lo',
229              'f:lo' => '$(F77_COMPILE_SHL) -c $< -o _s$*.o
230        @mv -f _s$*.o $*.lo',
231              'cxx:lo' => '$(CXX_COMPILE_SHL) -c $< -o _s$*.o
232        @mv -f _s$*.o $*.lo',
233              'cpp:lo' => '$(CXX_COMPILE_SHL) -c $< -o _s$*.o
234        @mv -f _s$*.o $*.lo',
235              'f90:lo' => '$(F90_COMPILE_SHL) -c $< -o _s$*.o
236        @mv -f _s$*.o $*.lo',
237## This has an MPICH-specific definition that we should eventually generalize
238## We use -o on the compile line to keep from overwriting the .o file;
239## this improves the behavior when weak symbols are not supported
240## We use _ for the profiling lib intermediates
241#              'c:pf' => '${C_COMPILE} -c $< -o _$*.o
242             );
243
244# When we are building profiled versions, we use a separate ext rule
245%extrules_with_profile = %extrules;
246# PROFILE_DEF_MPI is set when needed to create the profiling libraries.
247#$extrules_with_profile{'c:o'} =~ s/-c/-c \@PROFILE_DEF_MPI\@/;
248#print "rule = $extrules_with_profile{'c:o'}\n" if $debug;
249
250# Definitions for each extension (these are the defs needed for each ext->o
251# extension)
252%extdef = ( 'c:o'   => 'CC              = @CC@
253CFLAGS          = @CFLAGS@ $(MPICH2_MAKE_CFLAGS)
254C_COMPILE       = $(CC) $(DEFS) $(INCLUDES) $(CFLAGS) $(CPPFLAGS)',
255            'f:o'   => 'FC              = @FC@
256FFLAGS          = @FFLAGS@
257F77_COMPILE     = $(FC) $(FFLAGS) $(F77INCLUDES)',
258            'cxx:o' => 'CXX             = @CXX@
259CXXFLAGS        = @CXXFLAGS@
260CXX_COMPILE     = $(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS) $(CPPFLAGS)',
261            'cpp:o' => 'CXX             = @CXX@
262CXXFLAGS        = @CXXFLAGS@
263CXX_COMPILE     = $(CXX) $(DEFS) $(INCLUDES) $(CXXFLAGS) $(CPPFLAGS)',
264            'cs:o'  => 'CSHARP          = @CSHARP@
265CSFLAGS         = @CSFLAGS@
266CSHARP_COMPILE  = $(CSHARP) $(DEFS) $(INCLUDES) $(CSFLAGS) $(CPPFLAGS)',
267            's:o'   => 'AS              = @AS@
268AS_COMPILE      = $(AS)',
269            'f90:o'   => 'F90              = @F90@
270F90FLAGS        = @F90FLAGS@
271F90_COMPILE     = $(F90) $(F90FLAGS) $(F90INCLUDES)',
272# Similarly, but for shared-library versions
273            'c:lo'   => 'CC_SHL          = @CC_SHL@
274C_COMPILE_SHL   = $(CC_SHL) $(DEFS) $(INCLUDES) $(CFLAGS) $(CPPFLAGS)',
275            'f:lo'   => 'FC_SHL          = @FC_SHL@
276F77_COMPILE_SHL = $(FC_SHL) $(FFLAGS) $(F77INCLUDES)',
277            'f90:lo'   => 'F90_SHL          = @F90_SHL@
278F90_COMPILE_SHL = $(F90_SHL) $(F90FLAGS) $(F90INCLUDES)',
279            'cxx:lo' => 'CXX_SHL         = @CXX_SHL@
280CXX_COMPILE_SHL = $(CXX_SHL) $(DEFS) $(INCLUDES) $(CXXFLAGS) $(CPPFLAGS)',
281            'cpp:lo' => 'CXX_SHL         = @CXX_SHL@
282CXX_COMPILE_SHL = $(CXX_SHL) $(DEFS) $(INCLUDES) $(CXXFLAGS) $(CPPFLAGS)',
283           );
284
285%extstring = ( 'c:o'    => '  CC              $<',
286               'c:'     => '  CC              $<',
287               'f:o'    => '  FC              $<',
288               'cxx:o'  => '  CXX             $<',
289               'cpp:o'  => '  CXX             $<',
290               'cs:o'   => '  CS              $<',
291               's:o'    => '  AS              $<',
292               'f90:o'  => '  F90             $<',
293               'c:lo'   => '  CC              $<',
294               'f:lo'   => '  FC              $<',
295               'f90:lo' => '  F90             $<',
296               'cxx:lo' => '  CXX             $<',
297               'cpp:lo' => '  CPP             $<',
298    );
299
300#
301# Rules to build programs (.o:)
302#
303# We need to include the <lang>FLAGS, because configure links programs
304# that way when it tests programs.
305%progrules = ( 'c' => '$(C_LINK) $(CFLAGS) $(LDFLAGS)',
306               'cxx' => '$(CXX_LINK) $(CXXFLAGS) $(LDFLAGS)',
307               'cpp' => '$(CXX_LINK) $(CXXFLAGS) $(LDFLAGS)',
308               'cs'  => '$(CSHARP_LINK) $(LDFLAGS)',
309               'f'   => '$(F77_LINK) $(FFLAGS) $(LDFLAGS)',
310               'f90' => '$(F90_LINK) $(F90FLAGS) $(LDFLAGS)',
311              );
312%progdefs = ( 'c' =>   'C_LINK         = $(CC)',
313              'cxx' => 'CXX_LINK       = $(CXX)',
314              'cpp' => 'CXX_LINK       = $(CXX)',
315              'cs'  => 'CSHARP_LINK    = $(CSHARP)',
316              'f'   => 'F77_LINK       = $(FC)',
317              'f90' => 'F90_LINK       = $(F90)',
318             );
319
320# Rules to build shared libraries (these are like programs
321# Question: Do we want a common rule or separate rules for each language?
322# These are out-of-date.
323%shlibdefs = ( 'c' =>   'C_LINK_SHL      = @C_LINK_SHL@',
324               'cxx' => 'CXX_LINK_SHL    = @CXX_LINK_SHL@',
325               'cpp' => 'CXX_LINK_SHL    = @CXX_LINK_SHL@',
326               'f'   => 'F77_LINK_SHL    = @F77_LINK_SHL@',
327               'f90' => 'F90_LINK_SHL    = @F90_LINK_SHL@',
328             );
329#%shlibrules = ( 'c' => '$(C_LINK_SHL) $(LDFLAGS)',
330#              'cxx' => '$(CXX_LINK_SHL) $(LDFLAGS)',
331#              'cpp' => '$(CXX_LINK_SHL) $(LDFLAGS)',
332#              'f'   => '$(F77_LINK_SHL) $(LDFLAGS)',
333#              'f90' => '$(F90_LINK_SHL) $(LDFLAGS)',
334#             );
335
336#
337# Directories needed.  These are the prefix etc.  Many are needed only
338# at the top level, particularly for installation.  srcdir is needed only for
339# VPATH builds
340$srcdir_name =               "srcdir          = \@srcdir\@";
341$abs_srcdir_name =           "abs_srcdir      = \@abs_srcdir\@";
342$master_topsrcdir_name =     "master_top_srcdir  = \@master_top_srcdir\@";
343$topsrcdir_name =            "top_srcdir      = \@top_srcdir\@";
344$prefix_name =               "prefix          = \@prefix\@";
345$exec_prefix_name =          "exec_prefix     = \@exec_prefix\@";
346$bindir_name =               "bindir          = \@bindir\@";
347$sbindir_name =              "sbindir         = \@sbindir\@";
348$libdir_name =               "libdir          = \@libdir\@";
349$includedir_name =           "includedir      = \@includedir\@";
350$mandir_name =               "mandir          = \@mandir\@";
351$htmldir_name =              "htmldir         = \@htmldir\@";
352$docdir_name =               "docdir          = \@docdir\@";
353# datarootdir is new in autoconf 2.60, and is needed for other
354# dirs like mandir (much as prefix and execprefix are also needed)
355$datarootdir_name =          "datarootdir     = \@datarootdir\@";
356$datadir_name =              "datadir         = \@datadir\@";
357$sysconfdir_name =           "sysconfdir      = \@sysconfdir\@";
358$pkgconfigdir_name =         "pkgconfigdir    = \@libdir\@/pkgconfig";
359$builddir_name =             "builddir        = \@builddir\@";
360$abs_builddir_name =         "abs_builddir    = \@abs_builddir\@";
361# top_builddir is used by libtool.  We use master_top_builddir because
362# the various configure scripts need to use the root of the build (that
363# is the model that we use for simplemake projects)
364$top_builddir_name =         "top_builddir    = \@master_top_builddir\@";
365
366%dirdefs = ( 'srcdir'     => $srcdir_name,
367             'abs_srcdir' => $abs_srcdir_name,
368             'top_srcdir' => $topsrcdir_name,
369             'prefix'     => $prefix_name,
370             'exec_prefix'=> $exec_prefix_name,
371             'bindir'     => $bindir_name,
372             'sbindir'    => $sbindir_name,
373             'libdir'     => $libdir_name,
374             'includedir' => $includedir_name,
375             'master_top_srcdir' => $master_topsrcdir_name,
376             'top_builddir' => $top_builddir_name,
377             'builddir'     => $builddir_name,
378             'abs_builddir' => $abs_builddir_name,
379             'mandir'       => $mandir_name,
380             'datarootdir'  => $datarootdir_name,
381             'htmldir'      => $htmldir_name,
382             'docdir'       => $docdir_name,
383             'sysconfdir'   => $sysconfdir_name,
384             'pkgconfigdir' => $pkgconfigdir_name,
385             'datadir'      => $datadir_name,
386            );
387
388#InstallDirFromKind maps XXX from install_XXX into the GNU name
389%InstallDirFromKind = ( 'LIB' => 'libdir',
390                 'SHLIB' => 'libdir',    # SHLIB also signals library to build
391                 'DLLLIB' => 'libdir',   # DLLLIB also signals library to build
392                 'BIN' => 'bindir',
393                 'SCRIPT' => 'bindir',
394                 'INCLUDE' => 'includedir',
395                 'MAN' => 'mandir',
396                 'HTML' => 'htmldir',
397                 'DOC' => 'docdir',
398                 'ETC' => 'sysconfdir',
399                 'DATADIR' => 'datadir',
400                 'PKGCONFIG' => 'pkgconfigdir',
401                );
402# We add the -p switch to install for the libraries because libraries
403# that require ranlib may fail if installed without preserving the
404# data/time on the file.  This should work because configure looks for
405# a BSD-style install.
406# Sigh.  ginstall (!!!) doesn't support the -p switch.
407# This means that there is no way to install a library under Darwin
408# without defining INSTALL_DATA as install -p, which configure
409# does not figure out(!).  The MPICH2 configure does check for
410# whether install works with or without -p.
411#
412# CREATESHLIB is a special script for shared libraries
413%install_methods = ( 'LIB'     => '$(INSTALL_DATA)',
414                     'BIN'     => '$(INSTALL_PROGRAM) $(INSTALL_STRIP_FLAG)',
415                     'SCRIPT'  => '$(INSTALL_SCRIPT)',
416                     'SHLIB'   => '$(CREATESHLIB) --mode=install',
417                     'DLLLIB'  => '$(CREATESHLIB) --mode=install',
418                     'INCLUDE' => '$(INSTALL_DATA)',
419                     'MAN'     => '$(INSTALL_DATA)',
420                     'HTML'    => '$(INSTALL_DATA)',
421                     'DOC'     => '$(INSTALL_DATA)',
422                     'ETC'     => '$(INSTALL_DATA)',
423                     'DATADIR' => '$(INSTALL_DATA)',
424                     'PKGCONFIG' => '$(INSTALL_DATA)',
425                    );
426%uninstall_methods = ( 'SHLIB'   => '$(CREATESHLIB) --mode=uninstall',
427                       'DLLLIB'  => '$(CREATESHLIB) --mode=uninstall',
428                     );
429# These give the directories that autoconf will require for the
430%required_dirs = ( 'libdir'      => 'exec_prefix prefix',
431                   'bindir'      => 'exec_prefix prefix',
432                   'mandir'      => 'prefix datarootdir',
433                   'htmldir'     => 'prefix datarootdir',
434                   'docdir'      => 'prefix datarootdir',
435                   'includedir'  => 'prefix',
436                   'exec_prefix' => 'prefix',
437                   'sysconfdir'  => 'prefix',
438                   'exec_prefix' => 'prefix',
439                   'pkgconfigdir'=> 'libdir exec_prefix prefix',
440                   'datadir'     => 'prefix',
441                  );
442# etc.
443#
444# Remember which document types we've seen
445%globaldockind = ( "html" => 0, "man" => 0, "latex" => 0 );
446# Set globaldocdir to the location to use if no specific directory is
447# chosen.  It may contain ROOTDIR.
448$globaldocdir  = 'ROOTDIR/$dockinddirval';
449# Directories for documentation
450# These may be overridden how by setting docthiskinddir
451%dockinddir = ( "html" => "www/www3",
452                "man" => "man/man3",
453                "latex" => "doc/refman" );
454%docthiskinddir = ();
455# man targets for documentation
456%docTargetName = ( "html" => "htmldoc",
457                   "man" => "mandoc",
458                  "latex" => "latexdoc" );
459# doctext name to produce documentation
460%doctextOptionName = ( "html" => "-html",
461                       "man" => "-man",       # New version allows -man
462                      "latex" => "-latex" );
463$doc_namedefs   = "";
464$doc_attop = 1;
465#
466# Rules
467# (need a way to quote the rule here and unquote it when used)
468#
469# Need a way to substitute for additional or replacement default rules
470# Other global data
471$do_profilelibs   = 1; # Set to one if a profiling version of the library
472                       # should be created (required for MPI)
473$found_profilelib = 0;
474
475# Default values
476$distcleanfiles = "";
477
478@subdirs = ();
479@doc_subdirs = ();
480
481%notSimplemakeDirs = (); # This hash is used to note directories that
482                         # are part of the subdirs but are not
483                         # simplemake dirs
484
485# ---------------------------------------------------------------------------
486# Global variables that describe extensions
487#   Each extension has a name, related to the command-field in the
488#   Makefile.sm, and must be added to this array
489@KnownActions = ();
490# Load any extension definitions, in this order
491&SMReadDefnFiles( "maint/smlib" );
492# If we're not in the root of the source directory, then
493# also read that directory.  We can use stat to check the inode numbers of the
494# directories; if they are the same, the directories are the same.
495# (Only read if there is a local maint/smlib directory)
496@d1 = stat( "maint/smlib" );
497@d2 = stat( "$abs_mpich2srcdir/maint/smlib" );
498if ( (! -d "maint/smlib") || $d1[1] != $d2[1]) {
499    &SMReadDefnFiles( "$abs_mpich2srcdir/maint/smlib" );
500}
501if (defined($ENV{"SMDIR"})) {
502    &SMReadDefnFiles( $ENV{"SMDIR"} );
503}
504&SMReadDefnFiles( "." );
505# ---------------------------------------------------------------------------
506@keepargs = ();    # Used to recreate simplemake invocation for make target
507$foundFile = "no";
508foreach $_ (@ARGV) {
509    $keepargs[$#keepargs+1] = $_;    # Add all args by default
510    if (/-nocomments/) { $nocomments = 1; }
511    elsif (/-v/) { $verbose = 1; }
512    elsif (/-am/) { $am_a = "_a"; }
513    elsif (/-libdir=([^=]*)=(.*)$/) {
514        print "libdir{$1} = $2$newline" if (!$quiet);
515        $libdir{$1}  = "$2/";
516        # Replace with an easier-to-preserve version
517        # FIXME: Replace a single $ with double $$ in $1?
518        my $lname = $1;
519        my $rname = $2;
520        # Replace a single $ with a double $ in lname *only*
521        $lname =~ s/\$/\$\$/;
522        $keepargs[$#keepargs] = "-libdir=\'$lname=$rname\'";
523    }
524    elsif (/-common=(.*)$/) {
525        $filename = $1;
526        open( CD,"<$filename" ) || die "Could not open $filename\n";
527        while (<CD>) {
528            s/\r//g; # Strip \r for DOS
529            $commonmake .= $_;
530        }
531        close(CD);
532        # Replace this argument with an updated version
533        if ($filename =~ /^[^\/]/) {
534            $keepargs[$#keepargs] = "-common=\${master_top_srcdir}/$filename";
535        }
536    }
537    elsif (/-autoconf=(.*)$/) {
538        $autoconf_args = $1;
539    }
540    elsif (/-include=(.*)$/) {
541        $include_list = $1;
542    }
543    elsif (/-distrib/) {
544        # Turn off the maintenance targets in the distribution version
545        $maint_targets = 0;
546        $maint_perf_targets = 0;
547        $do_docs = 0;
548        # Use the robust sleep, not the fast perl version
549        $useSleepFast = 0;
550        $Sleep = $SleepSlow;
551        # FIXME: Sleep code only used if fixup set to 1
552        #$fixup_for_timestamps = 1; # make is broken
553    }
554    elsif (/-interdirsleep/) {
555        $useSleepFast = 0;
556        $fixup_for_timestamps = 1;
557        if (/-interdirsleep=(\d*)/) {
558            $sleepTime = $1;
559            $SleepSlow = "sleep $sleepTime";
560        }
561        $Sleep = $SleepSlow;
562    }
563    elsif (/-perftargets/) {
564        # This option enables any performance targets of interest to
565        # maintainers (currently adds options to build asm (.s) files)
566        $maint_perf_targets = 1;
567    }
568    elsif (/-dos/) {
569        $newline = "\r\n";
570    }
571    elsif (/-shared/) {
572        $do_sharedlibs = 1;
573    }
574    elsif (/-noshared/) {
575        $do_sharedlibs = 0;
576    }
577    elsif (/-docs/) {
578        $do_docs = 1;
579    }
580    elsif (/-nodocs/) {
581        $do_docs = 0;
582    }
583    elsif (/-vpath=?(.*)/) {
584        $val = $1;
585        if ($val eq "no") { $vpath_config = 0; }
586        else { $vpath_config = 1; }
587    }
588    elsif (/-depend=static/) {
589        $do_dependencies = "static";
590    }
591    elsif (/-depend/) {
592        $do_dependencies = "dynamic";
593    }
594    elsif (/-nodepend/) {
595        $do_dependencies = "no";
596    }
597    elsif (/-rootdir=(.*)$/) {
598        $rootdirpath = $1;
599        $#keepargs--;  # remove this entry (it is explicitly recreated)
600    }
601    elsif (/-distcleanfiles=(.*)/) {
602        # extra files to remove in this directory
603        if ($distcleanfiles ne "") { $distcleanfiles .= " "; }
604        $distcleanfiles .= $1;
605    }
606    elsif (/-checktargets/) {
607        $gCheckForTargets = 1;
608    }
609    elsif (/-configdir=(.*)/) {
610        # Use this option to specify the location of the configure
611        # that controls the Makefile.in in this directory.
612        # This is normally used when rebuilding a single Makefile.in
613        # from a Makefile.sm .
614        $last_config_dir = $1;
615        $#keepargs--;  # remove this entry (it is explicitly recreated)
616    }
617    elsif (/-debugdirs/) {
618        $debug_dirs = 1;
619    }
620    elsif (/-debug/) {
621        $debug = 1;
622    }
623    elsif (/-smvar_([\w_]*)=(.*)/) {
624        # Allow the command-line to override internal variables
625        my $varname = $1;
626        my $varvalue   = $2;
627        $${varname} = $varvalue;
628    }
629    elsif (/-quietmake/) { $quietmake = "@"; }
630    elsif (/-noquietmake/) { $quietmake = ""; }
631    elsif (/-quiet/) { $quiet = 1; }
632    elsif (/-docheading=(.$)/) { $doc_heading = $1; }
633    elsif (/-docdestdir=(.*)/) { $globaldocdir = $1; }     
634    elsif (/-docnamedefs=(.*)/) { $doc_namedefs = $1; }   
635    elsif (/-smroot=(.*)/) { $smrootdir = $1; $smdir = $1; }
636    elsif (/-help/) {
637        &printHelp;
638        exit 0;
639    }
640    else {
641        $#keepargs--;  # Remove filename from list
642        $foundFile = "yes";
643        &ProcessFile ( $_ );
644    }
645}
646
647
648# If there is no argument and the default filename, then process it
649print "found file = $foundFile\n" if $debug;
650if ($foundFile ne "yes" && -s "Makefile.sm") {
651    print "about to process file\n";
652    &ProcessFile( "Makefile.sm" );
653}
654
655
656# Check that gcc is available if we need it
657if ($do_dependencies eq "static") {
658    if ($make_depend =~ /gcc\s.*-MM/) {
659        # (we use the pattern match to allow other options)
660        # This was | 2>&1 but the redirect should go before the pipe.
661        if (open (TFD, "gcc --version 2>&1 |" )) {
662            close TFD;
663        }
664        else {
665            $do_dependencies = "no";
666        }
667    }
668    # insert check here.  Perhaps we should try #include <stdio.h>?
669}
670
671# Routines
672# =========================================================================
673# Read Makefile.sm
674sub ReadMfile {
675    my $Mfile = $_[0];
676    my $linecount = 0;
677    open (MFILE,"<$Mfile" ) || die "Could not open $Mfile in $curdir\n";
678    &ClearVars;
679    while (<MFILE>) {
680        $linecount++;
681        s/\r//g;              # Remove \r for DOS
682        $origline = $_;
683        # Remove trailing newline (we had trouble with chomp on DOS)
684        #chomp;
685        s/[\r\n]*$//;
686
687        # Handle continuation lines
688        while (s/\\$//) {  # Match and remove a trailing \
689            if (eof(MFILE)) {
690                print STDERR "Unexpected EOF in $curdir$Mfile\n";
691                last;
692            }
693            $nextline = <MFILE>;
694            $nextline =~ s/\r//g; # Remove \r for DOS
695            $linecount++;
696            $origline .= $nextline;
697            #chomp $nextline;
698            $nextline =~ s/[\r\n]*$//;
699            $_ .= $nextline;
700        }
701
702        # Check for portability problems
703        # Check for a blank line that starts with a tab
704        if (/^\t\s*$/) {
705            print STDERR "File $curdir$Mfile contains a blank line beginning with a tab\nat line $linecount.  Some make programs will fail with a syntax error.\n";
706        }
707        if (/^\t#/) {
708            print STDERR "File $curdir$Mfile contains a comment line beginning with a tab\nat line $linecount.  Some make programs will fail if this comment is part\nof a command script in a target\n";
709        }
710
711        # Look for commands that are defined by extensions.  These are
712        # of the form
713        #    name_COMMAND
714        # where COMMAND is all uppercase.  "name" may itself be of the form
715        #    name_subcommand
716        # an example is
717        #   libfoo_la_SOURCES
718        # where the command is SOURCES and the subcommand is la
719        # We allow the names to include make variables and autoconf
720        # variables
721        if (/^([@\${}\(\)\w-]+)_([A-Z]+)\s*=(.*)/) {
722            my $name    = $1;
723            my $command = $2;
724            my $value   = $3;
725            # See if this is a known extension command
726            my $fcnName = "Action" . $command;
727            if (defined(&$fcnName)) {
728                # This is an extension.  Invoke its function
729                print "Executing $fcnName for $_\n" if $debug;
730                $skipAction = 0;
731                &$fcnName( $_ );
732                $origline = "";
733                # skip the processing of this line for the default commands
734                if (!defined($skipAction) || $skipAction == 1) {
735                    next;
736                }
737            }
738        }
739
740        # Look for reserved forms:
741        #lib([\w-]*)_SOURCES = names
742        #lib([\w-]*)_DIR = name
743        #install_local_DIR = name(s)
744        #SUBDIRS = names
745        #DOC_SUBDIRS = names
746        #DOCDESTDIRS = kind:dir [, kind:dir ]*
747        # Also keep track of Makefile usages:
748        #target: ...
749        #variable = value
750        #.SUFFIXES:value
751        # Using the _a_ in the library lines is necessary to distinguish
752        # between libraries and programs that start with lib...
753        if (/^lib([@\${}\(\)\w-]+)_a_SOURCES\s*=\s*(.*)$/) {
754            $libname   = $1;
755            $libsource = $2;
756            $libraries{ $libname } = $libsource;
757            # Keep a number for each library; this is used for
758            # alternate targets used to handle filesystem timestamp problems
759            $libnum{$libname} = $libcount++;
760            # Add to targets
761            $libloc = &GetLibLoc( $libname );
762            $alltargets[$#alltargets+1] = "${libloc}lib$libname.a";
763            &LibraryTimestampTarget( "${libloc}lib$libname.a",
764                                     ".libstamp" . $libnum{$libname} );
765            # Shared libraries should not be built unconditionally. 
766            # Instead of adding them to the alltargets, add them
767            # to a allshlibtargets
768            # FIXME: Sometimes, we want to use a separate library
769            # for the shared library (e.g., for the C++ bindings)
770            # while using a single library for the static linking.
771            # here is where we would do that, using a special
772            # mapping of library name to shared library name
773            if ($do_sharedlibs && !defined($libNotShared{$libname})) {
774                $allshlibtargets[$#allshlibtargets+1] =
775                    "${libloc}lib$libname.la";
776                $dirs_seen{'top_builddir'} = 1;   # For libtool
777                $libnum{$libname.".la"} = $libcount++;
778            }
779            # Keep track of source types
780            &FindSrcTypes( $libsource );
781            # Keep track of source files
782            &SaveSrcNames( $libsource );
783        }
784        # In some cases, there is a library that should only be built as
785        # a non-shared library (e.g., built with Fortran)
786        elsif (/^lib([@\${}\(\)\w-]*)_a_NOSHARED\s*$/) {
787            print "Adding $1 as not-shared\n" if $debug;
788            $libNotShared{$1} = 1;
789        }
790        # Using the _so_ in the library lines is necessary to distinguish
791        # between libraries and programs that start with lib...
792        # This target is used for libraries that are *always* needed
793        # as shared libraries (e.g., they are used only in a dynamic
794        # link context).  No _so_DIR for these yet because stand-alone
795        # shared libraries are usually contained within a single
796        # directory.
797        elsif (/^lib([@\${}\(\)\w-]*)_so_SOURCES\s*=\s*(.*)$/) {
798            $found_sharedlib = 1;
799            $libname = "$1";
800            $libsource = $2;
801            $shared_libraries{ $libname } = $libsource;
802            # Add to targets
803            $libloc = &GetLibLoc( $libname );
804            $allshlibtargets[$#allshlibtargets+1] = "${libloc}lib$libname.\@SHLIB_EXT\@";
805            $dirs_seen{'top_builddir'} = 1;   # For libtool
806            # Keep track of source types
807            &FindSrcTypes( $libsource );
808            # Keep track of source files
809            &SaveSrcNames( $libsource );
810            # We need to include .lo as a necessary suffix.
811        }
812        elsif (/^lib([@\${}\(\)\w-]*)_so_EXPORTS\s*=\s*(.*)$/) {
813            $libname = "$1";
814            $libexports = $2;
815            $shared_libraries_exports{ $libname } = $libexports;
816        }
817        elsif (/^lib([@\${}\(\)\w-]*)_so_LIBS\s*=\s*(.*)$/) {
818            # Specify dependent libraries for a shared library
819            # (Some systems require knowledge of all of the libraries
820            # needed when creating a shared library.)
821            $libname = "$1";
822            $dependentlibs = $2;
823            $shared_libraries_libs{ $libname } = $dependentlibs;
824        }
825        elsif (/^lib([@\${}\(\)\w-]*)_a_DIR\s*=\s*(\S+)\s*$/) {
826            # This is an extension over automake.  It makes it easy
827            # to modify a library in a different directory
828            # Add a trailing / because this way we can unconditionally
829            # specify the library directory
830            print "Setting libdir{$1} to $2/\n" if $debug;
831            $libdir{$1}  = "$2/";
832        }
833        elsif (/^install_local_DIR\s*=\s*(.*)\s*$/) {
834            $install_local_dirs = $1;
835        }
836        elsif (/^doc_([\w-]*)_SOURCES\s*=\s*(.*)\s*$/) {
837            # Lowercase the type
838            $docsrc{lc($1)} = $2;
839            $globaldockind{lc($1)} = 1;
840            # Add any autoconf dir in $doc_namedefs
841            &LookForAutoconfDirs( $doc_namedefs );
842        }
843        elsif (/^doc_([\w-]*)_DIR\s*=\s*(.*)\s*$/) {
844            # Lowercase the type
845            $docdir{lc($1)} = $2;
846        }
847        elsif (/^profilelib_([@\${}\(\)\w-]*)_SOURCES\s*=\s*(.*)\s*$/) {
848            # proflib_<oldname>_SOURCES = files
849            $profile_library_sources{$1} = $2;
850            $found_profilelib = 1;
851        }
852        elsif (/^profilelib_([@\${}\(\)\w-]*)\s*=\s*(.*)\s*$/) {
853            # proflib_<oldname> = <newname>
854            $profile_libraries{$1} = $2;
855            $profile_libraries_basename{$2} = $1;
856            $libnum{$2} = $libcount++;
857            if ($do_sharedlibs) {
858                $libnum{$2.".la"} = $libcount++;
859            }
860            $found_profilelib = 1;
861        }
862        elsif (/^EXT_(\w+)_([\{\}\$\w]+)_SOURCES\s*=\s*(.*)/) {
863            # This is the extension hook for EXT_foo_name_SOURCES = data
864            # We can't just use foo_name_SOURCES because we allow
865            # programs to be defined that way (foo_name with SOURCES)
866            my $optype = $1;
867            my $opname = $2;
868            my $opsources = $3;
869            &CallModule( $optype, $opname, $opsources );
870        }
871        elsif (/^install_([\w-]*)\s*=\s*(.*)\s*$/) {
872            $install_files{$1} .= "$2 ";
873        }
874        elsif (/^installdir_([\w-]*)\s*=\s*(.*)\s*$/) {
875            $install_dirs{$1} .= "$2 ";
876        }
877        elsif (/^optinstall_([\w-]*)\s*=\s*(.*)\s*$/) {
878            # This is for files that will be installed only if present
879            $optinstall_files{$1} .= "$2 ";
880            if ($1 eq "DLLLIB") {
881                my $libname = $2;
882                $libname =~ s/\.\@SHLIB_EXT\@//;
883                $libname =~ s/^\s*lib//;
884                $alldlllibtargets[$#alldlllibtargets+1] =
885                    "${libloc}lib$libname.la";
886            }
887
888        }
889        elsif (/^optinstalldirs_([\w-]*)\s*=\s*(.*)\s*$/) {
890            # This is for files that will be installed only if present
891            $optinstall_dirs{$1} .= "$2 ";
892        }
893        elsif (/^SUBDIRS\s*=\s*(.*)\s*\r?$/) {
894            # The \r is used to remove any \r in DOS-style files
895            @subdirs = split(/\s+/,$1);
896            $subdirs_has_autoconf = 0;
897            $smmakevars{'SUBDIRS'} = $1;
898        }
899        elsif (/^SUBDIRS_(\w+)\s*=\s*(.*)\s*/) {
900            # use SUBDIRS_acname = realname to say that the
901            # autoconf variable acname, used in SUBDIRS, can
902            # have any of the values realname
903            $subdir_autoconf_vars{$1} = $2;
904            $subdir_optionals .= " $2";
905            # Also add as a make variable because other
906            # parts of the code will look for it as a raw variable.
907            $makevars{"SUBDIRS_$1"} = $2;
908        }
909        elsif (/^DOC_SUBDIRS\s*=\s*(.*)\s*\r?$/) {
910            # The \r is used to remove any \r in DOS-style files
911            @doc_subdirs = split(/\s+/,$1);
912            $smmakevars{'DOC_SUBDIRS'} = $1;
913        }
914        elsif (/^DOCDESTDIRS\s*=\s*(.*)\s*\r?$/) {
915        # kind:dir [, kind:dir ]*
916            $smmakevars{'DOCDESTDIRS'} = $1;
917            for $pair (split(/,\s*/,$1)) {
918                $pair =~ /(.*):(.*)/;
919                $docthiskinddir{$1} = $2;
920            }
921        }
922        elsif (/^INSTALL_SUBDIRS\s*=\s*(.*)\s*\r?$/) {
923            @install_subdirs = split(/\s+/,$1);
924            $smmakevars{'INSTALL_SUBDIRS'} = $1;
925        }
926        elsif (/^NOTSIMPLEMAKE_SUBDIRS\s*=\s*(.*)\s*\r?$/) {
927            foreach my $dir (split(/\s+/,$1)) {
928                $notSimplemakeDirs{$dir} = 1;
929            }
930        }
931        elsif (/^EXTRA_PROGRAMS\s*=\s*(.*)\s*$/) {
932            foreach $program (split(/\s+/,$1)) {
933                $extra_programs{$program} = 1;
934            }
935            $smmakevars{'EXTRA_PROGRAMS'} = $1;
936        }
937        elsif (/^EXTRA_LIBS\s*=\s*(.*)\s*$/) {
938            foreach $lib (split(/\s+/,$1)) {
939                $extra_libs{$lib} = 1;
940            }
941            $smmakevars{'EXTRA_LIBS'} = $1;
942        }
943        elsif (/^TAGS_DIRS\s*=\s*(.*)\s*$/) {
944            # Keep track of tags dirs
945            @tags_dirs = split( /\s+/,$1);
946            $smmakevars{'TAGS_DIRS'} = $1;
947        }
948        elsif (/^EXTRA_DIRS\s*=\s*(.*)\s*$/) {
949            @extra_dirs = split( /\s+/,$1);
950            $smmakevars{'EXTRA_DIRS'} = $1;
951        }
952        elsif (/^OTHER_DIRS\s*=\s*(.*)\s*$/) {
953            @other_dirs = split( /\s+/,$1);
954            $smmakevars{'OTHER_DIRS'} = $1;
955        }
956        elsif (/^EXTERNAL_LIBS\s*=\s*(.*)\s*$/) {
957            foreach $lib (split(/\s+/,$1)) {
958                $external_libraries{$lib} = 1;
959            }
960            $smmakevars{'EXTERNAL_LIBS'} = $1;
961        }
962        elsif (/^(\w+)\s*\+=\s*(.*)\s*$/){
963            # Use this form to prepend values to some of the
964            # autoconf generated names, e.g., to change
965            # LIBS = \@LIBS\@
966            # to
967            # LIBS = \@EXAMPLE_LIBS\@ \@LIBS\@
968            # use
969            # LIBS += \@EXAMPLE_LIBS\@
970            $varname = $1;
971            $varvalue = $2;
972            $PrependVar{$1} = $2;
973        }
974        elsif (/^(\w*)_ADD\s*=\s*(.*)\s*$/) {
975            # This lets us define "nameAdd = value" by
976            # adding "name_ADD = value" to the makefile.sm
977            # We Could use the smvar form or the prepend form, but
978            # this gives us a slightly cleaner and more controled
979            # way (used for now only with docargs_ADD)
980            $varname = $1 . "Add";
981            $varvalue = $2;
982            $${varname} = $varvalue;
983        }
984        elsif ($nocomments && /^\s*#/) {
985               ;
986           }
987        elsif (/^smvar_(\w+)\s*=\s*(.*)/) {
988            # Allow the user to override any simplemake variable
989            # E.g.,
990            # smvar_autoconf = /foo/bar/fixedac
991            # causes simplemake to replace "autoconf" with "/foo/bar/fixedac"
992            $varname = $1;
993            $value   = $2;
994            # Save old values
995            $simplemake_vars{$varname} = $$varname;
996            $$varname = $value;
997            print STDERR "setting $varname to $value\n" if $debug;
998        }
999        elsif (/^smvarSubdir_(\w+)\s*=\s*(.*)/) {
1000            my $varname = $1;
1001            my $varvalue = $2;
1002            if ($varname =~ /;/ || $varvalue =~ /;/) {
1003                print STDERR "smvarSubdir_$varname=$varvalue must not contain a semicolon\n";
1004                print STDERR "This command will be ignored\n";
1005            }
1006            else {
1007                # Save the name with the CURRENT value, then update the
1008                # value
1009                my $oldvalue = "";
1010                if (defined($$varname)) {
1011                    $oldvalue = $$varname;
1012                }
1013                if ($oldvalue =~ /;/) {
1014                    print STDERR "Cannot use smvarSubdir_$varname to replace a value that includes a semicolon (current value is $oldvalue)\n";
1015                }
1016                else {
1017                    $gSubdirSMVarsSeen .= "$varname=$oldvalue;";
1018                    $$varname = $varvalue;
1019                }
1020            }
1021        }           
1022        elsif (/^noinst/) {
1023            # Automake target to identify some programs/libraries as
1024            # not to be installed.
1025            # Skip for now
1026            ;
1027        }
1028        elsif (/^([\w-]*)_SOURCES\s*=\s*(.*)\s*$/) {
1029            # programs
1030            $pgm = $1;
1031            $pgmsrc = $2;
1032            $programs{$pgm} = $pgmsrc;
1033            # Add to targets
1034            $alltargets[$#alltargets+1] = $pgm;
1035            # Keep track of source types
1036            &FindSrcTypes( $pgmsrc );
1037            # Keep track of source files
1038            &SaveSrcNames( $pgmsrc );
1039            # Find program source type
1040            $pgmsrctype{$pgm} = &FindPgmSrcType( $pgm, $pgmsrc );
1041        }
1042        elsif (/^([\w-]*)_LDADD\s*=\s*(.*)\s*$/) {
1043            $pgm_ldadd{$1} = $2;
1044        }
1045        elsif (/^LDADD\s*=\s*(.*)\s*$/) {
1046            $ldadd_all = $1;
1047        }
1048        elsif (/^([\w-]*)_DEPADD\s*=\s*(.*)\s*$/) {
1049            $pgm_depadd{$1} = $2;
1050        }
1051        elsif (/^DEPADD\s*=\s*(.*)\s*$/) {
1052            $depadd_all = $1;
1053        }
1054        elsif (/^([\w-]+)\s*=\s*(.*)\s*$/) {
1055            $other_vars .= "$origline";
1056            # Save all variable names
1057            $makevars{$1} = $2;
1058            # Look for special autoconf directory names
1059            &LookForAutoconfDirs( $_ );
1060        }
1061        elsif (/^([^:\s]*)\s*:(.*)$/) {
1062            # Remember user-defined targets.
1063            $usertargets{$1} = $_;
1064            $other_text .= "$origline";
1065            # We could copy lines until we saw a blank line
1066            if ($1 eq ".SUFFIXES") { $ExplicitSuffixes .= $2; }
1067            # Look for special autoconf directory names
1068            &LookForAutoconfDirs( $_ );
1069            &LookForSuffixes( $_ );
1070            &LookForVariables( $_ );
1071        }
1072        else {
1073            $other_text .= "$origline";
1074            # Look for special autoconf directory names
1075            if (!/^\s*#/) {
1076                &LookForAutoconfDirs( $_ );
1077            }
1078            &LookForVariables( $_ );
1079        }
1080    $origline = "";
1081    }
1082
1083    # For the simplemake maint target, see if smdir references
1084    # any of the autoconf directories (so that we'll include the
1085    # appropriate lines in the Makefile.in header)
1086    if ($maint_targets && $smdir && $smdir ne "") {
1087        &LookForAutoconfDirs( $smdir );
1088    }
1089
1090}
1091
1092sub WriteMfile {
1093    $maxline = 80;
1094    $output_filename = $_[0];
1095    # Write out the generated Makefile
1096    unlink $output_filename . ".new";
1097    open( FD, ">$output_filename.new" ) || die "Could not open $output_filename\n.new";
1098
1099    print FD "# This $output_filename created by simplemake.  Do not edit$newline$newline";
1100    if ($output_filename =~ /Makefile\.in/) {
1101        print FD "# \@configure_input\@$newline";
1102    }
1103    # Ensure that the default target takes us to "all"
1104    print FD "$newline$makeBlockSep";
1105    print FD "all: all-redirect$newline$newline";
1106    # Autoconf sets a number of directories that some tools (such as libtool)
1107    # may rely on. 
1108    if ($useinclude) {
1109        printMakeVariable( FD, "SHELL", "\@SHELL\@" );
1110        print FD "include $includedir/$makefilebase$newline";
1111        # Print out variables before generated targets
1112        print FD $other_vars;
1113        print FD "$newline";
1114    }
1115    else {
1116        # We may want to break DefaultRules into a pre and post version
1117        &DefaultVariables;
1118
1119        # Other variables
1120       
1121        # Print out variables before generated targets
1122        print FD $other_vars;
1123        print FD "$newline";
1124
1125        # If there were any uses of the smmakevars, add them to the
1126        # output here
1127        my $sawvar = 0;
1128        foreach my $var (keys(%vars_seen)) {
1129            if (defined($smmakevars{$var})) {
1130                print FD "$var = ";
1131                my $contline = "";
1132                foreach my $varline (split(/\n/,$smmakevars{$var})) {
1133                    print FD "$contline$varline";
1134                    $contline = "\\$newline\t";
1135                }
1136                print FD $newline;
1137                $sawvar = 1;
1138            }
1139        }
1140        if ($sawvar) { print FD $newline; }
1141
1142        &DefaultRules;
1143    }
1144
1145    &SMInvokeAction( "OutputHeader" );
1146
1147    # Generate the all-redirect: target (libraries, programs, and
1148    # anything specified by all-local)
1149    &TargetAll;
1150
1151    # Output the generated targets.  First, the libraries and the shared
1152    # libraries
1153    &TargetLibraries;
1154    if ($do_sharedlibs) {
1155        &TargetSharedLibraries( \%libraries );
1156        if (defined($optinstall_files{'SHLIB'})) {
1157            &CreateOptInstallSHLibs( 'SHLIB' );
1158        }
1159        if (defined($optinstall_files{'DLLLIB'})) {
1160            print STDOUT "DLLLIB target in $curdir\n" if $debug;
1161            &CreateOptInstallSHLibs( 'DLLLIB' );
1162        }
1163    }
1164
1165    # Handle any specifically requested shared libraries (ones that
1166    # have no static counterpart)
1167    if (%shared_libraries) {
1168        # If any shared libraries were requested...
1169        &TargetSharedLibraries( \%shared_libraries );
1170        foreach $libname (keys(%shared_libraries)) {
1171            &TargetSharedLibraryFinal( "lib$libname.la", "lib$libname.\@SHLIB_EXT\@", "." );
1172        }
1173    }
1174
1175    if ($do_profilelibs && $found_profilelib) {
1176        &print_make_endline( FD );
1177        print FD $makeBlockSep;
1178        &TargetProfileLibraries;
1179        print FD $makeBlockSep;
1180    }
1181
1182    # Coverage analysis
1183    &TargetGcov;
1184
1185    # Next, the programs
1186    &TargetPrograms;
1187
1188    # Documentation
1189    &TargetDocs;
1190
1191    print FD $makeBlockSep;
1192    &TargetInstall;
1193    print FD $makeBlockSep;
1194   
1195    #------------kumud_parallel_fix---------------------------------------
1196    &TargetExecutables;
1197
1198    # This is ugly, but we need to tell the install target when we're at
1199    # the top for the documentation.  This should be promoted to
1200    # a more general sense of "at the top" for all areas.
1201    $doc_attop = 0;
1202
1203    if ($do_dependencies ne "no") {
1204        if ($do_dependencies eq "static") {
1205            &TargetDependenciesStatic;
1206        }
1207        elsif ($do_dependencies eq "ignore") {
1208            # Add a null target so that recursive targets work
1209            print FD "dependencies:$newline";
1210        }
1211        else {
1212            &TargetDependenciesDynamic;
1213        }
1214    }
1215    elsif ($dependenciesDummy eq "yes") {
1216        print FD "# Dummy target$newline";
1217        print FD "dependencies:$newline$newline";
1218    }
1219
1220
1221    # Tags
1222    print FD $makeBlockSep;
1223    &TargetTags;
1224    print FD $makeBlockSep;
1225
1226    # Unrecognized lines go here
1227    print FD $other_text;
1228
1229    # Add a final target, used by gnumake
1230    print FD "${newline}FORCE_TARGET:${newline}${newline}";
1231
1232    close FD;
1233
1234    &ReplaceIfDifferent( $output_filename, $output_filename . ".new" );
1235
1236    # FIXME: Make the file read only
1237    # ($dev,$ino,$mode) = stat $output_filename
1238    # Modifiy $mode to remove write permissions
1239    # use chmod $mode $output_filename
1240    # to change permissions
1241
1242    # If the user overrode any variables, restore them here
1243    foreach $varname (keys(%simplemake_vars)) {
1244        print STDERR "Restoring $varname to $simplemake_vars{$varname}\n" if $debug;
1245        $$varname = $simplemake_vars{$varname}
1246    }
1247}
1248
1249#
1250# ===========================================================================
1251# Output files may contain either a set of default rules, written by this
1252# routine, or an include of a set of base rules.
1253#
1254sub DefaultVariables {
1255    # SHELL must be in uppercase for Make to use it as the shell to
1256    # execute commands with.
1257    printMakeVariable( FD, "SHELL", "\@SHELL\@" );
1258    printMakeVariable( FD, "LIB_SUBSYSTEM", "\@LIB_SUBSYSTEM\@" );
1259    # Library definitions
1260    #if (scalar(%libraries)) {
1261        # Add ar, ranlib definitions if there are any library targets.
1262        printMakeVariable( FD, "AR", "\@AR\@" );
1263        printMakeVariable( FD, "RANLIB", "\@RANLIB\@" );
1264    #}
1265    if ($do_sharedlibs) {
1266        if (defined($optinstall_files{'SHLIB'}) ||
1267            defined($optinstall_files{'DLLLIB'})) {
1268            # Add the definition of libtool in case we're using
1269            # libtool to provide the shared library.
1270            printMakeVariable( FD, "LIBTOOL", "\@LIBTOOL\@" );
1271            printMakeVariable( FD, "CREATESHLIB", "\@CREATESHLIB\@" );
1272            print FD "$shlibdefs{'c'}$newline";
1273        }
1274        elsif ($found_sharedlib) {
1275            # No install target, but a shared library is begin built
1276            # Add the definition of libtool incase we're using
1277            # libtool to provide the shared library.
1278            printMakeVariable( FD, "LIBTOOL", "\@LIBTOOL\@" );
1279            printMakeVariable( FD, "CREATESHLIB", "\@CREATESHLIB\@" );
1280            print FD "$shlibdefs{'c'}$newline";
1281            printMakeVariable( FD, "MKDIR_P", "\@MKDIR_P\@" );
1282        }
1283    }
1284
1285    if (scalar(%install_files) || scalar(%optinstall_files)) {
1286        print FD "INSTALL         = \@INSTALL\@$newline";
1287        print FD "INSTALL_PROGRAM = \@INSTALL_PROGRAM\@$newline";
1288        print FD "INSTALL_SCRIPT  = \@INSTALL_SCRIPT\@$newline";
1289        print FD "INSTALL_DATA    = \@INSTALL_DATA\@$newline";
1290        printMakeVariable( FD, "MKDIR_P", "\@MKDIR_P\@" );
1291    }
1292
1293    # Directory definitions
1294    %dir_added = ();
1295    foreach $dir (keys(%dirs_seen)) {
1296        if (!defined($dir_added{$dir})) {
1297            print FD "$dirdefs{$dir}$newline";
1298            $dir_added{$dir} = 1;
1299            if (defined($required_dirs{$dir})) {
1300                foreach $rdir (split(/\s+/,$required_dirs{$dir})) {
1301                    if (!defined($dir_added{$rdir})) {
1302                        print FD "$dirdefs{$rdir}$newline";
1303                        $dir_added{$rdir} = 1;
1304                    }
1305                }
1306            }
1307        }
1308    }
1309    if (scalar(%install_files) || scalar(%optinstall_files)) {
1310        if (!defined($dir_added{'prefix'})) {
1311            $dir_added{'prefix'} = 1;
1312            print FD "$dirdefs{'prefix'}$newline";
1313        }
1314    }
1315    foreach $dir (keys(%install_files),keys(%optinstall_files)) {
1316        # Handle the derived dirs for the install directories
1317        $dir = $InstallDirFromKind{$dir};
1318        if (!defined($required_dirs{$dir})) {
1319            print STDERR "Warning: No entry $dir in required_dirs\n";
1320        }
1321        foreach $rdir (split(/\s+/,$required_dirs{$dir})) {
1322            if (!defined($dir_added{$rdir})) {
1323                print FD "$dirdefs{$rdir}$newline";
1324                $dir_added{$rdir} = 1;
1325            }
1326        }
1327    }
1328    foreach $dir (keys(%install_files),keys(%optinstall_files)) {
1329        $dir = $InstallDirFromKind{$dir};
1330        if (!defined($dir_added{$dir})) {
1331            #$resultdir = $dirdefs{$dir};
1332            if (!defined($dirdefs{$dir})) {
1333                print STDERR "Warning: no entry $dir in dirdefs\n";
1334            }
1335            print FD "$dirdefs{$dir}$newline";
1336            $dir_added{$dir} = 1;
1337        }
1338    }
1339
1340    &InstallDocDirs;
1341
1342    # Miscellaneous.  This needs to be improved.  This is really needed
1343    # only for some targets
1344    # The definition of DEFS is the same as for Automake
1345    if (defined($ext_seen{"c"}) || defined($ext_seen{"cxx"}) ||
1346        defined($ext_seen{"cpp"})) {
1347        if (!defined($makevars{'DEFS'})) {
1348            printMakeVariable( FD, "DEFS", "\@DEFS\@ -I. -I\${srcdir}" );
1349        }
1350        # What to do about includes?  If they were set explicitly,
1351        # don't use the default.
1352        if (!defined($makevars{"INCLUDES"})) {
1353            printMakeVariable( FD, "INCLUDES", $include_list );
1354        }
1355        if (!defined($makevars{"CPPFLAGS"})) {
1356            printMakeVariable( FD, "CPPFLAGS", "\@CPPFLAGS\@" );
1357        }
1358    }
1359    # Add the LIBS if there are any programs to build
1360    if (scalar(%pgmlinktypes)) {
1361        if (!defined($makevars{"LIBS"})) {
1362            printMakeVariable( FD, "LIBS", "\@LIBS\@" );
1363        }
1364    }
1365
1366    # If there are subdirs, we need make.  Also needed by
1367    #    shared library support
1368    #    profile library support
1369    #    postambles
1370    #    local targets
1371    #    install (but a subset of subdir)
1372    # so we always add MAKE (originally checked for $#subdirs >= 0
1373    # and $#doc_subdirs >= 0)
1374    if (! defined($makevars{"MAKE"}) ) {
1375        printMakeVariable( FD, "MAKE", "\@MAKE\@" );
1376    }
1377
1378    # Add any standard definitions
1379    if ($commonmake ne "") {
1380        print FD "$commonmake$newline";
1381    }
1382
1383    # Definitions for each possible program type seen
1384    $any_prog_def = 0;
1385    foreach $ext (keys(%ext_seen)) {
1386        print "ext seen is :$ext:\n" if $debug;
1387        $extkey = "$ext:o";
1388        if (defined($extdef{$extkey})) {
1389            foreach $line (split(/\n/,$extdef{$extkey})) {
1390                # Check for an override
1391                if ($line =~ /^(\w+)(\s*)=(.*)/) {
1392                    my $var = $1;
1393                    my $spacing = $2;
1394                    my $value = $3;
1395                    if (defined($makevars{$var})) {
1396                        print "Using override definition of $var\n" if $debug;
1397                        next;
1398                    }
1399                    if (defined($PrependVar{$var})) {
1400                        $line = "$var$spacing= " . $PrependVar{$var} . " $value";
1401                    }
1402                }
1403                print FD "$line$newline";
1404            }
1405        }
1406        if (defined($pgmlinktypes{$ext})) {
1407            # Allow the user to override the definition
1408            my $def = $progdefs{$ext};
1409            if ($def =~ /(\S+)\s*=.*/) {
1410                $def = $1;
1411            }
1412            if (!defined($makevars{$def})) {
1413                print FD "$progdefs{$ext}$newline";
1414            }
1415            $any_prog_def = 1;
1416        }
1417        if ($do_sharedlibs || $found_sharedlib) {
1418            if ($#allshlibtargets >= 0) {
1419                # Only add the libtool definition if there are targets that
1420                # may need it.
1421                printMakeVariable( FD, "LIBTOOL", "\@LIBTOOL\@" );
1422                # We only need CREATESHLIB to finish off the library
1423                if (%shared_libraries) {
1424                    printMakeVariable( FD, "CREATESHLIB", "\@CREATESHLIB\@" );
1425                }
1426            }
1427            $extkey = "$ext:lo";
1428            if (defined($extdef{$extkey})) {
1429                print FD "$extdef{$extkey}$newline";
1430            }
1431            else {
1432                print FD $newline;
1433            }
1434               
1435        }
1436    }
1437    if ($any_prog_def) {
1438        # These are special definitions that are shared by all
1439        # pgmlink types
1440        if (!defined($makevars{"LDFLAGS"})) {
1441            my $otherflags = "";
1442            if (defined($PrependVar{'LDFLAGS'})) {
1443                $otherflags = $PrependVar{'LDFLAGS'};
1444            }
1445            print FD "LDFLAGS     = $otherflags \@LDFLAGS\@ $ldadd_all$newline";
1446        }
1447    }
1448    print FD "$newline";
1449#    foreach $ext (keys(%pgmlinktypes)) {
1450#    }
1451
1452    if ($vpath_config) {
1453        print FD '@VPATH@'; print FD "$newline";
1454    }
1455    else {
1456        # Some make programs require a specific directory, not a make
1457        # variable, in the VPATH specification
1458        print FD "VPATH = .:\@srcdir\@$newline";
1459    }
1460
1461    &VariableDocs;
1462}
1463
1464sub DefaultRules {
1465
1466    # Add the compilation rules.  Include only those needed for the
1467    # given files.  Remove all default suffix rules
1468    if (scalar(%ext_seen)) {
1469        $suffixes = ".o";
1470        if ($maint_perf_targets && !($suffixes =~ /\.s/)) {
1471            $suffixes .= " .s";
1472        }
1473        if ($do_sharedlibs || $found_sharedlib) {
1474            $suffixes .= " .lo";
1475        }
1476    }
1477    foreach $ext (keys(%ext_seen)) {
1478        $suffixes .= " .$ext";
1479    }
1480   
1481    # Finally, update suffixes from any other source.  Currently, this
1482    # handles the suffixes for document generation.
1483    &SuffixDocs;
1484
1485    print FD ".SUFFIXES:$newline";
1486    # Grrr.
1487    # OSF1 make complains if there are no suffix items.  To make it happy,
1488    # *always* add .o .c
1489    if ("$suffixes $ExplicitSuffixes" ne " ") {
1490        print FD ".SUFFIXES: $suffixes $ExplicitSuffixes$newline";
1491    }
1492    else {
1493        print FD "# Some make programs complain if no suffixes are set$newline";
1494        print FD ".SUFFIXES: .c .o$newline";
1495    }
1496
1497    # To make it easier to build programs, conditionally add a
1498    # default "build program" rule from the seen sourcecode extensions
1499    foreach $ext (keys(%ext_seen)) {
1500        # Skip any rules for .o files that we've seen
1501        if ($ext eq "o") { next; }
1502        # If we overrode the default rule for this key, then skip that
1503        # as well
1504        if (defined($usertargets{".$ext.o"})) { next; }
1505        print FD ".$ext.o:$newline";
1506        if ($found_profilelib) {
1507            # Use a special rule when building the non-profile-lib version
1508            $extkey = "$ext:o";
1509            # COMMAND PRINTING
1510            if (defined($extstring{$extkey})) {
1511                &PrintVerboseOptionCommand( "$extrules_with_profile{$extkey}",
1512                                            "-", "$extstring{$extkey}" );
1513            }
1514            else {
1515                print FD "\t$extrules_with_profile{$extkey}$newline";
1516            }       
1517        }
1518        else {
1519            $extkey = "$ext:o";
1520            if (defined($extrules{$extkey})) {
1521                # COMMAND PRINTING
1522                if (defined($extstring{$extkey})) {
1523                    &PrintVerboseOptionCommand( "$extrules{$extkey}", "-",
1524                                                "$extstring{$extkey}" );
1525                }
1526                else {
1527                    print FD "\t$extrules{$extkey}$newline";
1528                }
1529            }
1530            else {
1531                print FD $newline;
1532            }
1533        }
1534        if ($do_sharedlibs || $found_sharedlib) {
1535            $extkey = "$ext:lo";
1536            print FD ".$ext.lo:$newline";
1537            if (defined($extrules{$extkey})) {
1538                # COMMAND PRINTING
1539                if (defined($extstring{$extkey})) {
1540                    # the lo rules have newlines in them, so we need to escape them,
1541                    # as well as remove any @ prefixes
1542                    my $escaped_rule = $extrules{$extkey};
1543                    $escaped_rule =~ s/$newline(\t+)\@*/ ; \\$newline$1echo /g;
1544                    &PrintVerboseOptionCommand( "$extrules{$extkey}", "-",
1545                                                "$extstring{$extkey}" );
1546                }
1547                else {
1548                    print FD "\t$extrules{$extkey}$newline";
1549                }
1550            }
1551        }
1552        # For maintainers, make it easy to create the asm versions
1553        if ($maint_perf_targets) {
1554            $extkey = "$ext:s";
1555            if (defined($extrules{$extkey})) {
1556                print FD ".$ext.s:$newline";
1557                print FD "\t$extrules{$extkey}$newline";
1558            }
1559        }
1560        if ($maint_targets) {
1561            # Add the target that applies the preprocessor to the source file
1562            $extkey = "$ext:txt";
1563            if (defined($extrules{$extkey})) {
1564                print FD ".$ext.txt:$newline";
1565                print FD "\t$extrules{$extkey}$newline";
1566            }
1567        }
1568
1569        $extkey = "$ext:";
1570        # We may want to make this conditional, only generating it
1571        # when desired.
1572        if (defined($extrules{$extkey})) {
1573            print FD ".$extkey$newline";
1574            # COMMAND PRINTING
1575            if (defined($extstring{$extkey})) {
1576                &PrintVerboseOptionCommand( "$extrules{$extkey}", "-",
1577                                            "$extstring{$extkey}" );
1578            }
1579            else {
1580                print FD "\t$extrules{$extkey}$newline";
1581            }
1582        }
1583    }
1584   
1585    # Other generic rules.  Currently, only for documents
1586    &RuleDocs;
1587
1588    # Configure update targets
1589    if ( -s "configure.in" && $maint_targets ) {
1590        # Convert ROOTDIR as necessary
1591        $aargs = $autoconf_args;
1592        if (!$rootdirpath || $rootdirpath eq "") {
1593            $aargs =~ s/ROOTDIR/\./;
1594        }
1595        else {
1596            #chomp( $rootdir =  $rootdirpath );
1597            ( $rootdir =  $rootdirpath ) =~ s/[\r\n]*$//; # David added
1598                #strip( $rootdir = $rootdirpath );
1599            $aargs =~ s/ROOTDIR/$rootdir/;
1600        }
1601        $aargs =~ s/\/\//\//;
1602        $autoconf_deps="";
1603        print "macro loc arg is $aargs\n" if $debug_confdir;
1604        # If there is a -l dir in the autoconf_args, then add that to the
1605        # dependencies (We use $acincdir_arg incase autoconf 2.57 is used,
1606        # in which case the argument is -I or -B, or in case autoconf 2.58
1607        # or later is used, in which case the argument may be changed again.
1608        # Argh.  In autoconf 2.59, -B doesn't work
1609        if ($aargs =~ /$acincdir_arg\s*([\.\/\w]*)/) {
1610            $macroloc = $1;
1611            # HACK.  If we've messed up the location, don't include it
1612            if (-s "$macroloc/aclocal.m4") {
1613                $autoconf_deps .= "$macroloc/aclocal.m4";
1614                # Extract includes from aclocal.m4
1615                open (AFD, "<$macroloc/aclocal.m4" );
1616                while (<AFD>) {
1617                    if (/^\s*builtin\(include,([\w-]*\.m4)\)\s*$/) {
1618                        $filename = "$macroloc/$1";
1619                        $autoconf_deps .= " $filename";
1620                    }
1621                }
1622                close (AFD);
1623            }
1624        }
1625        # Extract includes from configure.in
1626        open (AFD, "<configure.in" );
1627        while (<AFD>) {
1628            if (/^\s*builtin\(include,([\w\-\/\.]*\.m4)\)\s*$/)
1629            {
1630                $filename = $1;
1631                if (-s "$filename")
1632                {
1633                    $autoconf_deps .= " $filename";
1634                }
1635                elsif (($filename =~ /[^\.\/]+/) && defined($macroloc) && -s "$macroloc/$filename")
1636                {
1637                    $autoconf_deps .= " $macroloc/$filename";
1638                }
1639            }
1640        }
1641        close (AFD);
1642        #
1643        print FD "$newline";
1644        $header_depend="";
1645        if ($configure_has_config_headers ne "no") {
1646            $header_depend="\${srcdir}/$configure_has_config_headers ";
1647            if ($debugConfigHeaderDepend) {
1648                print "Adding $header_depend to configure target\n";
1649            }
1650        }
1651        &print_make_longline( FD,  "$header_depend \${srcdir}/configure: \${srcdir}/configure.in $autoconf_deps" );
1652        &print_make_setpos( 8 );
1653        &FindWorkingAutoconf ;
1654        # Use autoheader only if AC_CONFIG_HEADER is in the configure file
1655        #
1656        # With Autoconf 2.57, there is a "cache" that like all automake
1657        # caches, isn't reliable and must be removed
1658#       &print_make_longline( FD, "\t\@if [ -d autom4te.cache ] ; then rm -rf autom4te.cache ; fi" );
1659        # With some versions of autoconf, this cache has the version
1660        # number in it (!)
1661        &print_make_longline( FD, "\t\@rm -rf autom4te*.cache" );
1662        if ($configure_has_config_headers ne "no") {
1663            &print_make_longline( FD,  "\t(cd \${srcdir} && $autoheader_prog $aargs && \\$newline\t$autoconf $aargs )" );
1664        }
1665        else {
1666            &print_make_longline( FD,  "\t(cd \${srcdir} && $autoconf $aargs )" );
1667        }
1668        if ($fixup_autoconf_cd) {
1669            # This is needed for DOS in case the pwd contains blanks
1670            print FD "\t( cd \${srcdir} && sed -e 's/cd *\$\$ac_popdir/cd \"\$\$ac_popdir\"/g' configure > c.tmp ; mv -f c.tmp configure ; chmod a+x configure)$newline";
1671        }
1672    }
1673    if ($maint_targets && $smdir && $smdir ne "") {
1674        # FIXME: make smdir take a value from the Makefile.in (e.g,
1675        # $(top_abs_src)/maint instead of the location where it
1676        # was originally run.
1677        print FD "$newline";
1678        print FD $makeBlockSep;
1679        print FD "\${srcdir}/Makefile.in: \${srcdir}/Makefile.sm$newline";
1680        print FD "\t( cd \${srcdir} && $smdir/simplemake \\$newline";
1681        if ($rootdir) {
1682            print FD "\t-rootdir=$rootdir \\$newline";
1683        }
1684        print STDOUT "last_config_dir is $last_config_dir in $curdir\n" if $debug_confdir;
1685        if (defined($last_config_dir) && $last_config_dir ne "") {
1686            print FD "\t-configdir=$last_config_dir \\$newline";
1687        }
1688        foreach $curarg (@keepargs) {
1689            # Skip some special cases
1690            if ($curarg =~ /^-smvar_doc_attop=0/) { next; }
1691            # Must handle $ specially
1692            $tmparg = $curarg;
1693#           # FIXME: Should this be s/../g (change all instances)?
1694#           $tmparg =~ s/\$/\\\$\$/;
1695            if ($tmparg =~ /\s/) {
1696                print FD "\t\"$tmparg\" \\$newline";
1697            }
1698            else {
1699                print FD "\t$tmparg \\$newline";
1700            }
1701        }
1702        if ($lcurdir && defined($autoconf_files_by_dir{$lcurdir})) {
1703            print FD "\t-distcleanfiles=\"$autoconf_files_by_dir{$lcurdir}\" \\$newline";
1704        }
1705        print FD "\t-smvar_doc_attop=0 \\$newline";
1706        print FD "\t\tMakefile.sm )$newline";
1707        print FD "Makefile: \${srcdir}/Makefile.in$newline";
1708
1709        # The following does not always work correctly.  There may be
1710        # problem in handling jumps between directories
1711        my $real_last_config_dir = $last_config_dir;
1712        if (defined($makefile_configdir)) {
1713            $real_last_config_dir = $makefile_configdir;
1714            print "Replacing last config dir with $real_last_config_dir\n";
1715        }
1716       
1717        my $topdir = &GetPathToParent( $curdir, $real_last_config_dir );
1718        print "last config dir = $real_last_config_dir, topdir = $topdir\n" if $debug_confdir;
1719        if ($topdir eq "") {   
1720            $topdir = ".";
1721        }
1722
1723        # We need to use the enclosing configure, not always the top-level
1724        # configure.  Thus, we need to keep track of the directory of the
1725        # current configure, and the path to get to that configure.
1726        # We also allow this step to fail; for example, the
1727        # config.status may already have been removed.
1728        # Further, to make the clean step cleaner, we test for the
1729        # config.status file before trying to run it (using a simple
1730        # test -x config.status && ... works, but still generates noise
1731        # about ignoring a failing step.
1732
1733        $ignore_step = "-";
1734
1735        if ($topdir ne ".") {
1736            print FD "\t-cd $topdir && \\$newline";
1737            $ignore_step = "";
1738        }
1739        $relcurdir = $curdir;
1740        if ($real_last_config_dir) {
1741            my $quoted_dir = quotemeta $real_last_config_dir;
1742            $relcurdir =~ s/^$quoted_dir//;
1743        }
1744        print STDOUT "curdir is $curdir and relcurdir is $relcurdir\n" if $debug_confdir;
1745
1746        print FD "\t${ignore_step}if [ -x config.status ] ; then CONFIG_FILES=${relcurdir}Makefile CONFIG_HEADERS= \${SHELL} ./config.status ; fi$newline";
1747        print FD $makeBlockSep;
1748    }
1749    # The following are general targets that can be used to run a program
1750    # specified on the make command line
1751    &TargetInit( "apply" );
1752    print FD "\n";
1753    print FD "\t\$(ACTION) \$(ACTION_INPUT)$newline";
1754    # ToDo: we could control the subdirectories over which the recursion
1755    # is applied.
1756    &RecursiveOp( "apply" );
1757    &TargetPostamble( "apply" );
1758   
1759    # Clean targets
1760    &TargetClean;
1761}
1762
1763#
1764# ===========================================================================
1765#
1766# Look at a list of source files and determine the source types
1767#
1768# Eventually, make this $ext_seen{$extension} = 1,
1769# then generate code by using keys(%ext_seen).  Allows general
1770# extensions and simpler handling of rules (like adding .F and .f90 )
1771sub FindSrcTypes {
1772    my $source = $_[0];
1773    my $files = "";
1774    foreach my $sym (split(/\s+/,$source)) {
1775        print STDERR "Is $sym a make variable?\n" if $debug;
1776        $vsym = $sym;
1777        if ($vsym =~ /\$[\{\(]?(\w*)[\}\)]?/) {
1778            $vsym = $1;
1779        }
1780        if (defined($makevars{$vsym})) {
1781            print STDERR "yes, value is $makevars{$vsym}\n" if $debug;
1782            $files .= " $makevars{$vsym}";
1783        }
1784        else {
1785            $files .= " $sym";
1786        }
1787    }
1788    foreach my $file (split(/\s+/,$files)) {
1789        ($name,$ext) = split('\.',$file);
1790        if (defined($ext) && $ext ne "") {
1791            $ext_seen{$ext} = 1;
1792        }
1793    }
1794}
1795
1796# Save all conventional sources
1797# This is only approximate.
1798# We want to allow source files to be specified through other
1799# variables (e.g., ${Foo_sources}).
1800# Globals: regular_sources, regular_headers
1801sub SaveSrcNames {
1802    my $source = $_[0];
1803    my @files;
1804    my $file;
1805    # First, expand the source variable
1806    #print STDERR "Got $source ...\n";
1807    foreach $file (split(/\s+/,$source)) {
1808        #print STDERR "Checking $file ...\n";
1809        # Substitute for any make variables (1 level of substitution)
1810        $file = &ExpandMakeVars( $file );
1811        foreach $name (split(/\s+/,$file)) {
1812            $files[$#files+1] = $name;
1813        }
1814    }
1815   
1816    foreach $file (@files) {
1817        ($name,$ext) = split( '\.',$file);
1818        if (defined($ext)) {
1819            if (defined($extrules{"$ext:o"})) {
1820                $regular_sources .= " $file";
1821                $sources{$file} = 1;
1822            }
1823            elsif ($ext eq "h") {
1824                # FIXME: need to handle other header extensions;
1825                # e.g., MPICH2 uses .i as well
1826                $regular_headers .= " $file";
1827                $headers{$file} = 1;
1828            }
1829        }
1830    }
1831}
1832
1833#
1834# Find the name of the source file that matches the program.
1835# If none found, use c as the type
1836sub FindPgmSrcType {
1837    $pgm = $_[0];
1838    $pgmsrc = $_[1];
1839    # Also keep track of the types seen
1840    my %exttypes;
1841    my $firstext = "";
1842    foreach $file (split(/\s+/,$pgmsrc)) {
1843        ($name,$ext) = split('\.',$file);
1844        if ($name eq $pgm) {
1845            $pgmlinktypes{$ext} = 1;
1846            return $ext;
1847        }
1848        else {
1849            $exttypes{$ext} = 1;
1850            if ($firstext eq "") { $firstext = $ext; }
1851        }
1852    }
1853    if (defined($exttypes{"c"})) {
1854        $pgmlinktypes{"c"} = 1;
1855        return "c";
1856    }
1857    elsif (defined($exttypes{"cxx"})) {
1858        $pgmlinktypes{"cxx"} = 1;
1859        return "cxx";
1860    }
1861    elsif (defined($exttypes{"f90"})) {
1862        $pgmlinktypes{"f90"} = 1;
1863        return "f90";
1864    }
1865    else {
1866        $pgmlinktypes{$firstext} = 1;
1867        return $firstext;
1868    }
1869}
1870
1871sub ClearVars {
1872    # Extensions seen is a property of the makefile
1873    %ext_seen = ();
1874    # We include abs_srcdir because it is useful to know and some
1875    # steps may conditionally need it (so we may not know that we also
1876    # need abs_srcdir until it is too late to add it)
1877    # We include abs_builddir because it is useful to have the
1878    # build directory around (particularly for the TAGS step)
1879    %dirs_seen = ( "srcdir" => 1, "abs_srcdir" => 1, "abs_builddir" => 1 );
1880    $other_vars = "";
1881    $other_text = "";
1882    $regular_sources = "";
1883    #$header_sources = "";
1884    $regular_headers = "";
1885    %sources = ();
1886    %headers = ();
1887
1888    # Targets
1889    @alltargets = ();   # implicit targets
1890    @allshlibtargets = (); # implicit shared library targets
1891    @alldlllibtargets = (); # implicit dynamically loaded library targets
1892    %altalltargets = ();   # related targets to items in alltargets
1893    %usertargets = ();  # explicit, user-defined targets
1894    %extra_programs = ();
1895    %extra_libs     = ();
1896    %libraries = ();
1897    $libcount = 0;
1898    %libnum    = ();    # Gives number associated with library
1899    %shared_libraries = ();
1900    %shared_libraries_exports = ();
1901    %shared_libraries_libs = ();
1902    %profile_libraries = ();
1903    %profile_libraries_basename = (); # inverse of profile_libraries
1904    %profile_library_sources = ();
1905    %install_files = ();
1906    @install_subdirs = ();
1907    %install_dirs = ();
1908    %optinstall_files = ();
1909    $install_local_dirs = "";
1910    $gIssuedInstallLocal = 0;
1911    %libNotShared = ();
1912    %external_libraries = ();
1913    $found_profilelib = 0;
1914    $found_sharedlib  = 0;
1915    $InitSharedLibraryFinal = 0;
1916    %programs = ();
1917    %pgm_ldadd = ();
1918    $ldadd_all = "";
1919    %pgm_depadd = ();
1920    $depadd_all = "";
1921
1922    $gSubdirSMVarsSeen = "";
1923
1924    # Variables
1925    # makevars are variables seen in the Makefile.sm
1926    # addedMakeVars are variables that have been added to the output
1927    # Makefile.in
1928    %PrependVar = ();
1929    %makevars = ();
1930    %addedMakeVars = ();
1931    # smmakevars are variables that have been defined as SM variables.
1932    %smmakevars = ();
1933    # vars_seen is a hash of the variables used in the makefile
1934    %vars_seen = ();
1935    # Information about program targets
1936    %pgmlinktypes = ();
1937    # Other directories
1938    @subdirs = ();
1939    %notSimplemakeDirs = ();
1940    %subdir_autoconf_vars = ();
1941    $subdir_optionals = "";
1942    @doc_subdirs = ();
1943    $docargsAdd = "";
1944    %docthiskinddir = ();
1945    @extra_dirs = ();
1946    @tags_dirs  = ();
1947    @other_dirs = ();
1948    $subdirs_has_autoconf = 0;
1949    # Suffix definitions
1950    $ExplicitSuffixes = "";
1951    $suffixes = "";
1952
1953    # Document sources and directories
1954    %docdir = ();
1955    %docsrc = ();
1956    # These may be overriden on a file by file basis
1957    $autoconf = $autoconf_prog; # Name of autoconf program to use
1958    $autoconf_version = ""; # Any version is allowed
1959    # We cannot clear config_headers here because we may still
1960    # need to know that the configure in the current directory
1961    # has a header file, and this routine to clear vars is called for
1962    # every file.
1963    #$configure_has_config_headers = "no";
1964    %simplemake_vars = ();
1965
1966    # For any extensions, clear their global variables.
1967    &SMInvokeAction( "Clear" );
1968
1969}       
1970
1971#
1972# Expand all of the make variables in an expression.  This
1973# lets users use targets like
1974# libmpich_SOURCE_a = ${MPI_SOURCES}
1975sub ExpandMakeVars {
1976    # look for ${\w*} and replace with the value of $makevars{$1}
1977    my $line = $_[0];
1978    print "Looking at $line\n" if $debug;
1979
1980    if (!defined($line)) { return ""; }
1981
1982    my $after = "";
1983    my $processed = "";
1984    while ($line =~ /([^\$]*)\$([{\(])(\w+)([}\)])(.*)/) {
1985        my $before = $1;
1986        my $lb   = $2;
1987        my $mvar = $3;
1988        my $rb   = $4;
1989        $after   = $5;
1990        print "replacing \$$lb$mvar$rb\n" if $debug;
1991        # Rescan the replacement in case it contains a variable.
1992        # Undefined variables are left in place
1993        if (defined($makevars{$mvar})) {
1994            $processed .= $before;
1995            $line = $makevars{$mvar} . $after;
1996        }
1997#       elsif (defined($dirdefs{$mvar})) {
1998#           $processed .= $before;
1999#           $line = $dirdefs{$mvar} . $after;
2000#       }
2001        else {
2002            $processed .= $before . "\$$lb$mvar$rb";
2003            $line      = $after;
2004        }
2005    }
2006    $processed .= $line;
2007    print "expanded to $processed\n" if $debug;
2008    return $processed;
2009}
2010
2011#
2012# ===========================================================================
2013@config_dir = ();    # Stack of the location of the most recently seen
2014                     # configure script.  Used to create targets that
2015                     # need to run config.status from that directory.
2016
2017$last_config_dir = "";
2018
2019#
2020# ===========================================================================
2021
2022# These next two routines let us print out the file being processed only
2023# when we need to (e.g., before an error message).
2024$curFilename = "";
2025$curFilenamePrinted = 0;
2026sub ResetFileName {
2027    $curFilename = $_[0];
2028    $curFilenamePrinted = 0;
2029}
2030sub ShowFileName {
2031    if ($curFilenamePrinted) { return; }
2032    print "Processing $curdir$file\n" if (!$quiet && $debug_dirs);
2033    $curFilenamePrinted = 1;
2034}
2035
2036sub ProcessFile {
2037    $file = $_[0];
2038
2039    $gSubdirSMVarsSeen = "";
2040
2041    # FIXME: curdir?
2042    if (!$curdir) { $curdir = ""; }
2043    &ResetFileName( "$curdir$file" );
2044    print "Processing $curdir$file\n" if (!$quiet && $debug_dirs);
2045    $configure_has_config_headers = "no";
2046    if (-s "configure.in") {
2047        &ReadAutoconf;
2048        print "Found configure.in in $curdir, set last_config_dir to $curdir\n" if $debug_confdir;
2049        if ($curdir eq "") { $last_config_dir = "."; }
2050        else {  $last_config_dir = $curdir; }
2051    }
2052    &ReadMfile( $file );
2053    $output_name = $file;
2054    if ($create_configure_input) {
2055        $output_name =~ s/\.sm$/.in/;
2056    }
2057    &WriteMfile( $output_name );
2058   
2059    if ($gCheckForTargets) {
2060        &checkForTargets();
2061    }
2062
2063    # Process any subdirectories
2064    # The list of directories to process comes from the variables
2065    # defined in the Makefile.sm.  The following is the list
2066    my @dirs = (@subdirs,@other_dirs,@doc_subdirs,@tags_dirs);
2067    # Get a local copy of the "notsimplemake" hash
2068    my %notSimplemake = %notSimplemakeDirs;
2069    # First, check for names that are replaced by autoconf (e.g., @name@)
2070    # in the names of the directories.  For those variables, there should
2071    # be a corresponding SUBDIRS_name variable in the makefile that lists
2072    # *all* directories to which @name@ may be expanded by configure.
2073    my @actdirs = ();
2074    foreach my $dir (@dirs) {
2075        $sdir = $dir;
2076        print "Checking $sdir\n" if ($debug_dirs);
2077        if ($sdir =~ /@([^@]*)@/) {
2078            $subst_name = $1;
2079            $subdirs_has_autoconf = 1;
2080            #print "Found $subst_name\n";
2081            # Look up the special name
2082            $var_name = "SUBDIRS_$subst_name";
2083            #print "varname is $var_name\n";
2084            if (defined( $makevars{$var_name} )) {
2085                # Concatenate the value of the variable name to the list
2086                # of directories
2087                @actdirs = ( @actdirs, split( /\s+/, $makevars{$var_name} ) );
2088            }
2089        }
2090        else {
2091            $actdirs[$#actdirs+1] = $dir;
2092        }
2093    }
2094
2095    # Push the saved subdir vars onto a stack, to be popped at the end.
2096    print "Saving $gSubdirSMVarsSeen\n" if $gDebugSubdirVar && ($gSubdirSMVarsSeen ne "");
2097    $subdirsSMVars[$#subdirsSMVars+1] = $gSubdirSMVarsSeen;
2098   
2099    # For each of the directories, process it.
2100    M: foreach my $dir (@actdirs) {
2101        if ($dir eq ".") { next M; }
2102        if ($dir =~ /\.\./ || $dir =~ /.\/./) {
2103            # Skip directory changes that aren't simple
2104            &ShowFileName;
2105            print "$dir has .. in it (skipping)\n";
2106            print "Current dir is $curdir\n" if $debug;
2107            next M;
2108            #exit(1);
2109        }
2110        if (! -d $dir) {
2111            my $ldir = `pwd`;
2112            if (!defined($notSimplemake{$dir})) {
2113                &ShowFileName;
2114                print "Directory $curdir$dir does not exist\n";
2115                print "(Current location is $ldir)\n";
2116            }
2117            next M; }
2118        if (! -s "$dir/$file") {
2119            if (!defined($notSimplemake{$dir})) {
2120                print "File $curdir$dir/$file does not exist\n";
2121            }
2122            next M; }
2123        chdir $dir || die "Cannot change to directory $dir\n";
2124        $curdir .= "$dir/";
2125        $curdir = &CleanCurDir( $curdir );
2126        if ($dir =~ /\.\./) {
2127            &ShowFileName;
2128            print "changed to a non-obvious dir = $dir\n";
2129            my $ldir = $dir;
2130            while ($ldir =~ /^\.\.\//) {
2131                $rootdirpath =~ s/\.\.\/$//;
2132                $ldir =~ s/^\.\.\///;
2133            }
2134            while ($ldir =~ /^[^\/]+\//) {
2135                $rootdirpath .= "../";
2136                $ldir =~ s/^[^\/]+\///;
2137            }
2138            if ($ldir =~ /\S+/) {
2139                $rootdirpath .= "../";
2140            }           
2141        }
2142        else {
2143            $rootdirpath .= "../";
2144        }
2145        print "rootdir = $rootdirpath\n" if $debug_confdir;
2146        print "curdir = $curdir\n" if $debug_confdir;
2147        # Remember the last place that we saw a configure; push and
2148        # pop for each file that we process.
2149        $config_dir[$#config_dir+1] = $last_config_dir;
2150        print "config stack has depth $#config_dir\n" if $debug_confdir;
2151        print "relative path to configure dir is " . &GetPathToParent( $curdir, $last_config_dir ) . "\n" if $debug_confdir;
2152        &ProcessFile( $file );
2153        $last_config_dir = $config_dir[$#config_dir]; $#config_dir--;
2154        print "after processing, last_config_dir = $last_config_dir\n" if $debug_confdir;
2155        print "config stack has depth $#config_dir\n" if $debug_confdir;
2156        $rootdirpath =~ s/\.\.\/$//;
2157        chdir "..";
2158        $curdir =~ s/[^\/]*\/$//;
2159        $curdir = &CleanCurDir( $curdir );
2160    }
2161    # End of processing directories
2162
2163    # Restore any variables that were changed for the scope of this directory
2164    # subtree (emulate a stack; don't trust perls dynamic scoped local)
2165    my $subdirvars = $subdirsSMVars[$#subdirsSMVars]; $#subdirsSMVars--;
2166    if (!defined($subdirvars)) {
2167        print STDERR "subdirsSMVars stack count = $#subdirsSMVars in $curdir\n";
2168        print STDERR "previous value is $subdirsSMVars[$#subdirsSMVars]\n";
2169    }
2170    foreach my $varstring (split(/;/,$subdirvars)) {
2171        if ($varstring =~ /(\w+)=(.*)/s) {
2172            my $varname = $1;
2173            my $varvalue = $2;
2174            print "Restoring $$varname to $varvalue in $curdir\n" if $gDebugSubdirVar;
2175            $$varname = $varvalue;
2176        }
2177        elsif ($varstring ne "") {
2178            print STDERR "Internal Error: varstring = $varstring\n";
2179        }
2180    }                         
2181}
2182
2183sub ListTargets {
2184  foreach $target (@alltargets) {
2185      # Skip the extra programs
2186      if (defined($extra_programs{$target})) { next; }
2187      if (defined($extra_libs{$target})) { next; }
2188      # Add any alternate target (used for targets in other directories
2189      # to work around timestamp problems).
2190      if (defined($altalltargets{$target})) {
2191          print_make_line( FD, " " . $altalltargets{$target} );
2192      }
2193      print_make_line( FD,  " $target" );
2194  }
2195}
2196
2197
2198#
2199# Add to a target the designate operation in all subdirs (except for .)
2200#     &RecursiveOp( "target" [, optional array of directories, [checkMakefile] ] );
2201# If the array of directories is not included, (@extra_dirs,@subdirs)
2202# is used.  These are the arrays maintined by simplemake of the
2203# directories set by EXTRA_DIRS and SUB_DIRS.  The "optional array"
2204# is passed by name (i.e., the name of the array is passed, not the array
2205# itself).
2206#
2207# The third argument allows you to only execute the test if the
2208# Makefile is present.  This is used in the distclean targets and
2209# may be useful elsewhere.
2210#
2211# Special notes:
2212#    For a small number of directories, use a simpler (non loop) approach
2213#   
2214sub RecursiveOp {
2215    my $target = $_[0];
2216    my $subdirname = $_[1];
2217    my $checkForMakefile = $_[2];
2218    my $forThreashold = 3;
2219
2220    if (!defined($checkForMakefile) || $checkForMakefile eq "") {
2221        $checkForMakefile = 0;
2222    }
2223    # Get the optional arrays
2224    if (defined($subdirname) && $subdirname ne "") {
2225        @dirs = @$subdirname;
2226    }
2227    else {
2228        @dirs = (@extra_dirs, @subdirs);
2229    }
2230
2231    # Entries that are shell or autoconf variables have unknown count.
2232    #
2233    my $dirlistHasVariable = 0;
2234    foreach $dir (@dirs) {
2235        if ($dir =~ /@[^@]*@/) {
2236            $dirlistHasVariable = 1;
2237        }
2238        elsif ($dir =~ /\$/) {
2239            $dirlistHasVariable = 1;
2240        }
2241    }
2242
2243    print "n dirs = $#dirs\n" if $debug;
2244    if ($#dirs == 0 && $dirs[0] eq ".") { return; }
2245    if ($#dirs >= $forThreashold || $subdirs_has_autoconf ||
2246        $dirlistHasVariable) {
2247        print FD "\tfor dir in";
2248        foreach $dir (@dirs) {
2249            if ($dir ne ".") { print FD " $dir"; }
2250            if ($dir =~ /@[^@]*@/) {
2251                $subdirs_has_autoconf = 1;
2252            }       
2253        }
2254        # We may also want to check if subdirs is *only* autoconf;
2255        # if not, we don't need the -
2256        if ($subdirs_has_autoconf) {
2257            # Add a - incase there is a problem
2258          print FD " - ; do \\$newline";
2259          print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ; \\$newline";
2260          if ($checkForMakefile) {
2261              print FD "\t\tif [ ! -s \$\$dir/Makefile ] ; then continue ; fi ;\\$newline";
2262          }
2263          print FD "\t\t(cd \$\$dir && \${MAKE} $target ; ) ; done$newline";
2264        }       
2265        else {
2266          print FD " ; do \\$newline";
2267          if ($checkForMakefile) {
2268              print FD "\t\tif [ ! -s \$\$dir/Makefile ] ; then continue ; fi ;\\$newline";
2269          }
2270          print FD "\t\t(cd \$\$dir && \${MAKE} $target ; ) ; " .
2271            "done$newline";
2272        }
2273    }
2274    elsif ($#dirs >= 0) {
2275        foreach $dir (@dirs) {
2276            # Skip . and any empty names
2277            if ($dir ne "." && $dir =~ /\S/) {
2278                if ($checkForMakefile) {
2279                    print FD "\tif [ -s $dir/Makefile ] ; then (cd $dir && \$(MAKE) $target ) ; fi$newline";
2280                }
2281                else {
2282                    print FD "\t(cd $dir && \$(MAKE) $target )$newline";
2283                }
2284            }
2285        }
2286    }
2287}
2288
2289# A version of RecuriveOps for optional directories; this is careful
2290# to check for existence of both the directory and the Makefile
2291# RecursiveOpForOptionalDirs( dirs, target, checkmake )
2292sub RecursiveOpForOptionalDirs {
2293    my $subdirs = $_[0];
2294    my $target = $_[1];
2295    my $checkForMakefile = $_[2];
2296
2297    my $forThreshold = 3;
2298
2299    if ($subdirs ne "") {
2300        # Count the number of directories
2301        my @sdirs = split(/\s+/,$subdirs);
2302        if ($#sdirs >= $forThreshold) {
2303            print FD "\t-\@for dir in $subdirs ; do \\$newline";
2304            print FD "\t    if [ -s \$\$dir/Makefile ] ; then \\$newline";
2305            print FD "\t      (cd \$\$dir && \${MAKE} $target ;) ; fi ; \\$newline";
2306            print FD "\tdone$newline";
2307        }
2308        else {
2309            foreach my $dir (@sdirs) {
2310                if ($dir ne "." && $dir =~ /\S/) {
2311                    if ($checkForMakefile) {
2312                        print FD "\tif [ -s $dir/Makefile ] ; then (cd $dir && \$(MAKE) $target ) ; fi$newline";
2313                    }
2314                    else {
2315                        print FD "\t(cd $dir && \$(MAKE) $target )$newline";
2316                    }
2317                }
2318            }
2319        }
2320    }
2321}
2322
2323#
2324# Return the directory in which the named library should be in
2325sub GetLibLoc {
2326    my $libname = $_[0];
2327   
2328    my $libloc = "";
2329    if (defined($libdir{$libname})) {
2330        $libloc = $libdir{$libname};
2331        my $rootdir;
2332        if (!defined($rootdirpath)) {
2333            $rootdir = "."
2334            }
2335        else {
2336            $rootdir = $rootdirpath;
2337            $rootdir =~ s/\r?\n?$//; # strip off any newlines
2338        }
2339        $libloc =~ s/ROOTDIR/$rootdir/;
2340        # Remove duplicated //
2341        $libloc =~ s/\/\//\//;
2342    }
2343
2344    return $libloc;
2345}
2346
2347
2348#
2349# Look for autoconf directory variables that are used
2350sub LookForAutoconfDirs {
2351    $line = $_[0];
2352    print "Looking at $line\n" if $debug;
2353    # Look for \$\{\w*\} and \$\(\w*\)
2354    while ($line =~ /^[^\$]*\$(.*)/) {
2355        $line = $1;
2356        if ($line =~ /^\$\w+(.*)/) {
2357            # This is a shell variable; skip it
2358            $line = $1;
2359        }
2360        elsif ($line =~ /^[\{\(](\w+)[\}\)](.*)/) {
2361            $varname = $1;
2362            $line    = $2;
2363            print "Found $varname in line\n" if $debug;
2364            # Look for varname in the known names; add to dirs_seen
2365            if (defined($dirdefs{$varname})) {
2366                print "Adding $varname to dirs_seen\n" if $debug;
2367                $dirs_seen{$varname} = $varname;
2368            }
2369        }
2370        else {
2371            last;
2372        }
2373    }
2374}
2375
2376#
2377# Look for make variables that are used
2378sub LookForVariables {
2379    $line = $_[0];
2380    print "Looking at $line\n" if $debug;
2381    # Look for \$\{\w*\} and \$\(\w*\)
2382    while ($line =~ /^[^\$]*\$(.*)/) {
2383        $line = $1;
2384        if ($line =~ /^\$\w+(.*)/) {
2385            # This is a shell variable; skip it
2386            $line = $1;
2387        }
2388        elsif ($line =~ /^[\{\(](\w+)[\}\)](.*)/) {
2389            $varname = $1;
2390            $line    = $2;
2391            print "Found $varname in line\n" if $debug;
2392            $vars_seen{$varname} = 1;
2393        }
2394        else {
2395            last;
2396        }
2397    }
2398}
2399
2400sub LookForSuffixes {
2401    $line = $_[0];
2402    while ($line =~ /^[^\.]*\.(\w*)\s*(.*)$/) {
2403        $suffix = $1;
2404        $line   = $2;
2405        # For now, only check for suffixes that lead to .o files.
2406        # Later we can check the keys of extdef to see if they
2407        # match /$ext:.*/
2408        if (defined($extdef{"$suffix:o"})) { 
2409            $ext_seen{$suffix} = 1;
2410        }
2411    }
2412}
2413
2414#
2415# ===========================================================================
2416# The "all" target.
2417#
2418# Output the target list.  If there are extra_programs or
2419# extra_libs, note that.
2420# FIXME: there needs to be way to specify other local targets
2421# beyond the implicitly determined ones.  This needs to allow
2422# for both pre and post implicit target values
2423#
2424sub TargetAll {
2425    print_make_line( FD,  "all-redirect:" );
2426    if ($#subdirs > -1) {
2427        # If there are subdirectories, we must descend into them.
2428        # This branch does that, after adding the dependencies for the
2429        # target (if any).
2430        &TargetPreamble( "all" );
2431        print_make_endline( FD );
2432        # Now add the steps for the subdirectories
2433        $has_dot = 0;
2434        foreach $dir (@extra_dirs, @subdirs) {
2435            if ($dir eq ".") {
2436                if (scalar(@alltargets) ||
2437                    defined($usertargets{"all-local"})) {
2438                    $has_dot = 1;
2439                    print FD "\t\${MAKE} all-local$newline";
2440                    #----------------  Kumud check ----------------------------
2441                    #my $kumud_libloc= &GetLibLoc ( '${MPILIBNAME}');
2442                    #print FD "\tI am alive and the library location is $kumud_libloc";
2443                }
2444            }
2445            elsif ($dir =~ /@([^@]*)@/) {
2446                # May be a replaced variable
2447                print FD "\t${quietmake}for dir in $dir - ; do \\$newline";
2448                print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ; \\$newline";
2449                print FD "\t\tif ( cd \$\$dir && \${MAKE} all ) ; then : ; else exit 1; fi \\$newline";
2450                print FD "\tdone$newline";
2451            }
2452            else {
2453                print FD "\t${quietmake}(cd $dir && \${MAKE} all )$newline";
2454            }
2455        }
2456        # If subdirs has no dot but there are local targets, add an
2457        # implicit dot to the end.
2458        if (!$has_dot && $#alltargets > -1) {
2459            $has_dot = 1;
2460            print FD "\t\${MAKE} all-local$newline";
2461        }
2462
2463                   
2464        if ($has_dot && !defined($usertargets{"all-local"})) {
2465            # Add the default definition of all-local for the case where
2466            # a . is in the SUBDIR line
2467            print_make_line( FD, "all-local:" );
2468            &ListTargets;
2469            # ListTargets does *not* end the line
2470            print_make_endline( FD );
2471            # Add generation of shared libraries if necessary
2472            &TargetAllCommandsForSharedLibs;
2473            &TargetAllCommandsForDLLLibs;
2474        }
2475       
2476        #  Create the final shared library (typically .so) from the .la file
2477        if (defined($optinstall_files{'SHLIB'})) {
2478            # Conditionally create the shared libraries.
2479            print FD "\t\@if [ \"\@ENABLE_SHLIB\@\" != \"none\" ] ; then \\\n";
2480            foreach $libspec (split(/\s+/,$optinstall_files{'SHLIB'})) {
2481                if (defined($extra_libs{$libspec})) { next; }
2482                # Be careful of library names that are related to
2483                # the profile library (those libraries are built
2484                # as part of the "master" library name build)
2485                my $baselibname = $libspec;
2486                $baselibname =~ s/^.*\///g;
2487                $baselibname =~ s/^lib//;
2488                $baselibname =~ s/\..*//;
2489                # We need to be careful about the optional files, since
2490                # the prerequisites may not exist
2491                # We could either test on the conditions under which
2492                # the optional files should exist (this is probably the
2493                # best option), or we can coordinate with the
2494                # target that we invoke for each case.  We'll do the
2495                # latter for now and consider adding an optional predicate
2496                # that can be supplied for each OPTINSTALL item.
2497                if (!defined($profile_libraries_basename{$baselibname})) {
2498                    print "Building sharedlib library $baselibname (from $libspec) as part of all-redirect\n" if $gDebugWhy;
2499                    # Get the condition
2500                    my $prereq = $libspec;
2501                    $prereq =~ s/\.\@SHLIB_EXT\@/.la/;
2502                    print FD "\t    if [ -s $prereq ] ; then \\\n";
2503                    print FD "\t        echo \"make $libspec\" ;\\\n";
2504                    print FD "\t        \${MAKE} $libspec ; \\\n";
2505                    print FD "\t    fi ; \\\n";
2506                }
2507            }
2508            print FD "\tfi\n";
2509        }
2510        if (defined($optinstall_files{'DLLLIB'})) {
2511            #print STDOUT "in optinstall_files dlllib\n";
2512            # Conditionally create the dynamically loadable shared libraries.
2513            print FD "\t\@if [ \"\@BUILD_DLLS\@\" = \"yes\" ] ; then \\\n";
2514            foreach $libspec (split(/\s+/,$optinstall_files{'DLLLIB'})) {
2515                # Be careful of library names that are related to
2516                # the profile library (those libraries are built
2517                # as part of the "master" library name build)
2518                my $baselibname = $libspec;
2519                $baselibname =~ s/^.*\///g;
2520                $baselibname =~ s/^lib//;
2521                $baselibname =~ s/\..*//;
2522                # We need to be careful about the optional files, since
2523                # the prerequisites may not exist
2524                # We could either test on the conditions under which
2525                # the optional files should exist (this is probably the
2526                # best option), or we can coordinate with the
2527                # target that we invoke for each case.  We'll do the
2528                # latter for now and consider adding an optional predicate
2529                # that can be supplied for each OPTINSTALL item.
2530                if (!defined($profile_libraries_basename{$baselibname})) {
2531                    print "Building sharedlib library $baselibname (from $libspec) as part of all-redirect\n" if $gDebugWhy;
2532                    # Get the condition
2533                    my $prereq = $libspec;
2534                    $prereq =~ s/\.\@SHLIB_EXT\@/.la/;
2535                    print FD "\t    if [ -s $prereq ] ; then \\\n";
2536                    print FD "\t        echo \"make $libspec\" ;\\\n";
2537                    print FD "\t        \${MAKE} $libspec ; \\\n";
2538                    print FD "\t    fi ; \\\n";
2539                }
2540            }
2541            print FD "\tfi\n";
2542        }
2543        &TargetPostamble( "all" );
2544    }
2545    else {
2546        # This is a leaf, so we can list the dependencies. 
2547        &TargetPreamble( "all" );
2548        if (defined($usertargets{"all-local"})) {
2549            # Add all-local as a target
2550            print_make_line( FD, " all-local " );
2551        }
2552        &ListTargets;
2553        if ($found_profilelib) {
2554            print_make_endline( FD );
2555            # Add a conditional step
2556            print FD "\t\@if [ -n \"\@NO_WEAK_SYM\@\" ] ; then \\\n";
2557            foreach my $lib (keys(%profile_libraries)) {
2558                my $proflib = $profile_libraries{$lib};
2559                my $libstamp = ".libstamp" . $libnum{$proflib};
2560#               my $libloc = &GetLibLoc( $lib );
2561#               my $fullname = "${libloc}lib$proflib.a";
2562#               print FD "\t    \${MAKE} $fullname ; \\\n";
2563                print FD "\t    \${MAKE} $libstamp || exit 1; \\\n";
2564            }
2565            print FD "\tfi";
2566        }
2567        print_make_endline( FD );
2568        &TargetAllCommandsForSharedLibs;
2569        &TargetAllCommandsForDLLLibs;
2570        &TargetPostamble( "all" );
2571    }
2572    print_make_endline( FD );
2573} # TargetAll
2574# ---------------------------------------------------------------------------
2575# Routines to provide standard extensions through -preamble, -postamble,
2576# and -local
2577# -preamble allows you to *ADD* a step to be performed before the other
2578# dependencies, -postamble adds a step after the target is formed
2579#
2580# To ensure uniform handling of -preamble, the routine TargetInit( name )
2581# outputs the target and the preamble.
2582sub TargetInit {
2583    my $name = $_[0];
2584    print FD "$name: ";
2585    &TargetPreamble( $name );
2586}
2587sub TargetPreamble {
2588    my $name = $_[0];
2589    $name .= "-preamble";
2590    if (defined($usertargets{$name})) {
2591        print FD " $name";
2592    }
2593}
2594sub TargetPostamble {
2595    my $name = $_[0];
2596    $name .= "-postamble";
2597    if (defined($usertargets{$name})) {
2598        print FD "\t\${MAKE} $name$newline";
2599    }
2600}
2601# --------------------------------------------------------------------------
2602# Helper routines for the implementation of the "all" target.  Two
2603# complications here are that the handling of leaf Makefile.sm (those with
2604# no SUBDIRS) and non-leaf Makefile.sm are different for the "all" target.
2605# (a better long-term solution may be to redesign the handling of the all
2606# target).
2607# --------------------------------------------------------------------------
2608
2609# Add the commands to build shared libraries if any are defined
2610# (either explicitly or because we generate shared libraries for all
2611# libraries).
2612sub TargetAllCommandsForSharedLibs {
2613    if ($do_sharedlibs && $#allshlibtargets >= 0) {
2614        # Add a conditional step
2615        print FD "\t\@if [ \"\@ENABLE_SHLIB\@\" != \"none\" ] ; then \\\n";
2616        foreach $shlib (@allshlibtargets) {
2617            if (defined($extra_libs{$shlib})) { next; }
2618            # Get the library stamp name from the lib name
2619            my $libbase = $shlib;
2620            if ($shlib =~ /.*\/lib([^\/]*)/) {
2621                $libbase = $1;
2622            }
2623            my $libstamp = $shlib;
2624            if (defined($libnum{$libbase})) {
2625                $libstamp = ".libstamp" . $libnum{$libbase};
2626            }
2627            print FD "\t    \${MAKE} $libstamp || exit 1; \\\n";
2628        }
2629        if ($found_profilelib) {
2630            print FD "\t    if [ -n \"\@NO_WEAK_SYM\@\" ] ; then \\\n";
2631            foreach my $lib (keys(%profile_libraries)) {
2632                my $proflib = $profile_libraries{$lib};
2633                my $libloc = &GetLibLoc( $lib );
2634                my $fullname = "${libloc}lib$proflib.la";
2635                my $libstamp = ".libstamp" . $libnum{$proflib.".la"};
2636                print FD "\t        \${MAKE} $libstamp || exit 1; \\\n";
2637#               print FD "\t        \${MAKE} $fullname ; \\\n";
2638            }
2639            print FD "\t    fi ; \\\n";
2640        }
2641        print FD "\tfi\n";
2642    }
2643}
2644
2645sub TargetAllCommandsForDLLLibs {
2646    if ($do_sharedlibs && $#alldlllibtargets >= 0) {
2647        # Add a conditional step
2648        print FD "\t\@if [ \"\@BUILD_DLLS\@\" = \"yes\" ] ; then \\\n";
2649        foreach $shlib (@alldlllibtargets) {
2650            # Get the library stamp name from the lib name
2651            my $libbase = $shlib;
2652            if ($shlib =~ /.*\/lib([^\/]*)/) {
2653                $libbase = $1;
2654            }
2655            my $libstamp = $shlib;
2656            if (defined($libnum{$libbase})) {
2657                $libstamp = ".libstamp" . $libnum{$libbase};
2658            }
2659            print FD "\t    \${MAKE} $libstamp || exit 1; \\\n";
2660        }
2661        print FD "\tfi\n";
2662    }
2663}
2664
2665# --------------------------------------------------------------------------
2666#
2667# ===========================================================================
2668# The "clean" target
2669#
2670# Produces clean:, distclean:, and maintainerclean:
2671# If clean-local, distclean-local, or maintainer-clean-local were defined,
2672# they are included in the dependency lists
2673#
2674# The default for quietLine makes the clean lines quiet (no echo of the
2675# command).
2676#
2677# Notes:
2678# The clean target is relatively easy, because it involves only files
2679# created *after* the configure step. 
2680# The distclean and maintainer-clean steps are more complicated, because
2681# there is some interaction with the generated steps.  In particular,
2682# distclean must remove Makefile, but once the makefiles are gone,
2683# you can't execute another make step.  If you run maintainer-clean first,
2684# the the dependencies on Makefile:Makefile.in:Makefile.sm will force
2685# a reconstruction of some of the files that were just removed.
2686# Thus, we need to separate from the distclean and maintainer-clean targets
2687# the steps that remove the makefiles.  Thus, we have the
2688# following intermediate targets:
2689#    remove-makefile
2690#    remove-genmakefiles
2691# To simplify the construction of the targets, we use internal targets.
2692# Thus, distclean becomes:
2693# distclean: clean distclean-local distclean-xxx remove-makefile
2694#
2695# and maintainer-clean becomes
2696# maintainer-clean: clean maintainer-clean-local distclean-local \
2697#     distclean-xxx maintainer-clean-xxx remove-genmakefiles
2698#
2699#
2700#
2701sub TargetClean {
2702    my $otherMakefiles = "";
2703
2704    $programnames = join( ' ', keys(%programs));
2705    &TargetInit( "clean" );
2706    if (defined($usertargets{"clean-local"})) { print FD " clean-local"; }
2707    print FD "$newline";
2708    print FD "\t-${quietLine}rm -f *.o \${srcdir}/*.o $programnames$newline";
2709    &LibraryTimestampClean;
2710    # Add Windows names of executables
2711    if ($programnames ne "") {
2712        print FD "\t-${quietLine}rm -f";
2713        foreach $name (split(/\s+/,$programnames)) {
2714            print FD " $name.exe";
2715        }
2716        print FD "$newline";
2717        # Remove core files, including core files with process numbers
2718        # (produced by some versions of Linux)
2719        print FD "\t-${quietLine}rm -f core core.[0-9]*$newline";
2720    }
2721
2722    # Output this in all cases to clear any old files. 
2723    # (Don't make this conditional because it is important to remove
2724    # these files even if we're not building for enabling shared libraries
2725    # this time around.
2726    print FD "\t-${quietLine}rm -f *.lo \${srcdir}/*.lo$newline";
2727
2728    # Clean coverage analysis files
2729    &GcovClean;
2730
2731    # We can put a hook here to add additional clean targets.  For
2732    # the moment, we'll add an MPICH-2 specific target for this
2733    if ($programnames ne "") {
2734        # Testing of parallel program may produce log files.  This will remove
2735        # any existing irlog files
2736        print FD "\t-${quietLine}rm -f *.irlog*$newline";
2737    }
2738
2739    if ($maint_perf_targets) {
2740        # In this case, we want to remove any generated asm files,
2741        # to prevent them from being used in preference to the
2742        # original (e.g., C) source file
2743        my $input_sources;
2744        if ($regular_sources =~ /\S/) {
2745            $input_sources = $regular_sources;
2746        }
2747        elsif (defined($makevars{'SOURCES'})) {
2748            $input_sources = $makevars{'SOURCES'};
2749        }
2750        if (defined($input_sources)) {
2751            my $clean_files = "";
2752            foreach my $file (split(/\s+/,$input_sources)) {
2753                if ($file =~ /(.*)\.([^\.]+)/) {
2754                    my $base = $1;
2755                    my $ext  = $2;
2756                    if ($ext ne "s") {
2757                        $clean_files .= " $base.s";
2758                    }
2759                }
2760            }
2761            if ($clean_files ne "") {
2762                print FD "\t-${quietLine}rm -f $clean_files$newline";
2763            }
2764        }
2765    }
2766
2767    # For any extensions, handle the clean actions
2768    &SMInvokeAction( "OutputClean", FD );
2769
2770    # Finally, execute make clean in any subdirs
2771    &RecursiveOp( "clean" );
2772    &TargetPostamble( "clean" );
2773
2774    # --------------------------------------------
2775    # distclean target
2776    &TargetInit( "distclean" );
2777    print FD " clean";
2778    if (defined($usertargets{"distclean-local"})) {
2779        print FD " distclean-local";
2780    }
2781    print FD " distclean-xxx remove-makefile";
2782    &TargetPostamble( "distclean" );
2783
2784    print FD "$newline";
2785   
2786    print FD "distclean-xxx:$newline";
2787    # RecursiveOp uses extra_dirs,subdirs; the "1" forces it to check
2788    # for the existence of the Makefile
2789    &RecursiveOp( "distclean", "", 1 );
2790
2791    # Add clean of local libraries
2792    foreach $lib (keys(%extra_libs)) {
2793        print FD "\t-${quietLine}rm -f $lib$newline";
2794    }
2795
2796    # Remove any local files last (in case this file is one of them)
2797    $rmfile = "";
2798    if (!$curdir) { $curdir = ""; }
2799    $lcurdir = $curdir;
2800    $lcurdir =~ s/\/$//;
2801    if (defined($autoconf_files_by_dir{$lcurdir})) {
2802        $rmfile = $autoconf_files_by_dir{$lcurdir};
2803        # Remove the Makefile.in from this list because it will
2804        # be handled separately
2805        if ($rmfile =~ /Makefile.in/) {
2806            $otherMakefiles .= "Makefile.in ";
2807            $rmfile =~ s/Makefile.in\s*//;
2808        }
2809        print FD "\t-${quietLine}rm -f $rmfile$newline";
2810        # Remove the configure cache that autoconf 2.57+ adds
2811        print FD "\t-${quietLine}rm -rf autom4te*.cache$newline";
2812    }
2813    if ($configure_has_config_headers ne "no") {
2814        # Add the AC_CONFIG_HEADER file, if any.
2815        print FD "\t-${quietLine}rm -f $configure_has_config_headers$newline";
2816    }
2817    # Handle files that aren't part of subdirs
2818    if (defined($autoconf_files_by_dir_orig{$lcurdir})) {
2819        my $otherfiles = $autoconf_files_by_dir_orig{$lcurdir};
2820        foreach $dir (@subdirs) {
2821            $otherfiles =~ s/ $dir\/\S*//g;
2822        }
2823        $otherfiles =~ s/^\s*//;
2824        # Is there anything left?
2825        if ($otherfiles =~ /\S+/) {
2826            print FD "\t-${quietLine}rm -f $otherfiles$newline";
2827        }
2828    }
2829   
2830    # For any extensions, handle the clean actions
2831    &SMInvokeAction( "OutputDistClean", FD );
2832
2833    # Another difficulty are the optional directories.  For example,
2834    # a SUBDIRS = foo \@bar\@
2835    # line (without the \, included since the simplemake.in file is
2836    # itself processed with autoconf)
2837    &RecursiveOpForOptionalDirs( $subdir_optionals, "distclean", 1 );
2838
2839    &DistCleanDependencies;
2840
2841    if ($distcleanfiles ne "") {
2842        print FD "\t-${quietLine}rm -f $distcleanfiles$newline";
2843    }
2844    print FD "\t-${quietLine}rm -f TAGS$newline";
2845
2846    # --------------------------
2847    if ($maint_targets) {
2848        # Should maintainer-clean also perform a distclean?
2849        # No, because distclean needs to remove the Makefiles, and
2850        # this target needs to remove entries that have dependencies
2851        # (e.g., the Makefile : Makefile.in : Makefile.sm dependency)
2852        &TargetInit( "maintainer-clean" );
2853        if (defined($usertargets{"maintainer-clean-local"})) {
2854            print FD " maintainer-clean-local";
2855        }
2856        print FD " distclean-xxx remove-genmakefiles";
2857        &TargetPostamble( "maintainer-clean" );
2858        print FD "$newline";
2859
2860        # For any extensions, handle the clean actions
2861        &SMInvokeAction( "OutputMaintainerClean", FD );
2862
2863        &RecursiveOp( "maintainer-clean" );
2864        # Remove the file that simplemake creates
2865        $otherMakefiles .= " $output_name";
2866        #print FD "\t-rm -f $output_name$newline";
2867        # eventually, this should also invoke distclean, but it must
2868        # do that only once (not recursively) and only after all other
2869        # uses of the Makefile, since distclean removes the Makefile
2870        # Directories containing autoconf should include an rm of configure
2871
2872        # This should also remove any files that will be created with
2873        # autoheader.  We'll need to check for files that are created
2874        # by autoheader, not just rely on the AC_CONFIG_HEADER command,
2875        # since some headers may be created by hand.  We'll ignore
2876        # this for now, since we uniformly use autoheader (and
2877        # simplemake runs autoheader if it finds AC_CONFIG_HEADER)
2878        if ($configure_has_config_headers ne "no") {
2879            print FD "\t-rm -f ";
2880            foreach $file (split(/\s+/,$configure_has_config_headers)) {
2881                print FD "$file.in ";
2882            }
2883            print FD "$newline";
2884        }
2885        # We also need to remove configure and autom4ate/ if present
2886    }
2887    &TargetRmMakefiles( $otherMakefiles );
2888
2889}
2890
2891#
2892# Generate the makefile removal targets
2893# TargetRmMakfiles( otherMakefiles )
2894#
2895# These are *NOT* recursive targets because they are local to the
2896# particular directory.
2897sub TargetRmMakefiles {
2898    my $otherMakefiles = $_[0];
2899    print FD "remove-makefile:$newline";
2900    print FD "\trm -f Makefile$newline";
2901    print FD "remove-genmakefiles:$newline";
2902    print FD "\trm -f $otherMakefiles Makefile$newline";
2903}
2904#
2905# Generate the core part of the distclean target
2906sub TargetDistclean {
2907}
2908#
2909# ===========================================================================
2910# Libraries
2911#
2912# We want to generate either a generic "update library from object files"
2913# or "update library member" for makes that support that feature (this
2914# is normally used only for the maintenance target).
2915
2916#
2917# LibraryBuild ( libname, libloc, libfiles, lib extension, member extension )
2918# Not quite right.  Need to include the update command as well as ways
2919# to handle the "special extensions", both for the library (e.g., .a vs. .la)
2920# and members (e.g., .o vs .lo)
2921sub LibraryBuild {
2922    my $libname = $_[0];
2923    my $libloc  = $_[1];
2924    my $sourcefiles = $_[2];
2925    my $libext = $_[3];
2926    my $memext = $_[4];
2927    my @objects=();
2928    if (!$dolib_member) {
2929        &print_make_line( FD, "${libloc}lib$libname.$libext: " );
2930    }
2931    # Handle any variables in the lib line
2932    if (!defined($sourcefiles)) {
2933        print STDERR "Warning: no source files in library $libname in LibraryBuild\n" ; }
2934    $sourcefiles = &ExpandMakeVars($sourcefiles);
2935    foreach $sourcefile (split(/\s+/,$sourcefiles)) {
2936        $ext = "";
2937        $obj = "";
2938        if ($sourcefile =~ /(.*)\.([^\.]*)/) {
2939            $obj = "$1.$memext";
2940            $ext = $2;
2941        }
2942        else {
2943            # Don't warn about autoconf variables (see below)
2944            if (! ($sourcefile =~ /^\@/) ) {
2945                print STDERR "Sourcefile is $sourcefile\n";
2946            }
2947        }
2948        # The special case for an extension of h handles the case where the
2949        # .h files are derived, and hence have special rules for creating
2950        # them.  We also ignore autoconf variables (eventually, we might
2951        # want to insist that valid values for that autoconf variable be
2952        # available).
2953        if ( (!defined($extrules{"$ext:o"}) && ($ext ne "h") &&
2954              ! ($sourcefile =~ /^\@/))) {
2955            # Sometimes we use our own rules for building objects.
2956            # We allow the user to specify the object files rather than
2957            # the source files
2958            if ($ext ne "o") {
2959                print STDERR "Unknown extension $ext for $sourcefile for library $libname\n";
2960            }
2961        }
2962       
2963        if ($dolib_member) {
2964            &print_make_line( FD, "${libloc}lib$libname.$libext($obj): $obj" );
2965            &print_make_endline( FD );
2966            # COMMAND PRINTING
2967            # ------------------------ Kumud_Parallel_Fix ----------------------
2968            # &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$libname.$libext \$?", "  AR" );
2969           
2970            if ($obj =~/\s*(\S+)\s*/){
2971                &PrintVerboseOptionCommand( "rm -rf lib$libname.$libext.manifest", "  rm" );
2972                &PrintVerboseOptionCommand( "echo \"\${abs_builddir}/$obj\" >> lib$libname.$libext.manifest", "  echo" );               
2973                print FD "\ttouch \${top_builddir}/lib/.lib$libname.$libext.timestamp$newline";
2974            }
2975           
2976        }
2977        else {
2978            if ($ext ne "h") {
2979                &print_make_line( FD, "$obj " );
2980                if ($obj =~/\s*(\S+)\s*/){
2981                    $objects[ $#objects+1 ]= $1;
2982                }
2983            }
2984        }
2985    }
2986    &SMInvokeAction( "OutputLibDependencies", $lib, $libloc, $memext );
2987    if (!$dolib_member) {
2988        &print_make_endline( FD );
2989        # ------------------------ Kumud_Parallel_Fix ----------------------
2990        # &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$libname.$libext \$?",
2991        &PrintVerboseOptionCommand( "rm -rf lib$libname.$libext.manifest", "  rm" );
2992        foreach $object (@objects){
2993            &PrintVerboseOptionCommand( "echo \"\${abs_builddir}/$object\" >> lib$libname.$libext.manifest", "  echo"  );
2994        }
2995        print FD "\ttouch \${top_builddir}/lib/.lib$libname.$libext.timestamp$newline";
2996                                           
2997    }
2998}
2999
3000sub TargetLibraries {
3001    foreach $lib (keys(%libraries)) {
3002        my $libloc = &GetLibLoc( $lib );
3003        if (!defined($libraries{$lib})) { next; }
3004
3005        my $sourcefiles = &ExpandMakeVars($libraries{$lib});
3006
3007        &LibraryTimestampPrefix( $lib, $libloc );
3008        &LibraryBuild( $lib, $libloc, $sourcefiles, "a", "o" );
3009        # Add any additional actions for this library.
3010        &SMInvokeAction( "OutputLib", $lib, $libloc );
3011       
3012        # ------------------------ Kumud_Parallel_Fix ----------------------
3013        # if ($ranliblib) {
3014        #    # COMMAND PRINTING
3015        #    &PrintVerboseOptionCommand( "\${RANLIB} ${libloc}lib$lib.a", "-",
3016        #                               "  RANLIB          lib$lib.a" );
3017        #}
3018 
3019        # To handle timestamp problems with recursive makes, add a delay
3020        &LibraryTimestampFix( $lib, $libloc )
3021       
3022    }
3023}
3024
3025#
3026# Fix for problems with timestamps.  If the file is not local (not
3027# obviously in the current directory), then apply one of the fixes
3028#
3029# LibraryTimestampTarget - Save additional target name in altalltargets hash
3030#                          (used in ListTargets)
3031# LibraryTimestampPrefix - Additional target for the library
3032# LibraryTimestampFix - Fix *after* all other operations
3033# LibraryTimestampClean - Add clean commands for library timestamps
3034sub LibraryTimestampTarget {
3035    my ($fulllibname,$libstamp) = @_;
3036    my $expandedFullName = &ExpandMakeVars( $fulllibname );
3037    if ($expandedFullName =~ /^\.\./ && !$fixup_for_timestamps) {
3038        $altalltargets{$fulllibname} = $libstamp;
3039    }
3040}
3041sub LibraryTimestampPrefix {
3042    my ($lib, $libloc) = @_;
3043
3044    my $expandedlibloc = &ExpandMakeVars( $libloc );
3045
3046    if ($expandedlibloc =~ /^\.\./) {
3047        if (!$fixup_for_timestamps) {
3048            my $num = "";
3049            if (defined($libnum{$lib})) {
3050                $num = $libnum{$lib};
3051            }
3052            &print_make_line( FD, ".libstamp$num " );
3053        }
3054    }
3055}
3056sub LibraryTimestampFix {
3057    my ($lib,$libloc) = @_;
3058    my $expandedlibloc = &ExpandMakeVars( $libloc );
3059    if ($expandedlibloc =~ /^\.\./) {
3060        if ($fixup_for_timestamps) {
3061            my $SleepText = $Sleep;
3062            my $fulllibname = $libloc . "lib$lib.a";
3063            $SleepText =~ s/LIB/$fulllibname/;
3064            print FD "\t$SleepText$newline";
3065        } else {
3066            if (defined($libnum{$lib})) {
3067                my $num = "";
3068                $num = $libnum{$lib};
3069                print FD "\tdate > .libstamp$num\n";
3070            }
3071        }
3072   
3073    }
3074
3075
3076sub LibraryTimestampClean {
3077    if ($libcount > 0) {
3078        print FD "\t-${quietLine}rm -f ";
3079        for( my $i=0; $i<$libcount; $i++) {
3080            print FD ".libstamp$i ";
3081        }
3082        print FD "\n";
3083    }
3084}
3085# --------------------------------------------------------------------------
3086
3087# This code is similar to TargetLibraries.
3088sub TargetProfileLibraries {
3089    $found_source_files = 0;
3090    foreach $lib (keys(%profile_libraries)) {
3091        $proflib_name = $profile_libraries{$lib};
3092        $libloc = &GetLibLoc( $lib );
3093        # Take the sources from the base library unless
3094        # they were explicitly listed
3095        if (defined($profile_library_sources{$lib})) {
3096            $sourcefiles = $profile_library_sources{$lib};
3097        }
3098        else {
3099            $sourcefiles = $libraries{$lib};
3100        }
3101        $sourcefiles = &ExpandMakeVars( $sourcefiles );
3102        # FIXME: Use LibraryBuild here
3103        # Use the library stamp
3104        my $libstamp = ".libstamp" . $libnum{$proflib_name};
3105        print FD "$libstamp: ";
3106        #&print_make_line( FD, "${libloc}lib$proflib_name.a: " );
3107        foreach $sourcefile (split(/\s+/,$sourcefiles)) {
3108            $found_source_files = 1;
3109            $obj = $sourcefile;
3110            # Convert to object file
3111            $ext = $sourcefile;
3112            $ext =~ s/^.*\.//g;
3113            if ($ext eq "f") {
3114                # Ignore Fortran source files (setbotf.f in mpich2)
3115                next;
3116            }
3117            elsif (defined($extrules{"$ext:o"})) {
3118                $obj =~ s/\.$ext/\.o/g;
3119                $obj = "_" . $obj;
3120            }
3121            else {
3122                # Be silent on .h files
3123                if ($ext ne "h") {
3124                    print STDERR "Unknown extension $ext for $sourcefile for profile library $proflib_name\n";
3125                }
3126            }
3127            &print_make_line( FD, "$obj " );
3128        }
3129        &print_make_endline( FD );
3130        if ($found_source_files) {
3131            # Add these files as objects to the archive
3132            # COMMAND PRINTING
3133            &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$proflib_name.a \$?",
3134                                        "  AR" );
3135            if ($ranliblib) {
3136                # COMMAND PRINTING
3137                &PrintVerboseOptionCommand( "\${RANLIB} ${libloc}lib$proflib_name.a",
3138                                            "-", "  RANLIB          lib$proflib_name.a" );
3139            }
3140            # To handle timestamp problems with recursive makes,
3141            # add a delay
3142            &LibraryTimestampFix( $proflib_name, $libloc );
3143        }
3144
3145        if ($do_sharedlibs) {
3146            my $libstamp = ".libstamp" . $libnum{$proflib_name.".la"};
3147            print FD "$libstamp: ";
3148            #&print_make_line( FD, "${libloc}lib$proflib_name.la: " );
3149            foreach $sourcefile (split(/\s+/,$sourcefiles)) {
3150                $found_source_files = 1;
3151                $obj = $sourcefile;
3152                # Convert to object file
3153                $ext = $sourcefile;
3154                $ext =~ s/^.*\.//g;
3155                if ($ext eq "f") {
3156                    # Ignore Fortran source files (setbotf.f in mpich2)
3157                    next;
3158                }
3159                elsif (defined($extrules{"$ext:o"})) {
3160                    $obj =~ s/\.$ext/\.lo/g;
3161                    $obj = "_" . $obj;
3162                }
3163                else {
3164                    # Be silent on .h files
3165                    if ($ext ne "h") {
3166                        print STDERR "Unknown extension $ext for $sourcefile for profile library $proflib_name\n";
3167                    }
3168                }
3169                &print_make_line( FD, "$obj " );
3170            }
3171            &print_make_endline( FD );
3172            if ($found_source_files) {
3173                # Add these files as objects to the archive
3174                # COMMAND PRINTING
3175                &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$proflib_name.la \$?",
3176                                            "  AR" );
3177                # To handle timestamp problems with recursive makes,
3178                # add a delay
3179                &LibraryTimestampFix( $proflib_name.".la", $libloc );
3180            }
3181        }
3182       
3183        # The new dependencies on the object files
3184        foreach $sourcefile (split(/\s+/,$sourcefiles)) {
3185            $found_source_files = 1;
3186            $obj = $sourcefile;
3187            # Convert to object file
3188            $ext = $sourcefile;
3189            $ext =~ s/^.*\.//g;
3190            if ($ext ne "c") {
3191                print STDERR "Unknown extension $ext for $sourcefile for profile library $proflib_name\n";
3192                next;
3193            }
3194            $obj =~ s/\.$ext/.o/;
3195            $obj = "_" . $obj;
3196            # Note that many makes won't replace $< in an implicit rule,
3197            # so we explicitly list the source file
3198            print FD "$obj: $sourcefile$newline";
3199            # COMMAND PRINTING
3200            &PrintVerboseOptionCommand( "\$(C_COMPILE) -c \@PROFILE_DEF_MPI\@ \$(srcdir)/$sourcefile -o $obj", "-", "  CC             -D<profiling> \${srcdir}/$sourcefile" );
3201            if ($do_sharedlibs) {
3202                $obj =~ s/\.o/.lo/;
3203                print FD "$obj: $sourcefile$newline";
3204                &PrintVerboseOptionCommand( "\$(C_COMPILE_SHL) -c \@PROFILE_DEF_MPI\@ \$(srcdir)/$sourcefile -o $obj", "-", " CC           -D<profiling> \$(srcdir)/$sourcefile" );
3205            }
3206        }
3207    } # foreach lib
3208}
3209#
3210# ===========================================================================
3211# The following is a cache of comments on using libtool, based on the
3212# targets created by automake. 
3213# Issues include
3214#   Handling the simultaneous generation of dependency information
3215#    (automake assumes a GNU environment, including gnumake and gcc, unless
3216#    you work really, really hard)
3217#   
3218# .c.lo: (target in the automake is %.lo: %.c)  is roughly
3219# @echo '$(LTCOMPILE) -c $<'
3220# @$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
3221# @sed -e 's/^\([^:]*\)\.o[\t ]*;/\1.lo \1.o :/' \ <.deps/$(*F).pp > \
3222#   .deps/$(*F).P; \
3223# tr ' ' '\012' < .deps/$(*F).pp \
3224#  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
3225#  >> .deps/$(*F).P
3226# @rm -f .deps/$(*F).pp
3227#
3228# Most of this is used to handle the dependency generation, including
3229# makint the files refer to .lo and .o instead of just .o.  Also note that
3230# LTCOMPILE generates BOTH .o and .lo files.
3231# (most of this is similar to the .c.o target generated by automake
3232#
3233# Another important step is the install step, which is roughly
3234# install-libLTLIBRARIES: $(lib_LTLIBRARIES)
3235#   @$(NORMAL_INSTALL)
3236#   $(mkinstalldirs) $(DESTDIR)$(libdir)
3237#   @list='$(lib_LTLIBRARIES)'; for p in $$list ; do \
3238#     if test -f $$p; then \
3239#        echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p" ;\
3240#        $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p ;\
3241#     else : ; fi ; done
3242# uninstall-libLTLIBRARIES:
3243#   @$(NORMAL_UNINSTALL)
3244#   @list='$(lib_LTLIBRARIES)'; for p in $$list ; do \
3245#        $(LIBTOOL) --mode=uninstall $(INSTALL) rm -f $(DESTDIR)$(libdir)/$$p ;\
3246#     done
3247#
3248# clean target for libtool adds .libs and _libs (may be directories)
3249#
3250# NORMAL_INSTALL and UNINSTALL seem to be hooks; the base definition is :
3251#
3252# DESTDIR is a newer automake thing to make it easier to retarget an install
3253# into a test directory.
3254#
3255# ---------------------------------------------------------------------------
3256# This routine creates the library of shared objects.  There is a separate
3257# step that builds the shared library (which is really a kind of partially
3258# linked executable).
3259# Pass in the name (by reference) of the list of libraries.  This allows
3260# us to use this routine for both the general list of libraries (for -shared,
3261# which makes both static and dynamic libraries) and for the list of libraries
3262# that are only needed as shared libraries (e.g., Totalview and Java/SLOG
3263# interface libraries).
3264sub TargetSharedLibraries {
3265    # This provides a *reference* to the hash that is passed into the routine
3266    # See the perlsub and perlref manpages for this, and the %$libraries and
3267    # $$libraries used below.
3268    my $libraries = $_[0];
3269
3270    foreach $lib (keys(%$libraries)) {
3271        # Skip the libraries that have no shared counterpart
3272        if (defined($libNotShared{$lib})) {
3273            #print "Skipping $lib\n";
3274            next;
3275        }
3276        $libloc = &GetLibLoc( $lib );
3277        $sourcefiles = &ExpandMakeVars($$libraries{$lib});
3278        &LibraryTimestampPrefix( $lib.".la", $libloc );
3279        &LibraryBuild( $lib, $libloc, $sourcefiles, "la", "lo" );
3280        # no ranlib step here because we can't "link" the shared library
3281        # until all members are added.
3282        &SMInvokeAction( "OutputShLib", $lib, $libloc );
3283        &LibraryTimestampFix( $lib.".la", $libloc )
3284    }
3285}
3286
3287#
3288# This is the routine that creates a shared library from a library of
3289# shared objects. 
3290# This must be called from the directory containing the library.
3291# Still to do: provide a separate directory for the library, so
3292# that a build library may be used instead
3293#
3294# If we can't use .lo as an object extension, then after extracting,
3295# rename everything as .o and then build.
3296# TargetSharedLibraryFinal( "libmpich.la", "libmpich.so.1", dir )
3297#
3298# Note that we need to ensure that C_LINK_SHL is defined.  In turn,
3299# C_LINK_SHL may need CC, so we add that
3300#
3301# Another special feature: For some libraries, we may need an exports
3302# definition (by default, we'll export all symbols).  This is specified
3303# by defining the exports for a given library with a simplemake command:
3304# lib(name)_so_EXPORTS = filename
3305
3306sub TargetSharedLibraryFinal {
3307    my $libname = $_[0];
3308    my $newlibname = $_[1];
3309    my $libdir = $_[2];
3310
3311    my $libbasename = $libname;
3312    $libbasename =~ s/^lib//;
3313    $libbasename =~ s/\.la$//;
3314
3315    #print "Checing $libbasename in Final\n";
3316    if (defined($libNotShared{$libbasename})) {
3317        #print "Skipping $libbasename in final\n";
3318        return;
3319    }
3320
3321    if ($libdir eq "" || $newlibname eq "" || $libname eq "") {
3322        # If we don't have these names, we cannot create a valid library
3323        print STDOUT "Unable to create shared libary target (no directory\n\
3324library, or new library name)\n" if $debug;
3325        return;
3326    }
3327    if (!defined($ext_seen{"c"}) && $InitSharedLibraryFinal == 0) {
3328        # Remember that we made this definition
3329        $InitSharedLibraryFinal = 1;
3330        my $rule = $extdef{"c:o"};
3331        print FD "$rule\n";
3332    }
3333
3334    # See if this library needs an exports list
3335    my $exports = "";
3336    if (defined($shared_libraries_exports{$libbasename})) {
3337        my $exportFile = $shared_libraries_exports{$libbasename};
3338        if ($libdir ne "." && !($exportFile =~ /^\//)) {
3339            # make sure the exportFile refers to the correct location
3340            $exportFile = "\$(abs_srcdir)/$exportFile";
3341        }
3342        $exports = "-export $exportFile";
3343    }
3344    my $otherlibs = "";
3345    if (defined($shared_libraries_libs{$libbasename})) {
3346        $otherlibs = $shared_libraries_libs{$libbasename};
3347    }
3348    if (!defined($usertargets{"$libdir/$newlibname"})) {
3349        print FD "# Build the shared library from the shared object files\n";
3350        print FD "$libdir/$newlibname: $libdir/$libname
3351\t(cd $libdir && \$(CREATESHLIB) --mode=link -version-info \"\@ABIVERSION\@\" -o $libname $exports -rpath \$(libdir) $otherlibs)\n";
3352    }
3353    # If there is a profiling library, we need to build it
3354    # now, as part of this target, to handle the case where the
3355    # profiling library name might be the same as the regular name
3356    my $libbase = $libname;
3357    my $libext = ".so";
3358    if ($libbase =~ /lib(.*)(\..*)/) {
3359        $libbase = $1;
3360        $libext = $2;
3361    }
3362    if (defined($profile_libraries{$libbase})) {
3363        my $newbase = $profile_libraries{$libbase};
3364        $libname = "lib" . $newbase . $libext;
3365        if ($newlibname =~ /(.*lib)[^\/]*(\..*)/) {
3366            $newlibname = $1 . $newbase . $2;
3367        }
3368        print FD "\tif [ -n \"\@NO_WEAK_SYM\@\" -a \\
3369\t\t\"$libbase\" != \"$newbase\" ] ; then \\\n";
3370
3371        my $libbasename = $libname;
3372        $libbasename =~ s/^lib//;
3373        $libbasename =~ s/\.la$//;
3374        if (defined($shared_libraries_exports{$libbasename})) {
3375            my $exportFile = $shared_libraries_exports{$libbasename};
3376            if ($libdir ne "." && !($exportFile =~ /^\//)) {
3377                # make sure the exportFile refers to the correct location
3378                $exportFile = "\$(abs_srcdir)/$exportFile";
3379            }
3380            $exports = "-export $exportFile";
3381        }
3382        my $otherlibs = "";
3383        if (defined($shared_libraries_libs{$libbasename})) {
3384            $otherlibs = $shared_libraries_libs{$libbasename};
3385        }
3386
3387        print FD "\t(cd $libdir && \$(CREATESHLIB) --mode=link -version-info \"\@ABIVERSION\@\" -o $libname $exports -rpath \$(libdir) $otherlibs);\\\n";
3388
3389        print FD "\tfi\n";
3390    }
3391}
3392#
3393# ===========================================================================
3394sub TargetPrograms {
3395    foreach $pgm (keys(%programs)) {
3396        # If there was a manual target, skip
3397        if (defined($usertargets{$pgm})) {
3398            print "Skipping generation of rule for $pgm because Makefile.sm already contains one\n";
3399            next;
3400        }
3401        &print_make_line( FD,  "$pgm: " );
3402        $pgmobjs = "";
3403        foreach $sourcefile (split(/\s+/,$programs{$pgm})) {
3404            $obj = $sourcefile;
3405            # Convert to object file
3406            $ext = $sourcefile;
3407            $ext =~ s/^.*\.//g;
3408            if (defined($extrules{"$ext:o"})) {
3409                $obj =~ s/\.$ext/\.o/g;
3410                &print_make_line( FD, "$obj " );
3411                $pgmobjs .= "$obj ";
3412            }
3413            else {
3414                if ($ext ne "h") {
3415                    print STDERR "Unknown extension $ext for $sourcefile for program $pgm\n";
3416                }
3417            }
3418        }
3419        # Add dependencies on libraries if requested
3420        $debug_lib_dependencies = 0;
3421        if ($convert_Ldir_to_relative) {
3422            print STDERR "Checking for relative dirs\n" if $debug_lib_dependencies;
3423            # convert -L dir -lname into dir/libname.a
3424            $libdep = "";
3425            if (defined($pgm_ldadd{$pgm})) {
3426                $libdep = $pgm_ldadd{$pgm};
3427            }
3428            $libdep =~ s/-L\s*([\w\.\/]*)\s*-l([\w-]*)//;
3429            $libdir = $1;
3430            $libname = $2;
3431            print STDERR "Checking $libdir and $libname\n" if $debug_lib_dependencies;
3432            if (defined($libdir) && defined($libname) &&
3433                $libdir ne "" && $libname ne "" &&
3434                !defined($external_libraries{$libname})) {
3435                &print_make_line( FD, " $libdir/lib$libname.a" );
3436            }
3437        }
3438        $otherdep = "";
3439        if (defined($pgm_depadd{$pgm})) {
3440            $otherdep = $pgm_depadd{$pgm};
3441        }
3442        if (defined($otherdep)) {
3443            &print_make_line( FD, " $otherdep" );
3444        }
3445        if (defined($depadd_all)) {
3446            &print_make_line( FD, " $depadd_all" );
3447        }
3448
3449        # Use the link rule appropriate for this program type
3450        #$pgmtype = $pgmsrctype{$pgm};
3451        &print_make_endline( FD );
3452        &print_make_setpos( 8 );
3453        $ruleline = "\t$progrules{$pgmsrctype{$pgm}} -o $pgm $pgmobjs";
3454        # We really need an libs before LIBS and libs after libs.
3455        if (defined($pgmlibs{$pgm})) {
3456            $ruleline .= " $pgmlibs{$pgm}";
3457        }
3458        if (defined($pgm_ldadd{$pgm})) {
3459            $ruleline .= " $pgm_ldadd{$pgm}";
3460        }
3461        $ruleline .= " \${LIBS}";
3462        &print_make_longline( FD, $ruleline );
3463    }
3464
3465}
3466
3467#
3468# ===========================================================================
3469sub TargetTags {
3470    if (!$local_tags && !$root_tags) { return; }
3471
3472    my $headerFiles = "";
3473    my $foundDerivedHeader = 0;
3474    my $sourceFiles = "";
3475    my $foundDerivedSource = 0;
3476    my $inputSources = "";
3477
3478    # Generate a listing of header and source files
3479    $has_sources = 0;
3480    $has_headers = 0;
3481    if ($regular_sources =~ /\S/) {
3482        printMakeVariable( FD, "SOURCES", $regular_sources );
3483        $inputSources = $regular_sources;
3484        $has_sources = 1;
3485    }
3486    elsif (defined($makevars{'SOURCES'})) {
3487        if ($makevars{'SOURCES'} =~ /\S/) {
3488            $has_sources = 1;
3489            $inputSources = $makevars{'SOURCES'};
3490        }
3491    }
3492    if ($has_sources) {
3493        foreach my $file (split(/\s+/,$inputSources)) {
3494            if (! ($file =~ /\S/)) { next; }
3495            # Check that these files exist, either directly or
3496            # as a '.in' version
3497            if (-s "$file.in") {
3498                $sourceFiles .= "\$(abs_builddir)/$file ";
3499                $foundDerivedSource = 1;
3500            }
3501            elsif (-s "$file") {
3502                $sourceFiles .= "$file ";
3503            }
3504            else {
3505                # Only complain about C files for now
3506                if ($file =~ /.*\.c$/) {
3507                    print STDERR "Warning: source file $file or $file.in not found in $curdir\n";
3508                }
3509            }
3510        }
3511    }
3512
3513    if ($regular_headers ne "") {
3514        printMakeVariable( FD, "HEADERS", $regular_headers );
3515        $has_headers = 1;
3516    }
3517    if (defined($makevars{'HEADERS'})) {
3518        $has_headers = 1;
3519        # Add these files to the headers variable.
3520        # headers is used to check on files that aren't handled by
3521        # simplemake
3522        foreach my $file (split(/\s+/,$makevars{'HEADERS'})) {
3523            if (! ($file =~ /\S/)) { next; }
3524            $headers{$file} = 1;
3525            # Check that these files exist, either directly or
3526            # as a '.in' version
3527            if (-s "$file.in") {
3528                $headerFiles .= "\$(abs_builddir)/$file ";
3529                $foundDerivedHeader = 1;
3530            }
3531            elsif (-s "$file") {
3532                $headerFiles .= "$file ";
3533            }
3534            else {
3535                print STDERR "Warning: header file $file or $file.in not found in $curdir\n";
3536            }
3537        }
3538    }
3539
3540    if ($has_headers || $has_sources) {
3541        # Make it eaiser to change the tags program options.
3542        # For example, this adds .i as a known "C" language file
3543        printMakeVariable( FD, "ETAGS", "\@ETAGS\@ \@ETAGSADD\@" );
3544        # The value of ETAGS was "etags --langmap=c:+.i" but
3545        # some Linux systems have a very old version of etags
3546        # that does not support --langmap.
3547    }
3548
3549    # Add a synonym for tags.
3550    if ($foundDerivedHeader) {
3551        printMakeVariable( FD, "HEADERFILES", $headerFiles );
3552    }
3553    else {
3554        printMakeVariable( FD, "HEADERFILES", '$(HEADERS)' );
3555    }
3556    if ($foundDerivedSource) {
3557        printMakeVariable( FD, "SOURCEFILES", $sourceFiles );
3558    }
3559    else {
3560        printMakeVariable( FD, "SOURCEFILES", '$(SOURCES)' );
3561    }
3562    print FD "tags: TAGS$newline";
3563    # By adding "Makefile" to TAGS, we ensure that the TAGS target
3564    # will be rebuilt anytime the package is reconfigured.  We
3565    # could also make TAGS always rebuild, to catch any source changes.
3566    print FD "TAGS: Makefile";
3567    # Only generate a local etags call if there are local sources
3568    # This target is designed for VPATH builds to build a TAGS file in
3569    if ($has_headers || $has_sources) {
3570        if ($local_tags) {
3571            print FD '${HEADERFILES} ${SOURCEFILES}
3572        here=`pwd`;\
3573        (cd ${srcdir} && $(ETAGS) -o $$here/TAGS --append ${HEADERFILES} ${SOURCEFILES};)
3574';
3575        }
3576        elsif ($root_tags) {
3577            print FD "\${HEADERFILES} \${SOURCEFILES}$newline";
3578            if (defined($rootdirpath)) {
3579                $rpath = $rootdirpath;
3580                $rpath =~ s/\/$//;
3581            }
3582            else {
3583                # Use current directory
3584                # Question: in this case, should we leave out the tags
3585                # target?
3586                $rpath = ".";
3587            }
3588            # For vpath builds, make the root path point to the
3589            # VPATH root.
3590           
3591            print FD "\there=\`cd $rpath && pwd\` ; cd \${srcdir} && \$(ETAGS) -o \$\$here/TAGS --append \${HEADERFILES} \${SOURCEFILES}$newline";
3592        }
3593        else {
3594            print FD "$newline";
3595        }
3596    }
3597    else {
3598        print FD "$newline";
3599    }
3600    # Tags on only the subdirs (really the source subdirs) and any
3601    # additional tags dirs
3602    @tmp_tags_dirs = (@subdirs,@tags_dirs);
3603    &RecursiveOp( "TAGS", "tmp_tags_dirs" );
3604    $#tmp_tags_dirs = -1;
3605}
3606#
3607# The generation of documentation (e.g., manual pages) is handled
3608# a little differently.  To make it easier to manage a VPATH build of
3609# everything, including the documentation, we:
3610#    Add the document output types as file extensions to SUFFIX
3611#    Add generic build rules (using variables for options)
3612#    Create targets using variable substitution.
3613# For example, to add html output (this shows *only* the document rules)
3614#
3615# .SUFFIXES: .c .html
3616# .c.html:
3617# \tdoctext -html $(DOCTEXT_OPTIONS) $<
3618# HTML: ${mpi_sources:.c=.html}
3619#
3620# In addition, we may need to generate a document target even if there are
3621# no files in this directory *if* there are subdirectories (the usual
3622# recursive target).
3623#
3624# Temporary repository:
3625# the doctext line from MPICH1
3626#       $doctext -ext 3 -mpath ../../man/man3 -I pubinc -heading MPI \
3627#                -quotefmt /home/MPI/mansrc/fortnotes \
3628#                -ignore EXPORT_MPI_API \
3629#                /home/MPI/mansrc/errnotes *.c ; \
3630#
3631# SuffixDocs: Add any suffix rules for this directory
3632sub SuffixDocs {
3633    # global: do_docs, suffixes, docsrc
3634    if (! $do_docs) { return; }
3635    foreach my $kind (keys(%docsrc)) {
3636        if ($docsrc{$kind} ne "") {
3637            $suffixes .= " .$kind";
3638        }
3639    }
3640    # Add source file suffixes
3641    if (! $suffixes || ! ($suffixes =~ /\.txt/) ) {
3642        $suffixes .= " .txt";
3643    }
3644}
3645sub VariableDocs {
3646    # global: do_docs, suffixes, docsrc
3647    if (! $do_docs) { return; }
3648    foreach my $kind (keys(%docsrc)) {
3649        ;
3650    }
3651    # Let us set doctext from configure.  We only need this if
3652    # we saw any sources.  This expresion is true if docsrc is non-empty
3653    if (scalar(%docsrc)) {
3654        printMakeVariable( FD, "DOCTEXT", "\@DOCTEXT\@" );
3655    }
3656}
3657
3658#
3659# Generate the rule for generating documentation from the source files
3660#
3661sub RuleDocs {
3662    # global: do_docs, docsrc, FD, newline
3663    if (! $do_docs) { return; }
3664    $rootdir = $rootdirpath;
3665    foreach my $kind (keys(%docsrc)) {
3666        # Set the default suffix
3667        $docsrcsuffix = ".c";
3668        if (defined($docsrc{$kind}) && $docsrc{$kind} ne "") {
3669            $docdestdir = $globaldocdir;
3670            if (defined($docdir{$kind}) && $docdir{$kind} ne "") {
3671                $docdestdir = $docdir{$kind};
3672            }
3673            # Replace ROOTDIR, including handling any doubled //
3674            $docdestdir =~ s/ROOTDIR/$rootdir/g;
3675            $docdestdir =~ s/\/\//\//g;
3676            # Replace any occurance of $dockinddirval is docdestdir
3677            if (defined($docthiskinddir{$kind})) {
3678                $dockinddirval = $docthiskinddir{$kind};
3679            }
3680            else {
3681                $dockinddirval = $dockinddir{$kind};
3682            }
3683            $docdestdir =~ s/(\$\w+)/$1/eeg;     # see man perlfaq4
3684            #
3685            # Replace ROOTDIR etc in any doc_namedefs
3686            $docargs = $doc_namedefs;
3687            if ($docargsAdd ne "") {
3688                $docargs .= " $docargsAdd";
3689            }
3690            $docargs =~ s/ROOTDIR/$rootdir/g;
3691            $docargs =~ s/\/\//\//g;
3692           
3693            # Check for an alternative suffix
3694            $docfiles = &ExpandMakeVars( $docsrc{$kind} );
3695            print "file list = $docfiles\n" if $debug;
3696            for $file (split(/\s+/,$docfiles)) {
3697                $file =~ /.*(\..*)$/;
3698                $suffix = $1;
3699                if ($docsrcsuffix ne $suffix) {
3700                    $docsrcsuffix = $suffix;
3701                }
3702            }
3703            print FD "$docsrcsuffix.$kind:$newline";
3704            $extarg = "";
3705            if ($kind eq "man" && ($docdestdir =~ /man(\d)$/)) {
3706                $extarg = "-ext $1";
3707            }
3708            print FD "\t\$(DOCTEXT) $doctextOptionName{$kind} -mpath $docdestdir $extarg -heading $doc_heading \\$newline";
3709            print FD "\t\t-quotefmt $docargs \$<$newline";
3710        }
3711    }
3712}
3713
3714#
3715# Given a list of sources, return an array containing the distinct suffixes
3716# (without the leading .)
3717sub GetSuffixList {
3718    my %suffixSeen = ();
3719    my $vars = $_[0];
3720    my @suffixes = ();
3721
3722    # Check for an alternative suffix
3723    $vars = &ExpandMakeVars( $vars );
3724    print "file list = $vars\n" if $debug;
3725    for $file (split(/\s+/,$vars)) {
3726        $file =~ /.*\.(.*)$/;
3727        $suffix = $1;
3728        if (!defined($suffixSeen{$suffix})) {
3729            $suffixSeen{$suffix} = 1;
3730            $suffixes[$#suffixes+1] = $suffix
3731        }
3732    }
3733    return @suffixes;
3734}
3735
3736sub SubForSuffixes {
3737    my $src = $_[0];
3738    my $suffixarrayName = $_[1];
3739    my $repSuffix = $_[2];
3740 
3741    for $suffix (@$suffixarrayName) {
3742        $src =~ s/\.$suffix/\.$kind/;
3743    }
3744    return $src;
3745}
3746
3747#
3748# Generate the documentation targets.
3749#
3750sub TargetDocs {
3751    if (! $do_docs || ! $maint_targets) { return; }
3752    my %didkind = ( "html" => 0, "man" => 0, "latex" => 0 );
3753
3754    print FD $makeBlockSep;
3755    foreach my $kind (keys(%docsrc)) {
3756        $targetKind = $docTargetName{$kind};
3757        print FD "$targetKind: ";
3758        my $src = $docsrc{$kind};
3759        if ($src ne "") {
3760            if ($src =~ /^\s*\$[\{\(][_\w]*[\}\)]\s*$/) {
3761                # a single variable: use make substitution if a single
3762                # suffix
3763                @suffixes = &GetSuffixList( $src );
3764                if ($#suffixes == 0) {
3765                    $src =~ s/\}/:.$suffixes[0]=.$kind\}/;
3766                }
3767                else {
3768                    # manually substitute
3769                    $src = &SubForSuffixes( $src, "suffixes", $kind );
3770                }
3771            }
3772            elsif ($src =~ /\$/) {
3773                # Perform variable expansion if possible
3774                $src = &ExpandMakeVars( $src );
3775                @suffixes = &GetSuffixList( $src );
3776                # Convert the extensions to the document type
3777                #$src =~ s/\.c/.$kind/;
3778                $src = &SubForSuffixes( $src, "suffixes", $kind );
3779            }
3780            else {
3781                $src =~ s/\.c/.$kind/;
3782            }
3783            print FD "$src$newline";
3784        }
3785        else {
3786            # This is the recursive branch
3787            print FD "$newline";
3788        }
3789        # If we're at the top; create any directories that are needed
3790        # This assumes a particular layout for the directories that
3791        # we'll eventually want to make adjustable.
3792        if ($doc_attop) {
3793            my @dirs = ();
3794            if ($kind eq "html") {
3795                @dirs = ( "www", "www/www1", "www/www3" );
3796            }
3797            elsif ($kind eq "man") {
3798                @dirs = ( "man", "man/man1", "man/man3" );
3799            }
3800            elsif ($kind eq "latex") {
3801                @dirs = ( "doc", "doc/refman" );
3802            }
3803            else {
3804                print STDERR "Unrecognized document type $kind\n";
3805            }
3806            foreach my $dir (@dirs) {
3807                print FD "\tif [ ! -d \${DESTDIR}$dir ] ; then mkdir \${DESTDIR}$dir ; fi$newline";
3808            }
3809        }
3810        &RecursiveOp( $targetKind );
3811        if ($#doc_subdirs >= 0) {
3812            &RecursiveOp( $targetKind, "doc_subdirs" );
3813        }
3814        if (defined($usertargets{"${targetKind}-local"})) {
3815            print FD "\t\${MAKE} ${targetKind}-local$newline";
3816        }
3817        $didkind{$kind} = 1;
3818    }
3819    #
3820    # For any directory that does not have any source files, we must still
3821    # generate a target *if* any directory set the source.
3822    foreach $kind ("html", "man", "latex") {
3823        $targetKind = $docTargetName{$kind};
3824        if (! $didkind{$kind} && $globaldockind{$kind}) {
3825            print FD "$targetKind:$newline";
3826            &RecursiveOp( $targetKind );
3827            if ($#doc_subdirs >= 0) {
3828                &RecursiveOp( $targetKind, "doc_subdirs" );
3829            }
3830        }
3831    }
3832    print FD $makeBlockSep;
3833}
3834
3835#
3836# Install target.  Question: does this need to list (or use a shell command
3837# to get) the filename for each individual file?
3838#
3839sub InstallDocs {
3840    # Add target only at the top
3841    if (!$doc_attop) { return; }
3842
3843    # Instead of this approach, we used a more general installdir
3844    # that handles these cases.
3845#     print FD "install-docs:$newline";
3846#     # Each document type is different.  In addition, we want the install
3847#     # to work even if the documents have not been built.
3848#     if ((!$didkind{"html"}) && $globaldockind{"html"}) {
3849#         print FD "\tif [ ! -d \$(htmldir) ] ; then \$(MKDIR_P) \$(htmldir) ; fi\n";
3850#       print FD "\tif [ -d www/www3 ] ; then \\$newline";
3851#       print FD "\t\$(INSTALL_DATA) www/www3/* \$(htmldir)/www3/ ; fi$newline";
3852#       print FD "\tif [ -d www/www1 ] ; then \\$newline";
3853#       print FD "\t\$(INSTALL_DATA) www/www1/* \$(htmldir)/www1/ ; fi$newline";
3854#     }
3855#     if ((!$didkind{"man"}) && $globaldockind{"man"}) {
3856#         print FD "\tif [ ! -d \$(mandir) ] ; then \$(MKDIR_P) \$(mandir) ; fi\n";
3857#       print FD "\tif [ -d man/man3 ] ; then \\$newline";
3858#       print FD "\t\$(INSTALL_DATA) man/man3/* \$(mandir)/man3/ ; fi $newline";
3859#       print FD "\tif [ -d man/man1 ] ; then \\$newline";
3860#       print FD "\t\$(INSTALL_DATA) man/man1/* \$(mandir)/man1/ ; fi $newline";
3861#     }
3862    # LaTeX manual is different and requires a special case
3863}
3864
3865# Add any dirs that are referred to by InstallDocs
3866sub InstallDocDirs {
3867    # Add target only at the top
3868    if (!$doc_attop) { return; }
3869
3870    print FD "htmldir         = \@htmldir\@\nmandir          = \@mandir\@\n";
3871}
3872
3873#
3874# Installation is complicated by VPATH builds; files that are derived and
3875# files that are not may be in different locations (one relative, the other
3876# absolute with respect to the source tree)
3877#
3878# Also, note that the documents and some other files may be pre-existing, so
3879# that we need to get them from the srcdir, not the build dir.  However,
3880# maintainers may create them in the builddir.
3881sub TargetInstall {
3882    %dirschecked = ();
3883    if (!scalar(%install_files) && !scalar($install_dirs) &&
3884        !scalar(%optinstall_files) && !scalar($optinstall_dirs)) {
3885        if (defined($usertargets{"install-local"}) && !$gIssuedInstallLocal) {
3886            # First add the indirect to the install-local target (when
3887            # there are no local files to install at all)
3888            print FD "install: install-local $newline";
3889        }
3890        return;
3891    }
3892    print FD "# Install target$newline";
3893    &TargetInit( "install" );
3894    print FD " FORCE_TARGET $newline";
3895    # Create the directories for the install directories
3896    foreach $kind (keys(%install_dirs)) {
3897        $dir = $InstallDirFromKind{$kind};
3898        if ($dir eq "") {
3899            print STDERR "No known installation dir for install_$kind\n";
3900            next;
3901        }
3902        if (!defined($dirschecked{$dir})) {
3903            # Check on dependent directories
3904            foreach $checkdir (split(/\s+/,$required_dirs{$dir})) {
3905                if ($checkdir ne "" && !defined($dirschecked{$checkdir})) {
3906                    $dirschecked{$checkdir} = 1;
3907                    print FD "\tif [ ! -d \${DESTDIR}\${$checkdir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$checkdir} ; fi$newline";
3908                }
3909            }
3910            print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
3911            $dirschecked{$dir} = 1;
3912        }
3913    }
3914
3915    # Handle the files
3916    foreach $kind (keys(%install_files)) {
3917        $dir = $InstallDirFromKind{$kind};
3918        if ($dir eq "") {
3919            print STDERR "No known installation dir for install_$kind\n";
3920            next;
3921        }
3922        if (!defined($dirschecked{$dir})) {
3923            # Check on dependent directories
3924            foreach $checkdir (split(/\s+/,$required_dirs{$dir})) {
3925                if ($checkdir ne "" && !defined($dirschecked{$checkdir})) {
3926                    $dirschecked{$checkdir} = 1;
3927                    print FD "\tif [ ! -d \${DESTDIR}\${$checkdir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$checkdir} ; fi$newline";
3928                }
3929            }
3930            print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
3931            $dirschecked{$dir} = 1;
3932        }
3933        #
3934        # If there is an install-local target, invoke it here:
3935        if (defined($usertargets{"install-local"}) && !$gIssuedInstallLocal) {
3936            if ($install_local_dirs ne "") {
3937                foreach my $dir (split(/\s+/,$install_local_dirs)) {
3938                    foreach $checkdir (split(/\s+/,$required_dirs{$dir})) {
3939                        if ($checkdir ne "" && !defined($dirschecked{$checkdir})) {
3940                            $dirschecked{$checkdir} = 1;
3941                            print FD "\tif [ ! -d \${DESTDIR}\${$checkdir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$checkdir} ; fi$newline";
3942                        }
3943                    }
3944                    if ($dir ne "" && !defined($dirschecked{$dir})) {
3945                        $dirschecked{$dir} = 1;
3946                        print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
3947                    }
3948                }
3949            }
3950            print FD "\t\${MAKE} install-local$newline";
3951            $gIssuedInstallLocal = 1;
3952        }
3953
3954        foreach $file (split(/\s+/,$install_files{$kind})) {
3955            $destfile = $file;
3956            $destfile =~ s/.*\///;
3957            $this_install_method = $install_methods{$kind};
3958            if ($this_install_method eq "") {
3959                $this_install_method = '$(INSTALL)';
3960                }
3961            print FD "\t$this_install_method $file \${DESTDIR}\${$dir}/$destfile$newline";
3962        }
3963    }
3964
3965    # Install any directories.  This asks for all files in the directory
3966    # to be installed.  It is typically used for things like manpages
3967    # that may be very numerous
3968    foreach $kind (keys(%install_dirs),keys(%optinstall_dirs)) {
3969        $dir = $InstallDirFromKind{$kind};
3970        foreach $srcdir (split(/\s+/,$install_dirs{$kind})) {
3971            # Choose the installation method based on the kind value
3972            if (!defined($install_methods{$kind})) {
3973                $this_install_choice = '$(INSTALL_PROGRAM)';
3974            }
3975            else {
3976                $this_install_choice = $install_methods{$kind};
3977            }
3978
3979            # This handles 2-level directories, such as man pages and
3980            # html pages (organized as man/man1-8 or www/www1-8).  A fully
3981            # recursive approach could be used, but it is felt that an
3982            # install should be constrained.  If there is a reason for an
3983            # install with three levels of directories, either install the
3984            # subdirectories separately or modify this code.
3985
3986            # Sigh.  This causes some make programs (such as gnumake)
3987            # to print a message about an ignored error.  To avoid that,
3988            # we turn the @-test into an @if test
3989            #print FD "\t\@-test -d $srcdir && cd $srcdir && for name in * ; do \\
3990            print FD "\t\@if test -d $srcdir && cd $srcdir ; then \\
3991\t for name in * ; do \\
3992\t  if [ \"\$\$name\" = \"*\" ] ; then continue ; fi ; \\
3993\t  if [ -f \$\$name ] ; then \\
3994\t    echo \"$this_install_choice \$\$name \${DESTDIR}\${$dir}/\$\$name\" ; \\
3995\t    $this_install_choice \$\$name \${DESTDIR}\${$dir}/\$\$name ; \\
3996\t  elif [ -d \$\$name ] ; then \\
3997\t    if [ ! -d \${DESTDIR}\${$dir}/\$\$name ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir}/\$\$name ; fi ;\\
3998\t    ( cd \$\$name && for name2 in * ; do \\
3999\t        if [ \"\$\$name2\" = \"*\" ] ; then continue ; fi ; \\
4000\t        if [ -f \$\$name2 ] ; then \\
4001\t            echo \"$this_install_choice \$\$name2 \${DESTDIR}\${$dir}/\$\$name/\$\$name2\" ; \\
4002\t            $this_install_choice \$\$name2 \${DESTDIR}\${$dir}/\$\$name/\$\$name2 ; \\
4003\t        elif [ -d \$\$name2 ] ; then  \\
4004\t            echo \"cp -rp \$\$name2 \${DESTDIR}\${$dir}/\$\$name\" ; \\
4005\t            cp -rp \$\$name2 \${DESTDIR}\${$dir}/\$\$name ; \\
4006\t        fi \\
4007\t    done ) ; \\
4008\t  else \\
4009\t    echo \"Unknown file type for \$\$name\" ; \\
4010\t  fi ; \\
4011\t done ; \\
4012\tfi$newline";
4013        }
4014    }
4015
4016    foreach $kind (keys(%optinstall_files)) {
4017        $dir = $InstallDirFromKind{$kind};
4018        if (!defined($dirschecked{$dir})) {
4019            print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
4020            $dirschecked{$dir} = 1;
4021        }
4022        foreach $filelist ($optinstall_files{$kind}) {
4023            foreach $file (split( /\s+/, $filelist)) {
4024                $destfile = $file;
4025                $destfile =~ s/.*\///;
4026                # Choose the installation method based on the kind value
4027                if (!defined($install_methods{$kind})) {
4028                    $this_install_choice = '$(INSTALL_PROGRAM)';
4029                }
4030                else {
4031                    $this_install_choice = $install_methods{$kind};
4032                }
4033                print FD "\tif [ -s $file ] ; then $this_install_choice $file \${DESTDIR}\${$dir}/$destfile ; fi$newline";
4034            }
4035        }
4036    }
4037    foreach $extradir (@install_subdirs) {
4038        # Check for configure substitutions in the list.  Make
4039        # these conditional, so that they can be empty.  Also note that
4040        # they could also contain *multiple* directories, so we have
4041        # to handle them in a general way
4042        #$endline = "";
4043        if ($extradir =~ /^@/) {
4044            print FD "\tfor dir in $extradir - ; do \\$newline";
4045            print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ;\\$newline";
4046            print FD "\t\t(cd \$\$dir && \$(MAKE) INSTALL_STRIP_FLAG=\$(INSTALL_STRIP_FLAG) PACKAGE=\$(PACKAGE) install) ;\\$newline";
4047            print FD "\tdone$newline";
4048        }
4049        else {
4050            print FD "\t(cd $extradir && \$(MAKE) INSTALL_STRIP_FLAG=\$(INSTALL_STRIP_FLAG) install)$newline";
4051        }
4052    }
4053    &TargetPostamble( "install" );
4054    print FD "$newline";
4055
4056    # Install documentation
4057    &InstallDocs;
4058    #
4059    print FD "install-strip:$newline";
4060    print FD "\t\$(MAKE) INSTALL_STRIP_FLAG=-s install$newline";
4061   
4062    #
4063    # We should also create an uninstall target.  Rather than
4064    # unilaterally uninstalling files, we may want an option to create
4065    # a file that will uninstall only the installed files (as MPICH-1
4066    # does).
4067    &TargetInit( "uninstall" );
4068    print FD "\n";
4069    foreach $kind (keys(%install_files)) {
4070        $dir = $InstallDirFromKind{$kind};
4071        foreach $file (split(/\s+/,$install_files{$kind})) {
4072            $destfile = $file;
4073            $destfile =~ s/.*\///;
4074            if (defined($uninstall_methods{$kind})) {
4075                # This branch is subtly different from the else branch below
4076                # because it also passes the $file as the first argument. 
4077                # Strictly speaking, this is not compatible with using
4078                # libtool directly, so if we ever replace createshlib then
4079                # we should rework this uninstall target
4080                # just a bit. [goodell@mcs 2007-11-28]
4081                print FD "\t-$uninstall_methods{$kind} $file \${DESTDIR}\${$dir}/$destfile$newline";
4082            }
4083            else {
4084                print FD "\t-rm -f \${DESTDIR}\${$dir}/$destfile$newline";
4085            }
4086        }
4087    }
4088    foreach $kind (keys(%optinstall_files)) {
4089        $dir = $InstallDirFromKind{$kind};
4090        foreach $file (split(/\s+/,$optinstall_files{$kind})) {
4091            $destfile = $file;
4092            $destfile =~ s/.*\///;
4093            if (defined($uninstall_methods{$kind})) {
4094                # This branch is subtly different from the else branch below
4095                # because it also passes the $file as the first argument. 
4096                # Strictly speaking, this is not compatible with using
4097                # libtool directly, so if we ever replace createshlib then
4098                # we should rework this uninstall target just a
4099                # bit. [goodell@mcs 2007-11-28]
4100                print FD "\t-$uninstall_methods{$kind} $file \${DESTDIR}\${$dir}/$destfile$newline";
4101            }
4102            else {
4103                print FD "\t-rm -f \${DESTDIR}\${$dir}/$destfile$newline";
4104            }
4105        }
4106    }
4107    # Handle uninstalls controlled by subdirs
4108    if ($#install_subdirs >= 0) {
4109        &RecursiveOp( "uninstall", "install_subdirs" );
4110    }
4111    &TargetPostamble( "uninstall" );
4112
4113    # also add the recursive installcheck target
4114    &TargetInit( "installcheck" );
4115    if (defined($usertargets{"installcheck-local"})) {
4116        print FD " installcheck-local";
4117    }
4118    print FD $newline;
4119    if ($#install_subdirs >= 0) {
4120        &RecursiveOp( "installcheck", "install_subdirs" );
4121    }
4122    &TargetPostamble( "installcheck" );
4123}
4124
4125#--------------Kumud_parallel_fix--------------------------------
4126
4127#============================================================================
4128#The target to desend into sub-directories and create all the executables that
4129#needs to be created
4130#INSTALL_BIN = myexecutable
4131sub TargetExecutables {
4132
4133    print FD "all-executable: all-executable-local$newline";
4134    foreach $dir (@extra_dirs, @subdirs) {
4135        if ($dir eq ".") {
4136             # the pre-requisite all-executable-local already take care of this case.   
4137        }
4138        elsif ($dir =~ /@([^@]*)@/) {
4139            # May be a replaced variable
4140            print FD "\t${quietmake}for dir in $dir - ; do \\$newline";
4141            print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ; \\$newline";
4142            print FD "\t\tif ( cd \$\$dir && \${MAKE} all-executable ) ; then : ; else exit 1; fi \\$newline";
4143            print FD "\tdone$newline";
4144        }
4145        else {
4146            print FD "\t${quietmake}(cd $dir && \${MAKE} all-executable )$newline";
4147        }
4148    }
4149   
4150
4151   
4152}
4153
4154
4155#
4156# ===========================================================================
4157# Other targets and stuff to be added:
4158#   CPP
4159#   Including common headers (e.g., all file.sm's get a common header of
4160#       variables defined by configure.  This is cleaner than the automake
4161#       approach of including *every* AC_SUBST value).
4162#   Support for shared libraries.  Unlike automake, we will not require
4163#       separate rules (automake uses lib_LTLIBRARIES and la extensions)
4164#       for shared library support.
4165#   Handling files to be installed (e.g., automake's sbin_PROGRAMS = ...)
4166#      (automake understands <dir>_PROGRAMS and <dir>_LIBRARIES)
4167#   target_LDFLAGS and general LDFLAGS
4168#   INCLUDES (automake variable that we've adopted) needs better control.
4169#   Support for .F and .F90 extensions (Fortran with preprocessor)
4170#   FLIBS
4171#   Linker choice.  simplemake uses the file type of the *first* source file.
4172#       automake has a matrix that depends on the source files referred to.
4173#   SCRIPTS (as in bin_SCRIPTS) targets
4174#   HEADERS variables (as in prog_HEADERS).  In many cases, this should
4175#       be determined automatically.  Note that it is needed for correct TAGS
4176#       generation.
4177
4178# Miscellaneous Routines
4179sub printHelp {
4180    print STDERR "\
4181simplemake [ -nocomments ] [ -am ] [ -libdir=NAME=DIR ] [ -include=LIST ]\
4182           files \
4183    -nocomments      - Exclude Makefile comments from generated file\
4184    -libdir=NAME=DIR - library NAME is located in directory DIR\
4185    -am              - Automake style target names\
4186    -include=LIST    - CPP style list of include directories (e.g., -Ia -Ib)\
4187                       These define INCLUDES unless a Makefile.sm defines\
4188                       that value\
4189    -v               - verbose output\
4190    -common=file     - Read text to include in every output file\
4191    -distrib         - Turn off all maintenance targets (make a distribution\
4192                       version)\
4193    -vpath=[yes|no]  - Create VPATH targets\
4194\
4195    -depend          - Generate dependency information as a make target\
4196    -depend=static   - Generate dependency information when simplemake runs\
4197    -nodepend        - Do not generate dependency information\
4198\
4199    -rootdir=PATH    - Set the root directory for all Makefiles\
4200    -configdir=PATH  - Location of the configure that controls the Makefile\
4201                       in this directory (used to rebuild a single \
4202                       Makefile.in)\
4203    -debug           - Turn on debugging output\
4204    -dos             - Use DOS-style newlines on output files\
4205    -interdirsleep   - Use a sleep between directory builds to handle problems\
4206                       with file systems that are not time-synchronized\
4207                       with the build node.  -interdirsleep=nn specifies\
4208                       an nn second sleep.\
4209    -smroot=dir      - Location of simplemake (absolute location)\
4210    -help            - This output\
4211    \n";
4212    print STDERR "\
4213    Recognized target forms\
4214    libname_a_SOURCES = source files for library \"name\"\
4215    libname_a_DIR     = location of directory into which lib \"name\" goes\
4216    SUBDIRS = blank separated list of subdirectories to process.  Use \".\"\
4217              to control the order in which the current directory is processed\
4218    DOC_SUBDIRS = blank separate list of subdirectories containing \
4219              documentation but no code source.  These directories may\
4220              contain files used as input to documentation generators.\
4221    EXTRA_PROGRAMS = names of programs to define rules for but not to build\
4222                     by default\
4223    EXTRA_LIBS = names of libraries to define rules for but not to build\
4224                     by default\
4225    name_SOURCES = source files for program \"name\"\
4226    name_LDADD   = extra linker flags for building program \"name\"\
4227\
4228    LDADD = extra linker flags to add to all programs\
4229    simplemake also allows all usual Makefile commands, including variable\
4230    assignment and targets.\n";
4231}
4232
4233#
4234# Generate dependency information when possible.  This version simply
4235# uses gcc -MM; if that doesn't work, does nothing. 
4236#
4237# Automake strives to generate the dependencies.  This is a better approach,
4238# but it is very difficult to implement in practice, particularly where the
4239# development environment is not GNU. 
4240#
4241# This is somewhat tricky because the current organization of MPICH2
4242# makes use of many -I<dir> switches, that are selected at configure time,
4243# so some files may not be where expected.
4244sub AddDependency {
4245    $target = $_[0];
4246    if (defined($makevars{"INCLUDES"})) {
4247        $include = $makevars{"INCLUDES"};
4248    }
4249    else {
4250        $include = $include_list;
4251    }
4252    print "Trying $make_depend $include $target\n" if $debug;
4253    $cmdline = "$make_depend $include $target";
4254    if (! $debug) {
4255        $cmdline .= " 2>/dev/null";
4256    }
4257    $cmdline .= " |";
4258    print "Depend commandline = $cmdline\n" if $debug;
4259    open( DEPFD, $cmdline ) || return;
4260    while (<DEPFD>) {
4261        # Remove files that are provided by the device
4262        s/\S*mpidpre\.h//g;
4263        s/\S*mpidpost\.h//g;
4264
4265        # For derived object files like lo and _xxx.o, add these
4266        if ($do_profilelibs && $found_profilelib) {
4267            s/^(.*)\.o:(.*)/$1.o _$1.o:$2/;
4268        }
4269        if ($do_sharedlibs || $found_sharedlib) {
4270            s/^(.*)\.o(.*)/$1.o $1.lo$2/;
4271        }
4272        print FD $_ ;
4273    }
4274    close( DEPFD );
4275}
4276
4277#
4278#
4279sub TargetDependenciesStatic {
4280    print FD "# Dependencies$newline";
4281    # Libraries first
4282    foreach $lib (keys(%libraries)) {
4283        foreach $sourcefile (split(/\s+/,&ExpandMakeVars($libraries{$lib}))) {
4284            # Get extension
4285            $ext = $sourcefile;
4286            $ext =~ s/^.*\.//g;
4287            # We only know about C for now.
4288            if ($ext eq "c") {
4289                &AddDependency( $sourcefile );
4290            }
4291        }
4292    }
4293    # Programs
4294    foreach $pgm (keys(%programs)) {
4295        foreach $sourcefile (split(/\s+/,$programs{$pgm})) {
4296            $ext = $sourcefile;
4297            $ext =~ s/^.*\.//g;
4298            # We only know about C for now.
4299            if ($ext eq "c") {
4300                &AddDependency( $sourcefile );
4301            }
4302        }
4303    }
4304}
4305
4306#
4307# Design:
4308# Each source file has an associated file containing dependencies, stored in
4309# a subdirectory .deps
4310#    Each source file foo has .deps/foo.d
4311#    The Makefile includes .deps/alldeps
4312#
4313# Because we want to support VPATH builds, we can't create these in the
4314# real source directory, so these directories and files must be created
4315# at configure time.
4316#
4317sub TargetDependenciesDynamic {
4318    my $has_sources = 0;
4319
4320    # First, are there any sources?
4321    # a hash in a scalar context is 0 if empty and nonzero otherwise
4322    if (scalar(%libraries) || scalar(%programs)) {
4323        $has_sources = 1;
4324    }
4325   
4326   
4327    # Some makes will accept sinclude instead of -include
4328    # -include is gnumake for "include if file exists, ignore otherwise"
4329    if ($makeInclude eq "") { $makeInclude = "-include"; }
4330
4331    print FD $makeBlockSep;
4332    print FD "# Dependencies$newline";
4333    # This definition follows the one for COMPILE_C
4334    if ($has_sources) {
4335        # By setting DEPS_DIR to just ., you can use -MMD to update the
4336        # dependencies with gcc
4337        print FD "DEPS_DIR = .deps$newline";
4338        # We'd like to use $found_profilelib to decide whether
4339        # to include the _$*.o in the target string. 
4340        # But make wants to do the $* substitutions before variable
4341        # substitutions
4342        printMakeVariable( FD, "MAKE_DEPEND_C",
4343             "\@MAKE_DEPEND_C\@ \$(DEFS) \$(INCLUDES) \$(CPPFLAGS)$newline" );
4344        print FD "dependencies: \$(DEPS_DIR)/timestamp$newline";
4345    }
4346    else {
4347        print FD "dependencies:$newline";
4348    }
4349    &RecursiveOp( "dependencies" );
4350
4351    # First, generate the targets to maintain the individual files.
4352    # This makes it easy to update the dependency contents without
4353    # regenerating the entire list.
4354    # Note that we don't always want to use this target, since
4355    # the dependencies may need to be regenerated when other files change.
4356    # Even better is to use this to update the dependency files
4357    # when each file is compile (gcc can almost do this, as long as
4358    # you don't mind having .d files in the build directory)
4359    if ($has_sources) {
4360        # Use $found_profilelib to decide whether to add _xxx.o to the
4361        # target name.  This requires that the MAKE_DEPEND_C compiler
4362        # accept the -MT option
4363        #
4364        my %sawFile = ();
4365        foreach $lib (keys(%libraries)) {
4366            # Its possible that the same file is used in several libraries.
4367            # Thus, we only look at unique files.
4368            foreach $sourcefile (split(/\s+/,&ExpandMakeVars($libraries{$lib}))) {
4369                if (defined($sawFile{$sourcefile})) { next; }
4370                $sawFile{$sourcefile} = 1;
4371                # FIXME: If, for some reason, the source file is created by
4372                # configure, then simplemake will get confused.
4373                my $srcdirloc = '$(srcdir)/';
4374                $ext = $sourcefile;
4375                $ext =~ s/^.*\.//g;
4376                $sourcebasename = $sourcefile;
4377                $sourcebasename =~ s/\.\w*$//;
4378                my $targetOpts = "-MT \'_$sourcebasename.o $sourcebasename.o\'";
4379                if (!$found_profilelib) {
4380                    $targetOpts = "";
4381                }
4382                # We can not use $< in an explicit target context because
4383                # some Make programs do not handle them properly (Solaris,
4384                # for one)
4385                if ($ext eq "c") {
4386                    if (! -s $sourcefile) {
4387                        my $missingFile = "$curdir/$sourcefile";
4388                        $missingFile =~ s%//%/%g;
4389                        print STDERR "Sourcefile $missingFile does not exist.\
4390simplemake is assuming that this file will be created by the configure step\
4391in the build directory\n";
4392                        $srcdirloc = '';
4393                    }
4394                    print FD "\$(DEPS_DIR)/$sourcebasename.d: $srcdirloc$sourcefile$newline";
4395                    print FD "\t\$(MAKE_DEPEND_C) $targetOpts $srcdirloc$sourcefile >\$(DEPS_DIR)/$sourcebasename.d$newline";
4396                }
4397            }
4398        }
4399    }
4400
4401    if ($has_sources) {
4402        print FD "\$(DEPS_DIR)/timestamp: ";
4403        # FIXME: Create a single list of source files (remove duplicates)
4404        foreach $lib (keys(%libraries)) {
4405            $sourcefiles = $libraries{$lib};
4406            PrintMakeLongline( FD, "$sourcefiles ", "append" );
4407        }
4408        foreach $pgm (keys(%programs)) {
4409            print "Adding sources for $pgm to deps\n" if $debug;
4410            $sourcefiles = $programs{$pgm};
4411            PrintMakeLongline( FD, "$sourcefiles ", "append" );
4412        }
4413        # Add Makefile as a dependency, since changes in the Makefile
4414        # can change the dependencies (particularly different configure
4415        # choices)
4416        PrintMakeLongline( FD, "Makefile", "last" );
4417
4418        # We always use a "newalldeps" incase there is a failure
4419        # creating the new list of dependency files.
4420        print FD "\trm -f \$(DEPS_DIR)/newalldeps$newline";
4421        my %sawFile = ();
4422        foreach $lib (keys(%libraries)) {
4423            foreach $sourcefile (split(/\s+/,&ExpandMakeVars($libraries{$lib}))) {
4424                if (defined($sawFile{$sourcefile})) { next; }
4425                $sawFile{$sourcefile} = 1;
4426                my $srcdirloc = '$(srcdir)/';
4427                $ext = $sourcefile;
4428                $ext =~ s/^.*\.//g;
4429                $sourcebasename = $sourcefile;
4430                $sourcebasename =~ s/\.\w*$//;
4431                if ($ext eq "c") {
4432                    if (! -s $sourcefile) {
4433                        $srcdirloc = '';
4434                    }
4435                    $targetOpts = "-MT \'_$sourcebasename.o $sourcebasename.o\'";
4436                    if (!$found_profilelib) {
4437                        $targetOpts = "";
4438                    }
4439                    print FD "\t\$(MAKE_DEPEND_C) $targetOpts $srcdirloc$sourcefile >\$(DEPS_DIR)/$sourcebasename.d$newline";
4440                    print FD "\techo \"$makeInclude \$(DEPS_DIR)/$sourcebasename.d\" >>\$(DEPS_DIR)/newalldeps$newline";
4441                }
4442            }
4443        }
4444
4445        # Programs
4446        foreach $pgm (keys(%programs)) {
4447            foreach $sourcefile (split(/\s+/,$programs{$pgm})) {
4448                if (defined($sawFile{$sourcefile})) { next; }
4449                print "Adding deps command for program source $sourcefile\n" if $debug;
4450                $sawFile{$sourcefile} = 1;
4451                my $srcdirloc = '$(srcdir)/';
4452                $ext = $sourcefile;
4453                $ext =~ s/^.*\.//g;
4454                $sourcebasename = $sourcefile;
4455                $sourcebasename =~ s/\.\w*$//;
4456                if ($ext eq "c") {
4457                    if (! -s $sourcefile) {
4458                        $srcdirloc = '';
4459                    }
4460                    $targetOpts = "-MT \'_$sourcebasename.o $sourcebasename.o\'";
4461                    if (!$found_profilelib) {
4462                        $targetOpts = "";
4463                    }
4464                    print FD "\t\$(MAKE_DEPEND_C) $targetOpts $srcdirloc$sourcefile >\$(DEPS_DIR)/$sourcebasename.d$newline";
4465                    print FD "\techo \"$makeInclude \$(DEPS_DIR)/$sourcebasename.d\" >>\$(DEPS_DIR)/newalldeps$newline";
4466                }
4467            }
4468        }
4469
4470        print FD "\tif [ -s \$(DEPS_DIR)/newalldeps ] ; then mv -f \$(DEPS_DIR)/newalldeps \$(DEPS_DIR)/alldeps ; fi$newline";
4471        print FD "\tdate >\$(DEPS_DIR)/timestamp$newline";
4472
4473        print FD "$makeInclude \$(DEPS_DIR)/alldeps$newline";
4474    }
4475   
4476    print FD "# End of Dependencies$newline";
4477    print FD $makeBlockSep;
4478}
4479
4480sub DistCleanDependencies {
4481    # Eventually, this should output only in Makefiles that have the
4482    # dependencies directory
4483    print FD "\t-${quietLine}rm -rf \$(DEPS_DIR)$newline";
4484}
4485
4486# ===========================================================================
4487#
4488# Routines to support autoconf and configure, including extracting information
4489# from the configure file and rebuilding configure from configure.in
4490#
4491#
4492# Extract derived files from autoconf
4493# Also record whether there is an AC_CONFIG_HEADER
4494# If AC_OUTOUT contains any shell variables, you can use
4495#   <variable_name>_VALUES=vals
4496# (all on one line!) to provide the set of possible values.
4497# Otherwise, no special code will be generated for those output files,
4498# and a warning message will be issued.
4499# FIXME: the name is recorded and added to the files, but simplemake
4500# may not be careful about the file or about directory paths involving the
4501# xxx_VALUE variable.  Still experimental
4502sub ReadAutoconf {
4503    $configure_has_config_headers = "no";
4504    %confvars = ();
4505    open FDCONF, "configure.in" || die "Could not open configure.in file";
4506    while (<FDCONF>) {
4507        #if (/^\s*#/) { next; }
4508        if (/^\s*AC_CONFIG_HEADER\((.*)\)/) {
4509            # Record file name of header in result variable
4510            # We also need to add this to the list of files to remove
4511            # in the distclean target
4512            $configure_has_config_headers = $1;
4513        }
4514        if (/^\s*(\w*)_VALUES=(.*)/) {
4515            # This is a special case, used below
4516            $confvars{$1}=$2
4517        }
4518        if (/^\s*AC_OUTPUT\(/) {
4519            # First, read past all continued lines
4520            $line = "";
4521            # Remove any M4 dnl line
4522            s/\sdnl\s.*//;
4523            # Later versions of Autoconf do not require explicit continuation
4524            # so we also read until we find the closing paren
4525            while (/\\\s*$/) {
4526                s/\r?\n$//; # Removes eol on both Unix and Windows
4527                chop($_); # remove the backslash
4528                $line .= $_;
4529                $_ = <FDCONF>;
4530                die "unexpected EOF in configure.in, aborting" unless defined $_;
4531                # Remove any M4 dnl line
4532                s/\sdnl\s.*//;
4533                # Remove any shell comment line
4534                s/\s#.*//;
4535            }
4536            $line .= $_;
4537            $line =~ s/\r?\n$//; # Removes eol on both Unix and Windows
4538            $line =~ s/,.*/\)/;  # Changes a ,... to ) to handle
4539                                 # AC_OUTPUT(files...,[command]),
4540                                 # where the final ) may not be on this line
4541            #print $line;
4542            # If there's no closing paren yet, keep reading
4543            while (! ($line =~ /\)/)) {
4544                $_ = <FDCONF>;
4545                die "unexpected EOF in configure.in, aborting" unless defined $_;
4546                s/\r?\n$//; # Removes eol on both Unix and Windows
4547                # Remove any M4 dnl line
4548                s/\sdnl\s.*//;
4549                # Remove any shell comment line
4550                s/\s#.*//;
4551                $line .= $_ . " ";
4552            }
4553            #print "ac_output line = $line\n";
4554            $line =~ /^\s*AC_OUTPUT\((.*)\)\s*$/;
4555            $files = $1;
4556            if (! defined($files) ) {
4557                print STDERR "Unable to find file names in AC_OUTPUT\n";
4558                $files = "";
4559            }
4560            #print "files for ac_output = $files\n";
4561            @autoconf_files = split(/\s+/,$files);
4562            # Create a hash by directory
4563            # FIXME: Should curdir be blank by default?
4564            if (!$curdir) { $curdir = ""; }
4565            $lcurdir = $curdir;
4566            $lcurdir =~ s/\/$//;
4567            foreach $file (@autoconf_files) {
4568                if ($file =~ /^(.*)\/([^\/]*)$/) {
4569                    # File contains a directory path, so update the
4570                    # appropriate directory entry
4571                    my $ndir     = "$curdir$1";
4572                    my $leaffile = $2;
4573
4574                    if (defined($autoconf_files_by_dir{$ndir})) {
4575                        $autoconf_files_by_dir{$ndir} .= " $leaffile";
4576                    }
4577                    else {
4578                        $autoconf_files_by_dir{$ndir} = "$leaffile";
4579                    }
4580                    #print "{$ndir} .= $2\n";
4581                    # Also add files that are in directories with no simplemake
4582                    # input (e.g., in include directories with no makefile)
4583                    if (! -s "$ndir/Makefile.sm") {
4584                        if (defined($autoconf_files_by_dir{$lcurdir})) {
4585                            $autoconf_files_by_dir{$lcurdir} .= " $file";
4586                        }
4587                        else {
4588                            $autoconf_files_by_dir{$lcurdir} = "$file";
4589                        }
4590                    }
4591                    else {
4592                        # We also need to handle files that do have a
4593                        # Makefile.sm,
4594                        # but that aren't in the "usual" path.  Those
4595                        # are directories that are not included in the
4596                        # SUBDIRS path.  These are used only by the distclean
4597                        # target
4598                        $autoconf_files_by_dir_orig{$lcurdir} .= " $file";
4599                    }
4600                }
4601                elsif ($file =~ /^\$[\{\(]?(\w*)[\}\)]?/) {
4602                    # Another special case.  The name is actually
4603                    # a shell variable.  This is too hard for us right now,
4604                    # so generate a warning and do NOT add it to the list
4605                    # To handle this case, you can provide
4606                    # <variable-name>_VALUES
4607                    $varname = $1;
4608                    if (defined($confvars{$varname})) {
4609                        # add to autoconf_files_by_dir
4610                        foreach $filename (split(/\s+/,$confvars{$varname})) {
4611                            $autoconf_files_by_dir{$lcurdir} .= " $file";
4612                        }
4613                    }
4614                    else {
4615                        print STDERR "Shell variable $varname will not be added to the list\
4616of known autoconf files for ";
4617                        if (defined($lcurdir) && $lcurdir ne "") {
4618                            print STDERR "$lcurdir.\n";
4619                        }
4620                        else {
4621                            print STDERR "the top directory.\n";
4622                        }
4623                    }
4624                }
4625                elsif ($file =~ /^.*$/) {
4626                    if (defined($autoconf_files_by_dir{"$lcurdir"})) {
4627                        $autoconf_files_by_dir{"$lcurdir"} .= " $file";
4628                    }
4629                    else {
4630                        $autoconf_files_by_dir{"$lcurdir"} = "$file";
4631                    }
4632
4633                    #print "{$lcurdir} .= $file\n";
4634                }
4635            }
4636            # Add files that configure generates in the current directory
4637            $autoconf_files_by_dir{$lcurdir} .= " config.status config.log config.cache *conf.cache config.system";
4638            #print "$files\n";
4639            last;
4640        }
4641    }
4642    close FDCONF;
4643}
4644#
4645# Find how to get from path_child to path_parent.  Return as
4646# ../.. etc, suitable for using cd to get to the parent
4647sub GetPathToParent {
4648    my ($path_child, $path_parent) = @_;
4649    # Remove parent path from child path
4650    if (defined($path_parent)) {
4651        # first, deal with a possible "." path
4652        $path_parent = quotemeta $path_parent;
4653        #print "path_parent = $path_parent, child = $path_child\n";
4654        $path_child =~ s/^$path_parent//;
4655        #print "After parent, child = $path_child\n";
4656        # convert all of the non directory separators into ..
4657    }
4658    else {
4659        print STDERR "Path to parent is unknown in GetPathToParent\n";
4660        # Set a default
4661        $path_child = ".";
4662    }
4663    $path_child =~ s/[^\/\.]*\//..\//g;
4664    return $path_child;
4665}
4666
4667#
4668# Remove any trailing .. from the directory as well as that many directories
4669sub CleanCurDir {
4670    my $dir = $_[0];
4671    my $depth = 0;
4672
4673    # Handle any /.. at the end
4674    print "Cleaning directory name $dir...\n" if $debug_confdir;
4675    $dir =~ s/\/$//;
4676    while ($dir =~ /\/\.\.$/) {
4677        $depth++;
4678        $dir =~ s/\/\.\.$//;
4679    }
4680    while ($depth > 0) {
4681        $dir =~ s/\/[^\/]*//;
4682        $depth--;
4683    }
4684
4685    # We sometimes get ../ in the middle
4686    while ($dir =~ /(.*)\/[^\/\.]+\/\.\.(.*)/) {
4687        print "Changing $dir to $1$2\n" if $debug_confdir;
4688        $dir = "$1$2";
4689    }
4690    if ($dir ne "") { $dir .= "/"; }
4691    print "Cleaned directory name is $dir\n" if $debug_confdir;
4692    return "$dir";
4693}   
4694#
4695# ===========================================================================
4696# Pretty print output lines.  These routines insert line breaks and tabs
4697# to keep the generated makefile from being too ugly.  These also use
4698# tabs after a continuation line.
4699$linelen = 0;
4700sub printInit {
4701    $linelen = 0;
4702}
4703sub print_make_line {
4704    my $FD = $_[0];
4705    my $line = "$_[1]";
4706    my $len = length($line);
4707    if ($linelen + $len + 2 > $maxline) {
4708        print $FD "\\$newline\t";
4709        $linelen = 8;
4710    }
4711    print $FD $line;
4712    $linelen += $len;
4713    }
4714# print_make_line_nobreak is like print_make_line, but it never breaks a line
4715# This is needed when the output is a configure variable that may end
4716# up being replaced with blanks; if this occurs alone on a line, some
4717# make programs become confused.
4718sub print_make_line_nobreak {
4719    my $FD = $_[0];
4720    my $line = "$_[1]";
4721    my $len = length($line);
4722    print $FD $line;
4723    $linelen += $len;
4724    }
4725sub print_make_endline {
4726    my $FD = $_[0];
4727    print $FD $newline;
4728    $linelen = 0;
4729}
4730sub print_make_setpos {
4731    $linelen = $_[0];
4732}
4733# print_make_longline is intended for printing long lines that contains blanks
4734# This adds the newline at the end
4735sub print_make_longline {
4736    my $FD = $_[0];
4737    my $line = $_[1];
4738    &PrintMakeLongline( $FD, $line, "last" );
4739}
4740
4741# New print routines
4742# PrintMakeLongline( FD, line, flag ) - line may have spaces, will break
4743# as spaces in line.  Flag may be "append" or "last".  line may be empty
4744# (to use flag = "last" to terminate.
4745sub PrintMakeLongline {
4746    my $FD = $_[0];
4747    my $line = $_[1];
4748    my $flag = $_[2];
4749
4750    my $len = length( $line );
4751    if ($linelen + $len + 2 < $maxline) {
4752        print $FD $line;
4753    }
4754    else {
4755        # Use space, not \s, because we want tabs to remain tabs
4756        foreach my $token (split(/ /,$line)) {
4757            # We must be careful not to add a blank if the token is
4758            # a \ used at the end of a line to continue to the
4759            # next line
4760            if ($token eq "\\") {
4761                &print_make_line( $FD, "$token" );
4762            }
4763            else {
4764                &print_make_line( $FD, "$token " );
4765            }
4766        }
4767    }
4768    if ($flag eq "last") {
4769        &print_make_endline( $FD );
4770    }
4771}
4772# Print a Make variable definition only if it hasn't been made already
4773# Add and prepend value that may have been specified
4774sub printMakeVariable {
4775    my ($FD,$var,$definition) = @_;
4776
4777    if (!defined($addedMakeVars{$var})) {
4778        $addedMakeVars{$var} = $definition;
4779        if (defined($PrependVar{$var})) {
4780            $definition = $PrependVar{$var} . $definition;
4781        }
4782        my $nspace = 16 - length($var);
4783        my $blanks = "";
4784        while ($nspace > 0) { $blanks .= " "; $nspace-- }
4785        PrintMakeLongline( $FD, "$var$blanks= $definition", "last" );
4786    }
4787    elsif ($addedMakeVars{$var} ne $definition) {
4788        my $value = $addedMakeVars{$var};
4789        print STDERR "Variable $var, being defined with $definition, already has value $value\n";
4790    }
4791}
4792#
4793# Find a working autoconf.
4794# If the variables autoconf and autoconf_version are set, try to
4795# find one that works in the user's path.  The format for these
4796# variables is
4797#   autoconf = name:name:...:lasthope
4798#   autoconf_version = number
4799#   Check each autoconf name for handling version.  If all else fails,
4800#   unconditionally accept lasthope
4801sub FindWorkingAutoconf {
4802    if ($autoconf_version ne "") {
4803        foreach $file (split(/:/,$autoconf)) {
4804            $lastfile = $file;
4805            # Grumble.  I need to redirect stderr to stdout before this
4806            # open.  We use open with a pipe and then exec so that we
4807            # can get stderr redirection to work correctly.
4808            #
4809            # Additional grumble.  Perl doesn't flush output the
4810            # way you'd like.  Of course, if you turn on -debug,
4811            # things do get flushed.
4812            $pid = open( ACFD, "-|");
4813            if ($pid == 0) {
4814                close FD;  # without flushing
4815                open STDIN, "/dev/null";
4816                open STDERR, ">>&STDOUT";
4817                exec split(/\s+/,"$file --version");
4818            }
4819            else {
4820                $found_version = "";
4821                while (<ACFD>) {
4822                    print STDERR "$_" if $debug;
4823                    if (/[Aa]utoconf\s.*([12]\.[0-9]+)/) {
4824                        $found_version = $1;
4825                        last;
4826                    }
4827                }
4828                close( ACFD );
4829                print STDERR "Autoconf $file is version $found_version\n" if $debug;
4830                if ($found_version >= $autoconf_version) {
4831                    $autoconf = $file;
4832                    print STDERR "Using autoconf $file\n" if $debug;
4833                    return;
4834                }
4835            }
4836        }
4837        # If we got here, use the lastchance
4838        $autoconf = $lastfile;
4839    }
4840}
4841#
4842# ----------------------------------------------------------------------------
4843# Coverage analysis
4844# One useful target for package maintainers is coverage analysis. 
4845# The following code creates the targets for the gcc coverage analyzer,
4846# gcov.  In tests, this analyzer worked with programs built from libraries
4847# and with sources in multiple directories.
4848#
4849# To use the gcc coverage analyzer, the following steps must be taken
4850# 1.  All file must be compiled with -fprofile-arcs -ftest-coverage, and
4851#     without optimization
4852# 2.  Programs are run as usual
4853# 3.  To create coverage data, run
4854#         gcov -f -b sourcefile
4855#     over all source files.  The result is (for each sourcefile) a
4856#     new file, "sourcefile.gcov", which annotates the source file with
4857#     the number of times each statement was executed
4858#
4859# To add support for these, simplemake adds the following targets in
4860# maintenance target mode (e.g., not in the distributed version):
4861#     Add to clean (all with ${srcdir}) *.bb, *.bbg, *.da, *.c.gcov . 
4862#         These are all created by either gcc or by running programs
4863#         built with -ftest-coverage.
4864#     Add a recursive coverage target that does:
4865#         Run gcov on each source file (if any), where a .da file is present
4866#     We may be able to use a target like:
4867#         $*.c.gcov depends on $*.da (.da.gcov)
4868#     We let the configure step add the compiler options (so that a
4869#     separate simplemake build is not required to add or remove
4870#     coverage analysis.
4871#
4872# ToDo:
4873# In the install step, mkdir isn't right, since it will make only one
4874# directory level, and mkdir -p isn't universally available.  We probably
4875# need either a MKDIR_P command, determined byu configure, or an
4876# mkinstalldirs script.  I'd prefer a mkdirp script, used only if mkdir -p
4877# did not work, and chosen by configure in that case.
4878# This is partially done (MKDIR_P and that is set to mkdir -p)
4879# ----------------------------------------------------------------------------
4880# Add the clean target for the coverage analyzer.
4881# We inculde the local directory because, particularly for the test programs,
4882# these files may be left in the current directory rather than the source
4883# directory.
4884#
4885sub GcovClean {
4886    if ($maint_targets) {
4887        print FD "\t-${quietLine}rm -f \${srcdir}/*.bb \${srcdir}/*.bbg \${srcdir}/*.da$newline";
4888        print FD "\t-${quietLine}rm -f \${srcdir}/*.gcda \${srcdir}/*.gcno$newline";
4889        print FD "\t-${quietLine}rm -f *.gcov *.bb *.bbg *.da *.gcda *.gcno$newline";
4890    }
4891}
4892
4893# coverage target
4894sub TargetGcov {
4895    if (!$maint_targets) { return; }
4896    &TargetInit( "coverage" );
4897    print FD "$newline";
4898    foreach $lib (keys(%libraries)) {
4899        $sourcefiles = $libraries{$lib};
4900        PrintMakeLongline( FD,
4901           "\t-${quietmake}for file in $sourcefiles ; do \\", "last" );
4902        print FD "\t\tgcov -b -f \$\$file ; done$newline";
4903    }
4904    &RecursiveOp( "coverage" );
4905    &TargetPostamble( "coverage" );
4906}
4907#
4908# ----------------------------------------------------------------------------
4909#
4910# ToDo
4911# Should we add a target to strip debugging information from the object files?
4912# For example, strip -S *.o .  Ths usually isn't necessary if -g is not
4913# selected when building the object files.
4914#
4915# David Ashton suggests an option to print a warning message for
4916# each source file (e.g., *.c, *.cxx, *.f, *.f90) that has no corresponding
4917# entry in the Makefile.sm
4918#
4919# Here is a start on that.
4920# What is still needed is a way to check for defined sources when the source
4921# files are named in a variable (e.g., xxx_SOURCE = ${foobar}, then we
4922# need to expand foobar.  This is not done systematically yet, in part
4923# because we want to preserve the use of variables in the Makefile.
4924sub checkForTargets {
4925    opendir DIR, ".";
4926    my $filename;
4927    my %knownExts = ( "c" => 1, "f" => 1, "f90" => 1, "cxx" => 1 );
4928    my %knownHeaders = ( "h" => 1, "i" => 1 );
4929    while ($filename = readdir DIR) {
4930        my $ext = "";
4931        if ($filename =~ /\.(\w+)$/) {
4932            $ext = $1;
4933        }
4934        if (defined($knownExts{$ext})) {
4935            # Found a source file.  Did we see this file in the source lists?