root/juggler/branches/2.0_alpha_4/configure.pl

Revision 14519, 26.3 kB (checked in by patrickh, 4 years ago)

When generating the 'reconfig' script, ensure that the same Perl binary is
used to re-run configure.pl as was used to run it the first time. This is
helpful on platforms where multiple versions of Perl may be installed.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/env perl
2
3 # ************** <auto-copyright.pl BEGIN do not edit this line> **************
4 #
5 # VR Juggler is (C) Copyright 1998-2003 by Iowa State University
6 #
7 # Original Authors:
8 #   Allen Bierbaum, Christopher Just,
9 #   Patrick Hartling, Kevin Meinert,
10 #   Carolina Cruz-Neira, Albert Baker
11 #
12 # This library is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU Library General Public
14 # License as published by the Free Software Foundation; either
15 # version 2 of the License, or (at your option) any later version.
16 #
17 # This library is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 # Library General Public License for more details.
21 #
22 # You should have received a copy of the GNU Library General Public
23 # License along with this library; if not, write to the
24 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 # Boston, MA 02111-1307, USA.
26 #
27 # -----------------------------------------------------------------
28 # File:          $RCSfile$
29 # Date modified: $Date$
30 # Version:       $Revision$
31 # -----------------------------------------------------------------
32 #
33 # *************** <auto-copyright.pl END do not edit this line> ***************
34
35 use 5.005;
36
37 use strict 'vars';
38 use vars qw($base_dir $module $PRELUDE $FEATURE_ARGS $PACKAGE_ARGS $PROLOGUE
39             $LAST_ARG_GROUP $OS $Win32 $CFG_LOAD_FUNC);
40 use vars qw(%MODULES);
41
42 use Cwd qw(chdir getcwd);
43 use File::Basename;
44 use File::Path;
45 use Getopt::Long;
46 use Pod::Usage;
47
48 BEGIN
49 {
50    $base_dir = (fileparse("$0"))[1];
51 }
52
53 use lib("$base_dir");
54 use JugglerConfigure;
55
56 # Subroutine prototypes.
57 sub mergeArgArrays($$);
58 sub loadDefaultArgs($);
59 sub configureModule($);
60 sub regenModuleInfo($);
61 sub generateMakefile(;$);
62 sub generateReconfig($@);
63 sub listModules();
64 sub printHelp();
65 sub getConfigureHelp($$);
66 sub parseOutput($$);
67 sub getPlatform();
68 sub getRelativePath($$);
69
70 %MODULES = ();
71
72 my $all_help      = 0;
73 my $cfg           = "juggler.cfg";
74 my $user_cfg      = '';
75 $module           = '';
76 my $script_help   = 0;
77 my $manual        = 0;
78 my $regen         = 0;
79 my $mod_list      = 0;
80 my $args_file     = 'acdefaults.cfg';
81 my $args_mod_file = 'acdefaults.pl';
82 my $user_args     = '';
83 my $user_args_mod = '';
84 my $no_user_args  = 0;
85
86 $PRELUDE        = 0;
87 $FEATURE_ARGS   = 1;
88 $PACKAGE_ARGS   = 2;
89 $PROLOGUE       = 3;
90 $LAST_ARG_GROUP = 4;
91
92 $CFG_LOAD_FUNC = undef;
93 $OS            = '';
94
95 my @save_argv = @ARGV;
96
97 Getopt::Long::Configure('pass_through');
98 GetOptions('help|?' => \$script_help, 'cfg=s' => \$user_cfg,
99            'module=s' => \$module, 'all-help' => \$all_help,
100            'manual' => \$manual, 'regen' => \$regen, 'modlist' => \$mod_list,
101            'args=s' => \$user_args, 'argsmod=s' => \$user_args_mod,
102            'noargs' => \$no_user_args, 'os=s' => \$OS)
103    or pod2usage(2);
104
105 # Print the help output and exit if --help was on the command line.
106 pod2usage(1) if $script_help;
107 pod2usage(-exitstatus => 0, -verbose => 2) if $manual;
108
109 die "ERROR: No configuration given\n" unless $cfg || $user_cfg;
110
111 $Win32 = 1 if $ENV{'OS'} && $ENV{'OS'} =~ /Windows/;
112
113 # On Windows, the command-line arguments can confuse the Cygwin shell.  For
114 # example, the character used to separate paths is ';', but the shell sees
115 # that as a statement separator.  We can deal with this by ensuring that the
116 # shell interprets command-line arguments as literal strings (i.e., by
117 # putting quotes around each argument).
118 if ( $Win32 )
119 {
120    die "Absolute Cygwin paths confuse Visual C++.  Use a relative path.\n"
121       if $0 =~ /^\//;
122
123    for ( my $i = 0; $i <= $#save_argv; $i++ )
124    {
125       $save_argv[$i] = "\"$save_argv[$i]\"";
126    }
127
128    for ( my $i = 0; $i <= $#ARGV; $i++ )
129    {
130       $ARGV[$i] = "\"$ARGV[$i]\"";
131    }
132 }
133
134 my $cfg_load = ("$user_cfg" eq "") ? "$base_dir/$cfg" : "$user_cfg";
135 %MODULES = JugglerConfigure::parseConfigFile("$cfg_load");
136
137 listModules() && exit(0) if $mod_list;
138 printHelp() && exit(0) if $all_help;
139
140 if ( $regen )
141 {
142    if ( $module )
143    {
144       die "ERROR: No such module $module in $cfg!\n"
145          unless defined($MODULES{"$module"});
146
147       regenModuleInfo("$module");
148       generateMakefile("$module");
149    }
150    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
151            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
152    {
153       regenModuleInfo("$JugglerConfigure::DEFAULT_MODULE");
154       generateMakefile("$JugglerConfigure::DEFAULT_MODULE");
155    }
156    else
157    {
158       foreach ( keys(%MODULES) )
159       {
160          regenModuleInfo("$_");
161       }
162
163       generateMakefile();
164    }
165 }
166 else
167 {
168    my $cache_file_set = 0;
169
170    foreach ( @ARGV )
171    {
172       if ( /-cache-f/ )
173       {
174          $cache_file_set = 1;
175          last;
176       }
177    }
178
179    # Unless the user passed --noargs, try to find default argument values.
180    unless ( $no_user_args )
181    {
182       my $args_mod = ("$user_args_mod" eq "") ? "$base_dir/$args_mod_file"
183                                               : "$user_args_mod";
184
185       # Figure out what argument file to load, if any.  If the user specified
186       # a file name on the command line, it will be in $user_args.  Otherwise,
187       # we fall back on $base_dir/$args_file.
188       my $args_load = ("$user_args" eq "") ? "$base_dir/$args_file"
189                                            : "$user_args";
190
191       if ( -r "$args_mod" )
192       {
193          require "$args_mod";
194
195          if ( $CFG_LOAD_FUNC )
196          {
197             my @default_args = &$CFG_LOAD_FUNC();
198             mergeArgArrays(\@ARGV, \@default_args);
199          }
200       }
201       elsif ( -r "$args_load" )
202       {
203          loadDefaultArgs("$args_load");
204       }
205    }
206
207    if ( ! $cache_file_set )
208    {
209       my $cwd = getcwd();
210       push(@ARGV, "--cache-file=$cwd/config.cache");
211    }
212
213    # Configure the module named on the command line.
214    if ( $module )
215    {
216       die "ERROR: No such module $module in $cfg!\n"
217          unless defined($MODULES{"$module"});
218
219       generateReconfig("$module", @save_argv);
220       configureModule("$module");
221       generateMakefile("$module");
222    }
223    # If no module was named on the command line but we do have a default
224    # module, configure it.
225    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
226            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
227    {
228       generateReconfig("$JugglerConfigure::DEFAULT_MODULE", @save_argv);
229       configureModule("$JugglerConfigure::DEFAULT_MODULE");
230       generateMakefile("$JugglerConfigure::DEFAULT_MODULE");
231    }
232    # If neither of the above will do, just configure every module we know
233    # about from the input file.
234    else
235    {
236       generateReconfig('', @save_argv);
237
238       foreach ( keys(%MODULES) )
239       {
240          configureModule("$_");
241       }
242
243       generateMakefile();
244    }
245 }
246
247 exit(0);
248
249 # =============================================================================
250 # Subroutines follow.
251 # =============================================================================
252
253 sub mergeArgArrays ($$)
254 {
255    my $dest_list   = shift;
256    my $source_list = shift;
257
258    foreach ( @$source_list )
259    {
260       # Strip leading and trailing whitespace.
261       s/^\s+//;
262       s/\s+$//;
263       next if /^$/;   # Just to be safe...
264       
265       # Only add the argument if it is not already on the command line.
266       m/^(--[^=]+)/;
267       push(@$dest_list, "$_") unless grep(/$1/, @$dest_list);
268    }
269 }
270
271 sub loadDefaultArgs ($)
272 {
273    my $args_load = shift;
274
275    if ( open(ARGS_FILE, "$args_load") )
276    {
277       print "Loading default arguments from $args_load ...\n";
278       my $args_contents = '';
279
280       while ( <ARGS_FILE> )
281       {
282          s/#.*$//;           # Strip comments
283          next if /^\s*$/;    # Skip blank lines
284          $args_contents .= "$_";
285       }
286
287       close(ARGS_FILE) or warn "WARNING: Could not close $args_load: $!\n";
288
289       my $platform = getPlatform();
290
291       while ( "$args_contents" ne '' )
292       {
293          my @args_list = ();
294
295          # Read in the arguments for all platforms.
296          if ( $args_contents =~ /^\s*all\s*{(.+?)}\s*/si )
297          {
298             @args_list     = split(m|$/|, "$1");
299             $args_contents = $';
300          }
301          # Read in the arguments for the current platform.
302          elsif ( $args_contents =~ /^\s*$platform\s*{(.+?)}\s*/sio )
303          {
304             @args_list     = split(m|$/|, "$1");
305             $args_contents = $';
306          }
307          # Skip a platform that does not match $platform.
308          elsif ( $args_contents =~ /^\s*(\S+)\b\s*{(.+?)}\s*/s )
309          {
310             print "Skipping $1\n";
311             $args_contents = $';
312          }
313
314          mergeArgArrays(\@ARGV, \@args_list);
315       }
316    }
317    else
318    {
319       warn "WARNING: Coult not read from $args_load: $!\n";
320    }
321 }
322
323 sub configureModule ($)
324 {
325    my $module_name = shift;
326
327    my $cwd = getcwd();
328    my $safe_cwd;
329
330    if ( $Win32 )
331    {
332       $safe_cwd = `cygpath -w $cwd`;
333       chomp($safe_cwd);
334       $safe_cwd =~ s/\\/\//g;
335    }
336    else
337    {
338       $safe_cwd = "$cwd";
339    }
340
341    die "ERROR: No module $module_name defined\n"
342       unless defined($MODULES{"$module_name"});
343
344    # Use ksh to run configure if we are on Solaris.  Otherwise, use sh
345    my $shell = ((getPlatform() =~ /solaris/i) ? 'ksh' : '/bin/sh');
346
347    my $depencency;
348    foreach $depencency ( $MODULES{"$module_name"}->getDependencies() )
349    {
350       my $mod_path = $depencency->getPath();
351
352       mkpath("$mod_path", 1, 0755) unless -d "$mod_path";
353
354       # Do not try to proceed with $dependency unless we can chdir to
355       # $mod_path.
356       unless ( chdir("$mod_path") )
357       {
358          warn "WARNING: Could not chdir to $mod_path: $!\n";
359          next;
360       }
361
362       my $src_root;
363
364       # Dependeing on the value of $base_dir, assign $src_root such that it
365       # is an absolute path.
366       # XXX: This creates a problem on Win32 with $(srcdir) in generated
367       # makefiles!  Win32 utilities will not understand the Cygwin path, but
368       # they would understand a relative path...
369       if ( $base_dir =~ /^\// )
370       {
371          $src_root = "$base_dir";
372       }
373       else
374       {
375          $src_root = "$cwd/$base_dir";
376       }
377
378       # Ensure $src_root isn't terminated with a '/'.
379       $src_root =~ s/\/$//;
380
381       # If we're being run in Win32, force a relative path for $src_root
382       my $cfg_exec = "$src_root/$mod_path/configure";
383       if ($Win32)
384       {
385          $cfg_exec = getRelativePath(getcwd(), $cfg_exec);
386       }
387
388       print "Running $shell $cfg_exec @ARGV\n";
389       system("$shell $cfg_exec @ARGV 2>&1") == 0
390          or die "Configuration of $module_name in $ENV{'PWD'} failed\n" .
391                 "Check $ENV{'PWD'}/config.log for details\n";
392
393       my %mod_env = $depencency->getEnvironment();
394       foreach ( keys(%mod_env) )
395       {
396          my $env_val = $depencency->getEnvironmentValue($_);
397
398          if ( /_CONFIG$/ )
399          {
400             $ENV{"$_"}    = "$cwd/$mod_path/$env_val";
401             $ENV{'PATH'} .= ":$cwd/$mod_path";
402          }
403          elsif ( /_BASE_DIR$/ )
404          {
405             if ( "$env_val" eq "instlinks" )
406             {
407                $ENV{"$_"} = "$safe_cwd/instlinks";
408             }
409             else
410             {
411                $ENV{"$_"} = "$env_val";
412             }
413          }
414          else
415          {
416             $ENV{"$_"} = "$env_val";
417          }
418       }
419
420       $ENV{'USE_BASE_DIR'} = 'yes';
421
422       chdir("$cwd");
423    }
424 }
425
426 sub regenModuleInfo ($)
427 {
428    my $module_name = shift;
429
430    my $cwd = getcwd();
431
432    die "ERROR: No module $module_name defined\n"
433       unless defined($MODULES{"$module_name"});
434
435    my $depencency;
436    foreach $depencency ( $MODULES{"$module_name"}->getDependencies() )
437    {
438       my $mod_path = $depencency->getPath();
439
440       chdir("$mod_path")
441          or die "WARNING: Could not chdir to $mod_path\n";
442       system("./config.status 2>&1") == 0
443          or die "Regeneration for $module_name in $ENV{'PWD'} failed\n";
444       chdir("$cwd");
445    }
446 }
447
448 sub generateMakefile (;$)
449 {
450    my $gen_module = shift || '';
451
452    open(INPUT, "$base_dir/Makefile.in")
453       or die "ERROR: Could not read from $base_dir/Makefile.in: $!\n";
454
455    my $input_file;
456    while ( <INPUT> )
457    {
458       $input_file .= "$_";
459    }
460
461    close(INPUT);
462
463    my $modules;
464    my @module_array;
465
466    if ( $gen_module )
467    {
468       foreach ( $MODULES{"$gen_module"}->getDependencies() )
469       {
470          $modules .= $_->getPath() . " ";
471       }
472    }
473    else
474    {
475       my $mod_name;
476       foreach $mod_name ( keys(%MODULES) )
477       {
478          my $temp_mod;
479          foreach $temp_mod ( $MODULES{"$mod_name"}->getDependencies() )
480          {
481             $modules .= $temp_mod->getPath() . " ";
482          }
483       }
484    }
485
486    warn "WARNING: No modules defined!\n" unless $modules;
487
488    my $cwd = getcwd();
489    chdir("$base_dir");
490    $input_file =~ s/\@JUGGLER_PROJECTS\@/$modules/g;
491
492    if ( $Win32 )
493    {
494       # Get the Win32-friendly versions of these paths.  Then change the \'s
495       # to /'s just to be safe.
496       my $win_pwd = `cygpath -w $ENV{'PWD'}`;
497       my $win_cwd = `cygpath -w $cwd`;
498       chomp($win_pwd);
499       chomp($win_cwd);
500
501       $win_pwd =~ s/\\/\//g;
502       $win_cwd =~ s/\\/\//g;
503
504       $input_file =~ s/\@JUGGLERROOT_ABS\@/$win_pwd/g;
505       $input_file =~ s/\@topdir\@/$win_cwd/g;
506    }
507    else
508    {
509       $input_file =~ s/\@JUGGLERROOT_ABS\@/$ENV{'PWD'}/g;
510       $input_file =~ s/\@topdir\@/$cwd/g;
511    }
512
513    chdir("$cwd");
514
515    print "Generating Makefile\n";
516    open(OUTPUT, "> Makefile") or die "ERROR: Could not create Makefile: $!\n";
517    print OUTPUT "$input_file";
518    close(OUTPUT) or warn "WARNING: Failed to save Makefile: $!\n";
519 }
520
521 sub generateReconfig ($@)
522 {
523    my $gen_module = shift;
524    my @arg_list   = @_;
525
526    my $modules;
527
528    open(RECONFIG, "> reconfig");
529
530    if ( $gen_module )
531    {
532       foreach ( $MODULES{"$gen_module"}->getDependencies() )
533       {
534          print RECONFIG "(cd " . $_->getPath() . " && rm -f config.status " .
535                         "config.cache config.log)\n"
536       }
537    }
538    else
539    {
540       my $mod_name;
541       foreach $mod_name ( keys(%MODULES) )
542       {
543          foreach ( $MODULES{"$mod_name"}->getDependencies() )
544          {
545             print RECONFIG "(cd " . $_->getPath() . " && rm -f config.status " .
546                            "config.cache config.log)\n"
547          }
548       }
549    }
550
551    print RECONFIG "rm -f config.cache\n";
552
553    # Print the command to run this script again.  The actual output will be
554    # the exec shell command followed by the full path to the Perl
555    # interpreter used to run this script; the same path to the script that
556    # the user entered; and the full argument list given on the command line.
557    print RECONFIG "exec $^X $0 ", "@arg_list \n";
558    close(RECONFIG);
559    chmod(0755, "reconfig");
560 }
561
562 sub listModules ()
563 {
564    my $mod_name;
565    foreach $mod_name ( keys(%MODULES) )
566    {
567       print "$mod_name";
568
569 #      if ( $#{$MODULES{"$mod_name"}} != -1 )
570 #      {
571 #         print " (Requires:";
572 #
573 #         my $dep_ref;
574 #         foreach $dep_ref ( @{$MODULES{"$mod_name"}} )
575 #         {
576 #            print " ${$dep_ref}{'path'}";
577 #         }
578 #
579 #         print ")";
580 #      }
581
582       print "\n";
583    }
584
585    return 1;
586 }
587
588 sub printHelp ()
589 {
590    my @help_output = ();
591
592    # Initialize the references that are contained within @help_output.
593    my $i;
594    for ( $i = 0; $i < $LAST_ARG_GROUP; $i++ )
595    {
596       $help_output[$i] = {};
597    }
598
599    if ( $module )
600    {
601       getConfigureHelp("$module", \@help_output);
602    }
603    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
604            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
605    {
606       getConfigureHelp("$JugglerConfigure::DEFAULT_MODULE", \@help_output);
607    }
608    else
609    {
610       foreach ( keys(%MODULES) )
611       {
612          getConfigureHelp("$_", \@help_output);
613       }
614    }
615
616    for ( $i = 0; $i < $LAST_ARG_GROUP; $i++ )
617    {
618       SWITCH:
619       {
620          if ( $i == $PRELUDE )
621          {
622             last SWITCH;
623          }
624
625          if ( $i == $FEATURE_ARGS )
626          {
627             print "Optional Features:\n";
628             last SWITCH;
629          }
630
631          if ( $i == $PACKAGE_ARGS )
632          {
633             print "\nOptional Packages:\n";
634             last SWITCH;
635          }
636
637          if ( $i == $PROLOGUE )
638          {
639             print "\n";
640             last SWITCH;
641          }
642       }
643
644       foreach ( sort(keys(%{$help_output[$i]})) )
645       {
646          print "${$help_output[$i]}{$_}";
647       }
648    }
649
650    print "\n";
651
652    print "Modules that may be built:\n";
653    foreach ( keys(%MODULES) )
654    {
655       print "\t$_\n";
656    }
657
658    print "\nDefault module is $JugglerConfigure::DEFAULT_MODULE\n"
659       if $JugglerConfigure::DEFAULT_MODULE;
660
661    return 1;
662 }
663
664 sub getConfigureHelp ($$)
665 {
666    my $mod_name    = shift;
667    my $arg_arr_ref = shift;
668
669    foreach ( $MODULES{"$mod_name"}->getDependencies() )
670    {
671       next unless -x "$base_dir/$$_{'path'}/configure";
672
673       open(CFG_OUTPUT, "$base_dir/$$_{'path'}/configure --help |");
674
675       my $cfg_output;
676       while ( <CFG_OUTPUT> )
677       {
678          $cfg_output .= "$_";
679       }
680
681       close(CFG_OUTPUT);
682
683       parseOutput("$cfg_output", $arg_arr_ref);
684    }
685 }
686
687 sub parseOutput ($$)
688 {
689    my $string      = shift;
690    my $arg_arr_ref = shift;
691
692    while ( $string !~ /^\s*$/s )
693    {
694       # Match everything up to the list of optional features.  This forms the
695       # prelude of the help output.
696       if ( $string =~ /^(Usage:.*)(Optional Features:)/s )
697       {
698          $string = "$2$'";
699          ${$$arg_arr_ref[$PRELUDE]}{'all'} = "$1";
700       }
701       # Handle the --enable and --disable list of options.
702       elsif ( $string =~ /^(Optional Features:.*)(Optional Packages:)/s )
703       {
704          $string = "$2$'";
705
706          my @param_list = split(/\n/, "$1");
707
708          # Loop over all the lines of output in the "Optional Features" block.
709          my $i;
710          for ( $i = 0; $i <= $#param_list; $i++ )
711          {
712             if ( $param_list[$i] =~ /(--(enable|disable)\S+)/ )
713             {
714                my $param = "$1";
715
716                # If $param does not exist in the hash of feature arguments,
717                # we need to add it.
718                if ( ! exists(${$$arg_arr_ref[$FEATURE_ARGS]}{"$param"}) )
719                {
720                   # Add the first line of information for $param.
721                   my $param_info = "$param_list[$i]\n";
722
723                   # If the following lines are a continuation of the info for
724                   # $param, add them to $param_info as well.
725                   while ( $i + 1 <= $#param_list &&
726                           $param_list[$i + 1] !~ /--(enable|disable)/ )
727                   {
728                      $param_info .= "$param_list[$i + 1]\n";
729                      $i++;
730                   }
731
732                   # Store the complete information block for $param.
733                   ${$$arg_arr_ref[$FEATURE_ARGS]}{"$param"} = "$param_info";
734                }
735             }
736          }
737       }
738       # Handle the --with and --without list of options.
739       elsif ( $string =~ /^(Optional Packages:.*)(Some influential)/s )
740       {
741          $string = "$2$'";
742
743          my @param_list = split(/\n/, "$1");
744
745          # Loop over all the lines of output in the "Optional Packages" block.
746          my $i;
747          for ( $i = 0; $i <= $#param_list; $i++ )
748          {
749             if ( $param_list[$i] =~ /(--with\S+)/ )
750             {
751                my $param = "$1";
752
753                # If $param does not exist in the hash of package arguments,
754                # we need to add it.
755                if ( ! exists(${$$arg_arr_ref[$PACKAGE_ARGS]}{"$param"}) )
756                {
757                   # Add the first line of information for $param.
758                   my $param_info = "$param_list[$i]\n";
759
760                   # If the following lines are a continuation of the info for
761                   # $param, add them to $param_info as well.
762                   while ( $i + 1 <= $#param_list &&
763                           $param_list[$i + 1] !~ /--with/ )
764                   {
765                      $param_info .= "$param_list[$i + 1]\n";
766                      $i++;
767                   }
768
769                   # Store the complete information block for $param.
770                   ${$$arg_arr_ref[$PACKAGE_ARGS]}{"$param"} = "$param_info";
771                }
772             }
773          }
774       }
775       # We'll keep everything after the line beginning with "Some influential"
776       # to form the prologue of the help output.
777       elsif ( $string =~ /^(Some influential.*)$/s )
778       {
779          $string = "$'";   # This should be the empty string.
780          ${$$arg_arr_ref[$PROLOGUE]}{'all'} = "$1";
781       }
782       # Match anything else and strip it from the output.
783       elsif ( $string =~ /^.*$/m )
784       {
785          $string = $';
786       }
787
788       $string =~ s/^\s*//s;
789    }
790 }
791
792 sub getPlatform ()
793 {
794    my $platform = "unknown";
795
796    # Prefer the user-defined platform type over any auto-detected value.
797    if ( "$OS" ne '' )
798    {
799       $platform = "$OS";
800    }
801    elsif ( defined($ENV{'OS'}) )
802    {
803       $platform = "$ENV{'OS'}";
804    }
805    elsif ( defined($ENV{'OSTYPE'}) )
806    {
807       $platform = "$ENV{'OSTYPE'}";
808    }
809    elsif ( defined($ENV{'OS_TYPE'}) )
810    {
811       $platform = "$ENV{'OS_TYPE'}";
812    }
813    elsif ( defined($ENV{'HOSTTYPE'}) )
814    {
815       $platform = "$ENV{'HOSTTYPE'}";
816    }
817    # As a last resort, fall back on the use of uname(1).
818    else
819    {
820       chomp($platform = `uname -s`);
821    }
822
823    # XXX: This is a hack to deal with weird OS strings such as "linux-gnu".
824    # We just make the platform be "linux" unless the user set the platform
825    # type on the command line.
826    $platform = 'linux' if ! $OS && $platform =~ /linux/i;
827
828    return $platform;
829 }
830
831 sub getHostname ()
832 {
833    my $hostname = '';
834
835    if ( defined($ENV{'HOSTNAME'}) )