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

Revision 9180, 15.1 kB (checked in by patrickh, 6 years ago)

Copyright update.

  • 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/perl -w
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 $Win32);
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 configureModule($);
58 sub regenModuleInfo($);
59 sub generateMakefile(;$);
60 sub generateReconfig($@);
61 sub listModules();
62 sub printHelp();
63 sub getConfigureHelp($$);
64 sub parseOutput($$);
65
66 %MODULES = ();
67
68 my $all_help    = 0;
69 my $cfg         = "juggler.cfg";
70 my $user_cfg    = '';
71 $module         = '';
72 my $script_help = 0;
73 my $manual      = 0;
74 my $regen       = 0;
75 my $mod_list    = 0;
76
77 $CONFIG_ARGS    = 0;
78 $PATH_ARGS      = 1;
79 $HOST_ARGS      = 2;
80 $FEATURE_ARGS   = 3;
81 $CUSTOM_ARGS    = 4;
82 $LAST_ARG_GROUP = 5;
83
84 my @save_argv = @ARGV;
85
86 Getopt::Long::Configure('pass_through');
87 GetOptions('help|?' => \$script_help, 'cfg=s' => \$user_cfg,
88            'module=s' => \$module, 'all-help' => \$all_help,
89            'manual' => \$manual, 'regen' => \$regen, 'modlist' => \$mod_list)
90    or pod2usage(2);
91
92 # Print the help output and exit if --help was on the command line.
93 pod2usage(1) if $script_help;
94 pod2usage(-exitstatus => 0, -verbose => 2) if $manual;
95
96 die "ERROR: No configuration given\n" unless $cfg || $user_cfg;
97
98 $Win32 = 1 if $ENV{'OS'} && $ENV{'OS'} =~ /Windows/;
99
100 my $cfg_load = ("$user_cfg" eq "") ? "$base_dir/$cfg" : "$user_cfg";
101 %MODULES = JugglerConfigure::parseConfigFile("$cfg_load");
102
103 listModules() && exit(0) if $mod_list;
104 printHelp() && exit(0) if $all_help;
105
106 if ( $regen )
107 {
108    if ( $module )
109    {
110       die "ERROR: No such module $module in $cfg!\n"
111          unless defined($MODULES{"$module"});
112
113       regenModuleInfo("$module");
114       generateMakefile("$module");
115    }
116    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
117            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
118    {
119       regenModuleInfo("$JugglerConfigure::DEFAULT_MODULE");
120       generateMakefile("$JugglerConfigure::DEFAULT_MODULE");
121    }
122    else
123    {
124       foreach ( keys(%MODULES) )
125       {
126          regenModuleInfo("$_");
127       }
128
129       generateMakefile();
130    }
131 }
132 else
133 {
134    my $cache_file_set = 0;
135
136    foreach ( @ARGV )
137    {
138       if ( /-cache-f/ )
139       {
140          $cache_file_set = 1;
141          last;
142       }
143    }
144
145    if ( ! $cache_file_set )
146    {
147       my $cwd = getcwd();
148       push(@ARGV, "--cache-file=$cwd/config.cache");
149    }
150
151    if ( $module )
152    {
153       die "ERROR: No such module $module in $cfg!\n"
154          unless defined($MODULES{"$module"});
155
156       generateReconfig("$module", @save_argv);
157       configureModule("$module");
158       generateMakefile("$module");
159    }
160    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
161            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
162    {
163       generateReconfig("$JugglerConfigure::DEFAULT_MODULE", @save_argv);
164       configureModule("$JugglerConfigure::DEFAULT_MODULE");
165       generateMakefile("$JugglerConfigure::DEFAULT_MODULE");
166    }
167    else
168    {
169       generateReconfig('', @save_argv);
170
171       foreach ( keys(%MODULES) )
172       {
173          configureModule("$_");
174       }
175
176       generateMakefile();
177    }
178 }
179
180 exit(0);
181
182 # =============================================================================
183 # Subroutines follow.
184 # =============================================================================
185
186 sub configureModule ($)
187 {
188    my $module_name = shift;
189
190    my $cwd = getcwd();
191    my $safe_cwd;
192
193    if ( $Win32 )
194    {
195       $safe_cwd = `cygpath -w $cwd`;
196       chomp($safe_cwd);
197       $safe_cwd =~ s/\\/\//g;
198    }
199    else
200    {
201       $safe_cwd = "$cwd";
202    }
203
204    die "ERROR: No module $module_name defined\n"
205       unless defined($MODULES{"$module_name"});
206
207    my $depencency;
208    foreach $depencency ( $MODULES{"$module_name"}->getDependencies() )
209    {
210       my $mod_path = $depencency->getPath();
211
212       mkpath("$mod_path", 1, 0755) unless -d "$mod_path";
213       chdir("$mod_path")
214          or warn "WARNING: Could not chdir to $mod_path\n";
215
216       my $src_root;
217
218       if ( $base_dir =~ /^\// )
219       {
220          $src_root = "$base_dir";
221       }
222       else
223       {
224          $src_root = "$cwd/$base_dir";
225       }
226
227       print "Running $src_root/$mod_path/configure @ARGV\n";
228       system("$src_root/$mod_path/configure @ARGV 2>&1") == 0
229          or die "Configuration of $module_name in $ENV{'PWD'} failed\n" .
230                 "Check $ENV{'PWD'}/config.log for details\n";
231
232       my %mod_env = $depencency->getEnvironment();
233       foreach ( keys(%mod_env) )
234       {
235          my $env_val = $depencency->getEnvironmentValue($_);
236
237          if ( /_CONFIG$/ )
238          {
239             $ENV{"$_"} = "$cwd/$mod_path/$env_val";
240          }
241          elsif ( /_BASE_DIR$/ )
242          {
243             if ( "$env_val" eq "instlinks" )
244             {
245                $ENV{"$_"} = "$safe_cwd/instlinks";
246             }
247             else
248             {
249                $ENV{"$_"} = "$env_val";
250             }
251          }
252          else
253          {
254             $ENV{"$_"} = "$env_val";
255          }
256       }
257
258       $ENV{'USE_BASE_DIR'} = 'yes';
259
260       chdir("$cwd");
261    }
262 }
263
264 sub regenModuleInfo ($)
265 {
266    my $module_name = shift;
267
268    my $cwd = getcwd();
269
270    die "ERROR: No module $module_name defined\n"
271       unless defined($MODULES{"$module_name"});
272
273    my $depencency;
274    foreach $depencency ( $MODULES{"$module_name"}->getDependencies() )
275    {
276       my $mod_path = $depencency->getPath();
277
278       chdir("$mod_path")
279          or die "WARNING: Could not chdir to $mod_path\n";
280       system("./config.status 2>&1") == 0
281          or die "Regeneration for $module_name in $ENV{'PWD'} failed\n";
282       chdir("$cwd");
283    }
284 }
285
286 sub generateMakefile (;$)
287 {
288    my $gen_module = shift || '';
289
290    open(INPUT, "$base_dir/Makefile.in")
291       or die "ERROR: Could not read from $base_dir/Makefile.in: $!\n";
292
293    my $input_file;
294    while ( <INPUT> )
295    {
296       $input_file .= "$_";
297    }
298
299    close(INPUT);
300
301    my $modules;
302    my @module_array;
303
304    if ( $gen_module )
305    {
306       foreach ( $MODULES{"$gen_module"}->getDependencies() )
307       {
308          $modules .= $_->getPath() . " ";
309       }
310    }
311    else
312    {
313       my $mod_name;
314       foreach $mod_name ( keys(%MODULES) )
315       {
316          my $temp_mod;
317          foreach $temp_mod ( $MODULES{"$mod_name"}->getDependencies() )
318          {
319             $modules .= $temp_mod->getPath() . " ";
320          }
321       }
322    }
323
324    warn "WARNING: No modules defined!\n" unless $modules;
325
326    my $cwd = getcwd();
327    chdir("$base_dir");
328    $input_file =~ s/\@JUGGLER_PROJECTS\@/$modules/g;
329
330    if ( $Win32 )
331    {
332       # Get the Win32-friendly versions of these paths.  Then change the \'s
333       # to /'s just to be safe.
334       my $win_pwd = `cygpath -w $ENV{'PWD'}`;
335       my $win_cwd = `cygpath -w $cwd`;
336       chomp($win_pwd);
337       chomp($win_cwd);
338
339       $win_pwd =~ s/\\/\//g;
340       $win_cwd =~ s/\\/\//g;
341
342       $input_file =~ s/\@JUGGLERROOT_ABS\@/$win_pwd/g;
343       $input_file =~ s/\@topdir\@/$win_cwd/g;
344    }
345    else
346    {
347       $input_file =~ s/\@JUGGLERROOT_ABS\@/$ENV{'PWD'}/g;
348       $input_file =~ s/\@topdir\@/$cwd/g;
349    }
350
351    chdir("$cwd");
352
353    print "Generating Makefile\n";
354    open(OUTPUT, "> Makefile") or die "ERROR: Could not create Makefile: $!\n";
355    print OUTPUT "$input_file";
356    close(OUTPUT) or warn "WARNING: Failed to save Makefile: $!\n";
357 }
358
359 sub generateReconfig ($@)
360 {
361    my $gen_module = shift;
362    my @save_argv  = @_;
363
364    my $modules;
365
366    open(RECONFIG, "> reconfig");
367
368    if ( $gen_module )
369    {
370       foreach ( $MODULES{"$gen_module"}->getDependencies() )
371       {
372          print RECONFIG "(cd " . $_->getPath() . " && rm -f config.status " .
373                         "config.cache config.log)\n"
374       }
375    }
376    else
377    {
378       my $mod_name;
379       foreach $mod_name ( keys(%MODULES) )
380       {
381          foreach ( $MODULES{"$mod_name"}->getDependencies() )
382          {
383             print RECONFIG "(cd " . $_->getPath() . " && rm -f config.status " .
384                            "config.cache config.log)\n"
385          }
386       }
387    }
388
389    print RECONFIG "rm -f config.cache\n";
390    print RECONFIG "$0 ", "@save_argv\n";
391    close(RECONFIG);
392    chmod(0755, "reconfig");
393 }
394
395 sub listModules ()
396 {
397    my $mod_name;
398    foreach $mod_name ( keys(%MODULES) )
399    {
400       print "$mod_name";
401
402 #      if ( $#{$MODULES{"$mod_name"}} != -1 )
403 #      {
404 #         print " (Requires:";
405 #
406 #         my $dep_ref;
407 #         foreach $dep_ref ( @{$MODULES{"$mod_name"}} )
408 #         {
409 #            print " ${$dep_ref}{'path'}";
410 #         }
411 #
412 #         print ")";
413 #      }
414
415       print "\n";
416    }
417
418    return 1;
419 }
420
421 sub printHelp ()
422 {
423    my @help_output = ();
424
425    # Initialize the references that are contained within @help_output.
426    my $i;
427    for ( $i = 0; $i < $LAST_ARG_GROUP; $i++ )
428    {
429       $help_output[$i] = {};
430    }
431
432    if ( $module )
433    {
434       getConfigureHelp("$module", \@help_output);
435    }
436    elsif ( $JugglerConfigure::DEFAULT_MODULE &&
437            defined($MODULES{"$JugglerConfigure::DEFAULT_MODULE"}) )
438    {
439       getConfigureHelp("$JugglerConfigure::DEFAULT_MODULE", \@help_output);
440    }
441    else
442    {
443       foreach ( keys(%MODULES) )
444       {
445          getConfigureHelp("$_", \@help_output);
446       }
447    }
448
449    for ( $i = 0; $i < $LAST_ARG_GROUP; $i++ )
450    {
451       SWITCH:
452       {
453          if ( $i == $CONFIG_ARGS )
454          {
455             print "Configuration:\n";
456             last SWITCH;
457          }
458
459          if ( $i == $PATH_ARGS )
460          {
461             print "Directory and file names:\n";
462             last SWITCH;
463          }
464
465          if ( $i == $HOST_ARGS )
466          {
467             print "Host type:\n";
468             last SWITCH;
469          }
470
471          if ( $i == $FEATURE_ARGS )
472          {
473             print "Features and packages:\n";
474             last SWITCH;
475          }
476
477          if ( $i == $CUSTOM_ARGS )
478          {
479             print "--enable and --with options recognized:\n";
480             last SWITCH;
481          }
482       }
483
484       foreach ( sort(keys(%{$help_output[$i]})) )
485       {
486          print "  ${$help_output[$i]}{$_}\n";
487       }
488    }
489
490    print "\n";
491
492    print "Modules that may be built:\n";
493    foreach ( keys(%MODULES) )
494    {
495       print "\t$_\n";
496    }
497
498    print "\nDefault module is $JugglerConfigure::DEFAULT_MODULE\n"
499       if $JugglerConfigure::DEFAULT_MODULE;
500
501    return 1;
502 }
503
504 sub getConfigureHelp ($$)
505 {
506    my $mod_name    = shift;
507    my $arg_arr_ref = shift;
508
509    foreach ( $MODULES{"$mod_name"}->getDependencies() )
510    {
511       next unless -x "$base_dir/$$_{'path'}/configure";
512
513       open(CFG_OUTPUT, "$base_dir/$$_{'path'}/configure --help |");
514
515       my $cfg_output;
516       while ( <CFG_OUTPUT> )
517       {
518          $cfg_output .= "$_";
519       }
520
521       close(CFG_OUTPUT);
522
523       parseOutput("$cfg_output", $arg_arr_ref);
524    }
525 }
526
527 sub parseOutput ($$)
528 {
529    my $string      = shift;
530    my $arg_arr_ref = shift;
531
532    my $arg_group;
533
534    while ( $string !~ /^\s*$/s )
535    {
536       if ( $string =~ /^Configuration:\s*/s )
537       {
538          $arg_group = $CONFIG_ARGS;
539          $string = $';
540       }
541       elsif ( $string =~ /^Directory.*?:\s*/s )
542       {
543          $arg_group = $PATH_ARGS;
544          $string = $';
545       }
546       elsif ( $string =~ /^Host.*?:\s*/s )
547       {
548          $arg_group = $HOST_ARGS;
549          $string = $';
550       }
551       elsif ( $string =~ /^Features.*?:\s*/s )
552       {
553          $arg_group = $FEATURE_ARGS;
554          $string = $';
555       }
556       elsif ( $string =~ /^--enable and --with.*?:\s*/s )
557       {
558          $arg_group = $CUSTOM_ARGS;
559          $string = $';
560       }
561       elsif ( $string =~ /^\s*(--\w+,\s+--\w+)/s ||
562               $string =~ /^\s*(--[\w-]+)\W/s )
563       {
564          my $param = "$1";
565          ${$$arg_arr_ref[$arg_group]}{"$param"} = '';
566
567          my $temp_string = "$string";
568
569          if ( $temp_string =~ /($param.+?)\s+(--)/s ||
570               $temp_string =~ /($param.+?)\s*$/s )
571          {
572             my $desc = "$1";
573             my $remainder = "$2$'";
574
575             if ( $desc =~ /^(\w.+?:)$/m )
576             {
577                $desc = $`;
578                $remainder = "$1\n$remainder";
579             }
580
581             ${$$arg_arr_ref[$arg_group]}{"$param"} = "$desc";
582             $string = "$remainder";
583          }
584       }
585       elsif ( $string =~ /^(Usage|Options).*$/m )
586       {
587          $string = $';
588       }
589
590       $string =~ s/^\s*//s;
591    }
592 }
593
594 __END__
595
596 =head1 NAME
597
598 configure.pl
599
600 =head1 SYNOPSIS
601
602 This script acts as the "glue" for a collection of Autoconf-based configure
603 scripts.  Based on a configuration file, it is capable of building a
604 dependency tree and running the configure scripts in the correct order such
605 that the dependencies are satisfied correctly.  Note that all modules must
606 be capable of having dependencies satisfied based entirely on the results
607 of running a dependent module's configure script.
608
609 =head1 OPTIONS
610
611 =over 8
612
613 =item B<--help>
614
615 Print usage information of this script alone and exit.
616
617 =item B<--all-help>
618
619 Print usage information for all the known configure scripts.  The
620 knowledge of configure scripts comes from the configuration file.  The
621 output may be limited using the --module argument, described below.
622
623 =item B<--manual>
624
625 Print usage information of this script alone in UNIX manpage format and exit.
626
627 =item B<--modlist>
628
629 Print a list of the available modules.
630
631 =item B<--cfg>=file
632
633 Name the configuration file to be used by this script.  If not specified,
634 it defaults to juggler.cfg.  This file is discovered based on the run-time
635 path to this script, and thus the script and the configuration file must
636 be in the same directory.  For example, if this script is run as:
637
638 =over 4
639
640 ../configure.pl
641
642 =back
643
644 then juggler.cfg will be searched for as B<../juggler.cfg>.
645
646 =item B<--module>=name
647
648 Limit the work done by this script to what is required by the named
649 module.  The given name must correspond to one listed in the aforementioned
650 configuration file.  This can be specified in conjunction with B<--help>
651 to limit the output to only what is appropriate for the named module.
652
653 =item B<--regen>
654
655 Just regenerate the files previously generated without running the
656 configure script(s) again.
657
658 =back
659
660 =head1 DESCRIPTION
661
662
Note: See TracBrowser for help on using the browser.