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

Revision 4869, 172.6 KB (checked in by kumudb, 5 months ago)

simplemake.in modified so that all-executable target is added in every subdirectory and the subsequent subdirectories are descended to create any executables.

<
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   
1758    # Clean targets
1759    &TargetClean;
1760}
1761
1762#
1763# ===========================================================================
1764#
1765# Look at a list of source files and determine the source types
1766#
1767# Eventually, make this $ext_seen{$extension} = 1,
1768# then generate code by using keys(%ext_seen).  Allows general
1769# extensions and simpler handling of rules (like adding .F and .f90 )
1770sub FindSrcTypes {
1771    my $source = $_[0];
1772    my $files = "";
1773    foreach my $sym (split(/\s+/,$source)) {
1774        print STDERR "Is $sym a make variable?\n" if $debug;
1775        $vsym = $sym;
1776        if ($vsym =~ /\$[\{\(]?(\w*)[\}\)]?/) {
1777            $vsym = $1;
1778        }
1779        if (defined($makevars{$vsym})) {
1780            print STDERR "yes, value is $makevars{$vsym}\n" if $debug;
1781            $files .= " $makevars{$vsym}";
1782        }
1783        else {
1784            $files .= " $sym";
1785        }
1786    }
1787    foreach my $file (split(/\s+/,$files)) {
1788        ($name,$ext) = split('\.',$file);
1789        if (defined($ext) && $ext ne "") {
1790            $ext_seen{$ext} = 1;
1791        }
1792    }
1793}
1794
1795# Save all conventional sources
1796# This is only approximate.
1797# We want to allow source files to be specified through other
1798# variables (e.g., ${Foo_sources}).
1799# Globals: regular_sources, regular_headers
1800sub SaveSrcNames {
1801    my $source = $_[0];
1802    my @files;
1803    my $file;
1804    # First, expand the source variable
1805    #print STDERR "Got $source ...\n";
1806    foreach $file (split(/\s+/,$source)) {
1807        #print STDERR "Checking $file ...\n";
1808        # Substitute for any make variables (1 level of substitution)
1809        $file = &ExpandMakeVars( $file );
1810        foreach $name (split(/\s+/,$file)) {
1811            $files[$#files+1] = $name;
1812        }
1813    }
1814   
1815    foreach $file (@files) {
1816        ($name,$ext) = split( '\.',$file);
1817        if (defined($ext)) {
1818            if (defined($extrules{"$ext:o"})) {
1819                $regular_sources .= " $file";
1820                $sources{$file} = 1;
1821            }
1822            elsif ($ext eq "h") {
1823                # FIXME: need to handle other header extensions;
1824                # e.g., MPICH2 uses .i as well
1825                $regular_headers .= " $file";
1826                $headers{$file} = 1;
1827            }
1828        }
1829    }
1830}
1831
1832#
1833# Find the name of the source file that matches the program.
1834# If none found, use c as the type
1835sub FindPgmSrcType {
1836    $pgm = $_[0];
1837    $pgmsrc = $_[1];
1838    # Also keep track of the types seen
1839    my %exttypes;
1840    my $firstext = "";
1841    foreach $file (split(/\s+/,$pgmsrc)) {
1842        ($name,$ext) = split('\.',$file);
1843        if ($name eq $pgm) {
1844            $pgmlinktypes{$ext} = 1;
1845            return $ext;
1846        }
1847        else {
1848            $exttypes{$ext} = 1;
1849            if ($firstext eq "") { $firstext = $ext; }
1850        }
1851    }
1852    if (defined($exttypes{"c"})) {
1853        $pgmlinktypes{"c"} = 1;
1854        return "c";
1855    }
1856    elsif (defined($exttypes{"cxx"})) {
1857        $pgmlinktypes{"cxx"} = 1;
1858        return "cxx";
1859    }
1860    elsif (defined($exttypes{"f90"})) {
1861        $pgmlinktypes{"f90"} = 1;
1862        return "f90";
1863    }
1864    else {
1865        $pgmlinktypes{$firstext} = 1;
1866        return $firstext;
1867    }
1868}
1869
1870sub ClearVars {
1871    # Extensions seen is a property of the makefile
1872    %ext_seen = ();
1873    # We include abs_srcdir because it is useful to know and some
1874    # steps may conditionally need it (so we may not know that we also
1875    # need abs_srcdir until it is too late to add it)
1876    # We include abs_builddir because it is useful to have the
1877    # build directory around (particularly for the TAGS step)
1878    %dirs_seen = ( "srcdir" => 1, "abs_srcdir" => 1, "abs_builddir" => 1 );
1879    $other_vars = "";
1880    $other_text = "";
1881    $regular_sources = "";
1882    #$header_sources = "";
1883    $regular_headers = "";
1884    %sources = ();
1885    %headers = ();
1886
1887    # Targets
1888    @alltargets = ();   # implicit targets
1889    @allshlibtargets = (); # implicit shared library targets
1890    @alldlllibtargets = (); # implicit dynamically loaded library targets
1891    %altalltargets = ();   # related targets to items in alltargets
1892    %usertargets = ();  # explicit, user-defined targets
1893    %extra_programs = ();
1894    %extra_libs     = ();
1895    %libraries = ();
1896    $libcount = 0;
1897    %libnum    = ();    # Gives number associated with library
1898    %shared_libraries = ();
1899    %shared_libraries_exports = ();
1900    %shared_libraries_libs = ();
1901    %profile_libraries = ();
1902    %profile_libraries_basename = (); # inverse of profile_libraries
1903    %profile_library_sources = ();
1904    %install_files = ();
1905    @install_subdirs = ();
1906    %install_dirs = ();
1907    %optinstall_files = ();
1908    $install_local_dirs = "";
1909    $gIssuedInstallLocal = 0;
1910    %libNotShared = ();
1911    %external_libraries = ();
1912    $found_profilelib = 0;
1913    $found_sharedlib  = 0;
1914    $InitSharedLibraryFinal = 0;
1915    %programs = ();
1916    %pgm_ldadd = ();
1917    $ldadd_all = "";
1918    %pgm_depadd = ();
1919    $depadd_all = "";
1920
1921    $gSubdirSMVarsSeen = "";
1922
1923    # Variables
1924    # makevars are variables seen in the Makefile.sm
1925    # addedMakeVars are variables that have been added to the output
1926    # Makefile.in
1927    %PrependVar = ();
1928    %makevars = ();
1929    %addedMakeVars = ();
1930    # smmakevars are variables that have been defined as SM variables.
1931    %smmakevars = ();
1932    # vars_seen is a hash of the variables used in the makefile
1933    %vars_seen = ();
1934    # Information about program targets
1935    %pgmlinktypes = ();
1936    # Other directories
1937    @subdirs = ();
1938    %notSimplemakeDirs = ();
1939    %subdir_autoconf_vars = ();
1940    $subdir_optionals = "";
1941    @doc_subdirs = ();
1942    $docargsAdd = "";
1943    %docthiskinddir = ();
1944    @extra_dirs = ();
1945    @tags_dirs  = ();
1946    @other_dirs = ();
1947    $subdirs_has_autoconf = 0;
1948    # Suffix definitions
1949    $ExplicitSuffixes = "";
1950    $suffixes = "";
1951
1952    # Document sources and directories
1953    %docdir = ();
1954    %docsrc = ();
1955    # These may be overriden on a file by file basis
1956    $autoconf = $autoconf_prog; # Name of autoconf program to use
1957    $autoconf_version = ""; # Any version is allowed
1958    # We cannot clear config_headers here because we may still
1959    # need to know that the configure in the current directory
1960    # has a header file, and this routine to clear vars is called for
1961    # every file.
1962    #$configure_has_config_headers = "no";
1963    %simplemake_vars = ();
1964
1965    # For any extensions, clear their global variables.
1966    &SMInvokeAction( "Clear" );
1967
1968}       
1969
1970#
1971# Expand all of the make variables in an expression.  This
1972# lets users use targets like
1973# libmpich_SOURCE_a = ${MPI_SOURCES}
1974sub ExpandMakeVars {
1975    # look for ${\w*} and replace with the value of $makevars{$1}
1976    my $line = $_[0];
1977    print "Looking at $line\n" if $debug;
1978
1979    if (!defined($line)) { return ""; }
1980
1981    my $after = "";
1982    my $processed = "";
1983    while ($line =~ /([^\$]*)\$([{\(])(\w+)([}\)])(.*)/) {
1984        my $before = $1;
1985        my $lb   = $2;
1986        my $mvar = $3;
1987        my $rb   = $4;
1988        $after   = $5;
1989        print "replacing \$$lb$mvar$rb\n" if $debug;
1990        # Rescan the replacement in case it contains a variable.
1991        # Undefined variables are left in place
1992        if (defined($makevars{$mvar})) {
1993            $processed .= $before;
1994            $line = $makevars{$mvar} . $after;
1995        }
1996#       elsif (defined($dirdefs{$mvar})) {
1997#           $processed .= $before;
1998#           $line = $dirdefs{$mvar} . $after;
1999#       }
2000        else {
2001            $processed .= $before . "\$$lb$mvar$rb";
2002            $line      = $after;
2003        }
2004    }
2005    $processed .= $line;
2006    print "expanded to $processed\n" if $debug;
2007    return $processed;
2008}
2009
2010#
2011# ===========================================================================
2012@config_dir = ();    # Stack of the location of the most recently seen
2013                     # configure script.  Used to create targets that
2014                     # need to run config.status from that directory.
2015
2016$last_config_dir = "";
2017
2018#
2019# ===========================================================================
2020
2021# These next two routines let us print out the file being processed only
2022# when we need to (e.g., before an error message).
2023$curFilename = "";
2024$curFilenamePrinted = 0;
2025sub ResetFileName {
2026    $curFilename = $_[0];
2027    $curFilenamePrinted = 0;
2028}
2029sub ShowFileName {
2030    if ($curFilenamePrinted) { return; }
2031    print "Processing $curdir$file\n" if (!$quiet && $debug_dirs);
2032    $curFilenamePrinted = 1;
2033}
2034
2035sub ProcessFile {
2036    $file = $_[0];
2037
2038    $gSubdirSMVarsSeen = "";
2039
2040    # FIXME: curdir?
2041    if (!$curdir) { $curdir = ""; }
2042    &ResetFileName( "$curdir$file" );
2043    print "Processing $curdir$file\n" if (!$quiet && $debug_dirs);
2044    $configure_has_config_headers = "no";
2045    if (-s "configure.in") {
2046        &ReadAutoconf;
2047        print "Found configure.in in $curdir, set last_config_dir to $curdir\n" if $debug_confdir;
2048        if ($curdir eq "") { $last_config_dir = "."; }
2049        else {  $last_config_dir = $curdir; }
2050    }
2051    &ReadMfile( $file );
2052    $output_name = $file;
2053    if ($create_configure_input) {
2054        $output_name =~ s/\.sm$/.in/;
2055    }
2056    &WriteMfile( $output_name );
2057   
2058    if ($gCheckForTargets) {
2059        &checkForTargets();
2060    }
2061
2062    # Process any subdirectories
2063    # The list of directories to process comes from the variables
2064    # defined in the Makefile.sm.  The following is the list
2065    my @dirs = (@subdirs,@other_dirs,@doc_subdirs,@tags_dirs);
2066    # Get a local copy of the "notsimplemake" hash
2067    my %notSimplemake = %notSimplemakeDirs;
2068    # First, check for names that are replaced by autoconf (e.g., @name@)
2069    # in the names of the directories.  For those variables, there should
2070    # be a corresponding SUBDIRS_name variable in the makefile that lists
2071    # *all* directories to which @name@ may be expanded by configure.
2072    my @actdirs = ();
2073    foreach my $dir (@dirs) {
2074        $sdir = $dir;
2075        print "Checking $sdir\n" if ($debug_dirs);
2076        if ($sdir =~ /@([^@]*)@/) {
2077            $subst_name = $1;
2078            $subdirs_has_autoconf = 1;
2079            #print "Found $subst_name\n";
2080            # Look up the special name
2081            $var_name = "SUBDIRS_$subst_name";
2082            #print "varname is $var_name\n";
2083            if (defined( $makevars{$var_name} )) {
2084                # Concatenate the value of the variable name to the list
2085                # of directories
2086                @actdirs = ( @actdirs, split( /\s+/, $makevars{$var_name} ) );
2087            }
2088        }
2089        else {
2090            $actdirs[$#actdirs+1] = $dir;
2091        }
2092    }
2093
2094    # Push the saved subdir vars onto a stack, to be popped at the end.
2095    print "Saving $gSubdirSMVarsSeen\n" if $gDebugSubdirVar && ($gSubdirSMVarsSeen ne "");
2096    $subdirsSMVars[$#subdirsSMVars+1] = $gSubdirSMVarsSeen;
2097   
2098    # For each of the directories, process it.
2099    M: foreach my $dir (@actdirs) {
2100        if ($dir eq ".") { next M; }
2101        if ($dir =~ /\.\./ || $dir =~ /.\/./) {
2102            # Skip directory changes that aren't simple
2103            &ShowFileName;
2104            print "$dir has .. in it (skipping)\n";
2105            print "Current dir is $curdir\n" if $debug;
2106            next M;
2107            #exit(1);
2108        }
2109        if (! -d $dir) {
2110            my $ldir = `pwd`;
2111            if (!defined($notSimplemake{$dir})) {
2112                &ShowFileName;
2113                print "Directory $curdir$dir does not exist\n";
2114                print "(Current location is $ldir)\n";
2115            }
2116            next M; }
2117        if (! -s "$dir/$file") {
2118            if (!defined($notSimplemake{$dir})) {
2119                print "File $curdir$dir/$file does not exist\n";
2120            }
2121            next M; }
2122        chdir $dir || die "Cannot change to directory $dir\n";
2123        $curdir .= "$dir/";
2124        $curdir = &CleanCurDir( $curdir );
2125        if ($dir =~ /\.\./) {
2126            &ShowFileName;
2127            print "changed to a non-obvious dir = $dir\n";
2128            my $ldir = $dir;
2129            while ($ldir =~ /^\.\.\//) {
2130                $rootdirpath =~ s/\.\.\/$//;
2131                $ldir =~ s/^\.\.\///;
2132            }
2133            while ($ldir =~ /^[^\/]+\//) {
2134                $rootdirpath .= "../";
2135                $ldir =~ s/^[^\/]+\///;
2136            }
2137            if ($ldir =~ /\S+/) {
2138                $rootdirpath .= "../";
2139            }           
2140        }
2141        else {
2142            $rootdirpath .= "../";
2143        }
2144        print "rootdir = $rootdirpath\n" if $debug_confdir;
2145        print "curdir = $curdir\n" if $debug_confdir;
2146        # Remember the last place that we saw a configure; push and
2147        # pop for each file that we process.
2148        $config_dir[$#config_dir+1] = $last_config_dir;
2149        print "config stack has depth $#config_dir\n" if $debug_confdir;
2150        print "relative path to configure dir is " . &GetPathToParent( $curdir, $last_config_dir ) . "\n" if $debug_confdir;
2151        &ProcessFile( $file );
2152        $last_config_dir = $config_dir[$#config_dir]; $#config_dir--;
2153        print "after processing, last_config_dir = $last_config_dir\n" if $debug_confdir;
2154        print "config stack has depth $#config_dir\n" if $debug_confdir;
2155        $rootdirpath =~ s/\.\.\/$//;
2156        chdir "..";
2157        $curdir =~ s/[^\/]*\/$//;
2158        $curdir = &CleanCurDir( $curdir );
2159    }
2160    # End of processing directories
2161
2162    # Restore any variables that were changed for the scope of this directory
2163    # subtree (emulate a stack; don't trust perls dynamic scoped local)
2164    my $subdirvars = $subdirsSMVars[$#subdirsSMVars]; $#subdirsSMVars--;
2165    if (!defined($subdirvars)) {
2166        print STDERR "subdirsSMVars stack count = $#subdirsSMVars in $curdir\n";
2167        print STDERR "previous value is $subdirsSMVars[$#subdirsSMVars]\n";
2168    }
2169    foreach my $varstring (split(/;/,$subdirvars)) {
2170        if ($varstring =~ /(\w+)=(.*)/s) {
2171            my $varname = $1;
2172            my $varvalue = $2;
2173            print "Restoring $$varname to $varvalue in $curdir\n" if $gDebugSubdirVar;
2174            $$varname = $varvalue;
2175        }
2176        elsif ($varstring ne "") {
2177            print STDERR "Internal Error: varstring = $varstring\n";
2178        }
2179    }                         
2180}
2181
2182sub ListTargets {
2183  foreach $target (@alltargets) {
2184      # Skip the extra programs
2185      if (defined($extra_programs{$target})) { next; }
2186      if (defined($extra_libs{$target})) { next; }
2187      # Add any alternate target (used for targets in other directories
2188      # to work around timestamp problems).
2189      if (defined($altalltargets{$target})) {
2190          print_make_line( FD, " " . $altalltargets{$target} );
2191      }
2192      print_make_line( FD,  " $target" );
2193  }
2194}
2195
2196
2197#
2198# Add to a target the designate operation in all subdirs (except for .)
2199#     &RecursiveOp( "target" [, optional array of directories, [checkMakefile] ] );
2200# If the array of directories is not included, (@extra_dirs,@subdirs)
2201# is used.  These are the arrays maintined by simplemake of the
2202# directories set by EXTRA_DIRS and SUB_DIRS.  The "optional array"
2203# is passed by name (i.e., the name of the array is passed, not the array
2204# itself).
2205#
2206# The third argument allows you to only execute the test if the
2207# Makefile is present.  This is used in the distclean targets and
2208# may be useful elsewhere.
2209#
2210# Special notes:
2211#    For a small number of directories, use a simpler (non loop) approach
2212#   
2213sub RecursiveOp {
2214    my $target = $_[0];
2215    my $subdirname = $_[1];
2216    my $checkForMakefile = $_[2];
2217    my $forThreashold = 3;
2218
2219    if (!defined($checkForMakefile) || $checkForMakefile eq "") {
2220        $checkForMakefile = 0;
2221    }
2222    # Get the optional arrays
2223    if (defined($subdirname) && $subdirname ne "") {
2224        @dirs = @$subdirname;
2225    }
2226    else {
2227        @dirs = (@extra_dirs, @subdirs);
2228    }
2229
2230    # Entries that are shell or autoconf variables have unknown count.
2231    #
2232    my $dirlistHasVariable = 0;
2233    foreach $dir (@dirs) {
2234        if ($dir =~ /@[^@]*@/) {
2235            $dirlistHasVariable = 1;
2236        }
2237        elsif ($dir =~ /\$/) {
2238            $dirlistHasVariable = 1;
2239        }
2240    }
2241
2242    print "n dirs = $#dirs\n" if $debug;
2243    if ($#dirs == 0 && $dirs[0] eq ".") { return; }
2244    if ($#dirs >= $forThreashold || $subdirs_has_autoconf ||
2245        $dirlistHasVariable) {
2246        print FD "\tfor dir in";
2247        foreach $dir (@dirs) {
2248            if ($dir ne ".") { print FD " $dir"; }
2249            if ($dir =~ /@[^@]*@/) {
2250                $subdirs_has_autoconf = 1;
2251            }       
2252        }
2253        # We may also want to check if subdirs is *only* autoconf;
2254        # if not, we don't need the -
2255        if ($subdirs_has_autoconf) {
2256            # Add a - incase there is a problem
2257          print FD " - ; do \\$newline";
2258          print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ; \\$newline";
2259          if ($checkForMakefile) {
2260              print FD "\t\tif [ ! -s \$\$dir/Makefile ] ; then continue ; fi ;\\$newline";
2261          }
2262          print FD "\t\t(cd \$\$dir && \${MAKE} $target ; ) ; done$newline";
2263        }       
2264        else {
2265          print FD " ; do \\$newline";
2266          if ($checkForMakefile) {
2267              print FD "\t\tif [ ! -s \$\$dir/Makefile ] ; then continue ; fi ;\\$newline";
2268          }
2269          print FD "\t\t(cd \$\$dir && \${MAKE} $target ; ) ; " .
2270            "done$newline";
2271        }
2272    }
2273    elsif ($#dirs >= 0) {
2274        foreach $dir (@dirs) {
2275            # Skip . and any empty names
2276            if ($dir ne "." && $dir =~ /\S/) {
2277                if ($checkForMakefile) {
2278                    print FD "\tif [ -s $dir/Makefile ] ; then (cd $dir && \$(MAKE) $target ) ; fi$newline";
2279                }
2280                else {
2281                    print FD "\t(cd $dir && \$(MAKE) $target )$newline";
2282                }
2283            }
2284        }
2285    }
2286}
2287
2288# A version of RecuriveOps for optional directories; this is careful
2289# to check for existence of both the directory and the Makefile
2290# RecursiveOpForOptionalDirs( dirs, target, checkmake )
2291sub RecursiveOpForOptionalDirs {
2292    my $subdirs = $_[0];
2293    my $target = $_[1];
2294    my $checkForMakefile = $_[2];
2295
2296    my $forThreshold = 3;
2297
2298    if ($subdirs ne "") {
2299        # Count the number of directories
2300        my @sdirs = split(/\s+/,$subdirs);
2301        if ($#sdirs >= $forThreshold) {
2302            print FD "\t-\@for dir in $subdirs ; do \\$newline";
2303            print FD "\t    if [ -s \$\$dir/Makefile ] ; then \\$newline";
2304            print FD "\t      (cd \$\$dir && \${MAKE} $target ;) ; fi ; \\$newline";
2305            print FD "\tdone$newline";
2306        }
2307        else {
2308            foreach my $dir (@sdirs) {
2309                if ($dir ne "." && $dir =~ /\S/) {
2310                    if ($checkForMakefile) {
2311                        print FD "\tif [ -s $dir/Makefile ] ; then (cd $dir && \$(MAKE) $target ) ; fi$newline";
2312                    }
2313                    else {
2314                        print FD "\t(cd $dir && \$(MAKE) $target )$newline";
2315                    }
2316                }
2317            }
2318        }
2319    }
2320}
2321
2322#
2323# Return the directory in which the named library should be in
2324sub GetLibLoc {
2325    my $libname = $_[0];
2326   
2327    my $libloc = "";
2328    if (defined($libdir{$libname})) {
2329        $libloc = $libdir{$libname};
2330        my $rootdir;
2331        if (!defined($rootdirpath)) {
2332            $rootdir = "."
2333            }
2334        else {
2335            $rootdir = $rootdirpath;
2336            $rootdir =~ s/\r?\n?$//; # strip off any newlines
2337        }
2338        $libloc =~ s/ROOTDIR/$rootdir/;
2339        # Remove duplicated //
2340        $libloc =~ s/\/\//\//;
2341    }
2342
2343    return $libloc;
2344}
2345
2346
2347#
2348# Look for autoconf directory variables that are used
2349sub LookForAutoconfDirs {
2350    $line = $_[0];
2351    print "Looking at $line\n" if $debug;
2352    # Look for \$\{\w*\} and \$\(\w*\)
2353    while ($line =~ /^[^\$]*\$(.*)/) {
2354        $line = $1;
2355        if ($line =~ /^\$\w+(.*)/) {
2356            # This is a shell variable; skip it
2357            $line = $1;
2358        }
2359        elsif ($line =~ /^[\{\(](\w+)[\}\)](.*)/) {
2360            $varname = $1;
2361            $line    = $2;
2362            print "Found $varname in line\n" if $debug;
2363            # Look for varname in the known names; add to dirs_seen
2364            if (defined($dirdefs{$varname})) {
2365                print "Adding $varname to dirs_seen\n" if $debug;
2366                $dirs_seen{$varname} = $varname;
2367            }
2368        }
2369        else {
2370            last;
2371        }
2372    }
2373}
2374
2375#
2376# Look for make variables that are used
2377sub LookForVariables {
2378    $line = $_[0];
2379    print "Looking at $line\n" if $debug;
2380    # Look for \$\{\w*\} and \$\(\w*\)
2381    while ($line =~ /^[^\$]*\$(.*)/) {
2382        $line = $1;
2383        if ($line =~ /^\$\w+(.*)/) {
2384            # This is a shell variable; skip it
2385            $line = $1;
2386        }
2387        elsif ($line =~ /^[\{\(](\w+)[\}\)](.*)/) {
2388            $varname = $1;
2389            $line    = $2;
2390            print "Found $varname in line\n" if $debug;
2391            $vars_seen{$varname} = 1;
2392        }
2393        else {
2394            last;
2395        }
2396    }
2397}
2398
2399sub LookForSuffixes {
2400    $line = $_[0];
2401    while ($line =~ /^[^\.]*\.(\w*)\s*(.*)$/) {
2402        $suffix = $1;
2403        $line   = $2;
2404        # For now, only check for suffixes that lead to .o files.
2405        # Later we can check the keys of extdef to see if they
2406        # match /$ext:.*/
2407        if (defined($extdef{"$suffix:o"})) { 
2408            $ext_seen{$suffix} = 1;
2409        }
2410    }
2411}
2412
2413#
2414# ===========================================================================
2415# The "all" target.
2416#
2417# Output the target list.  If there are extra_programs or
2418# extra_libs, note that.
2419# FIXME: there needs to be way to specify other local targets
2420# beyond the implicitly determined ones.  This needs to allow
2421# for both pre and post implicit target values
2422#
2423sub TargetAll {
2424    print_make_line( FD,  "all-redirect:" );
2425    if ($#subdirs > -1) {
2426        # If there are subdirectories, we must descend into them.
2427        # This branch does that, after adding the dependencies for the
2428        # target (if any).
2429        &TargetPreamble( "all" );
2430        print_make_endline( FD );
2431        # Now add the steps for the subdirectories
2432        $has_dot = 0;
2433        foreach $dir (@extra_dirs, @subdirs) {
2434            if ($dir eq ".") {
2435                if (scalar(@alltargets) ||
2436                    defined($usertargets{"all-local"})) {
2437                    $has_dot = 1;
2438                    print FD "\t\${MAKE} all-local$newline";
2439                    #----------------  Kumud check ----------------------------
2440                    #my $kumud_libloc= &GetLibLoc ( '${MPILIBNAME}');
2441                    #print FD "\tI am alive and the library location is $kumud_libloc";
2442                }
2443            }
2444            elsif ($dir =~ /@([^@]*)@/) {
2445                # May be a replaced variable
2446                print FD "\t${quietmake}for dir in $dir - ; do \\$newline";
2447                print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ; \\$newline";
2448                print FD "\t\tif ( cd \$\$dir && \${MAKE} all ) ; then : ; else exit 1; fi \\$newline";
2449                print FD "\tdone$newline";
2450            }
2451            else {
2452                print FD "\t${quietmake}(cd $dir && \${MAKE} all )$newline";
2453            }
2454        }
2455        # If subdirs has no dot but there are local targets, add an
2456        # implicit dot to the end.
2457        if (!$has_dot && $#alltargets > -1) {
2458            $has_dot = 1;
2459            print FD "\t\${MAKE} all-local$newline";
2460        }
2461
2462                   
2463        if ($has_dot && !defined($usertargets{"all-local"})) {
2464            # Add the default definition of all-local for the case where
2465            # a . is in the SUBDIR line
2466            print_make_line( FD, "all-local:" );
2467            &ListTargets;
2468            # ListTargets does *not* end the line
2469            print_make_endline( FD );
2470            # Add generation of shared libraries if necessary
2471            &TargetAllCommandsForSharedLibs;
2472            &TargetAllCommandsForDLLLibs;
2473        }
2474       
2475        #  Create the final shared library (typically .so) from the .la file
2476        if (defined($optinstall_files{'SHLIB'})) {
2477            # Conditionally create the shared libraries.
2478            print FD "\t\@if [ \"\@ENABLE_SHLIB\@\" != \"none\" ] ; then \\\n";
2479            foreach $libspec (split(/\s+/,$optinstall_files{'SHLIB'})) {
2480                if (defined($extra_libs{$libspec})) { next; }
2481                # Be careful of library names that are related to
2482                # the profile library (those libraries are built
2483                # as part of the "master" library name build)
2484                my $baselibname = $libspec;
2485                $baselibname =~ s/^.*\///g;
2486                $baselibname =~ s/^lib//;
2487                $baselibname =~ s/\..*//;
2488                # We need to be careful about the optional files, since
2489                # the prerequisites may not exist
2490                # We could either test on the conditions under which
2491                # the optional files should exist (this is probably the
2492                # best option), or we can coordinate with the
2493                # target that we invoke for each case.  We'll do the
2494                # latter for now and consider adding an optional predicate
2495                # that can be supplied for each OPTINSTALL item.
2496                if (!defined($profile_libraries_basename{$baselibname})) {
2497                    print "Building sharedlib library $baselibname (from $libspec) as part of all-redirect\n" if $gDebugWhy;
2498                    # Get the condition
2499                    my $prereq = $libspec;
2500                    $prereq =~ s/\.\@SHLIB_EXT\@/.la/;
2501                    print FD "\t    if [ -s $prereq ] ; then \\\n";
2502                    print FD "\t        echo \"make $libspec\" ;\\\n";
2503                    print FD "\t        \${MAKE} $libspec ; \\\n";
2504                    print FD "\t    fi ; \\\n";
2505                }
2506            }
2507            print FD "\tfi\n";
2508        }
2509        if (defined($optinstall_files{'DLLLIB'})) {
2510            #print STDOUT "in optinstall_files dlllib\n";
2511            # Conditionally create the dynamically loadable shared libraries.
2512            print FD "\t\@if [ \"\@BUILD_DLLS\@\" = \"yes\" ] ; then \\\n";
2513            foreach $libspec (split(/\s+/,$optinstall_files{'DLLLIB'})) {
2514                # Be careful of library names that are related to
2515                # the profile library (those libraries are built
2516                # as part of the "master" library name build)
2517                my $baselibname = $libspec;
2518                $baselibname =~ s/^.*\///g;
2519                $baselibname =~ s/^lib//;
2520                $baselibname =~ s/\..*//;
2521                # We need to be careful about the optional files, since
2522                # the prerequisites may not exist
2523                # We could either test on the conditions under which
2524                # the optional files should exist (this is probably the
2525                # best option), or we can coordinate with the
2526                # target that we invoke for each case.  We'll do the
2527                # latter for now and consider adding an optional predicate
2528                # that can be supplied for each OPTINSTALL item.
2529                if (!defined($profile_libraries_basename{$baselibname})) {
2530                    print "Building sharedlib library $baselibname (from $libspec) as part of all-redirect\n" if $gDebugWhy;
2531                    # Get the condition
2532                    my $prereq = $libspec;
2533                    $prereq =~ s/\.\@SHLIB_EXT\@/.la/;
2534                    print FD "\t    if [ -s $prereq ] ; then \\\n";
2535                    print FD "\t        echo \"make $libspec\" ;\\\n";
2536                    print FD "\t        \${MAKE} $libspec ; \\\n";
2537                    print FD "\t    fi ; \\\n";
2538                }
2539            }
2540            print FD "\tfi\n";
2541        }
2542        &TargetPostamble( "all" );
2543    }
2544    else {
2545        # This is a leaf, so we can list the dependencies. 
2546        &TargetPreamble( "all" );
2547        if (defined($usertargets{"all-local"})) {
2548            # Add all-local as a target
2549            print_make_line( FD, " all-local " );
2550        }
2551        &ListTargets;
2552        if ($found_profilelib) {
2553            print_make_endline( FD );
2554            # Add a conditional step
2555            print FD "\t\@if [ -n \"\@NO_WEAK_SYM\@\" ] ; then \\\n";
2556            foreach my $lib (keys(%profile_libraries)) {
2557                my $proflib = $profile_libraries{$lib};
2558                my $libstamp = ".libstamp" . $libnum{$proflib};
2559#               my $libloc = &GetLibLoc( $lib );
2560#               my $fullname = "${libloc}lib$proflib.a";
2561#               print FD "\t    \${MAKE} $fullname ; \\\n";
2562                print FD "\t    \${MAKE} $libstamp || exit 1; \\\n";
2563            }
2564            print FD "\tfi";
2565        }
2566        print_make_endline( FD );
2567        &TargetAllCommandsForSharedLibs;
2568        &TargetAllCommandsForDLLLibs;
2569        &TargetPostamble( "all" );
2570    }
2571    print_make_endline( FD );
2572} # TargetAll
2573# ---------------------------------------------------------------------------
2574# Routines to provide standard extensions through -preamble, -postamble,
2575# and -local
2576# -preamble allows you to *ADD* a step to be performed before the other
2577# dependencies, -postamble adds a step after the target is formed
2578#
2579# To ensure uniform handling of -preamble, the routine TargetInit( name )
2580# outputs the target and the preamble.
2581sub TargetInit {
2582    my $name = $_[0];
2583    print FD "$name: ";
2584    &TargetPreamble( $name );
2585}
2586sub TargetPreamble {
2587    my $name = $_[0];
2588    $name .= "-preamble";
2589    if (defined($usertargets{$name})) {
2590        print FD " $name";
2591    }
2592}
2593sub TargetPostamble {
2594    my $name = $_[0];
2595    $name .= "-postamble";
2596    if (defined($usertargets{$name})) {
2597        print FD "\t\${MAKE} $name$newline";
2598    }
2599}
2600# --------------------------------------------------------------------------
2601# Helper routines for the implementation of the "all" target.  Two
2602# complications here are that the handling of leaf Makefile.sm (those with
2603# no SUBDIRS) and non-leaf Makefile.sm are different for the "all" target.
2604# (a better long-term solution may be to redesign the handling of the all
2605# target).
2606# --------------------------------------------------------------------------
2607
2608# Add the commands to build shared libraries if any are defined
2609# (either explicitly or because we generate shared libraries for all
2610# libraries).
2611sub TargetAllCommandsForSharedLibs {
2612    if ($do_sharedlibs && $#allshlibtargets >= 0) {
2613        # Add a conditional step
2614        print FD "\t\@if [ \"\@ENABLE_SHLIB\@\" != \"none\" ] ; then \\\n";
2615        foreach $shlib (@allshlibtargets) {
2616            if (defined($extra_libs{$shlib})) { next; }
2617            # Get the library stamp name from the lib name
2618            my $libbase = $shlib;
2619            if ($shlib =~ /.*\/lib([^\/]*)/) {
2620                $libbase = $1;
2621            }
2622            my $libstamp = $shlib;
2623            if (defined($libnum{$libbase})) {
2624                $libstamp = ".libstamp" . $libnum{$libbase};
2625            }
2626            print FD "\t    \${MAKE} $libstamp || exit 1; \\\n";
2627        }
2628        if ($found_profilelib) {
2629            print FD "\t    if [ -n \"\@NO_WEAK_SYM\@\" ] ; then \\\n";
2630            foreach my $lib (keys(%profile_libraries)) {
2631                my $proflib = $profile_libraries{$lib};
2632                my $libloc = &GetLibLoc( $lib );
2633                my $fullname = "${libloc}lib$proflib.la";
2634                my $libstamp = ".libstamp" . $libnum{$proflib.".la"};
2635                print FD "\t        \${MAKE} $libstamp || exit 1; \\\n";
2636#               print FD "\t        \${MAKE} $fullname ; \\\n";
2637            }
2638            print FD "\t    fi ; \\\n";
2639        }
2640        print FD "\tfi\n";
2641    }
2642}
2643
2644sub TargetAllCommandsForDLLLibs {
2645    if ($do_sharedlibs && $#alldlllibtargets >= 0) {
2646        # Add a conditional step
2647        print FD "\t\@if [ \"\@BUILD_DLLS\@\" = \"yes\" ] ; then \\\n";
2648        foreach $shlib (@alldlllibtargets) {
2649            # Get the library stamp name from the lib name
2650            my $libbase = $shlib;
2651            if ($shlib =~ /.*\/lib([^\/]*)/) {
2652                $libbase = $1;
2653            }
2654            my $libstamp = $shlib;
2655            if (defined($libnum{$libbase})) {
2656                $libstamp = ".libstamp" . $libnum{$libbase};
2657            }
2658            print FD "\t    \${MAKE} $libstamp || exit 1; \\\n";
2659        }
2660        print FD "\tfi\n";
2661    }
2662}
2663
2664# --------------------------------------------------------------------------
2665#
2666# ===========================================================================
2667# The "clean" target
2668#
2669# Produces clean:, distclean:, and maintainerclean:
2670# If clean-local, distclean-local, or maintainer-clean-local were defined,
2671# they are included in the dependency lists
2672#
2673# The default for quietLine makes the clean lines quiet (no echo of the
2674# command).
2675#
2676# Notes:
2677# The clean target is relatively easy, because it involves only files
2678# created *after* the configure step. 
2679# The distclean and maintainer-clean steps are more complicated, because
2680# there is some interaction with the generated steps.  In particular,
2681# distclean must remove Makefile, but once the makefiles are gone,
2682# you can't execute another make step.  If you run maintainer-clean first,
2683# the the dependencies on Makefile:Makefile.in:Makefile.sm will force
2684# a reconstruction of some of the files that were just removed.
2685# Thus, we need to separate from the distclean and maintainer-clean targets
2686# the steps that remove the makefiles.  Thus, we have the
2687# following intermediate targets:
2688#    remove-makefile
2689#    remove-genmakefiles
2690# To simplify the construction of the targets, we use internal targets.
2691# Thus, distclean becomes:
2692# distclean: clean distclean-local distclean-xxx remove-makefile
2693#
2694# and maintainer-clean becomes
2695# maintainer-clean: clean maintainer-clean-local distclean-local \
2696#     distclean-xxx maintainer-clean-xxx remove-genmakefiles
2697#
2698#
2699#
2700sub TargetClean {
2701    my $otherMakefiles = "";
2702
2703    $programnames = join( ' ', keys(%programs));
2704    &TargetInit( "clean" );
2705    if (defined($usertargets{"clean-local"})) { print FD " clean-local"; }
2706    print FD "$newline";
2707    print FD "\t-${quietLine}rm -f *.o \${srcdir}/*.o $programnames$newline";
2708    &LibraryTimestampClean;
2709    # Add Windows names of executables
2710    if ($programnames ne "") {
2711        print FD "\t-${quietLine}rm -f";
2712        foreach $name (split(/\s+/,$programnames)) {
2713            print FD " $name.exe";
2714        }
2715        print FD "$newline";
2716        # Remove core files, including core files with process numbers
2717        # (produced by some versions of Linux)
2718        print FD "\t-${quietLine}rm -f core core.[0-9]*$newline";
2719    }
2720
2721    # Output this in all cases to clear any old files. 
2722    # (Don't make this conditional because it is important to remove
2723    # these files even if we're not building for enabling shared libraries
2724    # this time around.
2725    print FD "\t-${quietLine}rm -f *.lo \${srcdir}/*.lo$newline";
2726
2727    # Clean coverage analysis files
2728    &GcovClean;
2729
2730    # We can put a hook here to add additional clean targets.  For
2731    # the moment, we'll add an MPICH-2 specific target for this
2732    if ($programnames ne "") {
2733        # Testing of parallel program may produce log files.  This will remove
2734        # any existing irlog files
2735        print FD "\t-${quietLine}rm -f *.irlog*$newline";
2736    }
2737
2738    if ($maint_perf_targets) {
2739        # In this case, we want to remove any generated asm files,
2740        # to prevent them from being used in preference to the
2741        # original (e.g., C) source file
2742        my $input_sources;
2743        if ($regular_sources =~ /\S/) {
2744            $input_sources = $regular_sources;
2745        }
2746        elsif (defined($makevars{'SOURCES'})) {
2747            $input_sources = $makevars{'SOURCES'};
2748        }
2749        if (defined($input_sources)) {
2750            my $clean_files = "";
2751            foreach my $file (split(/\s+/,$input_sources)) {
2752                if ($file =~ /(.*)\.([^\.]+)/) {
2753                    my $base = $1;
2754                    my $ext  = $2;
2755                    if ($ext ne "s") {
2756                        $clean_files .= " $base.s";
2757                    }
2758                }
2759            }
2760            if ($clean_files ne "") {
2761                print FD "\t-${quietLine}rm -f $clean_files$newline";
2762            }
2763        }
2764    }
2765
2766    # For any extensions, handle the clean actions
2767    &SMInvokeAction( "OutputClean", FD );
2768
2769    # Finally, execute make clean in any subdirs
2770    &RecursiveOp( "clean" );
2771
2772    # --------------------------------------------
2773    # distclean target
2774    &TargetInit( "distclean" );
2775    print FD " clean";
2776    if (defined($usertargets{"distclean-local"})) {
2777        print FD " distclean-local";
2778    }
2779    print FD " distclean-xxx remove-makefile";
2780    print FD "$newline";
2781   
2782    print FD "distclean-xxx:$newline";
2783    # RecursiveOp uses extra_dirs,subdirs; the "1" forces it to check
2784    # for the existence of the Makefile
2785    &RecursiveOp( "distclean", "", 1 );
2786
2787    # Add clean of local libraries
2788    foreach $lib (keys(%extra_libs)) {
2789        print FD "\t-${quietLine}rm -f $lib$newline";
2790    }
2791
2792    # Remove any local files last (in case this file is one of them)
2793    $rmfile = "";
2794    if (!$curdir) { $curdir = ""; }
2795    $lcurdir = $curdir;
2796    $lcurdir =~ s/\/$//;
2797    if (defined($autoconf_files_by_dir{$lcurdir})) {
2798        $rmfile = $autoconf_files_by_dir{$lcurdir};
2799        # Remove the Makefile.in from this list because it will
2800        # be handled separately
2801        if ($rmfile =~ /Makefile.in/) {
2802            $otherMakefiles .= "Makefile.in ";
2803            $rmfile =~ s/Makefile.in\s*//;
2804        }
2805        print FD "\t-${quietLine}rm -f $rmfile$newline";
2806        # Remove the configure cache that autoconf 2.57+ adds
2807        print FD "\t-${quietLine}rm -rf autom4te*.cache$newline";
2808    }
2809    if ($configure_has_config_headers ne "no") {
2810        # Add the AC_CONFIG_HEADER file, if any.
2811        print FD "\t-${quietLine}rm -f $configure_has_config_headers$newline";
2812    }
2813    # Handle files that aren't part of subdirs
2814    if (defined($autoconf_files_by_dir_orig{$lcurdir})) {
2815        my $otherfiles = $autoconf_files_by_dir_orig{$lcurdir};
2816        foreach $dir (@subdirs) {
2817            $otherfiles =~ s/ $dir\/\S*//g;
2818        }
2819        $otherfiles =~ s/^\s*//;
2820        # Is there anything left?
2821        if ($otherfiles =~ /\S+/) {
2822            print FD "\t-${quietLine}rm -f $otherfiles$newline";
2823        }
2824    }
2825   
2826    # For any extensions, handle the clean actions
2827    &SMInvokeAction( "OutputDistClean", FD );
2828
2829    # Another difficulty are the optional directories.  For example,
2830    # a SUBDIRS = foo \@bar\@
2831    # line (without the \, included since the simplemake.in file is
2832    # itself processed with autoconf)
2833    &RecursiveOpForOptionalDirs( $subdir_optionals, "distclean", 1 );
2834
2835    &DistCleanDependencies;
2836
2837    if ($distcleanfiles ne "") {
2838        print FD "\t-${quietLine}rm -f $distcleanfiles$newline";
2839    }
2840    print FD "\t-${quietLine}rm -f TAGS$newline";
2841
2842    # --------------------------
2843    if ($maint_targets) {
2844        # Should maintainer-clean also perform a distclean?
2845        # No, because distclean needs to remove the Makefiles, and
2846        # this target needs to remove entries that have dependencies
2847        # (e.g., the Makefile : Makefile.in : Makefile.sm dependency)
2848        &TargetInit( "maintainer-clean" );
2849        if (defined($usertargets{"maintainer-clean-local"})) {
2850            print FD " maintainer-clean-local";
2851        }
2852        print FD " distclean-xxx remove-genmakefiles";
2853        print FD "$newline";
2854
2855        # For any extensions, handle the clean actions
2856        &SMInvokeAction( "OutputMaintainerClean", FD );
2857
2858        &RecursiveOp( "maintainer-clean" );
2859        # Remove the file that simplemake creates
2860        $otherMakefiles .= " $output_name";
2861        #print FD "\t-rm -f $output_name$newline";
2862        # eventually, this should also invoke distclean, but it must
2863        # do that only once (not recursively) and only after all other
2864        # uses of the Makefile, since distclean removes the Makefile
2865        # Directories containing autoconf should include an rm of configure
2866
2867        # This should also remove any files that will be created with
2868        # autoheader.  We'll need to check for files that are created
2869        # by autoheader, not just rely on the AC_CONFIG_HEADER command,
2870        # since some headers may be created by hand.  We'll ignore
2871        # this for now, since we uniformly use autoheader (and
2872        # simplemake runs autoheader if it finds AC_CONFIG_HEADER)
2873        if ($configure_has_config_headers ne "no") {
2874            print FD "\t-rm -f ";
2875            foreach $file (split(/\s+/,$configure_has_config_headers)) {
2876                print FD "$file.in ";
2877            }
2878            print FD "$newline";
2879        }
2880        # We also need to remove configure and autom4ate/ if present
2881    }
2882    &TargetRmMakefiles( $otherMakefiles );
2883
2884}
2885
2886#
2887# Generate the makefile removal targets
2888# TargetRmMakfiles( otherMakefiles )
2889#
2890# These are *NOT* recursive targets because they are local to the
2891# particular directory.
2892sub TargetRmMakefiles {
2893    my $otherMakefiles = $_[0];
2894    print FD "remove-makefile:$newline";
2895    print FD "\trm -f Makefile$newline";
2896    print FD "remove-genmakefiles:$newline";
2897    print FD "\trm -f $otherMakefiles Makefile$newline";
2898}
2899#
2900# Generate the core part of the distclean target
2901sub TargetDistclean {
2902}
2903#
2904# ===========================================================================
2905# Libraries
2906#
2907# We want to generate either a generic "update library from object files"
2908# or "update library member" for makes that support that feature (this
2909# is normally used only for the maintenance target).
2910
2911#
2912# LibraryBuild ( libname, libloc, libfiles, lib extension, member extension )
2913# Not quite right.  Need to include the update command as well as ways
2914# to handle the "special extensions", both for the library (e.g., .a vs. .la)
2915# and members (e.g., .o vs .lo)
2916sub LibraryBuild {
2917    my $libname = $_[0];
2918    my $libloc  = $_[1];
2919    my $sourcefiles = $_[2];
2920    my $libext = $_[3];
2921    my $memext = $_[4];
2922    my @objects=();
2923    if (!$dolib_member) {
2924        &print_make_line( FD, "${libloc}lib$libname.$libext: " );
2925    }
2926    # Handle any variables in the lib line
2927    if (!defined($sourcefiles)) {
2928        print STDERR "Warning: no source files in library $libname in LibraryBuild\n" ; }
2929    $sourcefiles = &ExpandMakeVars($sourcefiles);
2930    foreach $sourcefile (split(/\s+/,$sourcefiles)) {
2931        $ext = "";
2932        $obj = "";
2933        if ($sourcefile =~ /(.*)\.([^\.]*)/) {
2934            $obj = "$1.$memext";
2935            $ext = $2;
2936        }
2937        else {
2938            # Don't warn about autoconf variables (see below)
2939            if (! ($sourcefile =~ /^\@/) ) {
2940                print STDERR "Sourcefile is $sourcefile\n";
2941            }
2942        }
2943        # The special case for an extension of h handles the case where the
2944        # .h files are derived, and hence have special rules for creating
2945        # them.  We also ignore autoconf variables (eventually, we might
2946        # want to insist that valid values for that autoconf variable be
2947        # available).
2948        if ( (!defined($extrules{"$ext:o"}) && ($ext ne "h") &&
2949              ! ($sourcefile =~ /^\@/))) {
2950            # Sometimes we use our own rules for building objects.
2951            # We allow the user to specify the object files rather than
2952            # the source files
2953            if ($ext ne "o") {
2954                print STDERR "Unknown extension $ext for $sourcefile for library $libname\n";
2955            }
2956        }
2957       
2958        if ($dolib_member) {
2959            &print_make_line( FD, "${libloc}lib$libname.$libext($obj): $obj" );
2960            &print_make_endline( FD );
2961            # COMMAND PRINTING
2962            # ------------------------ Kumud_Parallel_Fix ----------------------
2963            # &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$libname.$libext \$?", "  AR" );
2964           
2965            if ($obj =~/\s*(\S+)\s*/){
2966                &PrintVerboseOptionCommand( "rm -rf lib$libname.$libext.manifest", "  rm" );
2967                &PrintVerboseOptionCommand( "echo \"\${abs_builddir}/$obj\" >> lib$libname.$libext.manifest", "  echo" );               
2968                print FD "\ttouch \${top_builddir}/lib/.lib$libname.$libext.timestamp$newline";
2969            }
2970           
2971        }
2972        else {
2973            if ($ext ne "h") {
2974                &print_make_line( FD, "$obj " );
2975                if ($obj =~/\s*(\S+)\s*/){
2976                    $objects[ $#objects+1 ]= $1;
2977                }
2978            }
2979        }
2980    }
2981    &SMInvokeAction( "OutputLibDependencies", $lib, $libloc, $memext );
2982    if (!$dolib_member) {
2983        &print_make_endline( FD );
2984        # ------------------------ Kumud_Parallel_Fix ----------------------
2985        # &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$libname.$libext \$?",
2986        &PrintVerboseOptionCommand( "rm -rf lib$libname.$libext.manifest", "  rm" );
2987        foreach $object (@objects){
2988            &PrintVerboseOptionCommand( "echo \"\${abs_builddir}/$object\" >> lib$libname.$libext.manifest", "  echo"  );
2989        }
2990        print FD "\ttouch \${top_builddir}/lib/.lib$libname.$libext.timestamp$newline";
2991                                           
2992    }
2993}
2994
2995sub TargetLibraries {
2996    foreach $lib (keys(%libraries)) {
2997        my $libloc = &GetLibLoc( $lib );
2998        if (!defined($libraries{$lib})) { next; }
2999
3000        my $sourcefiles = &ExpandMakeVars($libraries{$lib});
3001
3002        &LibraryTimestampPrefix( $lib, $libloc );
3003        &LibraryBuild( $lib, $libloc, $sourcefiles, "a", "o" );
3004        # Add any additional actions for this library.
3005        &SMInvokeAction( "OutputLib", $lib, $libloc );
3006       
3007        # ------------------------ Kumud_Parallel_Fix ----------------------
3008        # if ($ranliblib) {
3009        #    # COMMAND PRINTING
3010        #    &PrintVerboseOptionCommand( "\${RANLIB} ${libloc}lib$lib.a", "-",
3011        #                               "  RANLIB          lib$lib.a" );
3012        #}
3013 
3014        # To handle timestamp problems with recursive makes, add a delay
3015        &LibraryTimestampFix( $lib, $libloc )
3016       
3017    }
3018}
3019
3020#
3021# Fix for problems with timestamps.  If the file is not local (not
3022# obviously in the current directory), then apply one of the fixes
3023#
3024# LibraryTimestampTarget - Save additional target name in altalltargets hash
3025#                          (used in ListTargets)
3026# LibraryTimestampPrefix - Additional target for the library
3027# LibraryTimestampFix - Fix *after* all other operations
3028# LibraryTimestampClean - Add clean commands for library timestamps
3029sub LibraryTimestampTarget {
3030    my ($fulllibname,$libstamp) = @_;
3031    my $expandedFullName = &ExpandMakeVars( $fulllibname );
3032    if ($expandedFullName =~ /^\.\./ && !$fixup_for_timestamps) {
3033        $altalltargets{$fulllibname} = $libstamp;
3034    }
3035}
3036sub LibraryTimestampPrefix {
3037    my ($lib, $libloc) = @_;
3038
3039    my $expandedlibloc = &ExpandMakeVars( $libloc );
3040
3041    if ($expandedlibloc =~ /^\.\./) {
3042        if (!$fixup_for_timestamps) {
3043            my $num = "";
3044            if (defined($libnum{$lib})) {
3045                $num = $libnum{$lib};
3046            }
3047            &print_make_line( FD, ".libstamp$num " );
3048        }
3049    }
3050}
3051sub LibraryTimestampFix {
3052    my ($lib,$libloc) = @_;
3053    my $expandedlibloc = &ExpandMakeVars( $libloc );
3054    if ($expandedlibloc =~ /^\.\./) {
3055        if ($fixup_for_timestamps) {
3056            my $SleepText = $Sleep;
3057            my $fulllibname = $libloc . "lib$lib.a";
3058            $SleepText =~ s/LIB/$fulllibname/;
3059            print FD "\t$SleepText$newline";
3060        } else {
3061            if (defined($libnum{$lib})) {
3062                my $num = "";
3063                $num = $libnum{$lib};
3064                print FD "\tdate > .libstamp$num\n";
3065            }
3066        }
3067   
3068    }
3069
3070
3071sub LibraryTimestampClean {
3072    if ($libcount > 0) {
3073        print FD "\t-${quietLine}rm -f ";
3074        for( my $i=0; $i<$libcount; $i++) {
3075            print FD ".libstamp$i ";
3076        }
3077        print FD "\n";
3078    }
3079}
3080# --------------------------------------------------------------------------
3081
3082# This code is similar to TargetLibraries.
3083sub TargetProfileLibraries {
3084    $found_source_files = 0;
3085    foreach $lib (keys(%profile_libraries)) {
3086        $proflib_name = $profile_libraries{$lib};
3087        $libloc = &GetLibLoc( $lib );
3088        # Take the sources from the base library unless
3089        # they were explicitly listed
3090        if (defined($profile_library_sources{$lib})) {
3091            $sourcefiles = $profile_library_sources{$lib};
3092        }
3093        else {
3094            $sourcefiles = $libraries{$lib};
3095        }
3096        $sourcefiles = &ExpandMakeVars( $sourcefiles );
3097        # FIXME: Use LibraryBuild here
3098        # Use the library stamp
3099        my $libstamp = ".libstamp" . $libnum{$proflib_name};
3100        print FD "$libstamp: ";
3101        #&print_make_line( FD, "${libloc}lib$proflib_name.a: " );
3102        foreach $sourcefile (split(/\s+/,$sourcefiles)) {
3103            $found_source_files = 1;
3104            $obj = $sourcefile;
3105            # Convert to object file
3106            $ext = $sourcefile;
3107            $ext =~ s/^.*\.//g;
3108            if ($ext eq "f") {
3109                # Ignore Fortran source files (setbotf.f in mpich2)
3110                next;
3111            }
3112            elsif (defined($extrules{"$ext:o"})) {
3113                $obj =~ s/\.$ext/\.o/g;
3114                $obj = "_" . $obj;
3115            }
3116            else {
3117                # Be silent on .h files
3118                if ($ext ne "h") {
3119                    print STDERR "Unknown extension $ext for $sourcefile for profile library $proflib_name\n";
3120                }
3121            }
3122            &print_make_line( FD, "$obj " );
3123        }
3124        &print_make_endline( FD );
3125        if ($found_source_files) {
3126            # Add these files as objects to the archive
3127            # COMMAND PRINTING
3128            &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$proflib_name.a \$?",
3129                                        "  AR" );
3130            if ($ranliblib) {
3131                # COMMAND PRINTING
3132                &PrintVerboseOptionCommand( "\${RANLIB} ${libloc}lib$proflib_name.a",
3133                                            "-", "  RANLIB          lib$proflib_name.a" );
3134            }
3135            # To handle timestamp problems with recursive makes,
3136            # add a delay
3137            &LibraryTimestampFix( $proflib_name, $libloc );
3138        }
3139
3140        if ($do_sharedlibs) {
3141            my $libstamp = ".libstamp" . $libnum{$proflib_name.".la"};
3142            print FD "$libstamp: ";
3143            #&print_make_line( FD, "${libloc}lib$proflib_name.la: " );
3144            foreach $sourcefile (split(/\s+/,$sourcefiles)) {
3145                $found_source_files = 1;
3146                $obj = $sourcefile;
3147                # Convert to object file
3148                $ext = $sourcefile;
3149                $ext =~ s/^.*\.//g;
3150                if ($ext eq "f") {
3151                    # Ignore Fortran source files (setbotf.f in mpich2)
3152                    next;
3153                }
3154                elsif (defined($extrules{"$ext:o"})) {
3155                    $obj =~ s/\.$ext/\.lo/g;
3156                    $obj = "_" . $obj;
3157                }
3158                else {
3159                    # Be silent on .h files
3160                    if ($ext ne "h") {
3161                        print STDERR "Unknown extension $ext for $sourcefile for profile library $proflib_name\n";
3162                    }
3163                }
3164                &print_make_line( FD, "$obj " );
3165            }
3166            &print_make_endline( FD );
3167            if ($found_source_files) {
3168                # Add these files as objects to the archive
3169                # COMMAND PRINTING
3170                &PrintVerboseOptionCommand( "\${AR} cr ${libloc}lib$proflib_name.la \$?",
3171                                            "  AR" );
3172                # To handle timestamp problems with recursive makes,
3173                # add a delay
3174                &LibraryTimestampFix( $proflib_name.".la", $libloc );
3175            }
3176        }
3177       
3178        # The new dependencies on the object files
3179        foreach $sourcefile (split(/\s+/,$sourcefiles)) {
3180            $found_source_files = 1;
3181            $obj = $sourcefile;
3182            # Convert to object file
3183            $ext = $sourcefile;
3184            $ext =~ s/^.*\.//g;
3185            if ($ext ne "c") {
3186                print STDERR "Unknown extension $ext for $sourcefile for profile library $proflib_name\n";
3187                next;
3188            }
3189            $obj =~ s/\.$ext/.o/;
3190            $obj = "_" . $obj;
3191            # Note that many makes won't replace $< in an implicit rule,
3192            # so we explicitly list the source file
3193            print FD "$obj: $sourcefile$newline";
3194            # COMMAND PRINTING
3195            &PrintVerboseOptionCommand( "\$(C_COMPILE) -c \@PROFILE_DEF_MPI\@ \$(srcdir)/$sourcefile -o $obj", "-", "  CC             -D<profiling> \${srcdir}/$sourcefile" );
3196            if ($do_sharedlibs) {
3197                $obj =~ s/\.o/.lo/;
3198                print FD "$obj: $sourcefile$newline";
3199                &PrintVerboseOptionCommand( "\$(C_COMPILE_SHL) -c \@PROFILE_DEF_MPI\@ \$(srcdir)/$sourcefile -o $obj", "-", " CC           -D<profiling> \$(srcdir)/$sourcefile" );
3200            }
3201        }
3202    } # foreach lib
3203}
3204#
3205# ===========================================================================
3206# The following is a cache of comments on using libtool, based on the
3207# targets created by automake. 
3208# Issues include
3209#   Handling the simultaneous generation of dependency information
3210#    (automake assumes a GNU environment, including gnumake and gcc, unless
3211#    you work really, really hard)
3212#   
3213# .c.lo: (target in the automake is %.lo: %.c)  is roughly
3214# @echo '$(LTCOMPILE) -c $<'
3215# @$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
3216# @sed -e 's/^\([^:]*\)\.o[\t ]*;/\1.lo \1.o :/' \ <.deps/$(*F).pp > \
3217#   .deps/$(*F).P; \
3218# tr ' ' '\012' < .deps/$(*F).pp \
3219#  | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
3220#  >> .deps/$(*F).P
3221# @rm -f .deps/$(*F).pp
3222#
3223# Most of this is used to handle the dependency generation, including
3224# makint the files refer to .lo and .o instead of just .o.  Also note that
3225# LTCOMPILE generates BOTH .o and .lo files.
3226# (most of this is similar to the .c.o target generated by automake
3227#
3228# Another important step is the install step, which is roughly
3229# install-libLTLIBRARIES: $(lib_LTLIBRARIES)
3230#   @$(NORMAL_INSTALL)
3231#   $(mkinstalldirs) $(DESTDIR)$(libdir)
3232#   @list='$(lib_LTLIBRARIES)'; for p in $$list ; do \
3233#     if test -f $$p; then \
3234#        echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p" ;\
3235#        $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p ;\
3236#     else : ; fi ; done
3237# uninstall-libLTLIBRARIES:
3238#   @$(NORMAL_UNINSTALL)
3239#   @list='$(lib_LTLIBRARIES)'; for p in $$list ; do \
3240#        $(LIBTOOL) --mode=uninstall $(INSTALL) rm -f $(DESTDIR)$(libdir)/$$p ;\
3241#     done
3242#
3243# clean target for libtool adds .libs and _libs (may be directories)
3244#
3245# NORMAL_INSTALL and UNINSTALL seem to be hooks; the base definition is :
3246#
3247# DESTDIR is a newer automake thing to make it easier to retarget an install
3248# into a test directory.
3249#
3250# ---------------------------------------------------------------------------
3251# This routine creates the library of shared objects.  There is a separate
3252# step that builds the shared library (which is really a kind of partially
3253# linked executable).
3254# Pass in the name (by reference) of the list of libraries.  This allows
3255# us to use this routine for both the general list of libraries (for -shared,
3256# which makes both static and dynamic libraries) and for the list of libraries
3257# that are only needed as shared libraries (e.g., Totalview and Java/SLOG
3258# interface libraries).
3259sub TargetSharedLibraries {
3260    # This provides a *reference* to the hash that is passed into the routine
3261    # See the perlsub and perlref manpages for this, and the %$libraries and
3262    # $$libraries used below.
3263    my $libraries = $_[0];
3264
3265    foreach $lib (keys(%$libraries)) {
3266        # Skip the libraries that have no shared counterpart
3267        if (defined($libNotShared{$lib})) {
3268            #print "Skipping $lib\n";
3269            next;
3270        }
3271        $libloc = &GetLibLoc( $lib );
3272        $sourcefiles = &ExpandMakeVars($$libraries{$lib});
3273        &LibraryTimestampPrefix( $lib.".la", $libloc );
3274        &LibraryBuild( $lib, $libloc, $sourcefiles, "la", "lo" );
3275        # no ranlib step here because we can't "link" the shared library
3276        # until all members are added.
3277        &SMInvokeAction( "OutputShLib", $lib, $libloc );
3278        &LibraryTimestampFix( $lib.".la", $libloc )
3279    }
3280}
3281
3282#
3283# This is the routine that creates a shared library from a library of
3284# shared objects. 
3285# This must be called from the directory containing the library.
3286# Still to do: provide a separate directory for the library, so
3287# that a build library may be used instead
3288#
3289# If we can't use .lo as an object extension, then after extracting,
3290# rename everything as .o and then build.
3291# TargetSharedLibraryFinal( "libmpich.la", "libmpich.so.1", dir )
3292#
3293# Note that we need to ensure that C_LINK_SHL is defined.  In turn,
3294# C_LINK_SHL may need CC, so we add that
3295#
3296# Another special feature: For some libraries, we may need an exports
3297# definition (by default, we'll export all symbols).  This is specified
3298# by defining the exports for a given library with a simplemake command:
3299# lib(name)_so_EXPORTS = filename
3300
3301sub TargetSharedLibraryFinal {
3302    my $libname = $_[0];
3303    my $newlibname = $_[1];
3304    my $libdir = $_[2];
3305
3306    my $libbasename = $libname;
3307    $libbasename =~ s/^lib//;
3308    $libbasename =~ s/\.la$//;
3309
3310    #print "Checing $libbasename in Final\n";
3311    if (defined($libNotShared{$libbasename})) {
3312        #print "Skipping $libbasename in final\n";
3313        return;
3314    }
3315
3316    if ($libdir eq "" || $newlibname eq "" || $libname eq "") {
3317        # If we don't have these names, we cannot create a valid library
3318        print STDOUT "Unable to create shared libary target (no directory\n\
3319library, or new library name)\n" if $debug;
3320        return;
3321    }
3322    if (!defined($ext_seen{"c"}) && $InitSharedLibraryFinal == 0) {
3323        # Remember that we made this definition
3324        $InitSharedLibraryFinal = 1;
3325        my $rule = $extdef{"c:o"};
3326        print FD "$rule\n";
3327    }
3328
3329    # See if this library needs an exports list
3330    my $exports = "";
3331    if (defined($shared_libraries_exports{$libbasename})) {
3332        my $exportFile = $shared_libraries_exports{$libbasename};
3333        if ($libdir ne "." && !($exportFile =~ /^\//)) {
3334            # make sure the exportFile refers to the correct location
3335            $exportFile = "\$(abs_srcdir)/$exportFile";
3336        }
3337        $exports = "-export $exportFile";
3338    }
3339    my $otherlibs = "";
3340    if (defined($shared_libraries_libs{$libbasename})) {
3341        $otherlibs = $shared_libraries_libs{$libbasename};
3342    }
3343    if (!defined($usertargets{"$libdir/$newlibname"})) {
3344        print FD "# Build the shared library from the shared object files\n";
3345        print FD "$libdir/$newlibname: $libdir/$libname
3346\t(cd $libdir && \$(CREATESHLIB) --mode=link -version-info \"\@ABIVERSION\@\" -o $libname $exports -rpath \$(libdir) $otherlibs)\n";
3347    }
3348    # If there is a profiling library, we need to build it
3349    # now, as part of this target, to handle the case where the
3350    # profiling library name might be the same as the regular name
3351    my $libbase = $libname;
3352    my $libext = ".so";
3353    if ($libbase =~ /lib(.*)(\..*)/) {
3354        $libbase = $1;
3355        $libext = $2;
3356    }
3357    if (defined($profile_libraries{$libbase})) {
3358        my $newbase = $profile_libraries{$libbase};
3359        $libname = "lib" . $newbase . $libext;
3360        if ($newlibname =~ /(.*lib)[^\/]*(\..*)/) {
3361            $newlibname = $1 . $newbase . $2;
3362        }
3363        print FD "\tif [ -n \"\@NO_WEAK_SYM\@\" -a \\
3364\t\t\"$libbase\" != \"$newbase\" ] ; then \\\n";
3365
3366        my $libbasename = $libname;
3367        $libbasename =~ s/^lib//;
3368        $libbasename =~ s/\.la$//;
3369        if (defined($shared_libraries_exports{$libbasename})) {
3370            my $exportFile = $shared_libraries_exports{$libbasename};
3371            if ($libdir ne "." && !($exportFile =~ /^\//)) {
3372                # make sure the exportFile refers to the correct location
3373                $exportFile = "\$(abs_srcdir)/$exportFile";
3374            }
3375            $exports = "-export $exportFile";
3376        }
3377        my $otherlibs = "";
3378        if (defined($shared_libraries_libs{$libbasename})) {
3379            $otherlibs = $shared_libraries_libs{$libbasename};
3380        }
3381
3382        print FD "\t(cd $libdir && \$(CREATESHLIB) --mode=link -version-info \"\@ABIVERSION\@\" -o $libname $exports -rpath \$(libdir) $otherlibs);\\\n";
3383
3384        print FD "\tfi\n";
3385    }
3386}
3387#
3388# ===========================================================================
3389sub TargetPrograms {
3390    foreach $pgm (keys(%programs)) {
3391        # If there was a manual target, skip
3392        if (defined($usertargets{$pgm})) {
3393            print "Skipping generation of rule for $pgm because Makefile.sm already contains one\n";
3394            next;
3395        }
3396        &print_make_line( FD,  "$pgm: " );
3397        $pgmobjs = "";
3398        foreach $sourcefile (split(/\s+/,$programs{$pgm})) {
3399            $obj = $sourcefile;
3400            # Convert to object file
3401            $ext = $sourcefile;
3402            $ext =~ s/^.*\.//g;
3403            if (defined($extrules{"$ext:o"})) {
3404                $obj =~ s/\.$ext/\.o/g;
3405                &print_make_line( FD, "$obj " );
3406                $pgmobjs .= "$obj ";
3407            }
3408            else {
3409                if ($ext ne "h") {
3410                    print STDERR "Unknown extension $ext for $sourcefile for program $pgm\n";
3411                }
3412            }
3413        }
3414        # Add dependencies on libraries if requested
3415        $debug_lib_dependencies = 0;
3416        if ($convert_Ldir_to_relative) {
3417            print STDERR "Checking for relative dirs\n" if $debug_lib_dependencies;
3418            # convert -L dir -lname into dir/libname.a
3419            $libdep = "";
3420            if (defined($pgm_ldadd{$pgm})) {
3421                $libdep = $pgm_ldadd{$pgm};
3422            }
3423            $libdep =~ s/-L\s*([\w\.\/]*)\s*-l([\w-]*)//;
3424            $libdir = $1;
3425            $libname = $2;
3426            print STDERR "Checking $libdir and $libname\n" if $debug_lib_dependencies;
3427            if (defined($libdir) && defined($libname) &&
3428                $libdir ne "" && $libname ne "" &&
3429                !defined($external_libraries{$libname})) {
3430                &print_make_line( FD, " $libdir/lib$libname.a" );
3431            }
3432        }
3433        $otherdep = "";
3434        if (defined($pgm_depadd{$pgm})) {
3435            $otherdep = $pgm_depadd{$pgm};
3436        }
3437        if (defined($otherdep)) {
3438            &print_make_line( FD, " $otherdep" );
3439        }
3440        if (defined($depadd_all)) {
3441            &print_make_line( FD, " $depadd_all" );
3442        }
3443
3444        # Use the link rule appropriate for this program type
3445        #$pgmtype = $pgmsrctype{$pgm};
3446        &print_make_endline( FD );
3447        &print_make_setpos( 8 );
3448        $ruleline = "\t$progrules{$pgmsrctype{$pgm}} -o $pgm $pgmobjs";
3449        # We really need an libs before LIBS and libs after libs.
3450        if (defined($pgmlibs{$pgm})) {
3451            $ruleline .= " $pgmlibs{$pgm}";
3452        }
3453        if (defined($pgm_ldadd{$pgm})) {
3454            $ruleline .= " $pgm_ldadd{$pgm}";
3455        }
3456        $ruleline .= " \${LIBS}";
3457        &print_make_longline( FD, $ruleline );
3458    }
3459
3460}
3461
3462#
3463# ===========================================================================
3464sub TargetTags {
3465    if (!$local_tags && !$root_tags) { return; }
3466
3467    my $headerFiles = "";
3468    my $foundDerivedHeader = 0;
3469    my $sourceFiles = "";
3470    my $foundDerivedSource = 0;
3471    my $inputSources = "";
3472
3473    # Generate a listing of header and source files
3474    $has_sources = 0;
3475    $has_headers = 0;
3476    if ($regular_sources =~ /\S/) {
3477        printMakeVariable( FD, "SOURCES", $regular_sources );
3478        $inputSources = $regular_sources;
3479        $has_sources = 1;
3480    }
3481    elsif (defined($makevars{'SOURCES'})) {
3482        if ($makevars{'SOURCES'} =~ /\S/) {
3483            $has_sources = 1;
3484            $inputSources = $makevars{'SOURCES'};
3485        }
3486    }
3487    if ($has_sources) {
3488        foreach my $file (split(/\s+/,$inputSources)) {
3489            if (! ($file =~ /\S/)) { next; }
3490            # Check that these files exist, either directly or
3491            # as a '.in' version
3492            if (-s "$file.in") {
3493                $sourceFiles .= "\$(abs_builddir)/$file ";
3494                $foundDerivedSource = 1;
3495            }
3496            elsif (-s "$file") {
3497                $sourceFiles .= "$file ";
3498            }
3499            else {
3500                # Only complain about C files for now
3501                if ($file =~ /.*\.c$/) {
3502                    print STDERR "Warning: source file $file or $file.in not found in $curdir\n";
3503                }
3504            }
3505        }
3506    }
3507
3508    if ($regular_headers ne "") {
3509        printMakeVariable( FD, "HEADERS", $regular_headers );
3510        $has_headers = 1;
3511    }
3512    if (defined($makevars{'HEADERS'})) {
3513        $has_headers = 1;
3514        # Add these files to the headers variable.
3515        # headers is used to check on files that aren't handled by
3516        # simplemake
3517        foreach my $file (split(/\s+/,$makevars{'HEADERS'})) {
3518            if (! ($file =~ /\S/)) { next; }
3519            $headers{$file} = 1;
3520            # Check that these files exist, either directly or
3521            # as a '.in' version
3522            if (-s "$file.in") {
3523                $headerFiles .= "\$(abs_builddir)/$file ";
3524                $foundDerivedHeader = 1;
3525            }
3526            elsif (-s "$file") {
3527                $headerFiles .= "$file ";
3528            }
3529            else {
3530                print STDERR "Warning: header file $file or $file.in not found in $curdir\n";
3531            }
3532        }
3533    }
3534
3535    if ($has_headers || $has_sources) {
3536        # Make it eaiser to change the tags program options.
3537        # For example, this adds .i as a known "C" language file
3538        printMakeVariable( FD, "ETAGS", "\@ETAGS\@ \@ETAGSADD\@" );
3539        # The value of ETAGS was "etags --langmap=c:+.i" but
3540        # some Linux systems have a very old version of etags
3541        # that does not support --langmap.
3542    }
3543
3544    # Add a synonym for tags.
3545    if ($foundDerivedHeader) {
3546        printMakeVariable( FD, "HEADERFILES", $headerFiles );
3547    }
3548    else {
3549        printMakeVariable( FD, "HEADERFILES", '$(HEADERS)' );
3550    }
3551    if ($foundDerivedSource) {
3552        printMakeVariable( FD, "SOURCEFILES", $sourceFiles );
3553    }
3554    else {
3555        printMakeVariable( FD, "SOURCEFILES", '$(SOURCES)' );
3556    }
3557    print FD "tags: TAGS$newline";
3558    # By adding "Makefile" to TAGS, we ensure that the TAGS target
3559    # will be rebuilt anytime the package is reconfigured.  We
3560    # could also make TAGS always rebuild, to catch any source changes.
3561    print FD "TAGS: Makefile";
3562    # Only generate a local etags call if there are local sources
3563    # This target is designed for VPATH builds to build a TAGS file in
3564    if ($has_headers || $has_sources) {
3565        if ($local_tags) {
3566            print FD '${HEADERFILES} ${SOURCEFILES}
3567        here=`pwd`;\
3568        (cd ${srcdir} && $(ETAGS) -o $$here/TAGS --append ${HEADERFILES} ${SOURCEFILES};)
3569';
3570        }
3571        elsif ($root_tags) {
3572            print FD "\${HEADERFILES} \${SOURCEFILES}$newline";
3573            if (defined($rootdirpath)) {
3574                $rpath = $rootdirpath;
3575                $rpath =~ s/\/$//;
3576            }
3577            else {
3578                # Use current directory
3579                # Question: in this case, should we leave out the tags
3580                # target?
3581                $rpath = ".";
3582            }
3583            # For vpath builds, make the root path point to the
3584            # VPATH root.
3585           
3586            print FD "\there=\`cd $rpath && pwd\` ; cd \${srcdir} && \$(ETAGS) -o \$\$here/TAGS --append \${HEADERFILES} \${SOURCEFILES}$newline";
3587        }
3588        else {
3589            print FD "$newline";
3590        }
3591    }
3592    else {
3593        print FD "$newline";
3594    }
3595    # Tags on only the subdirs (really the source subdirs) and any
3596    # additional tags dirs
3597    @tmp_tags_dirs = (@subdirs,@tags_dirs);
3598    &RecursiveOp( "TAGS", "tmp_tags_dirs" );
3599    $#tmp_tags_dirs = -1;
3600}
3601#
3602# The generation of documentation (e.g., manual pages) is handled
3603# a little differently.  To make it easier to manage a VPATH build of
3604# everything, including the documentation, we:
3605#    Add the document output types as file extensions to SUFFIX
3606#    Add generic build rules (using variables for options)
3607#    Create targets using variable substitution.
3608# For example, to add html output (this shows *only* the document rules)
3609#
3610# .SUFFIXES: .c .html
3611# .c.html:
3612# \tdoctext -html $(DOCTEXT_OPTIONS) $<
3613# HTML: ${mpi_sources:.c=.html}
3614#
3615# In addition, we may need to generate a document target even if there are
3616# no files in this directory *if* there are subdirectories (the usual
3617# recursive target).
3618#
3619# Temporary repository:
3620# the doctext line from MPICH1
3621#       $doctext -ext 3 -mpath ../../man/man3 -I pubinc -heading MPI \
3622#                -quotefmt /home/MPI/mansrc/fortnotes \
3623#                -ignore EXPORT_MPI_API \
3624#                /home/MPI/mansrc/errnotes *.c ; \
3625#
3626# SuffixDocs: Add any suffix rules for this directory
3627sub SuffixDocs {
3628    # global: do_docs, suffixes, docsrc
3629    if (! $do_docs) { return; }
3630    foreach my $kind (keys(%docsrc)) {
3631        if ($docsrc{$kind} ne "") {
3632            $suffixes .= " .$kind";
3633        }
3634    }
3635    # Add source file suffixes
3636    if (! $suffixes || ! ($suffixes =~ /\.txt/) ) {
3637        $suffixes .= " .txt";
3638    }
3639}
3640sub VariableDocs {
3641    # global: do_docs, suffixes, docsrc
3642    if (! $do_docs) { return; }
3643    foreach my $kind (keys(%docsrc)) {
3644        ;
3645    }
3646    # Let us set doctext from configure.  We only need this if
3647    # we saw any sources.  This expresion is true if docsrc is non-empty
3648    if (scalar(%docsrc)) {
3649        printMakeVariable( FD, "DOCTEXT", "\@DOCTEXT\@" );
3650    }
3651}
3652
3653#
3654# Generate the rule for generating documentation from the source files
3655#
3656sub RuleDocs {
3657    # global: do_docs, docsrc, FD, newline
3658    if (! $do_docs) { return; }
3659    $rootdir = $rootdirpath;
3660    foreach my $kind (keys(%docsrc)) {
3661        # Set the default suffix
3662        $docsrcsuffix = ".c";
3663        if (defined($docsrc{$kind}) && $docsrc{$kind} ne "") {
3664            $docdestdir = $globaldocdir;
3665            if (defined($docdir{$kind}) && $docdir{$kind} ne "") {
3666                $docdestdir = $docdir{$kind};
3667            }
3668            # Replace ROOTDIR, including handling any doubled //
3669            $docdestdir =~ s/ROOTDIR/$rootdir/g;
3670            $docdestdir =~ s/\/\//\//g;
3671            # Replace any occurance of $dockinddirval is docdestdir
3672            if (defined($docthiskinddir{$kind})) {
3673                $dockinddirval = $docthiskinddir{$kind};
3674            }
3675            else {
3676                $dockinddirval = $dockinddir{$kind};
3677            }
3678            $docdestdir =~ s/(\$\w+)/$1/eeg;     # see man perlfaq4
3679            #
3680            # Replace ROOTDIR etc in any doc_namedefs
3681            $docargs = $doc_namedefs;
3682            if ($docargsAdd ne "") {
3683                $docargs .= " $docargsAdd";
3684            }
3685            $docargs =~ s/ROOTDIR/$rootdir/g;
3686            $docargs =~ s/\/\//\//g;
3687           
3688            # Check for an alternative suffix
3689            $docfiles = &ExpandMakeVars( $docsrc{$kind} );
3690            print "file list = $docfiles\n" if $debug;
3691            for $file (split(/\s+/,$docfiles)) {
3692                $file =~ /.*(\..*)$/;
3693                $suffix = $1;
3694                if ($docsrcsuffix ne $suffix) {
3695                    $docsrcsuffix = $suffix;
3696                }
3697            }
3698            print FD "$docsrcsuffix.$kind:$newline";
3699            $extarg = "";
3700            if ($kind eq "man" && ($docdestdir =~ /man(\d)$/)) {
3701                $extarg = "-ext $1";
3702            }
3703            print FD "\t\$(DOCTEXT) $doctextOptionName{$kind} -mpath $docdestdir $extarg -heading $doc_heading \\$newline";
3704            print FD "\t\t-quotefmt $docargs \$<$newline";
3705        }
3706    }
3707}
3708
3709#
3710# Given a list of sources, return an array containing the distinct suffixes
3711# (without the leading .)
3712sub GetSuffixList {
3713    my %suffixSeen = ();
3714    my $vars = $_[0];
3715    my @suffixes = ();
3716
3717    # Check for an alternative suffix
3718    $vars = &ExpandMakeVars( $vars );
3719    print "file list = $vars\n" if $debug;
3720    for $file (split(/\s+/,$vars)) {
3721        $file =~ /.*\.(.*)$/;
3722        $suffix = $1;
3723        if (!defined($suffixSeen{$suffix})) {
3724            $suffixSeen{$suffix} = 1;
3725            $suffixes[$#suffixes+1] = $suffix
3726        }
3727    }
3728    return @suffixes;
3729}
3730
3731sub SubForSuffixes {
3732    my $src = $_[0];
3733    my $suffixarrayName = $_[1];
3734    my $repSuffix = $_[2];
3735 
3736    for $suffix (@$suffixarrayName) {
3737        $src =~ s/\.$suffix/\.$kind/;
3738    }
3739    return $src;
3740}
3741
3742#
3743# Generate the documentation targets.
3744#
3745sub TargetDocs {
3746    if (! $do_docs || ! $maint_targets) { return; }
3747    my %didkind = ( "html" => 0, "man" => 0, "latex" => 0 );
3748
3749    print FD $makeBlockSep;
3750    foreach my $kind (keys(%docsrc)) {
3751        $targetKind = $docTargetName{$kind};
3752        print FD "$targetKind: ";
3753        my $src = $docsrc{$kind};
3754        if ($src ne "") {
3755            if ($src =~ /^\s*\$[\{\(][_\w]*[\}\)]\s*$/) {
3756                # a single variable: use make substitution if a single
3757                # suffix
3758                @suffixes = &GetSuffixList( $src );
3759                if ($#suffixes == 0) {
3760                    $src =~ s/\}/:.$suffixes[0]=.$kind\}/;
3761                }
3762                else {
3763                    # manually substitute
3764                    $src = &SubForSuffixes( $src, "suffixes", $kind );
3765                }
3766            }
3767            elsif ($src =~ /\$/) {
3768                # Perform variable expansion if possible
3769                $src = &ExpandMakeVars( $src );
3770                @suffixes = &GetSuffixList( $src );
3771                # Convert the extensions to the document type
3772                #$src =~ s/\.c/.$kind/;
3773                $src = &SubForSuffixes( $src, "suffixes", $kind );
3774            }
3775            else {
3776                $src =~ s/\.c/.$kind/;
3777            }
3778            print FD "$src$newline";
3779        }
3780        else {
3781            # This is the recursive branch
3782            print FD "$newline";
3783        }
3784        # If we're at the top; create any directories that are needed
3785        # This assumes a particular layout for the directories that
3786        # we'll eventually want to make adjustable.
3787        if ($doc_attop) {
3788            my @dirs = ();
3789            if ($kind eq "html") {
3790                @dirs = ( "www", "www/www1", "www/www3" );
3791            }
3792            elsif ($kind eq "man") {
3793                @dirs = ( "man", "man/man1", "man/man3" );
3794            }
3795            elsif ($kind eq "latex") {
3796                @dirs = ( "doc", "doc/refman" );
3797            }
3798            else {
3799                print STDERR "Unrecognized document type $kind\n";
3800            }
3801            foreach my $dir (@dirs) {
3802                print FD "\tif [ ! -d \${DESTDIR}$dir ] ; then mkdir \${DESTDIR}$dir ; fi$newline";
3803            }
3804        }
3805        &RecursiveOp( $targetKind );
3806        if ($#doc_subdirs >= 0) {
3807            &RecursiveOp( $targetKind, "doc_subdirs" );
3808        }
3809        if (defined($usertargets{"${targetKind}-local"})) {
3810            print FD "\t\${MAKE} ${targetKind}-local$newline";
3811        }
3812        $didkind{$kind} = 1;
3813    }
3814    #
3815    # For any directory that does not have any source files, we must still
3816    # generate a target *if* any directory set the source.
3817    foreach $kind ("html", "man", "latex") {
3818        $targetKind = $docTargetName{$kind};
3819        if (! $didkind{$kind} && $globaldockind{$kind}) {
3820            print FD "$targetKind:$newline";
3821            &RecursiveOp( $targetKind );
3822            if ($#doc_subdirs >= 0) {
3823                &RecursiveOp( $targetKind, "doc_subdirs" );
3824            }
3825        }
3826    }
3827    print FD $makeBlockSep;
3828}
3829
3830#
3831# Install target.  Question: does this need to list (or use a shell command
3832# to get) the filename for each individual file?
3833#
3834sub InstallDocs {
3835    # Add target only at the top
3836    if (!$doc_attop) { return; }
3837
3838    # Instead of this approach, we used a more general installdir
3839    # that handles these cases.
3840#     print FD "install-docs:$newline";
3841#     # Each document type is different.  In addition, we want the install
3842#     # to work even if the documents have not been built.
3843#     if ((!$didkind{"html"}) && $globaldockind{"html"}) {
3844#         print FD "\tif [ ! -d \$(htmldir) ] ; then \$(MKDIR_P) \$(htmldir) ; fi\n";
3845#       print FD "\tif [ -d www/www3 ] ; then \\$newline";
3846#       print FD "\t\$(INSTALL_DATA) www/www3/* \$(htmldir)/www3/ ; fi$newline";
3847#       print FD "\tif [ -d www/www1 ] ; then \\$newline";
3848#       print FD "\t\$(INSTALL_DATA) www/www1/* \$(htmldir)/www1/ ; fi$newline";
3849#     }
3850#     if ((!$didkind{"man"}) && $globaldockind{"man"}) {
3851#         print FD "\tif [ ! -d \$(mandir) ] ; then \$(MKDIR_P) \$(mandir) ; fi\n";
3852#       print FD "\tif [ -d man/man3 ] ; then \\$newline";
3853#       print FD "\t\$(INSTALL_DATA) man/man3/* \$(mandir)/man3/ ; fi $newline";
3854#       print FD "\tif [ -d man/man1 ] ; then \\$newline";
3855#       print FD "\t\$(INSTALL_DATA) man/man1/* \$(mandir)/man1/ ; fi $newline";
3856#     }
3857    # LaTeX manual is different and requires a special case
3858}
3859
3860# Add any dirs that are referred to by InstallDocs
3861sub InstallDocDirs {
3862    # Add target only at the top
3863    if (!$doc_attop) { return; }
3864
3865    print FD "htmldir         = \@htmldir\@\nmandir          = \@mandir\@\n";
3866}
3867
3868#
3869# Installation is complicated by VPATH builds; files that are derived and
3870# files that are not may be in different locations (one relative, the other
3871# absolute with respect to the source tree)
3872#
3873# Also, note that the documents and some other files may be pre-existing, so
3874# that we need to get them from the srcdir, not the build dir.  However,
3875# maintainers may create them in the builddir.
3876sub TargetInstall {
3877    %dirschecked = ();
3878    if (!scalar(%install_files) && !scalar($install_dirs) &&
3879        !scalar(%optinstall_files) && !scalar($optinstall_dirs)) {
3880        if (defined($usertargets{"install-local"}) && !$gIssuedInstallLocal) {
3881            # First add the indirect to the install-local target (when
3882            # there are no local files to install at all)
3883            print FD "install: install-local $newline";
3884        }
3885        return;
3886    }
3887    print FD "# Install target$newline";
3888    &TargetInit( "install" );
3889    print FD " FORCE_TARGET $newline";
3890    # Create the directories for the install directories
3891    foreach $kind (keys(%install_dirs)) {
3892        $dir = $InstallDirFromKind{$kind};
3893        if ($dir eq "") {
3894            print STDERR "No known installation dir for install_$kind\n";
3895            next;
3896        }
3897        if (!defined($dirschecked{$dir})) {
3898            # Check on dependent directories
3899            foreach $checkdir (split(/\s+/,$required_dirs{$dir})) {
3900                if ($checkdir ne "" && !defined($dirschecked{$checkdir})) {
3901                    $dirschecked{$checkdir} = 1;
3902                    print FD "\tif [ ! -d \${DESTDIR}\${$checkdir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$checkdir} ; fi$newline";
3903                }
3904            }
3905            print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
3906            $dirschecked{$dir} = 1;
3907        }
3908    }
3909
3910    # Handle the files
3911    foreach $kind (keys(%install_files)) {
3912        $dir = $InstallDirFromKind{$kind};
3913        if ($dir eq "") {
3914            print STDERR "No known installation dir for install_$kind\n";
3915            next;
3916        }
3917        if (!defined($dirschecked{$dir})) {
3918            # Check on dependent directories
3919            foreach $checkdir (split(/\s+/,$required_dirs{$dir})) {
3920                if ($checkdir ne "" && !defined($dirschecked{$checkdir})) {
3921                    $dirschecked{$checkdir} = 1;
3922                    print FD "\tif [ ! -d \${DESTDIR}\${$checkdir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$checkdir} ; fi$newline";
3923                }
3924            }
3925            print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
3926            $dirschecked{$dir} = 1;
3927        }
3928        #
3929        # If there is an install-local target, invoke it here:
3930        if (defined($usertargets{"install-local"}) && !$gIssuedInstallLocal) {
3931            if ($install_local_dirs ne "") {
3932                foreach my $dir (split(/\s+/,$install_local_dirs)) {
3933                    foreach $checkdir (split(/\s+/,$required_dirs{$dir})) {
3934                        if ($checkdir ne "" && !defined($dirschecked{$checkdir})) {
3935                            $dirschecked{$checkdir} = 1;
3936                            print FD "\tif [ ! -d \${DESTDIR}\${$checkdir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$checkdir} ; fi$newline";
3937                        }
3938                    }
3939                    if ($dir ne "" && !defined($dirschecked{$dir})) {
3940                        $dirschecked{$dir} = 1;
3941                        print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
3942                    }
3943                }
3944            }
3945            print FD "\t\${MAKE} install-local$newline";
3946            $gIssuedInstallLocal = 1;
3947        }
3948
3949        foreach $file (split(/\s+/,$install_files{$kind})) {
3950            $destfile = $file;
3951            $destfile =~ s/.*\///;
3952            $this_install_method = $install_methods{$kind};
3953            if ($this_install_method eq "") {
3954                $this_install_method = '$(INSTALL)';
3955                }
3956            print FD "\t$this_install_method $file \${DESTDIR}\${$dir}/$destfile$newline";
3957        }
3958    }
3959
3960    # Install any directories.  This asks for all files in the directory
3961    # to be installed.  It is typically used for things like manpages
3962    # that may be very numerous
3963    foreach $kind (keys(%install_dirs),keys(%optinstall_dirs)) {
3964        $dir = $InstallDirFromKind{$kind};
3965        foreach $srcdir (split(/\s+/,$install_dirs{$kind})) {
3966            # Choose the installation method based on the kind value
3967            if (!defined($install_methods{$kind})) {
3968                $this_install_choice = '$(INSTALL_PROGRAM)';
3969            }
3970            else {
3971                $this_install_choice = $install_methods{$kind};
3972            }
3973
3974            # This handles 2-level directories, such as man pages and
3975            # html pages (organized as man/man1-8 or www/www1-8).  A fully
3976            # recursive approach could be used, but it is felt that an
3977            # install should be constrained.  If there is a reason for an
3978            # install with three levels of directories, either install the
3979            # subdirectories separately or modify this code.
3980
3981            # Sigh.  This causes some make programs (such as gnumake)
3982            # to print a message about an ignored error.  To avoid that,
3983            # we turn the @-test into an @if test
3984            #print FD "\t\@-test -d $srcdir && cd $srcdir && for name in * ; do \\
3985            print FD "\t\@if test -d $srcdir && cd $srcdir ; then \\
3986\t for name in * ; do \\
3987\t  if [ \"\$\$name\" = \"*\" ] ; then continue ; fi ; \\
3988\t  if [ -f \$\$name ] ; then \\
3989\t    echo \"$this_install_choice \$\$name \${DESTDIR}\${$dir}/\$\$name\" ; \\
3990\t    $this_install_choice \$\$name \${DESTDIR}\${$dir}/\$\$name ; \\
3991\t  elif [ -d \$\$name ] ; then \\
3992\t    if [ ! -d \${DESTDIR}\${$dir}/\$\$name ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir}/\$\$name ; fi ;\\
3993\t    ( cd \$\$name && for name2 in * ; do \\
3994\t        if [ \"\$\$name2\" = \"*\" ] ; then continue ; fi ; \\
3995\t        if [ -f \$\$name2 ] ; then \\
3996\t            echo \"$this_install_choice \$\$name2 \${DESTDIR}\${$dir}/\$\$name/\$\$name2\" ; \\
3997\t            $this_install_choice \$\$name2 \${DESTDIR}\${$dir}/\$\$name/\$\$name2 ; \\
3998\t        elif [ -d \$\$name2 ] ; then  \\
3999\t            echo \"cp -rp \$\$name2 \${DESTDIR}\${$dir}/\$\$name\" ; \\
4000\t            cp -rp \$\$name2 \${DESTDIR}\${$dir}/\$\$name ; \\
4001\t        fi \\
4002\t    done ) ; \\
4003\t  else \\
4004\t    echo \"Unknown file type for \$\$name\" ; \\
4005\t  fi ; \\
4006\t done ; \\
4007\tfi$newline";
4008        }
4009    }
4010
4011    foreach $kind (keys(%optinstall_files)) {
4012        $dir = $InstallDirFromKind{$kind};
4013        if (!defined($dirschecked{$dir})) {
4014            print FD "\tif [ ! -d \${DESTDIR}\${$dir} ] ; then \$(MKDIR_P) \${DESTDIR}\${$dir} ; fi$newline";
4015            $dirschecked{$dir} = 1;
4016        }
4017        foreach $filelist ($optinstall_files{$kind}) {
4018            foreach $file (split( /\s+/, $filelist)) {
4019                $destfile = $file;
4020                $destfile =~ s/.*\///;
4021                # Choose the installation method based on the kind value
4022                if (!defined($install_methods{$kind})) {
4023                    $this_install_choice = '$(INSTALL_PROGRAM)';
4024                }
4025                else {
4026                    $this_install_choice = $install_methods{$kind};
4027                }
4028                print FD "\tif [ -s $file ] ; then $this_install_choice $file \${DESTDIR}\${$dir}/$destfile ; fi$newline";
4029            }
4030        }
4031    }
4032    foreach $extradir (@install_subdirs) {
4033        # Check for configure substitutions in the list.  Make
4034        # these conditional, so that they can be empty.  Also note that
4035        # they could also contain *multiple* directories, so we have
4036        # to handle them in a general way
4037        #$endline = "";
4038        if ($extradir =~ /^@/) {
4039            print FD "\tfor dir in $extradir - ; do \\$newline";
4040            print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ;\\$newline";
4041            print FD "\t\t(cd \$\$dir && \$(MAKE) INSTALL_STRIP_FLAG=\$(INSTALL_STRIP_FLAG) PACKAGE=\$(PACKAGE) install) ;\\$newline";
4042            print FD "\tdone$newline";
4043        }
4044        else {
4045            print FD "\t(cd $extradir && \$(MAKE) INSTALL_STRIP_FLAG=\$(INSTALL_STRIP_FLAG) install)$newline";
4046        }
4047    }
4048    print FD "$newline";
4049
4050    # Install documentation
4051    &InstallDocs;
4052    #
4053    print FD "install-strip:$newline";
4054    print FD "\t\$(MAKE) INSTALL_STRIP_FLAG=-s install$newline";
4055   
4056    #
4057    # We should also create an uninstall target.  Rather than
4058    # unilaterally uninstalling files, we may want an option to create
4059    # a file that will uninstall only the installed files (as MPICH-1
4060    # does).
4061    &TargetInit( "uninstall" );
4062    print FD "\n";
4063    foreach $kind (keys(%install_files)) {
4064        $dir = $InstallDirFromKind{$kind};
4065        foreach $file (split(/\s+/,$install_files{$kind})) {
4066            $destfile = $file;
4067            $destfile =~ s/.*\///;
4068            if (defined($uninstall_methods{$kind})) {
4069                # This branch is subtly different from the else branch below
4070                # because it also passes the $file as the first argument. 
4071                # Strictly speaking, this is not compatible with using
4072                # libtool directly, so if we ever replace createshlib then
4073                # we should rework this uninstall target
4074                # just a bit. [goodell@mcs 2007-11-28]
4075                print FD "\t-$uninstall_methods{$kind} $file \${DESTDIR}\${$dir}/$destfile$newline";
4076            }
4077            else {
4078                print FD "\t-rm -f \${DESTDIR}\${$dir}/$destfile$newline";
4079            }
4080        }
4081    }
4082    foreach $kind (keys(%optinstall_files)) {
4083        $dir = $InstallDirFromKind{$kind};
4084        foreach $file (split(/\s+/,$optinstall_files{$kind})) {
4085            $destfile = $file;
4086            $destfile =~ s/.*\///;
4087            if (defined($uninstall_methods{$kind})) {
4088                # This branch is subtly different from the else branch below
4089                # because it also passes the $file as the first argument. 
4090                # Strictly speaking, this is not compatible with using
4091                # libtool directly, so if we ever replace createshlib then
4092                # we should rework this uninstall target just a
4093                # bit. [goodell@mcs 2007-11-28]
4094                print FD "\t-$uninstall_methods{$kind} $file \${DESTDIR}\${$dir}/$destfile$newline";
4095            }
4096            else {
4097                print FD "\t-rm -f \${DESTDIR}\${$dir}/$destfile$newline";
4098            }
4099        }
4100    }
4101    # Handle uninstalls controlled by subdirs
4102    if ($#install_subdirs >= 0) {
4103        &RecursiveOp( "uninstall", "install_subdirs" );
4104    }
4105
4106    # also add the recursive installcheck target
4107    &TargetInit( "installcheck" );
4108    if (defined($usertargets{"installcheck-local"})) {
4109        print FD " installcheck-local";
4110    }
4111    print FD $newline;
4112    if ($#install_subdirs >= 0) {
4113        &RecursiveOp( "installcheck", "install_subdirs" );
4114    }
4115    &TargetPostamble( "installcheck" );
4116}
4117
4118#--------------Kumud_parallel_fix--------------------------------
4119
4120#============================================================================
4121#The target to desend into sub-directories and create all the executables that
4122#needs to be created
4123#INSTALL_BIN = myexecutable
4124sub TargetExecutables {
4125
4126    print FD "all-executable: all-executable-local$newline";
4127    foreach $dir (@extra_dirs, @subdirs) {
4128        if ($dir eq ".") {
4129             # the pre-requisite all-executable-local already take care of this case.   
4130        }
4131        elsif ($dir =~ /@([^@]*)@/) {
4132            # May be a replaced variable
4133            print FD "\t${quietmake}for dir in $dir - ; do \\$newline";
4134            print FD "\t\tif [ \"\$\$dir\" = \"-\" ] ; then break ; fi ; \\$newline";
4135            print FD "\t\tif ( cd \$\$dir && \${MAKE} all-executable ) ; then : ; else exit 1; fi \\$newline";
4136            print FD "\tdone$newline";
4137        }
4138        else {
4139            print FD "\t${quietmake}(cd $dir && \${MAKE} all-executable )$newline";
4140        }
4141    }
4142   
4143
4144   
4145}
4146
4147
4148#
4149# ===========================================================================
4150# Other targets and stuff to be added:
4151#   CPP
4152#   Including common headers (e.g., all file.sm's get a common header of
4153#       variables defined by configure.  This is cleaner than the automake
4154#       approach of including *every* AC_SUBST value).
4155#   Support for shared libraries.  Unlike automake, we will not require
4156#       separate rules (automake uses lib_LTLIBRARIES and la extensions)
4157#       for shared library support.
4158#   Handling files to be installed (e.g., automake's sbin_PROGRAMS = ...)
4159#      (automake understands <dir>_PROGRAMS and <dir>_LIBRARIES)
4160#   target_LDFLAGS and general LDFLAGS
4161#   INCLUDES (automake variable that we've adopted) needs better control.
4162#   Support for .F and .F90 extensions (Fortran with preprocessor)
4163#   FLIBS
4164#   Linker choice.  simplemake uses the file type of the *first* source file.
4165#       automake has a matrix that depends on the source files referred to.
4166#   SCRIPTS (as in bin_SCRIPTS) targets
4167#   HEADERS variables (as in prog_HEADERS).  In many cases, this should
4168#       be determined automatically.  Note that it is needed for correct TAGS
4169#       generation.
4170
4171# Miscellaneous Routines
4172sub printHelp {
4173    print STDERR "\
4174simplemake [ -nocomments ] [ -am ] [ -libdir=NAME=DIR ] [ -include=LIST ]\
4175           files \
4176    -nocomments      - Exclude Makefile comments from generated file\
4177    -libdir=NAME=DIR - library NAME is located in directory DIR\
4178    -am              - Automake style target names\
4179    -include=LIST    - CPP style list of include directories (e.g., -Ia -Ib)\
4180                       These define INCLUDES unless a Makefile.sm defines\
4181                       that value\
4182    -v               - verbose output\
4183    -common=file     - Read text to include in every output file\
4184    -distrib         - Turn off all maintenance targets (make a distribution\
4185                       version)\
4186    -vpath=[yes|no]  - Create VPATH targets\
4187\
4188    -depend          - Generate dependency information as a make target\
4189    -depend=static   - Generate dependency information when simplemake runs\
4190    -nodepend        - Do not generate dependency information\
4191\
4192    -rootdir=PATH    - Set the root directory for all Makefiles\
4193    -configdir=PATH  - Location of the configure that controls the Makefile\
4194                       in this directory (used to rebuild a single \
4195                       Makefile.in)\
4196    -debug           - Turn on debugging output\
4197    -dos             - Use DOS-style newlines on output files\
4198    -interdirsleep   - Use a sleep between directory builds to handle problems\
4199                       with file systems that are not time-synchronized\
4200                       with the build node.  -interdirsleep=nn specifies\
4201                       an nn second sleep.\
4202    -smroot=dir      - Location of simplemake (absolute location)\
4203    -help            - This output\
4204    \n";
4205    print STDERR "\
4206    Recognized target forms\
4207    libname_a_SOURCES = source files for library \"name\"\
4208    libname_a_DIR     = location of directory into which lib \"name\" goes\
4209    SUBDIRS = blank separated list of subdirectories to process.  Use \".\"\
4210              to control the order in which the current directory is processed\
4211    DOC_SUBDIRS = blank separate list of subdirectories containing \
4212              documentation but no code source.  These directories may\
4213              contain files used as input to documentation generators.\
4214    EXTRA_PROGRAMS = names of programs to define rules for but not to build\
4215                     by default\
4216    EXTRA_LIBS = names of libraries to define rules for but not to build\
4217                     by default\
4218    name_SOURCES = source files for program \"name\"\
4219    name_LDADD   = extra linker flags for building program \"name\"\
4220\
4221    LDADD = extra linker flags to add to all programs\
4222    simplemake also allows all usual Makefile commands, including variable\
4223    assignment and targets.\n";
4224}
4225
4226#
4227# Generate dependency information when possible.  This version simply
4228# uses gcc -MM; if that doesn't work, does nothing. 
4229#
4230# Automake strives to generate the dependencies.  This is a better approach,
4231# but it is very difficult to implement in practice, particularly where the
4232# development environment is not GNU. 
4233#
4234# This is somewhat tricky because the current organization of MPICH2
4235# makes use of many -I<dir> switches, that are selected at configure time,
4236# so some files may not be where expected.
4237sub AddDependency {
4238    $target = $_[0];
4239    if (defined($makevars{"INCLUDES"})) {
4240        $include = $makevars{"INCLUDES"};
4241    }
4242    else {
4243        $include = $include_list;
4244    }
4245    print "Trying $make_depend $include $target\n" if $debug;
4246    $cmdline = "$make_depend $include $target";
4247    if (! $debug) {
4248        $cmdline .= " 2>/dev/null";
4249    }
4250    $cmdline .= " |";
4251    print "Depend commandline = $cmdline\n" if $debug;
4252    open( DEPFD, $cmdline ) || return;
4253    while (<DEPFD>) {
4254        # Remove files that are provided by the device
4255        s/\S*mpidpre\.h//g;
4256        s/\S*mpidpost\.h//g;
4257
4258        # For derived object files like lo and _xxx.o, add these
4259        if ($do_profilelibs && $found_profilelib) {
4260            s/^(.*)\.o:(.*)/$1.o _$1.o:$2/;
4261        }
4262        if ($do_sharedlibs || $found_sharedlib) {
4263            s/^(.*)\.o(.*)/$1.o $1.lo$2/;
4264        }
4265        print FD $_ ;
4266    }
4267    close( DEPFD );
4268}
4269
4270#
4271#
4272sub TargetDependenciesStatic {
4273    print FD "# Dependencies$newline";
4274    # Libraries first
4275    foreach $lib (keys(%libraries)) {
4276        foreach $sourcefile (split(/\s+/,&ExpandMakeVars($libraries{$lib}))) {
4277            # Get extension
4278            $ext = $sourcefile;
4279            $ext =~ s/^.*\.//g;
4280            # We only know about C for now.
4281            if ($ext eq "c") {
4282                &AddDependency( $sourcefile );
4283            }
4284        }
4285    }
4286    # Programs
4287    foreach $pgm (keys(%programs)) {
4288        foreach $sourcefile (split(/\s+/,$programs{$pgm})) {
4289            $ext = $sourcefile;
4290            $ext =~ s/^.*\.//g;
4291            # We only know about C for now.
4292            if ($ext eq "c") {
4293                &AddDependency( $sourcefile );
4294            }
4295        }
4296    }
4297}
4298
4299#
4300# Design:
4301# Each source file has an associated file containing dependencies, stored in
4302# a subdirectory .deps
4303#    Each source file foo has .deps/foo.d
4304#    The Makefile includes .deps/alldeps
4305#
4306# Because we want to support VPATH builds, we can't create these in the
4307# real source directory, so these directories and files must be created
4308# at configure time.
4309#
4310sub TargetDependenciesDynamic {
4311    my $has_sources = 0;
4312
4313    # First, are there any sources?
4314    # a hash in a scalar context is 0 if empty and nonzero otherwise
4315    if (scalar(%libraries) || scalar(%programs)) {
4316        $has_sources = 1;
4317    }
4318   
4319   
4320    # Some makes will accept sinclude instead of -include
4321    # -include is gnumake for "include if file exists, ignore otherwise"
4322    if ($makeInclude eq "") { $makeInclude = "-include"; }
4323
4324    print FD $makeBlockSep;
4325    print FD "# Dependencies$newline";
4326    # This definition follows the one for COMPILE_C
4327    if ($has_sources) {
4328        # By setting DEPS_DIR to just ., you can use -MMD to update the
4329        # dependencies with gcc
4330        print FD "DEPS_DIR = .deps$newline";
4331        # We'd like to use $found_profilelib to decide whether
4332        # to include the _$*.o in the target string. 
4333        # But make wants to do the $* substitutions before variable
4334        # substitutions
4335        printMakeVariable( FD, "MAKE_DEPEND_C",
4336             "\@MAKE_DEPEND_C\@ \$(DEFS) \$(INCLUDES) \$(CPPFLAGS)$newline" );
4337        print FD "dependencies: \$(DEPS_DIR)/timestamp$newline";
4338    }
4339    else {
4340        print FD "dependencies:$newline";
4341    }
4342    &RecursiveOp( "dependencies" );
4343
4344    # First, generate the targets to maintain the individual files.
4345    # This makes it easy to update the dependency contents without
4346    # regenerating the entire list.
4347    # Note that we don't always want to use this target, since
4348    # the dependencies may need to be regenerated when other files change.
4349    # Even better is to use this to update the dependency files
4350    # when each file is compile (gcc can almost do this, as long as
4351    # you don't mind having .d files in the build directory)
4352    if ($has_sources) {
4353        # Use $found_profilelib to decide whether to add _xxx.o to the
4354        # target name.  This requires that the MAKE_DEPEND_C compiler
4355        # accept the -MT option
4356        #
4357        my %sawFile = ();
4358        foreach $lib (keys(%libraries)) {
4359            # Its possible that the same file is used in several libraries.
4360            # Thus, we only look at unique files.
4361            foreach $sourcefile (split(/\s+/,&ExpandMakeVars($libraries{$lib}))) {
4362                if (defined($sawFile{$sourcefile})) { next; }
4363                $sawFile{$sourcefile} = 1;
4364                # FIXME: If, for some reason, the source file is created by
4365                # configure, then simplemake will get confused.
4366                my $srcdirloc = '$(srcdir)/';
4367                $ext = $sourcefile;
4368                $ext =~ s/^.*\.//g;
4369                $sourcebasename = $sourcefile;
4370                $sourcebasename =~ s/\.\w*$//;
4371                my $targetOpts = "-MT \'_$sourcebasename.o $sourcebasename.o\'";
4372                if (!$found_profilelib) {
4373                    $targetOpts = "";
4374                }
4375                # We can not use $< in an explicit target context because
4376                # some Make programs do not handle them properly (Solaris,
4377                # for one)
4378                if ($ext eq "c") {
4379                    if (! -s $sourcefile) {
4380                        my $missingFile = "$curdir/$sourcefile";
4381                        $missingFile =~ s%//%/%g;
4382                        print STDERR "Sourcefile $missingFile does not exist.\
4383simplemake is assuming that this file will be created by the configure step\
4384in the build directory\n";
4385                        $srcdirloc = '';
4386                    }
4387                    print FD "\$(DEPS_DIR)/$sourcebasename.d: $srcdirloc$sourcefile$newline";
4388                    print FD "\t\$(MAKE_DEPEND_C) $targetOpts $srcdirloc$sourcefile >\$(DEPS_DIR)/$sourcebasename.d$newline";
4389                }
4390            }
4391        }
4392    }
4393
4394    if ($has_sources) {
4395        print FD "\$(DEPS_DIR)/timestamp: ";
4396        # FIXME: Create a single list of source files (remove duplicates)
4397        foreach $lib (keys(%libraries)) {
4398            $sourcefiles = $libraries{$lib};
4399            PrintMakeLongline( FD, "$sourcefiles ", "append" );
4400        }
4401        foreach $pgm (keys(%programs)) {
4402            print "Adding sources for $pgm to deps\n" if $debug;
4403            $sourcefiles = $programs{$pgm};
4404            PrintMakeLongline( FD, "$sourcefiles ", "append" );
4405        }
4406        # Add Makefile as a dependency, since changes in the Makefile
4407        # can change the dependencies (particularly different configure
4408        # choices)
4409        PrintMakeLongline( FD, "Makefile", "last" );
4410
4411        # We always use a "newalldeps" incase there is a failure
4412        # creating the new list of dependency files.
4413        print FD "\trm -f \$(DEPS_DIR)/newalldeps$newline";
4414        my %sawFile = ();
4415        foreach $lib (keys(%libraries)) {
4416            foreach $sourcefile (split(/\s+/,&ExpandMakeVars($libraries{$lib}))) {
4417                if (defined($sawFile{$sourcefile})) { next; }
4418                $sawFile{$sourcefile} = 1;
4419                my $srcdirloc = '$(srcdir)/';
4420                $ext = $sourcefile;
4421                $ext =~ s/^.*\.//g;
4422                $sourcebasename = $sourcefile;
4423                $sourcebasename =~ s/\.\w*$//;
4424                if ($ext eq "c") {
4425                    if (! -s $sourcefile) {
4426                        $srcdirloc = '';
4427                    }
4428                    $targetOpts = "-MT \'_$sourcebasename.o $sourcebasename.o\'";
4429                    if (!$found_profilelib) {
4430                        $targetOpts = "";
4431                    }
4432                    print FD "\t\$(MAKE_DEPEND_C) $targetOpts $srcdirloc$sourcefile >\$(DEPS_DIR)/$sourcebasename.d$newline";
4433                    print FD "\techo \"$makeInclude \$(DEPS_DIR)/$sourcebasename.d\" >>\$(DEPS_DIR)/newalldeps$newline";
4434                }
4435            }
4436        }
4437
4438        # Programs
4439        foreach $pgm (keys(%programs)) {
4440            foreach $sourcefile (split(/\s+/,$programs{$pgm})) {
4441                if (defined($sawFile{$sourcefile})) { next; }
4442                print "Adding deps command for program source $sourcefile\n" if $debug;
4443                $sawFile{$sourcefile} = 1;
4444                my $srcdirloc = '$(srcdir)/';
4445                $ext = $sourcefile;
4446                $ext =~ s/^.*\.//g;
4447                $sourcebasename = $sourcefile;
4448                $sourcebasename =~ s/\.\w*$//;
4449                if ($ext eq "c") {
4450                    if (! -s $sourcefile) {
4451                        $srcdirloc = '';
4452                    }
4453                    $targetOpts = "-MT \'_$sourcebasename.o $sourcebasename.o\'";
4454                    if (!$found_profilelib) {
4455                        $targetOpts = "";
4456                    }
4457                    print FD "\t\$(MAKE_DEPEND_C) $targetOpts $srcdirloc$sourcefile >\$(DEPS_DIR)/$sourcebasename.d$newline";
4458                    print FD "\techo \"$makeInclude \$(DEPS_DIR)/$sourcebasename.d\" >>\$(DEPS_DIR)/newalldeps$newline";
4459                }
4460            }
4461        }
4462
4463        print FD "\tif [ -s \$(DEPS_DIR)/newalldeps ] ; then mv -f \$(DEPS_DIR)/newalldeps \$(DEPS_DIR)/alldeps ; fi$newline";
4464        print FD "\tdate >\$(DEPS_DIR)/timestamp$newline";
4465
4466        print FD "$makeInclude \$(DEPS_DIR)/alldeps$newline";
4467    }
4468   
4469    print FD "# End of Dependencies$newline";
4470    print FD $makeBlockSep;
4471}
4472
4473sub DistCleanDependencies {
4474    # Eventually, this should output only in Makefiles that have the
4475    # dependencies directory
4476    print FD "\t-${quietLine}rm -rf \$(DEPS_DIR)$newline";
4477}
4478
4479# ===========================================================================
4480#
4481# Routines to support autoconf and configure, including extracting information
4482# from the configure file and rebuilding configure from configure.in
4483#
4484#
4485# Extract derived files from autoconf
4486# Also record whether there is an AC_CONFIG_HEADER
4487# If AC_OUTOUT contains any shell variables, you can use
4488#   <variable_name>_VALUES=vals
4489# (all on one line!) to provide the set of possible values.
4490# Otherwise, no special code will be generated for those output files,
4491# and a warning message will be issued.
4492# FIXME: the name is recorded and added to the files, but simplemake
4493# may not be careful about the file or about directory paths involving the
4494# xxx_VALUE variable.  Still experimental
4495sub ReadAutoconf {
4496    $configure_has_config_headers = "no";
4497    %confvars = ();
4498    open FDCONF, "configure.in" || die "Could not open configure.in file";
4499    while (<FDCONF>) {
4500        #if (/^\s*#/) { next; }
4501        if (/^\s*AC_CONFIG_HEADER\((.*)\)/) {
4502            # Record file name of header in result variable
4503            # We also need to add this to the list of files to remove
4504            # in the distclean target
4505            $configure_has_config_headers = $1;
4506        }
4507        if (/^\s*(\w*)_VALUES=(.*)/) {
4508            # This is a special case, used below
4509            $confvars{$1}=$2
4510        }
4511        if (/^\s*AC_OUTPUT\(/) {
4512            # First, read past all continued lines
4513            $line = "";
4514            # Remove any M4 dnl line
4515            s/\sdnl\s.*//;
4516            # Later versions of Autoconf do not require explicit continuation
4517            # so we also read until we find the closing paren
4518            while (/\\\s*$/) {
4519                s/\r?\n$//; # Removes eol on both Unix and Windows
4520                chop($_); # remove the backslash
4521                $line .= $_;
4522                $_ = <FDCONF>;
4523                die "unexpected EOF in configure.in, aborting" unless defined $_;
4524                # Remove any M4 dnl line
4525                s/\sdnl\s.*//;
4526                # Remove any shell comment line
4527                s/\s#.*//;
4528            }
4529            $line .= $_;
4530            $line =~ s/\r?\n$//; # Removes eol on both Unix and Windows
4531            $line =~ s/,.*/\)/;  # Changes a ,... to ) to handle
4532                                 # AC_OUTPUT(files...,[command]),
4533                                 # where the final ) may not be on this line
4534            #print $line;
4535            # If there's no closing paren yet, keep reading
4536            while (! ($line =~ /\)/)) {
4537                $_ = <FDCONF>;
4538                die "unexpected EOF in configure.in, aborting" unless defined $_;
4539                s/\r?\n$//; # Removes eol on both Unix and Windows
4540                # Remove any M4 dnl line
4541                s/\sdnl\s.*//;
4542                # Remove any shell comment line
4543                s/\s#.*//;
4544                $line .= $_ . " ";
4545            }
4546            #print "ac_output line = $line\n";
4547            $line =~ /^\s*AC_OUTPUT\((.*)\)\s*$/;
4548            $files = $1;
4549            if (! defined($files) ) {
4550                print STDERR "Unable to find file names in AC_OUTPUT\n";
4551                $files = "";
4552            }
4553            #print "files for ac_output = $files\n";
4554            @autoconf_files = split(/\s+/,$files);
4555            # Create a hash by directory
4556            # FIXME: Should curdir be blank by default?
4557            if (!$curdir) { $curdir = ""; }
4558            $lcurdir = $curdir;
4559            $lcurdir =~ s/\/$//;
4560            foreach $file (@autoconf_files) {
4561                if ($file =~ /^(.*)\/([^\/]*)$/) {
4562                    # File contains a directory path, so update the
4563                    # appropriate directory entry
4564                    my $ndir     = "$curdir$1";
4565                    my $leaffile = $2;
4566
4567                    if (defined($autoconf_files_by_dir{$ndir})) {
4568                        $autoconf_files_by_dir{$ndir} .= " $leaffile";
4569                    }
4570                    else {
4571                        $autoconf_files_by_dir{$ndir} = "$leaffile";
4572                    }
4573                    #print "{$ndir} .= $2\n";
4574                    # Also add files that are in directories with no simplemake
4575                    # input (e.g., in include directories with no makefile)
4576                    if (! -s "$ndir/Makefile.sm") {
4577                        if (defined($autoconf_files_by_dir{$lcurdir})) {
4578                            $autoconf_files_by_dir{$lcurdir} .= " $file";
4579                        }
4580                        else {
4581                            $autoconf_files_by_dir{$lcurdir} = "$file";
4582                        }
4583                    }
4584                    else {
4585                        # We also need to handle files that do have a
4586                        # Makefile.sm,
4587                        # but that aren't in the "usual" path.  Those
4588                        # are directories that are not included in the
4589                        # SUBDIRS path.  These are used only by the distclean
4590                        # target
4591                        $autoconf_files_by_dir_orig{$lcurdir} .= " $file";
4592                    }
4593                }
4594                elsif ($file =~ /^\$[\{\(]?(\w*)[\}\)]?/) {
4595                    # Another special case.  The name is actually
4596                    # a shell variable.  This is too hard for us right now,
4597                    # so generate a warning and do NOT add it to the list
4598                    # To handle this case, you can provide
4599                    # <variable-name>_VALUES
4600                    $varname = $1;
4601                    if (defined($confvars{$varname})) {
4602                        # add to autoconf_files_by_dir
4603                        foreach $filename (split(/\s+/,$confvars{$varname})) {
4604                            $autoconf_files_by_dir{$lcurdir} .= " $file";
4605                        }
4606                    }
4607                    else {
4608                        print STDERR "Shell variable $varname will not be added to the list\
4609of known autoconf files for ";
4610                        if (defined($lcurdir) && $lcurdir ne "") {
4611                            print STDERR "$lcurdir.\n";
4612                        }
4613                        else {
4614                            print STDERR "the top directory.\n";
4615                        }
4616                    }
4617                }
4618                elsif ($file =~ /^.*$/) {
4619                    if (defined($autoconf_files_by_dir{"$lcurdir"})) {
4620                        $autoconf_files_by_dir{"$lcurdir"} .= " $file";
4621                    }
4622                    else {
4623                        $autoconf_files_by_dir{"$lcurdir"} = "$file";
4624                    }
4625
4626                    #print "{$lcurdir} .= $file\n";
4627                }
4628            }
4629            # Add files that configure generates in the current directory
4630            $autoconf_files_by_dir{$lcurdir} .= " config.status config.log config.cache *conf.cache config.system";
4631            #print "$files\n";
4632            last;
4633        }
4634    }
4635    close FDCONF;
4636}
4637#
4638# Find how to get from path_child to path_parent.  Return as
4639# ../.. etc, suitable for using cd to get to the parent
4640sub GetPathToParent {
4641    my ($path_child, $path_parent) = @_;
4642    # Remove parent path from child path
4643    if (defined($path_parent)) {
4644        # first, deal with a possible "." path
4645        $path_parent = quotemeta $path_parent;
4646        #print "path_parent = $path_parent, child = $path_child\n";
4647        $path_child =~ s/^$path_parent//;
4648        #print "After parent, child = $path_child\n";
4649        # convert all of the non directory separators into ..
4650    }
4651    else {
4652        print STDERR "Path to parent is unknown in GetPathToParent\n";
4653        # Set a default
4654        $path_child = ".";
4655    }
4656    $path_child =~ s/[^\/\.]*\//..\//g;
4657    return $path_child;
4658}
4659
4660#
4661# Remove any trailing .. from the directory as well as that many directories
4662sub CleanCurDir {
4663    my $dir = $_[0];
4664    my $depth = 0;
4665
4666    # Handle any /.. at the end
4667    print "Cleaning directory name $dir...\n" if $debug_confdir;
4668    $dir =~ s/\/$//;
4669    while ($dir =~ /\/\.\.$/) {
4670        $depth++;
4671        $dir =~ s/\/\.\.$//;
4672    }
4673    while ($depth > 0) {
4674        $dir =~ s/\/[^\/]*//;
4675        $depth--;
4676    }
4677
4678    # We sometimes get ../ in the middle
4679    while ($dir =~ /(.*)\/[^\/\.]+\/\.\.(.*)/) {
4680        print "Changing $dir to $1$2\n" if $debug_confdir;
4681        $dir = "$1$2";
4682    }
4683    if ($dir ne "") { $dir .= "/"; }
4684    print "Cleaned directory name is $dir\n" if $debug_confdir;
4685    return "$dir";
4686}   
4687#
4688# ===========================================================================
4689# Pretty print output lines.  These routines insert line breaks and tabs
4690# to keep the generated makefile from being too ugly.  These also use
4691# tabs after a continuation line.
4692$linelen = 0;
4693sub printInit {
4694    $linelen = 0;
4695}
4696sub print_make_line {
4697    my $FD = $_[0];
4698    my $line = "$_[1]";
4699    my $len = length($line);
4700    if ($linelen + $len + 2 > $maxline) {
4701        print $FD "\\$newline\t";
4702        $linelen = 8;
4703    }
4704    print $FD $line;
4705    $linelen += $len;
4706    }
4707# print_make_line_nobreak is like print_make_line, but it never breaks a line
4708# This is needed when the output is a configure variable that may end
4709# up being replaced with blanks; if this occurs alone on a line, some
4710# make programs become confused.
4711sub print_make_line_nobreak {
4712    my $FD = $_[0];
4713    my $line = "$_[1]";
4714    my $len = length($line);
4715    print $FD $line;
4716    $linelen += $len;
4717    }
4718sub print_make_endline {
4719    my $FD = $_[0];
4720    print $FD $newline;
4721    $linelen = 0;
4722}
4723sub print_make_setpos {
4724    $linelen = $_[0];
4725}
4726# print_make_longline is intended for printing long lines that contains blanks
4727# This adds the newline at the end
4728sub print_make_longline {
4729    my $FD = $_[0];
4730    my $line = $_[1];
4731    &PrintMakeLongline( $FD, $line, "last" );
4732}
4733
4734# New print routines
4735# PrintMakeLongline( FD, line, flag ) - line may have spaces, will break
4736# as spaces in line.  Flag may be "append" or "last".  line may be empty
4737# (to use flag = "last" to terminate.
4738sub PrintMakeLongline {
4739    my $FD = $_[0];
4740    my $line = $_[1];
4741    my $flag = $_[2];
4742
4743    my $len = length( $line );
4744    if ($linelen + $len + 2 < $maxline) {
4745        print $FD $line;
4746    }
4747    else {
4748        # Use space, not \s, because we want tabs to remain tabs
4749        foreach my $token (split(/ /,$line)) {
4750            # We must be careful not to add a blank if the token is
4751            # a \ used at the end of a line to continue to the
4752            # next line
4753            if ($token eq "\\") {
4754                &print_make_line( $FD, "$token" );
4755            }
4756            else {
4757                &print_make_line( $FD, "$token " );
4758            }
4759        }
4760    }
4761    if ($flag eq "last") {
4762        &print_make_endline( $FD );
4763    }
4764}
4765# Print a Make variable definition only if it hasn't been made already
4766# Add and prepend value that may have been specified
4767sub printMakeVariable {
4768    my ($FD,$var,$definition) = @_;
4769
4770    if (!defined($addedMakeVars{$var})) {
4771        $addedMakeVars{$var} = $definition;
4772        if (defined($PrependVar{$var})) {
4773            $definition = $PrependVar{$var} . $definition;
4774        }
4775        my $nspace = 16 - length($var);
4776        my $blanks = "";
4777        while ($nspace > 0) { $blanks .= " "; $nspace-- }
4778        PrintMakeLongline( $FD, "$var$blanks= $definition", "last" );
4779    }
4780    elsif ($addedMakeVars{$var} ne $definition) {
4781        my $value = $addedMakeVars{$var};
4782        print STDERR "Variable $var, being defined with $definition, already has value $value\n";
4783    }
4784}
4785#
4786# Find a working autoconf.
4787# If the variables autoconf and autoconf_version are set, try to
4788# find one that works in the user's path.  The format for these
4789# variables is
4790#   autoconf = name:name:...:lasthope
4791#   autoconf_version = number
4792#   Check each autoconf name for handling version.  If all else fails,
4793#   unconditionally accept lasthope
4794sub FindWorkingAutoconf {
4795    if ($autoconf_version ne "") {
4796        foreach $file (split(/:/,$autoconf)) {
4797            $lastfile = $file;
4798            # Grumble.  I need to redirect stderr to stdout before this
4799            # open.  We use open with a pipe and then exec so that we
4800            # can get stderr redirection to work correctly.
4801            #
4802            # Additional grumble.  Perl doesn't flush output the
4803            # way you'd like.  Of course, if you turn on -debug,
4804            # things do get flushed.
4805            $pid = open( ACFD, "-|");
4806            if ($pid == 0) {
4807                close FD;  # without flushing
4808                open STDIN, "/dev/null";
4809                open STDERR, ">>&STDOUT";
4810                exec split(/\s+/,"$file --version");
4811            }
4812            else {
4813                $found_version = "";
4814                while (<ACFD>) {
4815                    print STDERR "$_" if $debug;
4816                    if (/[Aa]utoconf\s.*([12]\.[0-9]+)/) {
4817                        $found_version = $1;
4818                        last;
4819                    }
4820                }
4821                close( ACFD );
4822                print STDERR "Autoconf $file is version $found_version\n" if $debug;
4823                if ($found_version >= $autoconf_version) {
4824                    $autoconf = $file;
4825                    print STDERR "Using autoconf $file\n" if $debug;
4826                    return;
4827                }
4828            }
4829        }
4830        # If we got here, use the lastchance
4831        $autoconf = $lastfile;
4832    }
4833}
4834#
4835# ----------------------------------------------------------------------------
4836# Coverage analysis
4837# One useful target for package maintainers is coverage analysis. 
4838# The following code creates the targets for the gcc coverage analyzer,
4839# gcov.  In tests, this analyzer worked with programs built from libraries
4840# and with sources in multiple directories.
4841#
4842# To use the gcc coverage analyzer, the following steps must be taken
4843# 1.  All file must be compiled with -fprofile-arcs -ftest-coverage, and
4844#     without optimization
4845# 2.  Programs are run as usual
4846# 3.  To create coverage data, run
4847#         gcov -f -b sourcefile
4848#     over all source files.  The result is (for each sourcefile) a
4849#     new file, "sourcefile.gcov", which annotates the source file with
4850#     the number of times each statement was executed
4851#
4852# To add support for these, simplemake adds the following targets in
4853# maintenance target mode (e.g., not in the distributed version):
4854#     Add to clean (all with ${srcdir}) *.bb, *.bbg, *.da, *.c.gcov . 
4855#         These are all created by either gcc or by running programs
4856#         built with -ftest-coverage.
4857#     Add a recursive coverage target that does:
4858#         Run gcov on each source file (if any), where a .da file is present
4859#     We may be able to use a target like:
4860#         $*.c.gcov depends on $*.da (.da.gcov)
4861#     We let the configure step add the compiler options (so that a
4862#     separate simplemake build is not required to add or remove
4863#     coverage analysis.
4864#
4865# ToDo:
4866# In the install step, mkdir isn't right, since it will make only one
4867# directory level, and mkdir -p isn't universally available.  We probably
4868# need either a MKDIR_P command, determined byu configure, or an
4869# mkinstalldirs script.  I'd prefer a mkdirp script, used only if mkdir -p
4870# did not work, and chosen by configure in that case.
4871# This is partially done (MKDIR_P and that is set to mkdir -p)
4872# ----------------------------------------------------------------------------
4873# Add the clean target for the coverage analyzer.
4874# We inculde the local directory because, particularly for the test programs,
4875# these files may be left in the current directory rather than the source
4876# directory.
4877#
4878sub GcovClean {
4879    if ($maint_targets) {
4880        print FD "\t-${quietLine}rm -f \${srcdir}/*.bb \${srcdir}/*.bbg \${srcdir}/*.da$newline";
4881        print FD "\t-${quietLine}rm -f \${srcdir}/*.gcda \${srcdir}/*.gcno$newline";
4882        print FD "\t-${quietLine}rm -f *.gcov *.bb *.bbg *.da *.gcda *.gcno$newline";
4883    }
4884}
4885
4886# coverage target
4887sub TargetGcov {
4888    if (!$maint_targets) { return; }
4889    &TargetInit( "coverage" );
4890    print FD "$newline";
4891    foreach $lib (keys(%libraries)) {
4892        $sourcefiles = $libraries{$lib};
4893        PrintMakeLongline( FD,
4894           "\t-${quietmake}for file in $sourcefiles ; do \\", "last" );
4895        print FD "\t\tgcov -b -f \$\$file ; done$newline";
4896    }
4897    &RecursiveOp( "coverage" );
4898}
4899#
4900# ----------------------------------------------------------------------------
4901#
4902# ToDo
4903# Should we add a target to strip debugging information from the object files?
4904# For example, strip -S *.o .  Ths usually isn't necessary if -g is not
4905# selected when building the object files.
4906#
4907# David Ashton suggests an option to print a warning message for
4908# each source file (e.g., *.c, *.cxx, *.f, *.f90) that has no corresponding
4909# entry in the Makefile.sm
4910#
4911# Here is a start on that.
4912# What is still needed is a way to check for defined sources when the source
4913# files are named in a variable (e.g., xxx_SOURCE = ${foobar}, then we
4914# need to expand foobar.  This is not done systematically yet, in part
4915# because we want to preserve the use of variables in the Makefile.
4916sub checkForTargets {
4917    opendir DIR, ".";
4918    my $filename;
4919    my %knownExts = ( "c" => 1, "f" => 1, "f90" => 1, "cxx" => 1 );
4920    my %knownHeaders = ( "h" => 1, "i" => 1 );
4921    while ($filename = readdir DIR) {
4922        my $ext = "";
4923        if ($filename =~ /\.(\w+)$/) {
4924            $ext = $1;
4925        }
4926        if (defined($knownExts{$ext})) {
4927            # Found a source file.  Did we see this file in the source lists?
4928            if (! defined($sources{$filename})) {
4929                print STDERR "File $filename did not appear in $curdir/Makefile.sm\n";
4930            }
4931        }
4932        if (defined($knownHeaders{$ext})) {
4933            # Found a header file
4934            if (! defined($headers{$filename})) {
4935                print STDERR "File $filename did not appear in headers in $curdir/Makefile.sm\n";
4936