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

Revision 4827, 171.5 KB (checked in by kumudb, 5 months ago)

the static library gets generated conditionally.

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