root/juggler/tags/1.1_dr_3/configure.pl

Revision 10914, 23.7 kB (checked in by anonymous, 6 years ago)

This commit was manufactured by cvs2svn to create tag
'VRJ_DEV_RELEASE_3'.

  • 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-2002 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 $CONFIG_ARGS $PATH_ARGS $HOST_ARGS $FEATURE_ARGS
39             $CUSTOM_ARGS $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 $CONFIG_ARGS    = 0;
87 $PATH_ARGS      = 1;
88 $HOST_ARGS      = 2;
89 $FEATURE_ARGS   = 3;
90 $CUSTOM_ARGS    = 4;
91 $LAST_ARG_GROUP = 5;
92
93 $CFG_LOAD_FUNC = undef;
94 $OS            = '';
95
96 my @save_argv = @ARGV;
97
98 Getopt::Long::Configure('pass_through');
99 GetOptions('help|?' => \$script_help, 'cfg=s' => \$user_cfg,
100            'module=s' => \$module, 'all-help' => \$all_help,
101            'manual' => \$manual, 'regen' => \$regen, 'modlist' => \$mod_list,
102            'args=s' => \$user_args, 'argsmod=s' => \$user_args_mod,
103            'noargs' => \$no_user_args, 'os=s' => \$OS)
104    or pod2usage(2);
105
106 # Print the help output and exit if --help was on the command line.
107 pod2usage(1) if $script_help;
108 pod2usage(-exitstatus => 0, -verbose => 2) if $manual;
109
110 die "ERROR: No configuration given\n" unless $cfg || $user_cfg;
111
112 $Win32 = 1 if $ENV{'OS'} && $ENV{'OS'} =~ /Windows/;
113
114 my $cfg_load = ("$user_cfg" eq "") ? "$base_dir/$cfg" : "$user_cfg";
115 %MODULES = JugglerConfigure::parseConfigFile("$cfg_load");
116
117 listModules() && exit(0) if $mod_list;
118 printHelp() && exit(0) if $all_help;
119
120 if ( $regen )
121 {
122    if ( $module )
123    {
124       die "ERROR: No such module $module in $cfg!\n"
125          unless defined($MODULES{"$module"});
126
127       regenModuleInfo("$module");
128       generateMakefile("$module");
129    }
130    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
131            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
132    {
133       regenModuleInfo("$JugglerConfigure::DEFAULT_MODULE");
134       generateMakefile("$JugglerConfigure::DEFAULT_MODULE");
135    }
136    else
137    {
138       foreach ( keys(%MODULES) )
139       {
140          regenModuleInfo("$_");
141       }
142
143       generateMakefile();
144    }
145 }
146 else
147 {
148    my $cache_file_set = 0;
149
150    foreach ( @ARGV )
151    {
152       if ( /-cache-f/ )
153       {
154          $cache_file_set = 1;
155          last;
156       }
157    }
158
159    # Unless the user passed --noargs, try to find default argument values.
160    unless ( $no_user_args )
161    {
162       my $args_mod = ("$user_args_mod" eq "") ? "$base_dir/$args_mod_file"
163                                               : "$user_args_mod";
164
165       # Figure out what argument file to load, if any.  If the user specified
166       # a file name on the command line, it will be in $user_args.  Otherwise,
167       # we fall back on $base_dir/$args_file.
168       my $args_load = ("$user_args" eq "") ? "$base_dir/$args_file"
169                                            : "$user_args";
170
171       if ( -r "$args_mod" )
172       {
173          require "$args_mod";
174
175          if ( $CFG_LOAD_FUNC )
176          {
177             my @default_args = &$CFG_LOAD_FUNC();
178             mergeArgArrays(\@ARGV, \@default_args);
179          }
180       }
181       elsif ( -r "$args_load" )
182       {
183          loadDefaultArgs("$args_load");
184       }
185    }
186
187    if ( ! $cache_file_set )
188    {
189       my $cwd = getcwd();
190       push(@ARGV, "--cache-file=$cwd/config.cache");
191    }
192
193    # Configure the module named on the command line.
194    if ( $module )
195    {
196       die "ERROR: No such module $module in $cfg!\n"
197          unless defined($MODULES{"$module"});
198
199       generateReconfig("$module", @save_argv);
200       configureModule("$module");
201       generateMakefile("$module");
202    }
203    # If no module was named on the command line but we do have a default
204    # module, configure it.
205    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
206            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
207    {
208       generateReconfig("$JugglerConfigure::DEFAULT_MODULE", @save_argv);
209       configureModule("$JugglerConfigure::DEFAULT_MODULE");
210       generateMakefile("$JugglerConfigure::DEFAULT_MODULE");
211    }
212    # If neither of the above will do, just configure every module we know
213    # about from the input file.
214    else
215    {
216       generateReconfig('', @save_argv);
217
218       foreach ( keys(%MODULES) )
219       {
220          configureModule("$_");
221       }
222
223       generateMakefile();
224    }
225 }
226
227 exit(0);
228
229 # =============================================================================
230 # Subroutines follow.
231 # =============================================================================
232
233 sub mergeArgArrays ($$)
234 {
235    my $dest_list   = shift;
236    my $source_list = shift;
237
238    foreach ( @$source_list )
239    {
240       # Strip leading and trailing whitespace.
241       s/^\s+//;
242       s/\s+$//;
243       next if /^$/;   # Just to be safe...
244       
245       # Only add the argument if it is not already on the command line.
246       m/^(--[^=]+)/;
247       push(@$dest_list, "$_") unless grep(/$1/, @$dest_list);
248    }
249 }
250
251 sub loadDefaultArgs ($)
252 {
253    my $args_load = shift;
254
255    if ( open(ARGS_FILE, "$args_load") )
256    {
257       print "Loading default arguments from $args_load ...\n";
258       my $args_contents = '';
259
260       while ( <ARGS_FILE> )
261       {
262          s/#.*$//;           # Strip comments
263          next if /^\s*$/;    # Skip blank lines
264          $args_contents .= "$_";
265       }
266
267       close(ARGS_FILE) or warn "WARNING: Could not close $args_load: $!\n";
268
269       my $platform = getPlatform();
270
271       while ( "$args_contents" ne '' )
272       {
273          my @args_list = ();
274
275          # Read in the arguments for all platforms.
276          if ( $args_contents =~ /^\s*all\s*{(.+?)}\s*/si )
277          {
278             @args_list     = split(m|$/|, "$1");
279             $args_contents = $';
280          }
281          # Read in the arguments for the current platform.
282          elsif ( $args_contents =~ /^\s*$platform\s*{(.+?)}\s*/sio )
283          {
284             @args_list     = split(m|$/|, "$1");
285             $args_contents = $';
286          }
287          # Skip a platform that does not match $platform.
288          elsif ( $args_contents =~ /^\s*(\S+)\b\s*{(.+?)}\s*/s )
289          {
290             print "Skipping $1\n";
291             $args_contents = $';
292          }
293
294          mergeArgArrays(\@ARGV, \@args_list);
295       }
296    }
297    else
298    {
299       warn "WARNING: Coult not read from $args_load: $!\n";
300    }
301 }
302
303 sub configureModule ($)
304 {
305    my $module_name = shift;
306
307    my $cwd = getcwd();
308    my $safe_cwd;
309
310    if ( $Win32 )
311    {
312       $safe_cwd = `cygpath -w $cwd`;
313       chomp($safe_cwd);
314       $safe_cwd =~ s/\\/\//g;
315    }
316    else
317    {
318       $safe_cwd = "$cwd";
319    }
320
321    die "ERROR: No module $module_name defined\n"
322       unless defined($MODULES{"$module_name"});
323
324    # Use ksh to run configure if we are on Solaris.  Otherwise, use sh
325    my $shell = ((getPlatform() =~ /solaris/i) ? 'ksh' : '/bin/sh');
326
327    my $depencency;
328    foreach $depencency ( $MODULES{"$module_name"}->getDependencies() )
329    {
330       my $mod_path = $depencency->getPath();
331
332       mkpath("$mod_path", 1, 0755) unless -d "$mod_path";
333
334       # Do not try to proceed with $dependency unless we can chdir to
335       # $mod_path.
336       unless ( chdir("$mod_path") )
337       {
338          warn "WARNING: Could not chdir to $mod_path: $!\n";
339          next;
340       }
341
342       my $src_root;
343
344       # Dependeing on the value of $base_dir, assign $src_root such that it
345       # is an absolute path.
346       # XXX: This creates a problem on Win32 with $(srcdir) in generated
347       # makefiles!  Win32 utilities will not understand the Cygwin path, but
348       # they would understand a relative path...
349       if ( $base_dir =~ /^\// )
350       {
351          $src_root = "$base_dir";
352       }
353       else
354       {
355          $src_root = "$cwd/$base_dir";
356       }
357
358       # Ensure $src_root isn't terminated with a '/'.
359       $src_root =~ s/\/$//;
360
361       # If we're being run in Win32, force a relative path for $src_root
362       my $cfg_exec = "$src_root/$mod_path/configure";
363       if ($Win32)
364       {
365          $cfg_exec = getRelativePath(getcwd(), $cfg_exec);
366       }
367
368       print "Running $shell $cfg_exec @ARGV\n";
369       system("$shell $cfg_exec @ARGV 2>&1") == 0
370          or die "Configuration of $module_name in $ENV{'PWD'} failed\n" .
371                 "Check $ENV{'PWD'}/config.log for details\n";
372
373       my %mod_env = $depencency->getEnvironment();
374       foreach ( keys(%mod_env) )
375       {
376          my $env_val = $depencency->getEnvironmentValue($_);
377
378          if ( /_CONFIG$/ )
379          {
380             $ENV{"$_"}    = "$cwd/$mod_path/$env_val";
381             $ENV{'PATH'} .= ":$cwd/$mod_path";
382          }
383          elsif ( /_BASE_DIR$/ )
384          {
385             if ( "$env_val" eq "instlinks" )
386             {
387                $ENV{"$_"} = "$safe_cwd/instlinks";
388             }
389             else
390             {
391                $ENV{"$_"} = "$env_val";
392             }
393          }
394          else
395          {
396             $ENV{"$_"} = "$env_val";
397          }
398       }
399
400       $ENV{'USE_BASE_DIR'} = 'yes';
401
402       chdir("$cwd");
403    }
404 }
405
406 sub regenModuleInfo ($)
407 {
408    my $module_name = shift;
409
410    my $cwd = getcwd();
411
412    die "ERROR: No module $module_name defined\n"
413       unless defined($MODULES{"$module_name"});
414
415    my $depencency;
416    foreach $depencency ( $MODULES{"$module_name"}->getDependencies() )
417    {
418       my $mod_path = $depencency->getPath();
419
420       chdir("$mod_path")
421          or die "WARNING: Could not chdir to $mod_path\n";
422       system("./config.status 2>&1") == 0
423          or die "Regeneration for $module_name in $ENV{'PWD'} failed\n";
424       chdir("$cwd");
425    }
426 }
427
428 sub generateMakefile (;$)
429 {
430    my $gen_module = shift || '';
431
432    open(INPUT, "$base_dir/Makefile.in")
433       or die "ERROR: Could not read from $base_dir/Makefile.in: $!\n";
434
435    my $input_file;
436    while ( <INPUT> )
437    {
438       $input_file .= "$_";
439    }
440
441    close(INPUT);
442
443    my $modules;
444    my @module_array;
445
446    if ( $gen_module )
447    {
448       foreach ( $MODULES{"$gen_module"}->getDependencies() )
449       {
450          $modules .= $_->getPath() . " ";
451       }
452    }
453    else
454    {
455       my $mod_name;
456       foreach $mod_name ( keys(%MODULES) )
457       {
458          my $temp_mod;
459          foreach $temp_mod ( $MODULES{"$mod_name"}->getDependencies() )
460          {
461             $modules .= $temp_mod->getPath() . " ";
462          }
463       }
464    }
465
466    warn "WARNING: No modules defined!\n" unless $modules;
467
468    my $cwd = getcwd();
469    chdir("$base_dir");
470    $input_file =~ s/\@JUGGLER_PROJECTS\@/$modules/g;
471
472    if ( $Win32 )
473    {
474       # Get the Win32-friendly versions of these paths.  Then change the \'s
475       # to /'s just to be safe.
476       my $win_pwd = `cygpath -w $ENV{'PWD'}`;
477       my $win_cwd = `cygpath -w $cwd`;
478       chomp($win_pwd);
479       chomp($win_cwd);
480
481       $win_pwd =~ s/\\/\//g;
482       $win_cwd =~ s/\\/\//g;
483
484       $input_file =~ s/\@JUGGLERROOT_ABS\@/$win_pwd/g;
485       $input_file =~ s/\@topdir\@/$win_cwd/g;
486    }
487    else
488    {
489       $input_file =~ s/\@JUGGLERROOT_ABS\@/$ENV{'PWD'}/g;
490       $input_file =~ s/\@topdir\@/$cwd/g;
491    }
492
493    chdir("$cwd");
494
495    print "Generating Makefile\n";
496    open(OUTPUT, "> Makefile") or die "ERROR: Could not create Makefile: $!\n";
497    print OUTPUT "$input_file";
498    close(OUTPUT) or warn "WARNING: Failed to save Makefile: $!\n";
499 }
500
501 sub generateReconfig ($@)
502 {
503    my $gen_module = shift;
504    my @save_argv  = @_;
505
506    my $modules;
507
508    open(RECONFIG, "> reconfig");
509
510    if ( $gen_module )
511    {
512       foreach ( $MODULES{"$gen_module"}->getDependencies() )
513       {
514          print RECONFIG "(cd " . $_->getPath() . " && rm -f config.status " .
515                         "config.cache config.log)\n"
516       }
517    }
518    else
519    {
520       my $mod_name;
521       foreach $mod_name ( keys(%MODULES) )
522       {
523          foreach ( $MODULES{"$mod_name"}->getDependencies() )
524          {
525             print RECONFIG "(cd " . $_->getPath() . " && rm -f config.status " .
526                            "config.cache config.log)\n"
527          }
528       }
529    }
530
531    print RECONFIG "rm -f config.cache\n";
532    print RECONFIG "$0 ", "@save_argv\n";
533    close(RECONFIG);
534    chmod(0755, "reconfig");
535 }
536
537 sub listModules ()
538 {
539    my $mod_name;
540    foreach $mod_name ( keys(%MODULES) )
541    {
542       print "$mod_name";
543
544 #      if ( $#{$MODULES{"$mod_name"}} != -1 )
545 #      {
546 #         print " (Requires:";
547 #
548 #         my $dep_ref;
549 #         foreach $dep_ref ( @{$MODULES{"$mod_name"}} )
550 #         {
551 #            print " ${$dep_ref}{'path'}";
552 #         }
553 #
554 #         print ")";
555 #      }
556
557       print "\n";
558    }
559
560    return 1;
561 }
562
563 sub printHelp ()
564 {
565    my @help_output = ();
566
567    # Initialize the references that are contained within @help_output.
568    my $i;
569    for ( $i = 0; $i < $LAST_ARG_GROUP; $i++ )
570    {
571       $help_output[$i] = {};
572    }
573
574    if ( $module )
575    {
576       getConfigureHelp("$module", \@help_output);
577    }
578    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
579            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
580    {
581       getConfigureHelp("$JugglerConfigure::DEFAULT_MODULE", \@help_output);
582    }
583    else
584    {
585       foreach ( keys(%MODULES) )
586       {
587          getConfigureHelp("$_", \@help_output);
588       }
589    }
590
591    for ( $i = 0; $i < $LAST_ARG_GROUP; $i++ )
592    {
593       SWITCH:
594       {
595          if ( $i == $CONFIG_ARGS )
596          {
597             print "Configuration:\n";
598             last SWITCH;
599          }
600
601          if ( $i == $PATH_ARGS )
602          {
603             print "Directory and file names:\n";
604             last SWITCH;
605          }
606
607          if ( $i == $HOST_ARGS )
608          {
609             print "Host type:\n";
610             last SWITCH;
611          }
612
613          if ( $i == $FEATURE_ARGS )
614          {
615             print "Features and packages:\n";
616             last SWITCH;
617          }
618
619          if ( $i == $CUSTOM_ARGS )
620          {
621             print "--enable and --with options recognized:\n";
622             last SWITCH;
623          }
624       }
625
626       foreach ( sort(keys(%{$help_output[$i]})) )
627       {
628          print "  ${$help_output[$i]}{$_}\n";
629       }
630    }
631
632    print "\n";
633
634    print "Modules that may be built:\n";
635    foreach ( keys(%MODULES) )
636    {
637       print "\t$_\n";
638    }
639
640    print "\nDefault module is $JugglerConfigure::DEFAULT_MODULE\n"
641       if $JugglerConfigure::DEFAULT_MODULE;
642
643    return 1;
644 }
645
646 sub getConfigureHelp ($$)
647 {
648    my $mod_name    = shift;
649    my $arg_arr_ref = shift;
650
651    foreach ( $MODULES{"$mod_name"}->getDependencies() )
652    {
653       next unless -x "$base_dir/$$_{'path'}/configure";
654
655       open(CFG_OUTPUT, "$base_dir/$$_{'path'}/configure --help |");
656
657       my $cfg_output;
658       while ( <CFG_OUTPUT> )
659       {
660          $cfg_output .= "$_";
661       }
662
663       close(CFG_OUTPUT);
664
665       parseOutput("$cfg_output", $arg_arr_ref);
666    }
667 }
668
669 sub parseOutput ($$)
670 {
671    my $string      = shift;
672    my $arg_arr_ref = shift;
673
674    my $arg_group;
675
676    while ( $string !~ /^\s*$/s )
677    {
678       if ( $string =~ /^Configuration:\s*/s )
679       {
680          $arg_group = $CONFIG_ARGS;
681          $string = $';
682       }
683       elsif ( $string =~ /^Directory.*?:\s*/s )
684       {
685          $arg_group = $PATH_ARGS;
686          $string = $';
687       }
688       elsif ( $string =~ /^Host.*?:\s*/s )
689       {
690          $arg_group = $HOST_ARGS;
691          $string = $';
692       }
693       elsif ( $string =~ /^Features.*?:\s*/s )
694       {
695          $arg_group = $FEATURE_ARGS;
696          $string = $';
697       }
698       elsif ( $string =~ /^--enable and --with.*?:\s*/s )
699       {
700          $arg_group = $CUSTOM_ARGS;
701          $string = $';
702       }
703       elsif ( $string =~ /^\s*(--\w+,\s+--\w+)/s ||
704               $string =~ /^\s*(--[\w-]+)\W/s )
705       {
706          my $param = "$1";
707          ${$$arg_arr_ref[$arg_group]}{"$param"} = '';
708
709          my $temp_string = "$string";
710
711          if ( $temp_string =~ /($param.+?)\s+(--)/s ||
712               $temp_string =~ /($param.+?)\s*$/s )
713          {
714             my $desc = "$1";
715             my $remainder = "$2$'";
716
717             if ( $desc =~ /^(\w.+?:)$/m )
718             {
719                $desc = $`;
720                $remainder = "$1\n$remainder";
721             }
722
723             ${$$arg_arr_ref[$arg_group]}{"$param"} = "$desc";
724             $string = "$remainder";
725          }
726       }
727       elsif ( $string =~ /^(Usage|Options).*$/m )
728       {
729          $string = $';
730       }
731       # Match anything else and strip it from the output.
732       elsif ( $string =~ /^.*$/m )
733       {
734          $string = $';
735       }
736
737       $string =~ s/^\s*//s;
738    }
739 }
740
741 sub getPlatform ()
742 {
743    my $platform = "unknown";
744
745    # Prefer the user-defined platform type over any auto-detected value.
746    if ( "$OS" ne '' )
747    {
748       $platform = "$OS";
749    }
750    elsif ( defined($ENV{'OS'}) )
751    {
752       $platform = "$ENV{'OS'}";
753    }
754    elsif ( defined($ENV{'OSTYPE'}) )
755    {
756       $platform = "$ENV{'OSTYPE'}";
757    }
758    elsif ( defined($ENV{'OS_TYPE'}) )
759    {
760       $platform = "$ENV{'OS_TYPE'}";
761    }
762    elsif ( defined($ENV{'HOSTTYPE'}) )
763    {
764       $platform = "$ENV{'HOSTTYPE'}";
765    }
766    # As a last resort, fall back on the use of uname(1).
767    else
768    {
769       chomp($platform = `uname -s`);
770    }
771
772    # XXX: This is a hack to deal with weird OS strings such as "linux-gnu".
773    # We just make the platform be "linux" unless the user set the platform
774    # type on the command line.
775    $platform = 'linux' if ! $OS && $platform =~ /linux/i;
776
777    return $platform;
778 }
779
780 sub getHostname ()
781 {
782    my $hostname = '';
783
784    if ( defined($ENV{'HOSTNAME'}) )
785    {
786       $hostname = "$ENV{'HOSTNAME'}";
787    }
788    else
789    {
790       chomp($hostname = `hostname`);
791    }
792
793    return $hostname;
794 }
795
796 #
797 # getRelativePath(wd, target)
798 # Given a working directory, returns the relative path to the target file.
799 #
800 sub getRelativePath ($$)
801 {
802    my ($wd, $target) = @_;
803
804    my @wd = split(/\//, $wd);
805    my @target = split(/\//, $target);
806
807    # Remove matching directory elements from both @wd and @target
808    while ((scalar(@wd) > 0) && (scalar(@target) > 0) && ($wd[0] eq $target[0]))
809    {
810       shift(@wd);
811       shift(@target);
812    }
813
814    # For each remaining part of the wd, prefix a .. to the target
815    foreach my $dir (@wd)
816    {
817       unshift(@target, '..');
818    }
819
820    return join('/', @target);
821 }
822
823 __END__
824
825 =head1 NAME
826
827 configure.pl
828
829 =head1 SYNOPSIS
830
831 This script acts as the "glue" for a collection of Autoconf-based configure
832 scripts.  Based on a configuration file, it is capable of building a
833 dependency tree and running the configure scripts in the correct order such
834 that the dependencies are satisfied correctly.  Note that all modules must
835 be capable of having dependencies satisfied based entirely on the results
836 of running a dependent module's configure script.
837
838 =head1 DESCRIPTION
839
840 (Still need to write this...)
841
842 =head1 OPTIONS
843
844 =over 8
845
846 =item B<--help>
847
848 Print usage information of this script alone and exit.
849
850 =item B<--all-help>
851
852 Print usage information for all the known configure scripts.  The
853 knowledge of configure scripts comes from the configuration file.  The
854 output may be limited using the B<--module> argument, described below.
855
856 =item B<--manual>
857
858 Print usage information of this script alone in UNIX manpage format and exit.
859