Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

cons (225463B)


      1 #!/usr/bin/env perl
      2 
      3 # NOTE:  Cons intentionally does not use the "perl -w" option or
      4 # "use strict."  Because Cons "configuration files" are actually
      5 # Perl scripts, enabling those restrictions here would force them
      6 # on every user's config files, wanted or not.  Would users write
      7 # "better" Construct and Conscript files if we forced "use strict"
      8 # on them?  Probably.  But we want people to use Cons to get work
      9 # done, not force everyone to become a Perl guru to use it, so we
     10 # don't insist.
     11 #
     12 # That said, Cons' code is both "perl -w" and "use strict" clean.
     13 # Regression tests keep the code honest by checking for warnings
     14 # and "use strict" failures.
     15 
     16 use vars qw( $CVS_id $CVS_ver $ver_num $ver_rev $version );
     17 
     18 $CVS_id = 'Id';
     19 $CVS_ver = (split(/\s+/, $CVS_id))[2];
     20 
     21 $ver_num = "2.3";
     22 $ver_rev = ".1";
     23 
     24 $version = "This is Cons $ver_num$ver_rev ($CVS_id)\n";
     25 
     26 # Cons: A Software Construction Tool.
     27 # Copyright (c) 1996-2001 Free Software Foundation, Inc.
     28 #
     29 # This program is free software; you can redistribute it and/or modify
     30 # it under the terms of the GNU General Public License as published by
     31 # the Free Software Foundation; either version 2 of the License, or
     32 # (at your option) any later version.
     33 #
     34 # This program is distributed in the hope that it will be useful,
     35 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     36 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     37 # GNU General Public License for more details.
     38 #
     39 # You should have received a copy of the GNU General Public License
     40 # along with this program; see the file COPYING.  If not, write to
     41 # the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     42 # Boston, MA 02111-1307, USA.
     43 
     44 require 5.003;
     45 # See the NOTE above about why Cons doesn't "use strict".
     46 use integer;
     47 use Cwd;
     48 use File::Copy;
     49 
     50 use vars qw( $_WIN32 $_a $_exe $_o $_so );
     51 
     52 #------------------------------------------------------------------
     53 # Determine if running on win32 platform - either Windows NT or 95
     54 #------------------------------------------------------------------
     55 
     56 use vars qw( $PATH_SEPARATOR $iswin32 $_WIN32 $usage $indent @targets );
     57 
     58 BEGIN {
     59     use Config;
     60 
     61     # if the version is 5.003, we can check $^O
     62     if ($] <  5.003) {
     63 	eval("require Win32");
     64 	$_WIN32 = (!$@);
     65     } else {
     66 	$_WIN32 = ($^O eq "MSWin32") ? 1 : 0;
     67     }
     68 
     69     # Fetch the PATH separator from Config;
     70     # provide our old defaults in case it's not set.
     71     $PATH_SEPARATOR = $Config{path_sep};
     72     $PATH_SEPARATOR = $_WIN32 ? ';' : ':' if ! defined $PATH_SEPARATOR;
     73 
     74     # Fetch file suffixes from Config,
     75     # accomodating differences in the Config variables
     76     # used by different Perl versions.
     77     $_exe = $Config{_exe};
     78     $_exe = $Config{exe_ext} if ! defined $_exe;
     79     $_exe = $_WIN32 ? '.exe' : '' if ! defined $_exe;
     80     $_o = $Config{_o};
     81     $_o = $Config{obj_ext}  if ! defined $_o;
     82     $_o = $_WIN32 ? '.obj' : '.o' if ! defined $_o;
     83     $_a = $Config{_a};
     84     $_a = $Config{lib_ext} if ! defined $_a;
     85     $_a = $_WIN32 ? '.lib' : '.a' if ! defined $_a;
     86     $_so = ".$Config{so}";
     87     $_so = $_WIN32 ? '.dll' : '.so' if ! defined $_so;
     88 }
     89 
     90 # Flush stdout each time.
     91 $| = 1;
     92 
     93 # Seed random number generator.
     94 srand(time . $$); # this works better than time ^ $$ in perlfunc manpage.
     95 
     96 $usage = q(
     97 Usage: cons <arguments> -- <construct-args>
     98 
     99 Arguments can be any of the following, in any order:
    100 
    101   <targets>	Build the specified targets. If <target> is a directory
    102 		recursively build everything within that directory.
    103 
    104   +<pattern>	Limit the cons scripts considered to just those that
    105 		match <pattern>. Multiple + arguments are accepted.
    106 
    107   <name>=<val>	Sets <name> to value <val> in the ARG hash passed to the
    108 		top-level Construct file.
    109 
    110   -cc           Show command that would have been executed, when
    111 		retrieving from cache. No indication that the file
    112 		has been retrieved is given; this is useful for
    113 		generating build logs that can be compared with
    114 		real build logs.
    115 
    116   -cd           Disable all caching. Do not retrieve from cache nor
    117 		flush to cache.
    118 
    119   -cr           Build dependencies in random order. This is useful when
    120 		building multiple similar trees with caching enabled.
    121 
    122   -cs           Synchronize existing build targets that are found to be
    123 		up-to-date with cache. This is useful if caching has
    124 		been disabled with -cc or just recently enabled with
    125 		UseCache.
    126 
    127   -d            Enable dependency debugging.
    128 
    129   -f <file>	Use the specified file instead of "Construct" (but first
    130 		change to containing directory of <file>).
    131 
    132   -h            Show a help message local to the current build if
    133 		one such is defined,  and exit.
    134 
    135   -k		Keep going as far as possible after errors.
    136 
    137   -o <file>	Read override file <file>.
    138 
    139   -p		Show construction products in specified trees.
    140   -pa		Show construction products and associated actions.
    141   -pw		Show products and where they are defined.
    142 
    143   -q		Be quiet; multiple -q flags increase quietness level:
    144 		1: quiet about Installing and Removing targets
    145 		2: quiet about build commands, up-to-date targets
    146 
    147   -r		Remove construction products associated with <targets>
    148 
    149   -R <repos>	Search for files in <repos>.  Multiple -R <repos>
    150 		directories are searched in the order specified.
    151 
    152   -S <pkg>	Use package sig::<pkg> to calculate file signatures.
    153 		Currently supported values are "md5" for MD5
    154 		signatures (the default) and "md5::debug" for MD5
    155 		signature debug information.
    156 
    157   -t            Traverse up the directory hierarchy looking for a
    158 		Construct file, if none exists in the current directory.
    159 		(Targets will be modified to be relative to the
    160 		Construct file.)
    161 
    162   -v		Show cons version and continue processing.
    163   -V            Show cons version and exit.
    164 
    165   -wf <file>    Write all filenames considered into <file>.
    166 
    167   -x		Show this message and exit.
    168 
    169 
    170    Please report any suggestions through the cons-discuss@gnu.org mailing
    171    list.
    172 
    173    To subscribe, send mail to cons-discuss-request@gnu.org with body
    174    'subscribe'.
    175 
    176    If you find a bug, please report it through the bug-cons@gnu.org
    177    mailing list.
    178 
    179    Information about CONS can be obtained from the official cons web site
    180    http://www.dsmit.com/cons/ or its mirrors (listed there).
    181 
    182    The cons maintainers can be contacted by email at cons-maintainers@gnu.org
    183 
    184    User documentation of cons is contained in cons and can be obtained
    185    by doing 'perldoc /path/to/cons'.
    186 
    187 );
    188 
    189 # Simplify program name, if it is a path.
    190 {
    191     my ($vol, $dir, $file) = File::Spec->splitpath(File::Spec->canonpath($0));
    192     $0 = $file;
    193 }
    194 
    195 # Default parameters.
    196 $param::topfile = 'Construct';	# Top-level construction file.
    197 $param::install = 1;		# Show installations
    198 $param::build = 1;		# Build targets
    199 ### $param::show = 1;		# Show building of targets.
    200 $param::sigpro = 'md5';		# Signature protocol.
    201 $param::depfile = '';		# Write all deps out to this file
    202 $param::salt = '';		# Salt derived file signatures with this.
    203 $param::sourcesig = ['*' => 'content'];# Source file signature calculation
    204 $param::rep_sig_times_ok = 1;	# Repository .consign times are in sync
    205 				#   w/files.
    206 $param::conscript_chdir = 0;	# Change dir to Conscript directory
    207 $param::quiet = 0;		# should we show the command being executed.
    208 
    209 @param::defaults = ();
    210 
    211 #
    212 $indent = '';
    213 
    214 # Display a command while executing or otherwise. This
    215 # should be called by command builder action methods.
    216 sub showcom {
    217     print($indent . $_[0] . "\n") if ($param::quiet < 2);
    218 }
    219 
    220 # Default environment.
    221 # This contains only the completely platform-independent information
    222 # we can figure out.  Platform-specific information (UNIX, Win32)
    223 # gets added below.
    224 @param::base = (
    225      'SIGNATURE'    => [ '*' => 'build' ],
    226      'SUFEXE'	    => $_exe,				# '' on UNIX systems
    227      'SUFLIB'	    => $_a,				# '.a' on UNIX systems
    228      'SUFLIBS'      => "$_so:$_a",			# '.so:.a' on UNIX
    229      'SUFOBJ'	    => $_o,				# '.o' on UNIX systems
    230      'SUFMAP'       => {
    231 	 '.c'  => 'build::command::cc',
    232 	 '.s'  => 'build::command::cc',
    233 	 '.S'  => 'build::command::cc',
    234 	 '.C'  => 'build::command::cxx',
    235 	 '.cc' => 'build::command::cxx',
    236 	 '.cxx'=> 'build::command::cxx',
    237 	 '.cpp'=> 'build::command::cxx',
    238 	 '.c++'=> 'build::command::cxx',
    239 	 '.C++'=> 'build::command::cxx',
    240      },
    241      'PERL'	    => $^X,
    242 );
    243 
    244 %param::rulesets =
    245     (
    246      # Defaults for Win32.
    247      # Defined for VC++ 6.0 by Greg Spencer <greg_spencer@acm.org>
    248      # Your mileage may vary.
    249      'msvc' => [
    250 		'CC'             => 'cl',
    251 		'CFLAGS'         => '/nologo',
    252 		'CCCOM'          => '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
    253 		'CXX'            => '%CC',
    254 		'CXXFLAGS'       => '%CFLAGS',
    255 		'CXXCOM'         => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
    256 		'INCDIRPREFIX'   => '/I',
    257 		'INCDIRSUFFIX'   => '',
    258 		'LINK'           => 'link',
    259 		'LINKCOM'        => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
    260 		'LINKMODULECOM'  => '%LD /r /o %> %<',
    261 		'LIBDIRPREFIX'   => '/LIBPATH:',
    262 		'LIBDIRSUFFIX'   => '',
    263 		'AR'             => 'lib',
    264 		'ARFLAGS'        => '/nologo ',
    265 		'ARCOM'          => "%AR %ARFLAGS /out:%> %<",
    266 		'RANLIB'         => '',
    267 		'LD'             => 'link',
    268 		'LDFLAGS'        => '/nologo ',
    269 		'PREFLIB'        => '',
    270 		],
    271      # Defaults for a typical (?) UNIX platform.
    272      # Your mileage may vary.
    273      'unix' => [
    274 		'CC'             => 'cc',
    275 		'CFLAGS'         => '',
    276 		'CCCOM'          => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
    277 		'CXX'            => '%CC',
    278 		'CXXFLAGS'       => '%CFLAGS',
    279 		'CXXCOM'         => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
    280 		'INCDIRPREFIX'   => '-I',
    281 		'INCDIRSUFFIX'   => '',
    282 		'LINK'           => '%CXX',
    283 		'LINKCOM'        => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
    284 		'LINKMODULECOM'  => '%LD -r -o %> %<',
    285 		'LIBDIRPREFIX'   => '-L',
    286 		'LIBDIRSUFFIX'   => '',
    287 		'AR'             => 'ar',
    288 		'ARFLAGS'        => 'r', # rs?
    289 		'ARCOM'          => ['%AR %ARFLAGS %> %<', '%RANLIB %>'],
    290 		'RANLIB'         => 'ranlib',
    291 		'AS'             => 'as',
    292 		'ASFLAGS'        => '',
    293 		'ASCOM'          => '%AS %ASFLAGS %< -o %>',
    294 		'LD'             => 'ld',
    295 		'LDFLAGS'        => '',
    296 		'PREFLIB'        => 'lib',
    297 		'ENV'            => { 'PATH' => '/bin:/usr/bin' },
    298 		],
    299      );
    300 
    301 # Set the rules based on the platform.
    302 script::DefaultRules(script::RuleSet($_WIN32 ? 'msvc' : 'unix'));
    303 
    304 # Handle command line arguments.
    305 while (@ARGV) {
    306     $_ = shift @ARGV;
    307     last if /^--$/;		# Argument passing to Construct.
    308     &option, next			if s/^-//;
    309     push (@param::include, $_), next	if s/^\+//;
    310     &equate, next			if /=/;
    311     push (@targets, $_), next;
    312 }
    313 
    314 sub option {
    315     my %opt = (
    316 		    'cc' =>   sub { $param::cachecom = 1; },
    317 		    'cd' =>   sub { $param::cachedisable = 1; },
    318 		    'cr' =>   sub { $param::random = 1; },
    319 		    'cs' =>   sub { $param::cachesync = 1; },
    320 		    'd' =>    sub { $param::depends = 1; },
    321 		    'h' =>    sub { $param::localhelp = 1; },
    322 		    'k' =>    sub { $param::kflag = 1; },
    323 		    'p' =>    sub { $param::pflag = 1;
    324 				    $param::build = 0; },
    325 		    'pa' =>   sub { $param::pflag = 1;
    326 				    $param::aflag = 1;
    327 				    $indent = "... ";
    328 				    $param::build = 0; },
    329 		    'pw' =>   sub { $param::pflag = 1;
    330 				    $param::wflag = 1;
    331 				    $param::build = 0; },
    332 		    'q' =>    sub { $param::quiet++; },
    333 		    'r' =>    sub { $param::rflag = 1;
    334 				    $param::build = 0; },
    335 		    't' =>    sub { $param::traverse = 1; },
    336 		    'v' =>    sub { print($version); },
    337 		    'V' =>    sub { print($version), exit(0); },
    338 		    'x' =>    sub { print($usage), exit 0; },
    339 		);
    340 
    341     my %opt_arg = (
    342 		    'f' =>    sub { $param::topfile = $_[0]; },
    343 		    'o' =>    sub { $param::overfile = $_[0]; },
    344 		    'R' =>    sub { script::Repository($_[0]); },
    345 		    'S' =>    sub { $param::sigpro = $_[0]; },
    346 		    'wf' =>   sub { $param::depfile = $_[0]; },
    347 		);
    348 
    349     if (defined $opt{$_}) {
    350 	&{$opt{$_}}();
    351 	return;
    352     }
    353     while ($_) {
    354 	$_  =~ m/(.)(.*)/;
    355 	if (defined $opt{$1}) {
    356 	    &{$opt{$1}}();
    357 	    $_ = $2;
    358 	    next;
    359 	}
    360 	if (defined $opt_arg{$1}) {
    361 	    if (! $2) {
    362 		$_ = shift @ARGV;
    363 		die("$0: -$1 option requires an argument.\n") if ! $_;
    364 	    }
    365 	    &{$opt_arg{$1}}($2 || $_);
    366 	    return;
    367 	}
    368 	$_  =~ m/(..)(.*)/;
    369 	if (defined $opt_arg{$1}) {
    370 	    if (! $2) {
    371 		$_ = shift @ARGV;
    372 		die("$0: -$1 option requires an argument.\n") if ! $_;
    373 	    }
    374 	    &{$opt_arg{$1}}($2 || $_);
    375 	    return;
    376 	}
    377 	if ($_) {
    378 	    die qq($0: unrecognized option "-$_".  Use -x for a usage message.\n);
    379 	}
    380     }
    381 }
    382 
    383 # Process an equate argument (var=val).
    384 sub equate {
    385     my($var, $val) = /([^=]*)=(.*)/;
    386     $script::ARG{$var} = $val;
    387 }
    388 
    389 # Define file signature protocol.
    390 'sig'->select($param::sigpro);
    391 
    392 # Cleanup after an interrupt.
    393 $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
    394     $SIG{PIPE} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = 'IGNORE';
    395     $SIG{HUP} = $SIG{INT} if ! $main::_WIN32;
    396     warn("\n$0: killed\n");
    397     # Call this first, to make sure that this processing
    398     # occurs even if a child process does not die (and we
    399     # hang on the wait).
    400     sig::hash::END();
    401     wait();
    402     exit(1);
    403 };
    404 $SIG{HUP} = $SIG{INT} if ! $main::_WIN32;
    405 
    406 # Cleanup after a broken pipe (someone piped our stdout?)
    407 $SIG{PIPE} = sub {
    408     $SIG{PIPE} = $SIG{HUP} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = 'IGNORE';
    409     warn("\n$0: broken pipe\n");
    410     sig::hash::END();
    411     wait();
    412     exit(1);
    413 };
    414 
    415 if ($param::depfile) {
    416   open (main::DEPFILE, ">".$param::depfile) ||
    417     die ("$0: couldn't open $param::depfile ($!)\n");
    418 }
    419 
    420 # If the supplied top-level Conscript file is not in the
    421 # current directory, then change to that directory.
    422 {
    423     my ($vol, $dir, $file) =
    424       File::Spec->splitpath(File::Spec->canonpath($param::topfile));
    425     if ($vol || $dir) {
    426 	my($cd) = File::Spec->catpath($vol, $dir, undef);
    427 	chdir($cd) || die("$0: couldn't change to directory $cd ($!)\n");
    428 	$param::topfile = $file;
    429     }
    430 }
    431 
    432 # Walk up the directory hierarchy looking for a Conscript file (if -t set).
    433 my($target_top);
    434 my(@targetdir) = ();
    435 if ($param::traverse && ! -f $param::topfile) {
    436     my($vol, $dirs, $file) = File::Spec->splitpath(cwd());
    437     my(@dirs) = (File::Spec->splitdir($dirs), $file);
    438     while (! -f File::Spec->catpath($vol, File::Spec->catdir(@dirs),
    439 				    $param::topfile)) {
    440 	die("$0: unable to find $param::topfile.\n") if ! @dirs;
    441 	unshift(@targetdir, pop(@dirs));
    442     }
    443     my($cwd) = File::Spec->catpath($vol, File::Spec->catdir(@dirs), '');
    444     print "$0: Entering directory `$cwd'\n";
    445     chdir($cwd);
    446     @targets = map {File::Spec->catdir(@targetdir, $_)} @targets;
    447 }
    448 
    449 # Set up $dir::top and $dir::cwd, now that we are in the right directory.
    450 dir::init();
    451 
    452 #
    453 if (@targetdir) {
    454     $target_top = $dir::top->lookupdir(File::Spec->catdir(@targetdir));
    455 }
    456 
    457 # Now handle override file.
    458 package override;
    459 if ($param::overfile) {
    460     my($ov) = $param::overfile;
    461     die qq($0: can\'t read override file "$ov" ($!)\n) if ! -f $ov; #'
    462     do $ov;
    463     if ($@) {
    464 	chop($@);
    465 	die qq($0: errors in override file "$ov" ($@)\n);
    466     }
    467 }
    468 
    469 # Provide this to user to setup override patterns.
    470 sub Override {
    471     my($re, @env) = @_;
    472     return if $param::overrides{$re}; # if identical, first will win.
    473     $param::overrides = 1;
    474     $param::overrides{$re} = \@env;
    475     push(@param::overrides, $re);
    476 }
    477 
    478 package main;
    479 
    480 use vars qw( %priority $errors );
    481 
    482 # Check script inclusion regexps
    483 my $re;
    484 for $re (@param::include) {
    485     if (! defined eval {"" =~ /$re/}) {
    486 	my($err) = $@;
    487 	$err =~ s/in regexp at .*$//;
    488 	die("$0: error in regexp $err");
    489     }
    490 }
    491 
    492 # Read the top-level construct file and its included scripts.
    493 doscripts($param::topfile);
    494 
    495 # Status priorities. This lets us aggregate status for directories
    496 # and print an appropriate message (at the top-level).
    497 %priority =
    498     ('none' => 1, 'handled' => 2, 'built' => 3, 'unknown' => 4, 'errors' => 5);
    499 
    500 # If no targets were specified, supply default targets (if any).
    501 @targets = @param::default_targets if ! @targets;
    502 
    503 $errors = 0;
    504 
    505 # Build the supplied target patterns.
    506 my $tgt;
    507 for $tgt (map($dir::top->lookup($_), @targets)) {
    508     if ($target_top && ! $tgt->is_under($target_top)) {
    509 	# A -t option was used, and this target is not underneath
    510 	# the directory where we were invoked via -t.
    511 	# If the target is a directory and the -t directory
    512 	# is underneath it, then build the -t directory.
    513 	if (ref $tgt ne "dir" || ! $target_top->is_under($tgt)) {
    514 	    next;
    515 	}
    516 	$tgt = $target_top;
    517     }
    518     buildtoptarget($tgt);
    519 }
    520 
    521 exit 0 + ($errors != 0);
    522 
    523 sub buildtoptarget {
    524     my($tgt) = @_;
    525     return if ! $tgt;
    526     my($status) = buildtarget($tgt);
    527     if ($status ne 'built') {
    528 	my($path) = $tgt->path;
    529 	if ($status eq "errors") {
    530 	    print qq($0: "$path" not remade because of errors.\n);
    531 	    $errors++;
    532 	} elsif ($status eq "handled") {
    533 	    print qq($0: "$path" is up-to-date.\n) if ($param::quiet < 2);
    534 	} elsif ($status eq "unknown") {
    535 	    # cons error already reported.
    536 	    $errors++;
    537 	} elsif ($status eq "none") {
    538 	    # search for targets that may be linked to the given path.
    539 	    my @linked = dir::linked_targets($tgt) if $target_top;
    540 	    if (@linked) {
    541 		my @names = map($_->path, @linked);
    542 		print "Linked targets: @names\n" if ($param::quiet < 1);
    543 		map(buildtoptarget($_), @linked);
    544 	    } else {
    545 		print qq($0: nothing to be built in "$path".\n)
    546 		      if $param::build && ($param::quiet < 2);
    547 	    }
    548 	} else {
    549 	    print qq($0: don\'t know how to construct "$path".\n); #'
    550 	    $errors++;
    551 	}
    552     }
    553 }
    554 
    555 # Build the supplied target directory or files. Return aggregated status.
    556 sub buildtarget {
    557     my($tgt) = @_;
    558     if (ref($tgt) eq "dir") {
    559 	my($result) = "none";
    560 	my($priority) = $priority{$result};
    561 	if (exists $tgt->{member}) {
    562 	    my($members) = $tgt->{member};
    563 	    my $entry;
    564 	    for $entry (sort keys %$members) {
    565 		next if $entry eq $dir::CURDIR || $entry eq $dir::UPDIR;
    566 		my($tgt) = $members->{$entry};
    567 		next if ref($tgt) ne "dir" && !exists($tgt->{builder});
    568 		my($stat) = buildtarget($members->{$entry});
    569 		my($pri) = $priority{$stat};
    570 		if ($pri > $priority) {
    571 		    $priority = $pri;
    572 		    $result = $stat;
    573 		}
    574 	    }
    575 	}
    576 	return $result;
    577     }
    578     if ($param::depends) {
    579 	my($path) = $tgt->path;
    580 	if ($tgt->{builder}) {
    581 	    my(@dep) = (@{$tgt->{dep}}, @{$tgt->{sources}});
    582 	    my($dep) = join(' ',map($_->path, @dep));
    583 	    print("Target $path: $dep\n");
    584 	} else {
    585 	    print("Target $path: not a derived file\n");
    586 	}
    587     }
    588     if ($param::build) {
    589 	return build $tgt;
    590     } elsif ($param::pflag || $param::wflag || $param::aflag) {
    591 	if ($tgt->{builder}) {
    592 	    if ($param::wflag) {
    593 		print qq(${\$tgt->path}: $tgt->{script}\n);
    594 	    } elsif ($param::pflag) {
    595 		print qq(${\$tgt->path}:\n) if $param::aflag;
    596 		print qq(${\$tgt->path}\n) if !$param::aflag;
    597 	    }
    598 	    if ($param::aflag) {
    599 		$tgt->{builder}->action($tgt);
    600 	    }
    601 	}
    602     } elsif ($param::rflag && $tgt->{builder}) {
    603 	my($path) = $tgt->path;
    604 	if (-f $path) {
    605 	    if (unlink($path)) {
    606 		print("Removed $path\n") if ($param::quiet < 1);
    607 	    } else {
    608 		warn("$0: couldn't remove $path\n");
    609 	    }
    610 	}
    611     }
    612 
    613     return "none";
    614 }
    615 
    616 package NameSpace;
    617 
    618 # Return a hash that maps the name of symbols in a namespace to an
    619 # array of refs for all types for which the name has a defined value.
    620 # A list of symbols may be specified; default is all symbols in the
    621 # name space.
    622 sub save {
    623     my $package = shift;
    624     my(%namerefs, $var, $type);
    625     no strict 'refs';
    626     @_ = keys %{$package."::"} if ! @_;
    627     foreach $var (@_) {
    628 	$namerefs{$var} = [];
    629 	my $fqvar = $package."::".$var;
    630 	# If the scalar for this variable name doesn't already
    631 	# exist, *foo{SCALAR} will autovivify the reference
    632 	# instead of returning undef, so unlike the other types,
    633 	# we have to dereference to find out if it exists.
    634 	push(@{$namerefs{$var}}, *{$fqvar}{SCALAR})
    635 		    if defined ${*{$fqvar}{SCALAR}};
    636 	foreach $type (qw(ARRAY HASH CODE IO)) {
    637 	    push(@{$namerefs{$var}}, *{$fqvar}{$type})
    638 			  if defined *{$fqvar}{$type};
    639 	}
    640     }
    641     return \%namerefs;
    642 }
    643 
    644 # Remove the specified symbols from the namespace.
    645 # Default is to remove all.
    646 sub remove {
    647     my $package = shift;
    648     my(%namerefs, $var);
    649     no strict 'refs';
    650     @_ = keys %{$package."::"} if ! @_;
    651     foreach $var (@_) {
    652 	delete ${$package."::"}{$var};
    653     }
    654 }
    655 
    656 # Restore values to symbols specified in a hash as returned
    657 # by NameSpace::save.
    658 sub restore {
    659     my($package, $namerefs) = @_;
    660     my($var, $ref);
    661     no strict 'refs';
    662     foreach $var (keys %$namerefs) {
    663 	my $fqvar = $package."::".$var;
    664 	foreach $ref (@{$namerefs->{$var}}) {
    665 	    *{$fqvar} = $ref;
    666 	}
    667     }
    668 }
    669 
    670 # Support for "building" scripts, importing and exporting variables.
    671 # With the exception of the top-level routine here (invoked from the
    672 # main package by cons), these are all invoked by user scripts.
    673 package script;
    674 
    675 use vars qw( $ARG $caller_dir_path %special_var );
    676 
    677 BEGIN {
    678     # We can't Export or Import the following variables because Perl always
    679     # treats them as part of the "main::" package (see perlvar(1)).
    680     %special_var = map {$_ => 1} qw(ENV INC ARGV ARGVOUT SIG
    681 				    STDIN STDOUT STDERR);
    682 }
    683 
    684 # This is called from main to interpret/run the top-level Construct
    685 # file, passed in as the single argument.
    686 sub main::doscripts {
    687     my($script) = @_;
    688     Build($script);
    689     # Now set up the includes/excludes (after the Construct file is read).
    690     $param::include = join('|', @param::include);
    691 
    692     # Save the original variable names from the script package.
    693     # These will stay intact, but any other "script::" variables
    694     # defined in a Conscript file will get saved, deleted,
    695     # and (when necessary) restored.
    696     my(%orig_script_var) = map {$_ => 1} keys %script::;
    697     $caller_dir_path = undef;
    698     my $cwd = Cwd::cwd();
    699     my(@scripts) = pop(@priv::scripts);
    700     while ($priv::self = shift(@scripts)) {
    701 	my($path) = $priv::self->{script}->rsrcpath;
    702 	if (-f $path) {
    703 	    $dir::cwd = $priv::self->{script}->{dir};
    704 	    # Handle chdir to the Conscript file directory, if necessary.
    705 	    my ($vol, $dir, $file);
    706 	    if ($param::conscript_chdir) {
    707 		($vol, $dir, $file) =
    708 		  File::Spec->splitpath(File::Spec->canonpath($path));
    709 		if ($vol ne '' || $dir ne '') {
    710 		    $caller_dir_path = File::Spec->catpath($vol, $dir, undef);
    711 		    chdir($caller_dir_path) ||
    712 			die "Could not chdir to $caller_dir_path: $!\n";
    713 		}
    714 	    } else {
    715 		$file = $path;
    716 	    }
    717 	    # Actually process the Conscript file.
    718 	    do $file;
    719 	    # Save any variables defined by the Conscript file
    720 	    # so we can restore them later, if needed;
    721 	    # then delete them from the script:: namespace.
    722 	    my(@del) = grep(! $orig_script_var{$_}, keys %script::);
    723 	    if (@del) {
    724 		$priv::self->{script}->{pkgvars} = NameSpace::save('script',
    725 								   @del);
    726 		NameSpace::remove('script', @del);
    727 	    }
    728 	    if ($caller_dir_path) {
    729 		chdir($cwd);
    730 		$caller_dir_path = undef;
    731 	    }
    732 	    if ($@) {
    733 		chomp($@);
    734 		my $err = ($@ =~ /\n/ms) ? ":\n$@" : " ($@)";
    735 		print qq($0: error in file "$path"$err\n);
    736 		$run::errors++;
    737 	    } else {
    738 		# Only process subsidiary scripts if no errors in parent.
    739 		unshift(@scripts, @priv::scripts);
    740 	    }
    741 	    undef @priv::scripts;
    742 	} else {
    743 	    my $where = '';
    744 	    my $cref = $priv::self->{script}->creator;
    745 	    if (defined $cref) {
    746 		my($_foo, $script, $line, $sub) = @$cref;
    747 		$where = " ($sub in $script, line $line)";
    748 	    }
    749 	    warn qq(Ignoring missing script "$path"$where);
    750 	}
    751     }
    752     die("$0: script errors encountered: construction aborted\n")
    753 	if $run::errors;
    754 }
    755 
    756 # Return caller info about the method being invoked.
    757 # This is everything from the Perl "caller" builtin function,
    758 # including which Construct/Conscript file, line number,
    759 # subroutine name, etc.
    760 sub caller_info {
    761     my($lev) = 1;
    762     my(@frame);
    763     do {
    764 	@frame = caller ++$lev;
    765 	if (defined($frame[3]) && $frame[3] eq '(eval)') {
    766 	    @frame = caller --$lev;
    767 	    if ($caller_dir_path) {
    768 		$frame[1] = File::Spec->catfile($caller_dir_path, $frame[1]);
    769 	    }
    770 	    return @frame;
    771 	}
    772     } while ($frame[3]);
    773     return;
    774 }
    775 
    776 # Link a directory to another. This simply means set up the *source*
    777 # for the directory to be the other directory.
    778 sub Link {
    779     dir::link(@_);
    780 }
    781 
    782 # Add directories to the repository search path for files.
    783 # Strip our current directory from the list so Repository
    784 # (or -R options) can be used from within the repository.
    785 sub Repository {
    786     my($my_dir) = Cwd::cwd();
    787     my $dir;
    788     foreach $dir (@_) {
    789 	# The following more direct call isn't available in
    790 	# Cwd.pm until some time after 5.003...
    791 	#	my($d) = Cwd::abs_path($dir);
    792 	chdir($dir);
    793 	my($d) = Cwd::cwd();
    794 	chdir($my_dir);
    795 	#
    796 	next if ! $d || ! -d $d || $d eq $my_dir;
    797 	# We know we can get away with passing undef to lookupdir
    798 	# as the directory because $dir is an absolute path.
    799 	push(@param::rpath, dir::lookupdir(undef, $dir));
    800 	push @INC, $d;
    801     }
    802 }
    803 
    804 # Return the list of Repository directories specified.
    805 sub Repository_List {
    806     map($_->path, @param::rpath);
    807 }
    808 
    809 # Specify whether the .consign signature times in repository files are,
    810 # in fact, consistent with the times on the files themselves.
    811 sub Repository_Sig_Times_OK {
    812     $param::rep_sig_times_ok = shift;
    813 }
    814 
    815 sub SourceSignature {
    816     $param::sourcesig = [@_];
    817 }
    818 
    819 # Specify whether we should chdir to the containing directories
    820 # of Conscript files.
    821 sub Conscript_chdir {
    822     $param::conscript_chdir = shift;
    823 }
    824 
    825 # Specify files/targets that must be present and built locally,
    826 # even if they exist already-built in a Repository.
    827 sub Local {
    828     my(@files) = map($dir::cwd->lookupfile($_), @_);
    829     map($_->local(1), @files);
    830 }
    831 
    832 # Export variables to any scripts invoked from this one.
    833 sub Export {
    834     my(@illegal) = grep($special_var{$_}, @_);
    835     if (@illegal) {
    836 	die qq($0: cannot Export special Perl variables: @illegal\n);
    837     }
    838     @{$priv::self->{exports}} = grep(! defined $special_var{$_}, @_);
    839 }
    840 
    841 # Import variables from the export list of the caller
    842 # of the current script.
    843 sub Import {
    844     my(@illegal) = grep($special_var{$_}, @_);
    845     if (@illegal) {
    846 	die qq($0: cannot Import special Perl variables: @illegal\n);
    847     }
    848     my($parent) = $priv::self->{parent};
    849     my($imports) = $priv::self->{imports};
    850     @{$priv::self->{exports}} = keys %$imports;
    851     my($var);
    852     foreach $var (grep(! defined $special_var{$_}, @_)) {
    853 	if (!exists $imports->{$var}) {
    854 	    my($path) = $parent->{script}->path;
    855 	    die qq($0: variable "$var" not exported by file "$path"\n);
    856 	}
    857 	if (!defined $imports->{$var}) {
    858 	    my $path = $parent->{script}->path;
    859 	    my $err = "$0: variable \"$var\" exported but not " .
    860 		      "defined by file \"$path\"\n";
    861 	    die $err;
    862 	}
    863 	${"script::$var"} = $imports->{$var};
    864     }
    865 }
    866 
    867 # Build an inferior script. That is, arrange to read and execute
    868 # the specified script, passing to it any exported variables from
    869 # the current script.
    870 sub Build {
    871     my(@files) = map($dir::cwd->lookupfile($_), @_);
    872     my(%imports) = map {$_ => ${"script::$_"}} @{$priv::self->{exports}};
    873     my $file;
    874     for $file (@files) {
    875 	next if $param::include && $file->path !~ /$param::include/o;
    876 	my($self) = {'script' => $file,
    877 		     'parent' => $priv::self,
    878 		     'imports' => \%imports};
    879 	bless $self;  # may want to bless into class of parent in future
    880 	push(@priv::scripts, $self);
    881     }
    882 }
    883 
    884 # Set up regexps dependencies to ignore. Should only be called once.
    885 sub Ignore {
    886     die("Ignore called more than once\n") if $param::ignore;
    887     $param::ignore = join("|", map("($_)", @_)) if @_;
    888 }
    889 
    890 # Specification of default targets.
    891 sub Default {
    892     push(@param::default_targets, map($dir::cwd->lookup($_)->path, @_));
    893 }
    894 
    895 # Local Help.  Should only be called once.
    896 sub Help {
    897     if ($param::localhelp) {
    898 	print "@_\n";
    899 	exit 2;
    900     }
    901 }
    902 
    903 # For windows platforms which use unix tool sets, the msvc defaults may
    904 # not be useful. Also, in the future, other platforms (Mac?) may have the
    905 # same problem.
    906 sub RuleSet {
    907     my $style = shift;
    908     my @rulesets = sort keys %param::rulesets;
    909     die "Unknown style for rules: $style.\n" .
    910 	"Supported rules are: (" . join(" ", @rulesets) . ")"
    911 	    unless eval(join("||", map("\$style eq '$_'", @rulesets)));
    912     return @param::base, @{$param::rulesets{$style}};
    913 }
    914 
    915 sub DefaultRules {
    916     @param::defaults = ();
    917     push @param::defaults, @_;
    918 }
    919 
    920 # Return the build name(s) of a file or file list.
    921 sub FilePath {
    922     wantarray
    923 	? map($dir::cwd->lookupfile($_)->path, @_)
    924 	: $dir::cwd->lookupfile($_[0])->path;
    925 }
    926 
    927 # Return the build name(s) of a directory or directory list.
    928 sub DirPath {
    929     wantarray
    930 	? map($dir::cwd->lookupdir($_)->path, @_)
    931 	: $dir::cwd->lookupdir($_[0])->path;
    932 }
    933 
    934 # Split the search path provided into components. Look each up
    935 # relative to the current directory.
    936 # The usual path separator problems abound; for now we'll use :
    937 sub SplitPath {
    938     my($dirs) = @_;
    939     if (ref($dirs) ne "ARRAY") {
    940 	$dirs = [ split(/$main::PATH_SEPARATOR/o, $dirs) ];
    941     }
    942     map { DirPath($_) } @$dirs;
    943 }
    944 
    945 # Return true if the supplied path is available as a source file
    946 # or is buildable (by rules seen to-date in the build).
    947 sub ConsPath {
    948     my($path) = @_;
    949     my($file) = $dir::cwd->lookup($path);
    950     return $file->accessible;
    951 }
    952 
    953 # Return the source path of the supplied path.
    954 sub SourcePath {
    955     wantarray
    956 	? map($dir::cwd->lookupfile($_)->rsrcpath, @_)
    957 	: $dir::cwd->lookupfile($_[0])->rsrcpath;
    958 }
    959 
    960 # Search up the tree for the specified cache directory, starting with
    961 # the current directory. Returns undef if not found, 1 otherwise.
    962 # If the directory is found, then caching is enabled. The directory
    963 # must be readable and writable. If the argument "mixtargets" is provided,
    964 # then targets may be mixed in the cache (two targets may share the same
    965 # cache file--not recommended).
    966 sub UseCache($@) {
    967     my($dir, @args) = @_;
    968     # NOTE: it's important to process arguments here regardless of whether
    969     # the cache is disabled temporarily, since the mixtargets option affects
    970     # the salt for derived signatures.
    971     for (@args) {
    972 	if ($_ eq "mixtargets") {
    973 	    # When mixtargets is enabled, we salt the target signatures.
    974 	    # This is done purely to avoid a scenario whereby if
    975 	    # mixtargets is turned on or off after doing builds, and
    976 	    # if cache synchronization with -cs is used, then
    977 	    # cache files may be shared in the cache itself (linked
    978 	    # under more than one name in the cache). This is not bad,
    979 	    # per se, but simply would mean that a cache cleaning algorithm
    980 	    # that looked for a link count of 1 would never find those
    981 	    # particular files; they would always appear to be in use.
    982 	    $param::salt = 'M' . $param::salt;
    983 	    $param::mixtargets = 1;
    984 	} else {
    985 	    die qq($0: UseCache unrecognized option "$_"\n);
    986 	}
    987     }
    988     if ($param::cachedisable) {
    989 	warn("Note: caching disabled by -cd flag\n");
    990 	return 1;
    991     }
    992     my($depth) = 15;
    993     while ($depth-- && ! -d $dir) {
    994 	$dir = File::Spec->catdir($dir::UPDIR, $dir);
    995     }
    996     if (-d $dir) {
    997 	$param::cache = $dir;
    998 	return 1;
    999     }
   1000     return undef;
   1001 }
   1002 
   1003 # Salt the signature generator. The salt (a number of string) is added
   1004 # into the signature of each derived file. Changing the salt will
   1005 # force recompilation of all derived files.
   1006 sub Salt($) {
   1007     # We append the value, so that UseCache and Salt may be used
   1008     # in either order without changing the signature calculation.
   1009     $param::salt .= $_[0];
   1010 }
   1011 
   1012 # Mark files (or directories) to not be removed before building.
   1013 sub Precious {
   1014     map($_->{precious} = 1, map($dir::cwd->lookup($_), @_));
   1015 }
   1016 
   1017 
   1018 # These methods are callable from Conscript files, via a cons
   1019 # object. Procs beginning with _ are intended for internal use.
   1020 package cons;
   1021 
   1022 use vars qw( %envcache );
   1023 
   1024 # This is passed the name of the base environment to instantiate.
   1025 # Overrides to the base environment may also be passed in
   1026 # as key/value pairs.
   1027 sub new {
   1028     my($package) = shift;
   1029     my ($env) = {@param::defaults, @_};
   1030     @{$env->{_envcopy}} = %$env; # Note: we never change PATH
   1031     $env->{_cwd} = $dir::cwd; # Save directory of environment for
   1032     bless $env, $package;	# any deferred name interpretation.
   1033 }
   1034 
   1035 # Clone an environment.
   1036 # Note that the working directory will be the initial directory
   1037 # of the original environment.
   1038 sub clone {
   1039     my($env) = shift;
   1040     my $clone = {@{$env->{_envcopy}}, @_};
   1041     @{$clone->{_envcopy}} = %$clone; # Note: we never change PATH
   1042     $clone->{_cwd} = $env->{_cwd};
   1043     bless $clone, ref $env;
   1044 }
   1045 
   1046 # Create a flattened hash representing the environment.
   1047 # It also contains a copy of the PATH, so that the path
   1048 # may be modified if it is converted back to a hash.
   1049 sub copy {
   1050     my($env) = shift;
   1051     (@{$env->{_envcopy}}, 'ENV' => {%{$env->{ENV}}}, @_)
   1052 }
   1053 
   1054 # Resolve which environment to actually use for a given
   1055 # target. This is just used for simple overrides.
   1056 sub _resolve {
   1057     return $_[0] if !$param::overrides;
   1058     my($env, $tgt) = @_;
   1059     my($path) = $tgt->path;
   1060     my $re;
   1061     for $re (@param::overrides) {
   1062 	next if $path !~ /$re/;
   1063 	# Found one. Return a combination of the original environment
   1064 	# and the override.
   1065 	my($ovr) = $param::overrides{$re};
   1066 	return $envcache{$env,$re} if $envcache{$env,$re};
   1067 	my($newenv) = {@{$env->{_envcopy}}, @$ovr};
   1068 	@{$newenv->{_envcopy}} = %$env;
   1069 	$newenv->{_cwd} = $env->{_cwd};
   1070 	return $envcache{$env,$re} = bless $newenv, ref $env;
   1071     }
   1072     return $env;
   1073 }
   1074 
   1075 # Substitute construction environment variables into a string.
   1076 # Internal function/method.
   1077 sub _subst {
   1078     my($env, $str) = @_;
   1079     if (! defined $str) {
   1080 	return undef;
   1081     } elsif (ref($str) eq "ARRAY") {
   1082 	return [ map($env->_subst($_), @$str) ];
   1083     } else {
   1084 	# % expansion.  %% gets converted to % later, so expand any
   1085 	# %keyword construction that doesn't have a % in front of it,
   1086 	# modulo multiple %% pairs in between.
   1087 	# In Perl 5.005 and later, we could actually do this in one regex
   1088 	# using a conditional expression as follows,
   1089 	#	while ($str =~ s/($pre)\%(\{)?([_a-zA-Z]\w*)(?(2)\})/"$1".
   1090 	#                      $env->{$3}/ge) {}
   1091 	# The following two-step approach is backwards-compatible
   1092 	# to (at least) Perl5.003.
   1093 	my $pre = '^|[^\%](?:\%\%)*';
   1094 	while (($str =~ s/($pre)\%([_a-zA-Z]\w*)/$1.($env->{$2}||'')/ge) ||
   1095 	       ($str =~ s/($pre)\%\{([_a-zA-Z]\w*)\}/$1.($env->{$2}||'')/ge)) {
   1096 	}
   1097 	return $str;
   1098     }
   1099 }
   1100 
   1101 sub AfterBuild {
   1102     my($env) = shift;
   1103     my($perl_eval_str) = pop(@_);
   1104     my $file;
   1105     for $file (map($dir::cwd->lookup($_), @_)) {
   1106 	$file->{after_build_func} = $perl_eval_str;
   1107     }
   1108 }
   1109 
   1110 sub Install {
   1111     my($env) = shift;
   1112     my($tgtdir) = $dir::cwd->lookupdir($env->_subst(shift));
   1113     my $file;
   1114     for $file (map($dir::cwd->lookupfile($env->_subst($_)), @_)) {
   1115 	my($tgt) = $tgtdir->lookupfile($file->{entry});
   1116 	$tgt->bind(find build::install($env), $file);
   1117     }
   1118 }
   1119 
   1120 sub InstallAs {
   1121     my $env = shift;
   1122     my $tgt = shift;
   1123     my $src = shift;
   1124     my @sources = ();
   1125     my @targets = ();
   1126 
   1127     if (ref $tgt) {
   1128 	die "InstallAs: Source is a file and target is a list!\n"
   1129 	    if (!ref($src));
   1130 	@sources = @$src;
   1131 	@targets = @$tgt;
   1132     } elsif (ref $src) {
   1133 	die "InstallAs: Target is a file and source is a list!\n";
   1134     } else {
   1135 	push @sources, $src;
   1136 	push @targets, $tgt;
   1137     }
   1138 
   1139     if ($#sources != $#targets) {
   1140 	my $tn = $#targets+1;
   1141 	my $sn = $#sources+1;
   1142 	die "InstallAs: Source file list ($sn) and target file list ($tn) " .
   1143 	    "are inconsistent in length!\n";
   1144     } else {
   1145 	foreach (0..$#sources) {
   1146 	    my $tfile = $dir::cwd->lookupfile($env->_subst($targets[$_]));
   1147 	    my $sfile = $dir::cwd->lookupfile($env->_subst($sources[$_]));
   1148 	    $tfile->bind(find build::install($env), $sfile);
   1149 	}
   1150     }
   1151 }
   1152 
   1153 # Installation in a local build directory,
   1154 # copying from the repository if it's already built there.
   1155 # Functionally equivalent to:
   1156 #	Install $env $dir, $file;
   1157 #	Local "$dir/$file";
   1158 sub Install_Local {
   1159     my($env) = shift;
   1160     my($tgtdir) = $dir::cwd->lookupdir($env->_subst(shift));
   1161     my $file;
   1162     for $file (map($dir::cwd->lookupfile($env->_subst($_)), @_)) {
   1163 	my($tgt) = $tgtdir->lookupfile($file->{entry});
   1164 	$tgt->bind(find build::install($env), $file);
   1165 	$tgt->local(1);
   1166     }
   1167 }
   1168 
   1169 sub Objects {
   1170     my($env) = shift;
   1171     map($dir::cwd->relpath($_), $env->_Objects(@_));
   1172 }
   1173 
   1174 # Called with multiple source file references (or object files).
   1175 # Returns corresponding object files references.
   1176 sub _Objects {
   1177     my($env) = shift;
   1178     my($suffix) = $env->{SUFOBJ};
   1179     map($env->_Object($_, $_->{dir}->lookupfile($_->base_suf($suffix))),
   1180 	map { ref $_ ? $_ : $dir::cwd->lookupfile($env->_subst($_)) }
   1181 		grep(defined $_, @_));
   1182 }
   1183 
   1184 # Called with an object and source reference.  If no object reference
   1185 # is supplied, then the object file is determined implicitly from the
   1186 # source file's extension. Sets up the appropriate rules for creating
   1187 # the object from the source.  Returns the object reference.
   1188 sub _Object {
   1189     my($env, $src, $obj) = @_;
   1190     return $obj if $src eq $obj; # don't need to build self from self.
   1191     my($objenv) = $env->_resolve($obj);
   1192     my($suffix) = $src->suffix;
   1193 
   1194     my($builder) = $env->{SUFMAP}{$suffix};
   1195 
   1196     if ($builder) {
   1197 	$obj->bind((find $builder($objenv)), $src);
   1198     } else {
   1199 	die("don't know how to construct ${\$obj->path} from " .
   1200 	    "${\$src->path}.\n");
   1201     }
   1202     $obj
   1203 }
   1204 
   1205 sub Program {
   1206     my($env) = shift;
   1207     my($tgt) = $dir::cwd->lookupfile(file::addsuffix($env->_subst(shift),
   1208 						 $env->{SUFEXE}));
   1209     my($progenv) = $env->_resolve($tgt);
   1210     $tgt->bind(find build::command::link($progenv, $progenv->{LINKCOM}),
   1211 	       $env->_Objects(@_));
   1212 }
   1213 
   1214 sub Module {
   1215     my($env) = shift;
   1216     my($tgt) = $dir::cwd->lookupfile($env->_subst(shift));
   1217     my($modenv) = $env->_resolve($tgt);
   1218     my($com) = pop(@_);
   1219     $tgt->bind(find build::command::link($modenv, $com), $env->_Objects(@_));
   1220 }
   1221 
   1222 sub LinkedModule {
   1223     my($env) = shift;
   1224     my($tgt) = $dir::cwd->lookupfile($env->_subst(shift));
   1225     my($progenv) = $env->_resolve($tgt);
   1226     $tgt->bind(find build::command::linkedmodule
   1227 	       ($progenv, $progenv->{LINKMODULECOM}),
   1228 	       $env->_Objects(@_));
   1229 }
   1230 
   1231 sub Library {
   1232     my($env) = shift;
   1233     my($lib) = $dir::cwd->lookupfile(file::addsuffix($env->_subst(shift),
   1234 						 $env->{SUFLIB}));
   1235     my($libenv) = $env->_resolve($lib);
   1236     $lib->bind(find build::command::library($libenv), $env->_Objects(@_));
   1237 }
   1238 
   1239 # Simple derivation: you provide target, source(s), command.
   1240 # Special variables substitute into the rule.
   1241 # Target may be a reference, in which case it is taken
   1242 # to be a multiple target (all targets built at once).
   1243 sub Command {
   1244     my($env) = shift;
   1245     my($tgt) = $env->_subst(shift);
   1246     my($builder) = find build::command::user($env, pop(@_), 'script');
   1247     my(@sources) = map($dir::cwd->lookupfile($env->_subst($_)), @_);
   1248     if (ref($tgt)) {
   1249 	# A multi-target command.
   1250 	my(@tgts) = map($dir::cwd->lookupfile($_), @$tgt);
   1251 	die("empty target list in multi-target command\n") if !@tgts;
   1252 	$env = $env->_resolve($tgts[0]);
   1253 	my($multi) = build::multiple->new($builder, \@tgts);
   1254 	for $tgt (@tgts) {
   1255 	    $tgt->bind($multi, @sources);
   1256 	}
   1257     } else {
   1258 	$tgt = $dir::cwd->lookupfile($tgt);
   1259 	$env = $env->_resolve($tgt);
   1260 	$tgt->bind($builder, @sources);
   1261     }
   1262 }
   1263 
   1264 sub Depends {
   1265     my($env) = shift;
   1266     my($tgt) = $env->_subst(shift);
   1267     my(@deps) = map($dir::cwd->lookup($env->_subst($_)), @_);
   1268     if (! ref($tgt)) {
   1269 	$tgt = [ $tgt ];
   1270     }
   1271     my($t);
   1272     foreach $t (map($dir::cwd->lookupfile($_), @$tgt)) {
   1273 	push(@{$t->{dep}}, @deps);
   1274     }
   1275 }
   1276 
   1277 # Setup a quick scanner for the specified input file, for the
   1278 # associated environment. Any use of the input file will cause the
   1279 # scanner to be invoked, once only. The scanner sees just one line at
   1280 # a time of the file, and is expected to return a list of
   1281 # dependencies.
   1282 sub QuickScan {
   1283     my($env, $code, $file, $path) = @_;
   1284     $dir::cwd->lookup($env->_subst($file))->{'srcscan',$env} =
   1285 	find scan::quickscan($code, $env, $env->_subst($path));
   1286 }
   1287 
   1288 # Generic builder module. Just a few default methods.  Every derivable
   1289 # file must have a builder object of some sort attached.  Usually
   1290 # builder objects are shared.
   1291 package build;
   1292 
   1293 use vars qw( %builder );
   1294 
   1295 # Every builder must now have at least an associated environment,
   1296 # so we can find its sigarray and calculate the proper signature.
   1297 sub find {
   1298     my($class, $env) = @_;
   1299     $builder{$env} || do {
   1300 	my $self = { env => $env };
   1301 	$builder{$env} = bless $self, $class;
   1302     }
   1303 }
   1304 
   1305 # Null signature for dynamic includes.
   1306 sub includes { () }
   1307 
   1308 # Null signature for build script.
   1309 sub scriptsig { () }
   1310 
   1311 # Not compatible with any other builder, by default.
   1312 sub compatible { 0 }
   1313 
   1314 
   1315 # Builder module for the Install command.
   1316 package build::install;
   1317 
   1318 use vars qw( @ISA );
   1319 
   1320 BEGIN { @ISA = qw(build) }
   1321 
   1322 # Caching not supported for Install: generally install is trivial anyway,
   1323 # and we don't want to clutter the cache.
   1324 sub cachin { undef }
   1325 sub cachout { }
   1326 
   1327 # Do the installation.
   1328 sub action {
   1329     my($self, $tgt) = @_;
   1330     my($src) = $tgt->{sources}[0];
   1331     main::showcom("Install ${\$src->rpath} as ${\$tgt->path}")
   1332 	if ($param::install && $param::quiet < 1);
   1333     return unless $param::build;
   1334     futil::install($src->rpath, $tgt);
   1335     return 1;
   1336 }
   1337 
   1338 
   1339 # Builder module for generic UNIX commands.
   1340 package build::command;
   1341 
   1342 use vars qw( @ISA %com );
   1343 
   1344 BEGIN { @ISA = qw(build) }
   1345 
   1346 sub find {
   1347     my($class, $env, $cmd, $package) = @_;
   1348     my($act) = action::new($env, $cmd);
   1349     $package ||= '';
   1350     $com{$env,$act,$package} || do {
   1351 	my $self = { env => $env, act => $act, 'package' => $package };
   1352 	$com{$env,$act,$package} = bless $self, $class;
   1353     }
   1354 }
   1355 
   1356 # Default cache in function.
   1357 sub cachin {
   1358     my($self, $tgt, $sig) = @_;
   1359     if (cache::in($tgt, $sig)) {
   1360 	if ($param::cachecom) {
   1361 	    $self->{act}->show($self->{env}, $tgt);
   1362 	} else {
   1363 	    printf("Retrieved %s from cache\n", $tgt->path)
   1364 		if ($param::quiet < 1);
   1365 	}
   1366 	return 1;
   1367     }
   1368     return undef;
   1369 }
   1370 
   1371 # Default cache out function.
   1372 sub cachout {
   1373     my($self, $tgt, $sig) = @_;
   1374     cache::out($tgt, $sig);
   1375 }
   1376 
   1377 # Build the target using the previously specified commands.
   1378 sub action {
   1379     my($self, $tgt) = @_;
   1380     $self->{act}->execute($self->{env}, $tgt, $self->{'package'});
   1381 }
   1382 
   1383 # Return script signature.
   1384 sub scriptsig {
   1385     $_[0]->{act}->scriptsig
   1386 }
   1387 
   1388 
   1389 # Create a linked module.
   1390 package build::command::link;
   1391 
   1392 use vars qw( @ISA );
   1393 
   1394 BEGIN { @ISA = qw(build::command) }
   1395 
   1396 # Find an appropriate linker.
   1397 sub find {
   1398     my($class, $env, $command) = @_;
   1399     if (!exists $env->{_LDIRS}) {
   1400 	my($ldirs) = '';
   1401 	my($wd) = $env->{_cwd};
   1402 	my($pdirs) = $env->{LIBPATH};
   1403 	if (! defined $pdirs) {
   1404 	    $pdirs = [ ];
   1405 	} elsif (ref($pdirs) ne 'ARRAY') {
   1406 	    $pdirs = [ split(/$main::PATH_SEPARATOR/o, $pdirs) ];
   1407 	}
   1408 	my($dir, $dpath);
   1409 	for $dir (map($wd->lookupdir($env->_subst($_)), @$pdirs)) {
   1410 	    $dpath = $dir->path;
   1411 	    # Add the (presumably local) directory to the -L flags
   1412 	    # if we're not using repositories, the directory exists,
   1413 	    # or it's Linked to a source directory (that is, it *will*
   1414 	    # exist by the time the link occurs).
   1415 	    $ldirs .= " ".$env->{LIBDIRPREFIX}.$dpath.$env->{LIBDIRSUFFIX}
   1416 			if ! @param::rpath || -d $dpath || $dir->is_linked;
   1417 	    next if File::Spec->file_name_is_absolute($dpath);
   1418 	    if (@param::rpath) {
   1419 		my $d;
   1420 		if ($dpath eq $dir::CURDIR) {
   1421 		    foreach $d (map($_->path, @param::rpath)) {
   1422 			$ldirs .= " " . $env->{LIBDIRPREFIX} .
   1423 				  $d . $env->{LIBDIRSUFFIX};
   1424 		    }
   1425 		} else {
   1426 		    my($rpath);
   1427 		    foreach $d (map($_->path, @param::rpath)) {
   1428 			$rpath = File::Spec->catfile($d, $dpath);
   1429 			$ldirs .= " ". $env->{LIBDIRPREFIX} .
   1430 				  $rpath . $env->{LIBDIRSUFFIX} if -d $rpath;
   1431 		    }
   1432 		}
   1433 	    }
   1434 	}
   1435 	$env->{_LDIRS} = "%($ldirs%)";
   1436     }
   1437 
   1438     # Introduce a new magic _LIBS symbol which allows to use the
   1439     # Unix-style -lNAME syntax for Win32 only. -lNAME will be replaced
   1440     # with %{PREFLIB}NAME%{SUFLIB}. <schwarze@isa.de> 1998-06-18
   1441 
   1442     if ($main::_WIN32 && !exists $env->{_LIBS}) {
   1443 	my $libs;
   1444 	my $name;
   1445 	for $name (split(' ', $env->_subst($env->{LIBS} || ''))) {
   1446 	    if ($name =~ /^-l(.*)/) {
   1447 		$name = "$env->{PREFLIB}$1$env->{SUFLIB}";
   1448 	    }
   1449 	    $libs .= ' ' . $name;
   1450 	}
   1451 	$env->{_LIBS} = $libs ? "%($libs%)" : '';
   1452     }
   1453     bless find build::command($env, $command);
   1454 }
   1455 
   1456 # Called from file::build. Make sure any libraries needed by the
   1457 # environment are built, and return the collected signatures
   1458 # of the libraries in the path.
   1459 sub includes {
   1460     return $_[0]->{'bsig'} if exists $_[0]->{'bsig'};
   1461     my($self, $tgt) = @_;
   1462     my($env) = $self->{env};
   1463     my($ewd) = $env->{_cwd};
   1464     my $ldirs = $env->{LIBPATH};
   1465     if (! defined $ldirs) {
   1466 	$ldirs = [ ];
   1467     } elsif (ref($ldirs) ne 'ARRAY') {
   1468 	$ldirs = [ split(/$main::PATH_SEPARATOR/o, $ldirs) ];
   1469     }
   1470     my @lpath = map($ewd->lookupdir($_), @$ldirs);
   1471     my(@sigs);
   1472     my(@names);
   1473 
   1474     # Pass %LIBS symbol through %-substituition
   1475     # <schwarze@isa.de> 1998-06-18
   1476     @names = split(' ', $env->_subst($env->{LIBS} || ''));
   1477     my $name;
   1478     for $name (@names) {
   1479 	my ($lpath, @allnames);
   1480 	if ($name =~ /^-l(.*)/) {
   1481 	    # -l style names are looked up on LIBPATH, using all
   1482 	    # possible lib suffixes in the same search order the
   1483 	    # linker uses (according to SUFLIBS).
   1484 	    # Recognize new PREFLIB symbol, which should be 'lib' on
   1485 	    # Unix, and empty on Win32. TODO: What about shared
   1486 	    # library suffixes?  <schwarze@isa.de> 1998-05-13
   1487 	   @allnames = map("$env->{PREFLIB}$1$_",
   1488 			   split(/:/, $env->{SUFLIBS}));
   1489 	    $lpath = \@lpath;
   1490 	} else {
   1491 	    @allnames = ($name);
   1492 	    # On Win32, all library names are looked up in LIBPATH
   1493 	    # <schwarze@isa.de> 1998-05-13
   1494 	    if ($main::_WIN32) {
   1495 		$lpath = [$dir::top, @lpath];
   1496 	    }
   1497 	    else {
   1498 		$lpath = [$dir::top];
   1499 	    }
   1500 	}
   1501 	my $dir;
   1502 	DIR: for $dir (@$lpath) {
   1503 	    my $n;
   1504 	    for $n (@allnames) {
   1505 		my($lib) = $dir->lookup_accessible($n);
   1506 		if ($lib) {
   1507 		    last DIR if $lib->ignore;
   1508 		    if ((build $lib) eq 'errors') {
   1509 			$tgt->{status} = 'errors';
   1510 			return undef;
   1511 		    }
   1512 		    push(@sigs, 'sig'->signature($lib));
   1513 		    last DIR;
   1514 		}
   1515 	    }
   1516 	}
   1517     }
   1518     $self->{'bsig'} = 'sig'->collect(@sigs);
   1519 }
   1520 
   1521 # Always compatible with other such builders, so the user
   1522 # can define a single program or module from multiple places.
   1523 sub compatible {
   1524     my($self, $other) = @_;
   1525     ref($other) eq "build::command::link";
   1526 }
   1527 
   1528 # Link a program.
   1529 package build::command::linkedmodule;
   1530 
   1531 use vars qw( @ISA );
   1532 
   1533 BEGIN { @ISA = qw(build::command) }
   1534 
   1535 # Always compatible with other such builders, so the user
   1536 # can define a single linked module from multiple places.
   1537 sub compatible {
   1538     my($self, $other) = @_;
   1539     ref($other) eq "build::command::linkedmodule";
   1540 }
   1541 
   1542 # Builder for a C module
   1543 package build::command::cc;
   1544 
   1545 use vars qw( @ISA );
   1546 
   1547 BEGIN { @ISA = qw(build::command) }
   1548 
   1549 sub find {
   1550     $_[1]->{_cc} || do {
   1551 	my($class, $env) = @_;
   1552 	my($cpppath) = $env->_subst($env->{CPPPATH});
   1553 	my($cscanner) = find scan::cpp($env->{_cwd}, $cpppath);
   1554 	$env->{_IFLAGS} = "%(" . $cscanner->iflags($env) . "%)";
   1555 	my($self) = find build::command($env, $env->{CCCOM});
   1556 	$self->{scanner} = $cscanner;
   1557 	bless $env->{_cc} = $self;
   1558     }
   1559 }
   1560 
   1561 # Invoke the associated	 C scanner to get signature of included files.
   1562 sub includes {
   1563     my($self, $tgt) = @_;
   1564     $self->{scanner}->includes($tgt, $tgt->{sources}[0]);
   1565 }
   1566 
   1567 # Builder for a C++ module
   1568 package build::command::cxx;
   1569 
   1570 use vars qw( @ISA );
   1571 
   1572 BEGIN { @ISA = qw(build::command) }
   1573 
   1574 sub find {
   1575     $_[1]->{_cxx} || do {
   1576 	my($class, $env) = @_;
   1577 	my($cpppath) = $env->_subst($env->{CPPPATH});
   1578 	my($cscanner) = find scan::cpp($env->{_cwd}, $cpppath);
   1579 	$env->{_IFLAGS} = "%(" . $cscanner->iflags($env) . "%)";
   1580 	my($self) = find build::command($env, $env->{CXXCOM});
   1581 	$self->{scanner} = $cscanner;
   1582 	bless $env->{_cxx} = $self;
   1583     }
   1584 }
   1585 
   1586 # Invoke the associated	 C scanner to get signature of included files.
   1587 sub includes {
   1588     my($self, $tgt) = @_;
   1589     $self->{scanner}->includes($tgt, $tgt->{sources}[0]);
   1590 }
   1591 
   1592 # Builder for a user command (cons::Command).  We assume that a user
   1593 # command might be built and implement the appropriate dependencies on
   1594 # the command itself (actually, just on the first word of the command
   1595 # line).
   1596 package build::command::user;
   1597 
   1598 use vars qw( @ISA );
   1599 
   1600 BEGIN { @ISA = qw(build::command) }
   1601 
   1602 sub includes {
   1603     my($self, $tgt) = @_;
   1604     my($sig) = '';
   1605 
   1606     # Check for any quick scanners attached to source files.
   1607     my $dep;
   1608     for $dep (@{$tgt->{dep}}, @{$tgt->{sources}}) {
   1609 	my($scanner) = $dep->{'srcscan',$self->{env}};
   1610 	if ($scanner) {
   1611 	    $sig .= $scanner->includes($tgt, $dep);
   1612 	}
   1613     }
   1614 
   1615     # XXX Optimize this to not use ignored paths.
   1616     if (! exists $self->{_comsig}) {
   1617 	my($env) = $self->{env};
   1618 	$self->{_comsig} = '';
   1619 	my($com, $dir);
   1620       com:
   1621 	for $com ($self->{act}->commands) {
   1622 	    my($pdirs) = $env->{ENV}->{PATH};
   1623 	    if (! defined $pdirs) {
   1624 		$pdirs = [ ];
   1625 	    } elsif (ref($pdirs) ne 'ARRAY') {
   1626 		$pdirs = [ split(/$main::PATH_SEPARATOR/o, $pdirs) ];
   1627 	    }
   1628 	    for $dir (map($dir::top->lookupdir($_), @$pdirs)) {
   1629 		my($prog) = $dir->lookup_accessible($com);
   1630 		if ($prog) { # XXX Not checking execute permission.
   1631 		    if ((build $prog) eq 'errors') {
   1632 			$tgt->{status} = 'errors';
   1633 			return $sig;
   1634 		    }
   1635 		    next com if $prog->ignore;
   1636 		    $self->{_comsig} .= 'sig'->signature($prog);
   1637 		    next com;
   1638 		}
   1639 	    }
   1640 	}
   1641     }
   1642 
   1643     return $self->{_comsig} . $sig
   1644 }
   1645 
   1646 
   1647 # Builder for a library module (archive).
   1648 # We assume that a user command might be built and implement the
   1649 # appropriate dependencies on the command itself.
   1650 package build::command::library;
   1651 
   1652 use vars qw( @ISA );
   1653 
   1654 BEGIN { @ISA = qw(build::command) }
   1655 
   1656 sub find {
   1657     my($class, $env) = @_;
   1658     bless find build::command($env, $env->{ARCOM})
   1659 }
   1660 
   1661 # Always compatible with other library builders, so the user
   1662 # can define a single library from multiple places.
   1663 sub compatible {
   1664     my($self, $other) = @_;
   1665     ref($other) eq "build::command::library";
   1666 }
   1667 
   1668 # A multi-target builder.
   1669 # This allows multiple targets to be associated with a single build
   1670 # script, without forcing all the code to be aware of multiple targets.
   1671 package build::multiple;
   1672 
   1673 sub new {
   1674     my($class, $builder, $tgts) = @_;
   1675     bless { 'builder' => $builder, 'env' => $builder->{env}, 'tgts' => $tgts };
   1676 }
   1677 
   1678 sub scriptsig {
   1679     my($self, $tgt) = @_;
   1680     $self->{builder}->scriptsig($tgt);
   1681 }
   1682 
   1683 sub includes {
   1684     my($self, $tgt) = @_;
   1685     $self->{builder}->includes($tgt);
   1686 }
   1687 
   1688 sub compatible {
   1689     my($self, $tgt) = @_;
   1690     $self->{builder}->compatible($tgt);
   1691 }
   1692 
   1693 sub cachin {
   1694     my($self, $tgt, $sig) = @_;
   1695     $self->{builder}->cachin($tgt, $sig);
   1696 }
   1697 
   1698 sub cachout {
   1699     my($self, $tgt, $sig) = @_;
   1700     $self->{builder}->cachout($tgt, $sig);
   1701 }
   1702 
   1703 sub action {
   1704     my($self, $invoked_tgt) = @_;
   1705     return $self->{built} if exists $self->{built};
   1706 
   1707     # Make sure all targets in the group are unlinked before building any.
   1708     my($tgts) = $self->{tgts};
   1709     my $tgt;
   1710     for $tgt (@$tgts) {
   1711 	futil::mkdir($tgt->{dir});
   1712 	unlink($tgt->path) if ! $tgt->precious;
   1713     }
   1714 
   1715     # Now do the action to build all the targets. For consistency
   1716     # we always call the action on the first target, just so that
   1717     # $> is deterministic.
   1718     $self->{built} = $self->{builder}->action($tgts->[0]);
   1719 
   1720     # Now "build" all the other targets (except for the one
   1721     # we were called with). This guarantees that the signature
   1722     # of each target is updated appropriately. We force the
   1723     # targets to be built even if they have been previously
   1724     # considered and found to be OK; the only effect this
   1725     # has is to make sure that signature files are updated
   1726     # correctly.
   1727     for $tgt (@$tgts) {
   1728 	if ($tgt ne $invoked_tgt) {
   1729 	    delete $tgt->{status};
   1730 	    'sig'->invalidate($tgt);
   1731 	    build $tgt;
   1732 	}
   1733     }
   1734 
   1735     # Status of action.
   1736     $self->{built};
   1737 }
   1738 
   1739 package action;
   1740 
   1741 sub new {
   1742     my($env, $act) = @_;
   1743     if (ref($act) eq 'CODE') {
   1744 	return action::perl->new($act);
   1745     } else {
   1746 	return action::command->new($env, $act);
   1747     }
   1748 }
   1749 
   1750 package action::command;
   1751 
   1752 use vars qw( @ISA %cmd %_varopts $_varletters );
   1753 
   1754 BEGIN {
   1755     @ISA = $main::_WIN32 ? 'action::command::win32' : 'action::command::unix';
   1756 
   1757     # Internal hash for processing variable options.
   1758     # f: return file part
   1759     # d: return directory part
   1760     # F: return file part, but strip any suffix
   1761     # b: return full path, but strip any suffix (a.k.a. return basename)
   1762     # s: return only the suffix (or an empty string, if no suffix is there)
   1763     # a: return the absolute path to the file
   1764     # S: return the absolute path to a Linked source file
   1765     %_varopts = (
   1766 	'f' => sub { return $_[0]->{entry}; },
   1767 	'd' => sub { return $_[0]->{dir}->path; },
   1768 	'F' => sub { my $subst = $_[0]->{entry};
   1769 		     $subst =~ s/\.[^\.]+$//;
   1770 		     return $subst; },
   1771 	'b' => sub { my $subst =  $_[0]->path;
   1772 		     $subst =~ s/\.[^\.]+$//;
   1773 		     return $subst; },
   1774 	's' => sub { my $subst = $_[0]->{entry};
   1775 		     $subst =~ m/(\.[^\.]+)$/;
   1776 		     return $1; },
   1777 	'a' => sub { my $path = $_[0]->path;
   1778 		     if (! File::Spec->file_name_is_absolute($path)) {
   1779 			$path = File::Spec->catfile(Cwd::cwd(), $path);
   1780 		     }
   1781 		     return $path; },
   1782 	'S' => sub { my $path = $_[0]->srcpath;
   1783 		     if (! File::Spec->file_name_is_absolute($path)) {
   1784 			my $cwd = File::Spec->canonpath(Cwd::cwd());
   1785 			$path = File::Spec->catfile($cwd, $path);
   1786 		     }
   1787 		     return $path; },
   1788     );
   1789 
   1790     $_varletters = join('', keys %_varopts);
   1791 }
   1792 
   1793 # Internal routine for processing variable options.
   1794 # Options are specified in hash in the BEGIN block above.
   1795 # no option: return path to file (relative to top,
   1796 # or absolute if it's outside)
   1797 sub _variant {
   1798     my($opt, $file) = @_;
   1799     $opt = '' if ! defined $opt;
   1800     if (defined $_varopts{$opt}) {
   1801 	return &{$_varopts{$opt}}($file);
   1802     }
   1803     return $file->path;
   1804 }
   1805 
   1806 sub new {
   1807     my($class, $env, $cmd) = @_;
   1808     $cmd = $env->_subst($cmd);
   1809     $cmd{$env,$cmd} || do {
   1810 	# Remove unwanted bits from signature -- those bracketed by %( ... %)
   1811 	my $sigs = $cmd;
   1812 	my $sig = '';
   1813 	if (ref($sigs) eq 'ARRAY') {
   1814 	    # This is an array of commands..
   1815 	    my $f;
   1816 	    foreach $f (@$sigs) {
   1817 		$sig .= _strip($f);
   1818 	    }
   1819 	} else {
   1820 	    $sig = _strip($sigs);
   1821 	}
   1822 	my $self = { cmd => $cmd, cmdsig => 'sig'->cmdsig($sig) };
   1823 	$cmd{$env,$cmd} = bless $self, $class;
   1824     }
   1825 }
   1826 
   1827 sub _strip {
   1828     my $sig = shift;
   1829     $sig =~ s/^\@\s*//mg;
   1830     while ($sig =~ s/%\(([^%]|%[^\(])*?%\)//g) { }
   1831     $sig;
   1832 }
   1833 
   1834 sub scriptsig {
   1835     $_[0]->{cmdsig};
   1836 }
   1837 
   1838 # Return an array of all the commands (first word on each line).
   1839 sub commands {
   1840     my($self) = @_;
   1841     my(@cmds) = ();
   1842     my $com;
   1843     my $cmd = $self->{'cmd'};
   1844     my @allcoms;
   1845 
   1846     push @allcoms, ref $cmd ? @{$cmd} : split(/\n/, $cmd);
   1847 
   1848     for $com (@allcoms) {
   1849 	$com =~ s/^\s*//;
   1850 	$com =~ s/\s.*//;
   1851 	next if ! $com; # blank line
   1852 	push @cmds, $com;
   1853     }
   1854     @cmds;
   1855 }
   1856 
   1857 # For the signature of a basic command, we don't bother
   1858 # including the command itself. This is not strictly correct,
   1859 # and if we wanted to be rigorous, we might want to insist
   1860 # that the command was checked for all the basic commands
   1861 # like gcc, etc. For this reason we don't have an includes
   1862 # method.
   1863 
   1864 # Call this to get the command line script: an array of
   1865 # fully substituted commands.
   1866 sub getcoms {
   1867     my($self, $env, $tgt) = @_;
   1868     my(@coms);
   1869     my $com;
   1870     my @allcoms = ();
   1871     my $cmd = $self->{'cmd'};
   1872 
   1873     push @allcoms, ref $cmd ? @{$cmd} : split(/\n/, $cmd);
   1874 
   1875     for $com (@allcoms) {
   1876 	my(@src) = (undef, @{$tgt->{sources}});
   1877 	my(@src1) = @src;
   1878 
   1879 	next if $com =~ /^\s*$/;
   1880 
   1881 	# NOTE: we used to have a more elegant s//.../e solution
   1882 	# for the items below, but this caused a bus error...
   1883 
   1884 	# Remove %( and %) -- those are only used to bracket parts
   1885 	# of the command that we don't depend on.
   1886 	$com =~ s/%[()]//g;
   1887 
   1888 	# Deal with %n, n=1,9 and variants.
   1889 	while ($com =~ /%([1-9])(:([$_varletters]?))?/o) {
   1890 	    my($match) = $&;
   1891 	    my($src) = $src1[$1];
   1892 	    my($subst) = _variant($3, $src1[$1]->rfile);
   1893 	    undef $src[$1];
   1894 	    $com =~ s/$match/$subst/;
   1895 	}
   1896 
   1897 	# Deal with %0 aka %> and variants.
   1898 	while ($com =~ /%[0>](:([$_varletters]?))?/o) {
   1899 	    my($match) = $&;
   1900 	    my($subst) = _variant($2, $tgt);
   1901 	    $com =~ s/$match/$subst/;
   1902 	}
   1903 
   1904 	# Deal with %< (all sources except %n's already used)
   1905 	while ($com =~ /%<(:([$_varletters]?))?/o) {
   1906 	    my($match) = $&;
   1907 	    my @list = ();
   1908 	    foreach (@src) {
   1909 		push(@list, _variant($2, $_->rfile)) if $_;
   1910 	    }
   1911 	    my($subst) = join(' ', @list);
   1912 	    $com =~ s/$match/$subst/;
   1913 	}
   1914 
   1915 	# Deal with %[ %].
   1916 	$com =~ s{%\[(.*?)%\]}{
   1917 	    my($func, @args) = grep { $_ ne '' } split(/\s+/, $1);
   1918 	    die("$0: \"$func\" is not defined.\n")
   1919 		unless ($env->{$func});
   1920 	    &{$env->{$func}}(@args);
   1921 	}gex;
   1922 
   1923 	# Convert left-over %% into %.
   1924 	$com =~ s/%%/%/g;
   1925 
   1926 	# White space cleanup. XXX NO WAY FOR USER TO HAVE QUOTED SPACES
   1927 	$com = join(' ', split(' ', $com));
   1928 	next if $com =~ /^:/ && $com !~ /^:\S/;
   1929 	push(@coms, $com);
   1930     }
   1931     @coms
   1932 }
   1933 
   1934 # Build the target using the previously specified commands.
   1935 sub execute {
   1936     my($self, $env, $tgt, $package) = @_;
   1937 
   1938     if ($param::build) {
   1939 	futil::mkdir($tgt->{dir});
   1940 	unlink($tgt->path) if ! $tgt->precious;
   1941     }
   1942 
   1943     # Set environment.
   1944     map(delete $ENV{$_}, keys %ENV);
   1945     %ENV = %{$env->{ENV}};
   1946 
   1947     # Handle multi-line commands.
   1948     my $com;
   1949     for $com ($self->getcoms($env, $tgt)) {
   1950 	if ($com !~ s/^\@\s*//) {
   1951 	    main::showcom($com);
   1952 	}
   1953 	next if ! $param::build;
   1954 
   1955 	if ($com =~ /^\[perl\]\s*/) {
   1956 	    my $perlcmd = $';
   1957 	    my $status;
   1958 	    {
   1959 		# Restore the script package variables that were defined
   1960 		# in the Conscript file that defined this [perl] build,
   1961 		# so the code executes with the expected variables.
   1962 		# Then actually execute (eval) the [perl] command to build
   1963 		# the target, followed by cleaning up the name space
   1964 		# by deleting the package variables we just restored.
   1965 		my($pkgvars) = $tgt->{conscript}->{pkgvars};
   1966 		NameSpace::restore($package, $pkgvars) if $pkgvars;
   1967 		$status = eval "package $package; $perlcmd";
   1968 		NameSpace::remove($package, keys %$pkgvars) if $pkgvars;
   1969 	    }
   1970 	    if (!defined($status)) {
   1971 		warn "$0: *** Error during perl command eval: $@.\n";
   1972 		return undef;
   1973 	    } elsif ($status == 0) {
   1974 		warn "$0: *** Perl command returned $status "
   1975 		   . "(this indicates an error).\n";
   1976 		return undef;
   1977 	    }
   1978 	    next;
   1979 	}
   1980 	if (! $self->do_command($com, $tgt->path)) {
   1981 		return undef;
   1982 	}
   1983     }
   1984 
   1985     # success.
   1986     return 1;
   1987 }
   1988 
   1989 sub show {
   1990     my($self, $env, $tgt) = @_;
   1991     my $com;
   1992     for $com ($self->getcoms($env, $tgt)) {
   1993 	if ($com !~ /^\@\s*/) {
   1994 	    main::showcom($com);
   1995 	}
   1996     }
   1997 }
   1998 
   1999 package action::command::unix;
   2000 
   2001 sub do_command {
   2002     my($class, $com, $path) = @_;
   2003     my($pid) = fork();
   2004     die("$0: unable to fork child process ($!)\n") if !defined $pid;
   2005     if (!$pid) {
   2006 	# This is the child.  We eval the command to suppress -w
   2007 	# warnings about not reaching the statements afterwards.
   2008 	eval 'exec($com)';
   2009 	$com =~ s/\s.*//;
   2010 	die qq($0: failed to execute "$com" ($!). )
   2011 	  . qq(Is this an executable on path "$ENV{PATH}"?\n);
   2012     }
   2013     for (;;) {
   2014 	do {} until wait() == $pid;
   2015 	my ($b0, $b1) = ($? & 0xFF, $? >> 8);
   2016 	# Don't actually see 0177 on stopped process; is this necessary?
   2017 	next if $b0 == 0177; # process stopped; we can wait.
   2018 	if ($b0) {
   2019 	    my($core, $sig) = ($b0 & 0200, $b0 & 0177);
   2020 	    my($coremsg) = $core ? "; core dumped" : "";
   2021 	    $com =~ s/\s.*//;
   2022 	    my $err = "$0: *** \[$path\] $com terminated by signal " .
   2023 		  "$sig$coremsg\n";
   2024 	    warn $err;
   2025 	    return undef;
   2026 	}
   2027 	if ($b1) {
   2028 	    warn qq($0: *** [$path] Error $b1\n); # trying to be like make.
   2029 	    return undef;
   2030 	}
   2031 	last;
   2032     }
   2033     return 1;
   2034 }
   2035 
   2036 package action::command::win32;
   2037 
   2038 sub do_command {
   2039     my($class, $com, $path) = @_;
   2040     system($com);
   2041     if ($?) {
   2042 	my ($b0, $b1) = ($? & 0xFF, $? >> 8);
   2043 	my $err = $b1 || $?;
   2044 	my $warn = qq($0: *** [$path] Error $err);
   2045 	$warn .= " (executable not found in path?)" if $b1 == 0xFF;
   2046 	warn "$warn\n";
   2047 	return undef;
   2048     }
   2049     return 1;
   2050 }
   2051 
   2052 package action::perl;
   2053 
   2054 # THIS IS AN EXPERIMENTAL PACKAGE.  It's entirely possible that the
   2055 # interface may change as this gets completed, so use at your own risk.
   2056 #
   2057 # There are (at least) two issues that need to be solved before blessing
   2058 # this as a real, fully-supported feature:
   2059 #
   2060 #   --	We need to calculate a signature value for a Perl code ref, in
   2061 #	order to rebuild the target if there's a change to the Perl code
   2062 #	used to generate it.
   2063 #
   2064 #	This is not straightforward.  A B::Deparse package exists that
   2065 #	decompiles a coderef into text.  It's reportedly not completely
   2066 #	reliable for closures; it misses which variables are global, and
   2067 #	the values of private lexicals.  Nevertheless, it'd probably
   2068 #	be perfect for our purposes, except that it wasn't added until
   2069 #	some time between Perl 5.00502 and 5.00554, and doesn't seem to
   2070 #	really work until Perl 5.6.0, so by relying on it, we'd lose
   2071 #	support for Perl versions back to 5.003*.
   2072 #
   2073 #   --	Ideally, a code ref should be able to use something like
   2074 #	$env->_subst to fetch values from the construction environment
   2075 #	to modify its behavior without having to cut-and-paste code.
   2076 #	(Actually, since we pass the environment to the executed code
   2077 #	ref, there's no reason you can't do this with the code as it
   2078 #	stands today.)  But this REALLY complicates the signature
   2079 #	calculation, because now the actual signature would depend not
   2080 #	just on the code contents, but on the construction variables (or
   2081 #	maybe just the environment).
   2082 #
   2083 # A potentially valid workaround would be to use the contents of the
   2084 # Conscript file in which the code reference is defined as the code
   2085 # ref's signature.  This has the drawback of causing a recompilation of
   2086 # the target file even in response to unrelated changes in the Conscript
   2087 # file, but it would ensure correct builds without having to solve the
   2088 # messy issues of generating a signature directly from a code ref.
   2089 #
   2090 # Nevertheless, this seemed a useful enough skeleton of a feature that
   2091 # it made sense to release it in hopes that some practical experience
   2092 # will encourage someone to figure out how to solve the signature
   2093 # issues.  Or maybe we'll discover these aren't big issues in practice
   2094 # and end up blessing it as is.
   2095 
   2096 use vars qw( %code );
   2097 
   2098 sub new {
   2099     my($class, $cref) = @_;
   2100     $code{$cref} || do {
   2101 	my $sig = '';
   2102 	# Generating a code signature using B::Deparse doesn't really
   2103 	# work for us until Perl 5.6.0.  Here's the code in case
   2104 	# someone wants to use it.
   2105 	#use B::Deparse;
   2106 	#my $deparse = B::Deparse->new();
   2107 	#my $body = $deparse->coderef2text($cref);
   2108 	#$sig = $body;	# should be an MD5 sig
   2109 	my($self) = { cref => $cref, crefsig => $sig };
   2110 	$code{$cref} = bless $self, $class;
   2111     }
   2112 }
   2113 
   2114 sub scriptsig {
   2115     $_[0]->{crefsig}
   2116 }
   2117 
   2118 sub execute {
   2119     my($self, $env, $tgt) = @_;
   2120     if ($param::build) {
   2121 	futil::mkdir($tgt->{dir});
   2122 	unlink($tgt->path) if ! $tgt->precious;
   2123 	my($cref) = $self->{cref};
   2124 	&$cref($env, $tgt->path, map($_->rpath, @{$tgt->{sources}}));
   2125     }
   2126 }
   2127 
   2128 sub commands {
   2129     return ();
   2130 }
   2131 
   2132 
   2133 # Generic scanning module.
   2134 package scan;
   2135 
   2136 # Returns the signature of files included by the specified files on
   2137 # behalf of the associated target. Any errors in handling the included
   2138 # files are propagated to the target on whose behalf this processing
   2139 # is being done. Signatures are cached for each unique file/scanner
   2140 # pair.
   2141 sub includes {
   2142     my($self, $tgt, @files) = @_;
   2143     my(%files, $file);
   2144     my($inc) = $self->{includes} || ($self->{includes} = {});
   2145     while ($file = pop @files) {
   2146 	next if exists $files{$file};
   2147 	if ($inc->{$file}) {
   2148 	    push(@files, @{$inc->{$file}});
   2149 	    $files{$file} = 'sig'->signature($file->rfile);
   2150 	} else {
   2151 	    if ((build $file) eq 'errors') {
   2152 		$tgt->{status} = 'errors'; # tgt inherits build status
   2153 		return ();
   2154 	    }
   2155 	    $files{$file} = 'sig'->signature($file->rfile);
   2156 	    my(@includes) = $self->scan($file);
   2157 	    $inc->{$file} = \@includes;
   2158 	    push(@files, @includes);
   2159 	}
   2160     }
   2161     'sig'->collect(sort values %files)
   2162 }
   2163 
   2164 
   2165 # A simple scanner. This is used by the QuickScanfunction, to setup
   2166 # one-time target and environment-independent scanning for a source
   2167 # file. Only used for commands run by the Command method.
   2168 package scan::quickscan;
   2169 
   2170 use vars qw( @ISA %scanner );
   2171 
   2172 BEGIN { @ISA = qw(scan) }
   2173 
   2174 sub find {
   2175     my($class, $code, $env, $pdirs) = @_;
   2176     if (! defined $pdirs) {
   2177 	$pdirs = [ ] ;
   2178     } elsif (ref($pdirs) ne 'ARRAY') {
   2179 	$pdirs = [ split(/$main::PATH_SEPARATOR/o, $pdirs) ];
   2180     }
   2181     my(@path) = map { $dir::cwd->lookupdir($_) } @$pdirs;
   2182     my($spath) = "@path";
   2183     $scanner{$code,$env,$spath} || do {
   2184 	my($self) = { code => $code, env => $env, path => \@path };
   2185 	$scanner{$code,$env,$spath} = bless $self;
   2186     }
   2187 }
   2188 
   2189 # Scan the specified file for included file names.
   2190 sub scan {
   2191     my($self, $file) = @_;
   2192     my($code) = $self->{code};
   2193     my(@includes);
   2194     # File should have been built by now. If not, we'll ignore it.
   2195     return () unless open(SCAN, $file->rpath);
   2196     while(<SCAN>) {
   2197 	push(@includes, grep($_ ne '', &$code));
   2198     }
   2199     close(SCAN);
   2200     my($wd) = $file->{dir};
   2201     my(@files);
   2202     my $name;
   2203     for $name (@includes) {
   2204 	my $dir;
   2205 	for $dir ($file->{dir}, @{$self->{path}}) {
   2206 	    my($include) = $dir->lookup_accessible($name);
   2207 	    if ($include) {
   2208 		push(@files, $include) unless $include->ignore;
   2209 		last;
   2210 	    }
   2211 	}
   2212     }
   2213     @files
   2214 }
   2215 
   2216 
   2217 # CPP (C preprocessor) scanning module
   2218 package scan::cpp;
   2219 
   2220 use vars qw( @ISA %scanner );
   2221 
   2222 BEGIN { @ISA = qw(scan) }
   2223 
   2224 # For this constructor, provide the include path argument (colon
   2225 # separated). Each path is taken relative to the provided directory.
   2226 
   2227 # Note: a particular scanning object is assumed to always return the
   2228 # same result for the same input. This is why the search path is a
   2229 # parameter to the constructor for a CPP scanning object. We go to
   2230 # some pains to make sure that we return the same scanner object
   2231 # for the same path: otherwise we will unecessarily scan files.
   2232 sub find {
   2233     my($class, $dir, $pdirs) = @_;
   2234     if (! defined $pdirs) {
   2235 	$pdirs = [ ];
   2236     } elsif (ref($pdirs) ne 'ARRAY') {
   2237 	$pdirs = [ split(/$main::PATH_SEPARATOR/o, $pdirs) ];
   2238     }
   2239     my @path = map($dir->lookupdir($_), @$pdirs);
   2240     my($spath) = "@path";
   2241     $scanner{$spath} || do {
   2242 	my($self) = {'path' => \@path};
   2243 	$scanner{$spath} = bless $self;
   2244     }
   2245 }
   2246 
   2247 # Scan the specified file for include lines.
   2248 sub scan {
   2249     my($self, $file) = @_;
   2250     my($angles, $quotes);
   2251 
   2252     if (exists $file->{angles}) {
   2253 	$angles = $file->{angles};
   2254 	$quotes = $file->{quotes};
   2255     } else {
   2256 	my(@anglenames, @quotenames);
   2257 	return () unless open(SCAN, $file->rpath);
   2258 	while (<SCAN>) {
   2259 	    next unless /^\s*#/;
   2260 	    if (/^\s*#\s*include\s*([<"])(.*?)[>"]/) {
   2261 		if ($1 eq "<") {
   2262 		    push(@anglenames, $2);
   2263 		} else {
   2264 		    push(@quotenames, $2);
   2265 		}
   2266 	    }
   2267 	}
   2268 	close(SCAN);
   2269 	$angles = $file->{angles} = \@anglenames;
   2270 	$quotes = $file->{quotes} = \@quotenames;
   2271     }
   2272 
   2273 
   2274     my(@shortpath) = @{$self->{path}};	  # path for <> style includes
   2275     my(@longpath) = ($file->{dir}, @shortpath); # path for "" style includes
   2276 
   2277     my(@includes);
   2278 
   2279     my $name;
   2280     for $name (@$angles) {
   2281 	my $dir;
   2282 	for $dir (@shortpath) {
   2283 	    my($include) = $dir->lookup_accessible($name);
   2284 	    if ($include) {
   2285 		push(@includes, $include) unless $include->ignore;
   2286 		last;
   2287 	    }
   2288 	}
   2289     }
   2290 
   2291     for $name (@$quotes) {
   2292 	my $dir;
   2293 	for $dir(@longpath) {
   2294 	    my($include) = $dir->lookup_accessible($name);
   2295 	    if ($include) {
   2296 		push(@includes, $include) unless $include->ignore;
   2297 		last;
   2298 	    }
   2299 	}
   2300     }
   2301 
   2302     return @includes
   2303 }
   2304 
   2305 # Return the include flags that would be used for a C Compile.
   2306 sub iflags {
   2307     my($self, $env) = @_;
   2308     my($iflags) = '';
   2309     my($dir, $dpath);
   2310     for $dir (@{$self->{path}}) {
   2311 	$dpath = $dir->path;
   2312 	# Add the (presumably local) directory to the -I flags
   2313 	# if we're not using repositories, the directory exists,
   2314 	# or it's Linked to a source directory (that is, it *will*
   2315 	# exist by the time the compilation occurs).
   2316 	$iflags .= " ".$env->{INCDIRPREFIX}.$dpath.$env->{INCDIRSUFFIX}
   2317 		if ! @param::rpath || -d $dpath || $dir->is_linked;
   2318 	next if File::Spec->file_name_is_absolute($dpath);
   2319 	if (@param::rpath) {
   2320 	    my $d;
   2321 	    if ($dpath eq $dir::CURDIR) {
   2322 		foreach $d (map($_->path, @param::rpath)) {
   2323 		    $iflags .= " ".$env->{INCDIRPREFIX}.$d.$env->{INCDIRSUFFIX};
   2324 		}
   2325 	    } else {
   2326 		my($rpath);
   2327 		foreach $d (map($_->path, @param::rpath)) {
   2328 		    $rpath = File::Spec->catfile($d, $dpath);
   2329 		    $iflags .= " ".$env->{INCDIRPREFIX}.$rpath.$env->{INCDIRSUFFIX}
   2330 				if -d $rpath;
   2331 		}
   2332 	    }
   2333 	}
   2334     }
   2335     $iflags
   2336 }
   2337 
   2338 package File::Spec;
   2339 
   2340 use vars qw( $_SEP $_MATCH_SEP $_MATCH_VOL );
   2341 
   2342 # Cons is migrating to using File::Spec for portable path name
   2343 # manipulation.  This is the right long-term direction, but there are
   2344 # some problems with making the transition:
   2345 #
   2346 #	For multi-volume support, we need to use newer interfaces
   2347 #	(splitpath, catpath, splitdir) that are only available in
   2348 #	File::Spec 0.8.
   2349 #
   2350 #	File::Spec 0.8 doesn't work with Perl 5.00[34] due to
   2351 #	regular expression incompatibilities (use of \z).
   2352 #
   2353 #	Forcing people to use a new version of a module is painful
   2354 #	because (in the workplace) their administrators aren't
   2355 #	always going to agree to install it everywhere.
   2356 #
   2357 # As a middle ground, we provide our own versions of all the File::Spec
   2358 # methods we use, supporting both UNIX and Win32.  Some of these methods
   2359 # are home brew, some are cut-and-pasted from the real File::Spec methods.
   2360 # This way, we're not reinventing the whole wheel, at least.
   2361 #
   2362 # We can (and should) get rid of this class whenever 5.00[34] and
   2363 # versions of File::Spec prior to 0.9 (?) have faded sufficiently.
   2364 # We also may need to revisit whenever someone first wants to use
   2365 # Cons on some platform other than UNIX or Win32.
   2366 
   2367 BEGIN {
   2368     if ($main::_WIN32) {
   2369 	$_SEP = '\\';
   2370 	$_MATCH_SEP = "[\Q/$_SEP\E]";
   2371 	$_MATCH_VOL = "([a-z]:)?$_MATCH_SEP";
   2372     } else {
   2373 	$_SEP = '/';
   2374 	$_MATCH_SEP = "\Q$_SEP\E";
   2375 	$_MATCH_VOL = $_MATCH_SEP;
   2376     }
   2377 }
   2378 
   2379 sub canonpath {
   2380     my ($self, $path) = @_;
   2381     if ($main::_WIN32) {
   2382 	$path =~ s/^([a-z]:)/\u$1/s;
   2383 	$path =~ s|/|\\|g;
   2384 	$path =~ s|([^\\])\\+|$1\\|g;                  # xx////xx  -> xx/xx
   2385 	$path =~ s|(\\\.)+\\|\\|g;                     # xx/././xx -> xx/xx
   2386 	$path =~ s|^(\.\\)+||s unless $path eq ".\\";  # ./xx      -> xx
   2387 	$path =~ s|\\$||
   2388 		 unless $path =~ m#^([A-Z]:)?\\$#s;   # xx/       -> xx
   2389     } else {
   2390 	$path =~ s|/+|/|g unless($^O eq 'cygwin');     # xx////xx  -> xx/xx
   2391 	$path =~ s|(/\.)+/|/|g;                        # xx/././xx -> xx/xx
   2392 	$path =~ s|^(\./)+||s unless $path eq "./";    # ./xx      -> xx
   2393 	$path =~ s|^/(\.\./)+|/|s;                     # /../../xx -> xx
   2394 	$path =~ s|/$|| unless $path eq "/";          # xx/       -> xx
   2395     }
   2396     return $path;
   2397 }
   2398 
   2399 sub catdir {
   2400     my $self = shift;
   2401     my @args = @_;
   2402     foreach (@args) {
   2403 	# append a slash to each argument unless it has one there
   2404 	$_ .= $_SEP if $_ eq '' || substr($_,-1) ne $_SEP;
   2405     }
   2406     return $self->canonpath(join('', @args));
   2407 }
   2408 
   2409 sub catfile {
   2410     my $self = shift;
   2411     my $file = pop @_;
   2412     return $file unless @_;
   2413     my $dir = $self->catdir(@_);
   2414     $dir .= $_SEP unless substr($dir,-1) eq $_SEP;
   2415     $file = '' if ! defined($file);
   2416     return $dir.$file;
   2417 }
   2418 
   2419 sub catpath {
   2420     my $path = $_[1] . $_[0]->catfile(@_[2..$#_]);
   2421     $path =~ s/(.)$_MATCH_SEP*$/$1/;
   2422     $path;
   2423 }
   2424 
   2425 sub curdir {
   2426     '.'
   2427 }
   2428 
   2429 sub file_name_is_absolute {
   2430     my ($self, $file) = @_;
   2431     return scalar($file =~ m{^$_MATCH_VOL}is);
   2432 }
   2433 
   2434 sub splitdir {
   2435     my @dirs = split(/$_MATCH_SEP/, $_[1], -1);
   2436     push(@dirs, '') if $dirs[$#dirs];
   2437     @dirs;
   2438 }
   2439 
   2440 sub splitpath {
   2441     my ($self, $path) = @_;
   2442     my $vol = '';
   2443     my $sep = $_SEP;
   2444     if ($main::_WIN32) {
   2445 	if ($path =~ s#^([A-Za-z]:|(?:\\\\|//)[^\\/]+[\\/][^\\/]+)([\\/])#$2#) {
   2446 	    $vol = $1;
   2447 	    $sep = $2;
   2448 	}
   2449     }
   2450     my(@path) = split(/$_MATCH_SEP/, $path, -1);
   2451     my $file = pop @path;
   2452     my $dirs = join($sep, @path, '');
   2453     return ($vol, $dirs, $file);
   2454 }
   2455 
   2456 sub updir {
   2457     '..'
   2458 }
   2459 
   2460 sub case_tolerant {
   2461     return $main::_WIN32;
   2462 }
   2463 
   2464 # Directory and file handling. Files/dirs are represented by objects.
   2465 # Other packages are welcome to add component-specific attributes.
   2466 package dir;
   2467 
   2468 use vars qw( $SEPARATOR $MATCH_SEPARATOR $CURDIR $UPDIR
   2469 	     $cwd_vol %root $top $cwd );
   2470 
   2471 BEGIN {
   2472     # A portable way of determing our directory separator.
   2473     $SEPARATOR = File::Spec->catdir('', '');
   2474     # A fast-path regular expression to match a directory separator
   2475     # anywhere in a path name.
   2476     if ($SEPARATOR eq '/') {
   2477 	$MATCH_SEPARATOR = "\Q$SEPARATOR\E";
   2478     } else {
   2479 	$MATCH_SEPARATOR = "[\Q/$SEPARATOR\E]";
   2480     }
   2481     # Cache these values so we don't have to make a method call
   2482     # every time we need them.
   2483     $CURDIR = File::Spec->curdir;	# '.' on UNIX
   2484     $UPDIR = File::Spec->updir;	# '..' on UNIX
   2485     #
   2486     $cwd_vol = '';
   2487 }
   2488 
   2489 # Annotate a node (file or directory) with info about the
   2490 # method that created it.
   2491 sub creator {
   2492     my($self, @frame) = @_;
   2493     $self->{'creator'} = \@frame if @frame;
   2494     $self->{'creator'};
   2495 }
   2496 
   2497 # Handle a file|dir type exception.  We only die if we find we were
   2498 # invoked by something in a Conscript/Construct file, because
   2499 # dependencies created directly by Cons' analysis shouldn't cause
   2500 # an error.
   2501 sub _type_exception {
   2502     my($e) = @_;
   2503     my($line, $sub);
   2504     (undef, undef, $line, $sub) = script::caller_info;
   2505     if (defined $line) {
   2506 	my $err = "\"${\$e->path}\" already in use as a " . ref($e) . " before $sub on line $line";
   2507 	if ($e->{'creator'}) {
   2508 	    my $script;
   2509 	    (undef, $script, $line, $sub) = @{$e->{'creator'}};
   2510 	    $err = "\t" . $err . ",\n\t\tdefined by $sub in $script, line $line";
   2511 	}
   2512 	$err .= "\n";
   2513 	die $err;
   2514     }
   2515 }
   2516 
   2517 # This wraps up all the common File::Spec logic that we use for parsing
   2518 # directory separators in a path and turning it into individual
   2519 # subdirectories that we must create, as well as creation of root
   2520 # nodes for any new file system volumes we find.  File::Spec doesn't have
   2521 # intuitively obvious interfaces, so this is heavily commented.
   2522 #
   2523 # Note:  This is NOT an object or class method;
   2524 # it's just a utility subroutine.
   2525 sub _parse_path {
   2526     my($dir, $path) = @_;
   2527 
   2528     # Convert all slashes to the native directory separator.
   2529     # This allows Construct files to always be written with good
   2530     # old POSIX path names, regardless of what we're running on.
   2531     $path = File::Spec->canonpath($path);
   2532 
   2533     # File::Spec doesn't understand the Cons convention of
   2534     # an initial '#' for top-relative files.  Strip it.
   2535     my($toprel) = $path =~ s/^#//;
   2536 
   2537     # Let File::Spec do the heavy lifting of parsing the path name.
   2538     my($vol, $directories, $entry) = File::Spec->splitpath($path);
   2539     my @dirs = File::Spec->splitdir($directories);
   2540 
   2541     # If there was a file entry on the end of the path, then the
   2542     # last @dirs element is '' and we don't need it.  If there
   2543     # wasn't a file entry on the end (File::Spec->splitpath() knew
   2544     # the last component was a directory), then the last @dirs
   2545     # element becomes the entry we want to look up.
   2546     my($e) = pop @dirs;
   2547     $entry = $e if $entry eq '';
   2548 
   2549     if (File::Spec->file_name_is_absolute($path)) {
   2550 	# An absolute path name.  If no volume was supplied,
   2551 	# use the volume of our current directory.
   2552 	$vol = $cwd_vol if $vol eq '';
   2553 	$vol = uc($vol) if File::Spec->case_tolerant;
   2554 	if (! defined $root{$vol}) {
   2555 	    # This is our first time looking up a path name
   2556 	    # on this volume, so create a root node for it.
   2557 	    # (On UNIX systems, $vol is always '', so '/'
   2558 	    # always maps to the $root{''} node.)
   2559 	    $root{$vol} = {path => $vol.$SEPARATOR,
   2560 			prefix => $vol.$SEPARATOR,
   2561 			srcpath => $vol.$SEPARATOR,
   2562 			'exists' => 1 };
   2563 	    $root{$vol}->{'srcdir'} = $root{$vol};
   2564 	    bless $root{$vol};
   2565 	}
   2566 	# We're at the top, so strip the blank entry from the front of
   2567 	# the @dirs array since the initial '/' it represents will now
   2568 	# be supplied by the root node we return.
   2569 	shift @dirs;
   2570 	$dir = $root{$vol};
   2571     } elsif ($toprel) {
   2572 	$dir = $dir::top;
   2573     }
   2574     ($dir, \@dirs, $entry);
   2575 }
   2576 
   2577 # Common subroutine for creating directory nodes.
   2578 sub _create_dirs {
   2579     my ($dir, @dirs) = @_;
   2580     my $e;
   2581     foreach $e (@dirs) {
   2582 	my $d = $dir->{member}->{$e};
   2583 	if (! defined $d) {
   2584 	    bless $d = { 'entry' => $e, 'dir' => $dir, }, 'dir';
   2585 	    $d->creator(script::caller_info);
   2586 	    $d->{member}->{$dir::CURDIR} = $d;
   2587 	    $d->{member}->{$dir::UPDIR} = $dir;
   2588 	    $dir->{member}->{$e} = $d;
   2589 	} elsif (ref $d eq 'entry') {
   2590 	    bless $d, 'dir';
   2591 	    $d->{member}->{$dir::CURDIR} = $d;
   2592 	    $d->{member}->{$dir::UPDIR} = $dir;
   2593 	} elsif (ref $d eq 'file') {
   2594 	    # This clause is to supply backwards compatibility,
   2595 	    # with a warning, for anyone that's used FilePath
   2596 	    # to refer to a directory.  After people have using
   2597 	    # 1.8 have had time to adjust (sometime in version
   2598 	    # 1.9 or later), we should remove this entire clause.
   2599 	    my($script, $line, $sub);
   2600 	    (undef, $script, $line, $sub) = @{$d->{'creator'}};
   2601 	    if ($sub eq 'script::FilePath') {
   2602 		print STDERR "$0:  Warning:  $sub used to refer to a directory\n"
   2603 			. "\tat line $line of $script.  Use DirPath instead.\n";
   2604 		bless $d, 'dir';
   2605 	    } else {
   2606 		_type_exception($d);
   2607 	    }
   2608 	} elsif (ref $d ne 'dir') {
   2609 	    _type_exception($d);
   2610 	}
   2611 	$dir = $d;
   2612     }
   2613     $dir;
   2614 }
   2615 
   2616 # Look up an entry in a directory.  This method is for when we don't
   2617 # care whether a file or directory is returned, so if the entry already
   2618 # exists, it will simply be returned.  If not, we create it as a
   2619 # generic "entry" which can be later turned into a file or directory
   2620 # by a more-specific lookup.
   2621 #
   2622 # The file entry may be specified as relative, absolute (starts with /),
   2623 # or top-relative (starts with #).
   2624 sub lookup {
   2625     my($dir, $entry) = @_;
   2626 
   2627     if ($entry !~ m#$MATCH_SEPARATOR#o) {
   2628 	# Fast path: simple entry name in a known directory.
   2629 	if ($entry =~ s/^#//) {
   2630 	    # Top-relative names begin with #.
   2631 	    $dir = $dir::top;
   2632 	} elsif ($entry =~ s/^!//) {
   2633 	    $dir = $dir::cwd->srcdir;
   2634 	}
   2635     } else {
   2636 	my $dirsref;
   2637 	($dir, $dirsref, $entry) = _parse_path($dir, $entry);
   2638 	$dir = _create_dirs($dir, @$dirsref) if @$dirsref;
   2639 	return if ! defined $dir;
   2640 	return $dir if $entry eq '';
   2641     }
   2642 
   2643     my $e = $dir->{member}->{$entry};
   2644     if (! defined $e) {
   2645 	bless $e = { 'entry' => $entry, 'dir' => $dir, }, 'entry';
   2646 	$e->creator(script::caller_info);
   2647 	$dir->{member}->{$entry} = $e;
   2648     }
   2649 
   2650     $e;
   2651 }
   2652 
   2653 # Look up a file entry in a directory.
   2654 #
   2655 # The file entry may be specified as relative, absolute (starts with /),
   2656 # or top-relative (starts with #).
   2657 sub lookupfile {
   2658     my($dir, $entry) = @_;
   2659 
   2660     if ($entry !~ m#$MATCH_SEPARATOR#o) {
   2661 	# Fast path: simple entry name in a known directory.
   2662 	if ($entry =~ s/^#//) {
   2663 	    # Top-relative names begin with #.
   2664 	    $dir = $dir::top;
   2665 	} elsif ($entry =~ s/^!//) {
   2666 	    $dir = $dir::cwd->srcdir;
   2667 	}
   2668     } else {
   2669 	my $dirsref;
   2670 	($dir, $dirsref, $entry) = _parse_path($dir, $entry);
   2671 	$dir = _create_dirs($dir, @$dirsref) if @$dirsref;
   2672 	return undef if $entry eq '';
   2673     }
   2674 
   2675     my $f = $dir->{member}->{$entry};
   2676     if (! defined $f) {
   2677 	bless $f = { 'entry' => $entry, 'dir' => $dir, }, 'file';
   2678 	$f->creator(script::caller_info);
   2679 	$dir->{member}->{$entry} = $f;
   2680     } elsif (ref $f eq 'entry') {
   2681 	bless $f, 'file';
   2682     } elsif (ref $f ne 'file') {
   2683 	_type_exception($f);
   2684     }
   2685 
   2686     $f;
   2687 }
   2688 
   2689 # Look up a (sub-)directory entry in a directory.
   2690 #
   2691 # The (sub-)directory entry may be specified as relative, absolute
   2692 # (starts with /), or top-relative (starts with #).
   2693 sub lookupdir {
   2694     my($dir, $entry) = @_;
   2695 
   2696     my $dirsref;
   2697     if ($entry !~ m#$MATCH_SEPARATOR#o) {
   2698 	# Fast path: simple entry name in a known directory.
   2699 	if ($entry =~ s/^#//) {
   2700 	    # Top-relative names begin with #.
   2701 	    $dir = $dir::top;
   2702 	} elsif ($entry =~ s/^!//) {
   2703 	    $dir = $dir::cwd->srcdir;
   2704 	}
   2705     } else {
   2706 	($dir, $dirsref, $entry) = _parse_path($dir, $entry);
   2707     }
   2708     push(@$dirsref, $entry) if $entry ne '';
   2709     _create_dirs($dir, @$dirsref);
   2710 }
   2711 
   2712 # Look up a file entry and return it if it's accessible.
   2713 sub lookup_accessible {
   2714     my $file = $_[0]->lookupfile($_[1]);
   2715     return ($file && $file->accessible) ? $file : undef;
   2716 }
   2717 
   2718 # Return the parent directory without doing a lookupdir,
   2719 # which would create a parent if it doesn't already exist.
   2720 # A return value of undef (! $dir->up) indicates a root directory.
   2721 sub up {
   2722     $_[0]->{member}->{$dir::UPDIR};
   2723 }
   2724 
   2725 # Return whether this is an entry somewhere underneath the
   2726 # specified directory.
   2727 sub is_under {
   2728     my $dir = $_[0];
   2729     while ($dir) {
   2730 	return 1 if $_[1] == $dir;
   2731 	$dir = $dir->up;
   2732     }
   2733     return undef;
   2734 }
   2735 
   2736 # Return the relative path from the calling directory ($_[1])
   2737 # to the object.  If the object is not under the directory, then
   2738 # we return it as a top-relative or absolute path name.
   2739 sub relpath {
   2740     my ($dir, $obj) = @_;
   2741     my @dirs;
   2742     my $o = $obj;
   2743     while ($o) {
   2744 	if ($dir == $o) {
   2745 	    if (@dirs < 2) {
   2746 		return $dirs[0] || '';
   2747 	    } else {
   2748 		return File::Spec->catdir(@dirs);
   2749 	    }
   2750 	}
   2751 	unshift(@dirs, $o->{entry});
   2752 	$o = $o->up;
   2753     }
   2754     # The object was not underneath the specified directory.
   2755     # Use the node's cached path, which is either top-relative
   2756     # (in which case we append '#' to the beginning) or
   2757     # absolute.
   2758     my $p = $obj->path;
   2759     $p = '#' . $p if ! File::Spec->file_name_is_absolute($p);
   2760     return $p;
   2761 }
   2762 
   2763 # Return the path of the directory (file paths implemented
   2764 # separately, below).
   2765 sub path {
   2766     $_[0]->{path} ||
   2767 	($_[0]->{path} = $_[0]->{dir}->prefix . $_[0]->{entry});
   2768 }
   2769 
   2770 # Return the pathname as a prefix to be concatenated with an entry.
   2771 sub prefix {
   2772     return $_[0]->{prefix} if exists $_[0]->{prefix};
   2773     $_[0]->{prefix} = $_[0]->path . $SEPARATOR;
   2774 }
   2775 
   2776 # Return the related source path prefix.
   2777 sub srcprefix {
   2778     return $_[0]->{srcprefix} if exists $_[0]->{srcprefix};
   2779     my($srcdir) = $_[0]->srcdir;
   2780     $srcdir->{srcprefix} = $srcdir eq $_[0] ? $srcdir->prefix
   2781 					    : $srcdir->srcprefix;
   2782 }
   2783 
   2784 # Return the related source directory.
   2785 sub srcdir {
   2786     $_[0]->{'srcdir'} ||
   2787 	($_[0]->{'srcdir'} = $_[0]->{dir}->srcdir->lookupdir($_[0]->{entry}))
   2788 }
   2789 
   2790 # Return if the directory is linked to a separate source directory.
   2791 sub is_linked {
   2792     return $_[0]->{is_linked} if defined $_[0]->{is_linked};
   2793     $_[0]->{is_linked} = $_[0]->path ne $_[0]->srcdir->path;
   2794 }
   2795 
   2796 sub link {
   2797     my(@paths) = @_;
   2798     my($srcdir) = $dir::cwd->lookupdir(pop @paths)->srcdir;
   2799     map($dir::cwd->lookupdir($_)->{'srcdir'} = $srcdir, @paths);
   2800 
   2801     # make a reverse lookup for the link.
   2802     $srcdir->{links} = [] if ! $srcdir->{links};
   2803     push @{$srcdir->{links}}, @paths;
   2804 }
   2805 
   2806 use vars qw( @tail ); # TODO: Why global ????
   2807 
   2808 sub linked_targets {
   2809     my $tgt = shift;
   2810     my @targets = ();
   2811     my $dir;
   2812     if (ref $tgt eq 'dir') {
   2813 	$dir = $tgt;
   2814     } else {
   2815 	push @tail, $tgt;
   2816 	$dir = $tgt->{dir};
   2817     }
   2818     while ($dir) {
   2819 	if (defined $dir->{links} && @{$dir->{links}}) {
   2820 	    push @targets,
   2821 		 map(File::Spec->catdir($_, @tail), @{$dir->{links}});
   2822 	    #print STDERR "Found Link: ${\$dir->path} -> @{\$dir->{links}}\n";
   2823 	}
   2824 	unshift @tail, $dir->{entry};
   2825 	$dir = $dir->up;
   2826     }
   2827 
   2828     return map($dir::top->lookupdir($_), @targets);
   2829 }
   2830 
   2831 sub accessible {
   2832     my $path = $_[0]->path;
   2833     my $err = "$0: you have attempted to use path \"$path\" both as a file " .
   2834 	      "and as a directory!\n";
   2835     die $err;
   2836 }
   2837 
   2838 sub init {
   2839     my $path = Cwd::cwd();
   2840 
   2841     # We know we can get away with passing undef to lookupdir
   2842     # as the directory because $dir is an absolute path.
   2843     $top = lookupdir(undef, $path);
   2844     $top->{'path'} = $top->{srcpath} = $dir::CURDIR;
   2845     $top->{'prefix'} = '';
   2846     $top->{'srcdir'} = $top;
   2847 
   2848     $cwd = $top;
   2849 
   2850     ($cwd_vol, undef, undef) = File::Spec->splitpath($path);
   2851     $cwd_vol = '' if ! defined $cwd_vol;
   2852     $cwd_vol = uc($cwd_vol) if File::Spec->case_tolerant;
   2853 }
   2854 
   2855 package file;
   2856 
   2857 use vars qw( @ISA $level );
   2858 
   2859 BEGIN { @ISA = qw(dir); $level = 0 }
   2860 
   2861 # Return the pathname of the file.
   2862 # Define this separately from dir::path because we don't want to
   2863 # cache all file pathnames (just directory pathnames).
   2864 sub path {
   2865     $_[0]->{dir}->prefix . $_[0]->{entry}
   2866 }
   2867 
   2868 # Return the related source file path.
   2869 sub srcpath {
   2870     $_[0]->{dir}->srcprefix . $_[0]->{entry}
   2871 }
   2872 
   2873 # Return if the file is (should be) linked to a separate source file.
   2874 sub is_linked {
   2875     $_[0]->{dir}->is_linked
   2876 }
   2877 
   2878 # Repository file search.  If the local file exists, that wins.
   2879 # Otherwise, return the first existing same-named file under a
   2880 # Repository directory.  If there isn't anything with the same name
   2881 # under a Repository directory, return the local file name anyway
   2882 # so that some higher layer can try to construct it.
   2883 sub rfile {
   2884     return $_[0]->{rfile} if exists $_[0]->{rfile};
   2885     my($self) = @_;
   2886     my($rfile) = $self;
   2887     if (@param::rpath) {
   2888 	my($path) = $self->path;
   2889 	if (! File::Spec->file_name_is_absolute($path) && ! -f $path) {
   2890 	    my($dir);
   2891 	    foreach $dir (@param::rpath) {
   2892 		my($t) = $dir->prefix . $path;
   2893 		if (-f $t) {
   2894 		    $rfile = $_[0]->lookupfile($t);
   2895 		    $rfile->{'lfile'} = $self;
   2896 		    last;
   2897 		}
   2898 	    }
   2899 	}
   2900     }
   2901     $self->{rfile} = $rfile;
   2902 }
   2903 
   2904 # Returns the local file for a repository file;
   2905 # returns self if it's already a local file.
   2906 sub lfile {
   2907     $_[0]->{'lfile'} || $_[0]
   2908 }
   2909 
   2910 # returns the "precious" status of this file.
   2911 sub precious {
   2912     return $_[0]->{precious};
   2913 }
   2914 
   2915 # "Erase" reference to a Repository file,
   2916 # making this a completely local file object
   2917 # by pointing it back to itself.
   2918 sub no_rfile {
   2919     $_[0]->{'rfile'} = $_[0];
   2920 }
   2921 
   2922 # Return a path to the first existing file under a Repository directory,
   2923 # implicitly returning the current file's path if there isn't a
   2924 # same-named file under a Repository directory.
   2925 sub rpath {
   2926     $_[0]->{rpath} ||
   2927 	($_[0]->{rpath} = $_[0]->rfile->path)
   2928 }
   2929 
   2930 # Return a path to the first linked srcpath file under a Repositoy
   2931 # directory, implicitly returning the current file's srcpath if there
   2932 # isn't a same-named file under a Repository directory.
   2933 sub rsrcpath {
   2934     return $_[0]->{rsrcpath} if exists $_[0]->{rsrcpath};
   2935     my($self) = @_;
   2936     my($path) = $self->{rsrcpath} = $self->srcpath;
   2937     if (@param::rpath && ! File::Spec->file_name_is_absolute($path) && ! -f $path) {
   2938 	my($dir);
   2939 	foreach $dir (@param::rpath) {
   2940 	    my($t) = $dir->prefix . $path;
   2941 	    if (-f $t) {
   2942 		$self->{rsrcpath} = $t;
   2943 		last;
   2944 	    }
   2945 	}
   2946     }
   2947     $self->{rsrcpath};
   2948 }
   2949 
   2950 # Return if a same-named file source file exists.
   2951 # This handles the interaction of Link and Repository logic.
   2952 # As a side effect, it will link a source file from its Linked
   2953 # directory (preferably local, but maybe in a repository)
   2954 # into a build directory from its proper Linked directory.
   2955 sub source_exists {
   2956     return $_[0]->{source_exists} if defined $_[0]->{source_exists};
   2957     my($self) = @_;
   2958     my($path) = $self->path;
   2959     my($mtime, $ctime) = (stat($path))[9,10];
   2960     if ($self->is_linked) {
   2961 	# Linked directory, local logic.
   2962 	my($srcpath) = $self->srcpath;
   2963 	my($src_mtime, $src_ctime) = (stat($srcpath))[9,10];
   2964 	if ($src_mtime) {
   2965 	    if (! $mtime || $src_mtime != $mtime || $src_ctime != $ctime) {
   2966 		futil::install($srcpath, $self);
   2967 	    }
   2968 	    return $self->{source_exists} = 1;
   2969 	}
   2970 	# Linked directory, repository logic.
   2971 	if (@param::rpath) {
   2972 	    if ($self != $self->rfile) {
   2973 		return $self->{source_exists} = 1;
   2974 	    }
   2975 	    my($rsrcpath) = $self->rsrcpath;
   2976 	    if ($path ne $rsrcpath) {
   2977 		my($rsrc_mtime, $rsrc_ctime) = (stat($rsrcpath))[9,10];
   2978 		if ($rsrc_mtime) {
   2979 		    if (! $mtime || $rsrc_mtime != $mtime
   2980 				 || $rsrc_ctime != $ctime) {
   2981 			futil::install($rsrcpath, $self);
   2982 		    }
   2983 		    return $self->{source_exists} = 1;
   2984 		}
   2985 	    }
   2986 	}
   2987 	# There was no source file in any Linked directory
   2988 	# under any Repository.  If there's one in the local
   2989 	# build directory, it no longer belongs there.
   2990 	if ($mtime) {
   2991 	    unlink($path) || die("$0: couldn't unlink $path ($!)\n");
   2992 	}
   2993 	return $self->{source_exists} = '';
   2994     } else {
   2995 	if ($mtime) {
   2996 	    return $self->{source_exists} = 1;
   2997 	}
   2998 	if (@param::rpath && $self != $self->rfile) {
   2999 	    return $self->{source_exists} = 1;
   3000 	}
   3001 	return $self->{source_exists} = '';
   3002     }
   3003 }
   3004 
   3005 # Return if a same-named derived file exists under a Repository directory.
   3006 sub derived_exists {
   3007     $_[0]->{derived_exists} ||
   3008 	($_[0]->{derived_exists} = ($_[0] != $_[0]->rfile));
   3009 }
   3010 
   3011 # Return if this file is somewhere under a Repository directory.
   3012 sub is_on_rpath {
   3013     defined $_[0]->{'lfile'};
   3014 }
   3015 
   3016 sub local {
   3017     my($self, $arg) = @_;
   3018     if (defined $arg) {
   3019 	$self->{'local'} = $arg;
   3020     }
   3021     $self->{'local'};
   3022 }
   3023 
   3024 # Return the entry name of the specified file with the specified
   3025 # suffix appended.  Leave it untouched if the suffix is already there.
   3026 # Differs from the addsuffix function, below, in that this strips
   3027 # the existing suffix (if any) before appending the desired one.
   3028 sub base_suf {
   3029     my($entry) = $_[0]->{entry};
   3030     if ($entry !~ m/$_[1]$/) {
   3031 	$entry =~ s/\.[^\.]*$//;
   3032 	$entry .= $_[1];
   3033     }
   3034     $entry;
   3035 }
   3036 
   3037 # Return the suffix of the file; everything including and to the
   3038 # right of the last dot.
   3039 sub suffix {
   3040     my @pieces = split(/\./, $_[0]->{entry});
   3041     my $suffix = pop(@pieces);
   3042     return ".$suffix";
   3043 }
   3044 
   3045 # Called as a simple function file::addsuffix(name, suffix)
   3046 sub addsuffix {
   3047     my($name, $suffix) = @_;
   3048 
   3049     if ($suffix && substr($name, -length($suffix)) ne $suffix) {
   3050 	return $name .= $suffix;
   3051     }
   3052     $name;
   3053 }
   3054 
   3055 # Return true if the file is (or will be) accessible.
   3056 # That is, if we can build it, or if it is already present.
   3057 sub accessible {
   3058     (exists $_[0]->{builder}) || ($_[0]->source_exists);
   3059 }
   3060 
   3061 # Return true if the file should be ignored for the purpose
   3062 # of computing dependency information (should not be considered
   3063 # as a dependency and, further, should not be scanned for
   3064 # dependencies).
   3065 sub ignore {
   3066     return 0 if !$param::ignore;
   3067     return $_[0]->{ignore} if exists $_[0]->{ignore};
   3068     $_[0]->{ignore} = $_[0]->path =~ /$param::ignore/o;
   3069 }
   3070 
   3071 # Build the file, if necessary.
   3072 sub build {
   3073     return $_[0]->{status} if $_[0]->{status};
   3074     my($status) = &file::_build;
   3075     if ($_[0]->{after_build_func}) {
   3076 	my($pkgvars) = $_[0]->{conscript}->{pkgvars};
   3077 	NameSpace::restore('script', $pkgvars) if $pkgvars;
   3078 	eval("package script; " . $_[0]->{after_build_func});
   3079 	print "Error running AfterBuild for ${\$_[0]->path}: $@\n" if ($@);
   3080 	NameSpace::remove('script', keys %$pkgvars) if $pkgvars;
   3081     }
   3082     return $status;
   3083 }
   3084 
   3085 sub _build {
   3086     my($self) = @_;
   3087     print main::DEPFILE $self->path, "\n" if $param::depfile;
   3088     print((' ' x $level), "Checking ", $self->path, "\n") if $param::depends;
   3089     if (!exists $self->{builder}) {
   3090 	# We don't know how to build the file. This is OK, if
   3091 	# the file is present as a source file, under either the
   3092 	# local tree or a Repository.
   3093 	if ($self->source_exists) {
   3094 	    return $self->{status} = 'handled';
   3095 	} else {
   3096 	    my($name) = $self->path;
   3097 	    print("$0: don't know how to construct \"$name\"\n");
   3098 	    exit(1) unless $param::kflag;
   3099 	    return $self->{status} = 'errors'; # xxx used to be 'unknown'
   3100 	}
   3101     }
   3102 
   3103     # An associated build object exists, so we know how to build
   3104     # the file. We first compute the signature of the file, based
   3105     # on its dependendencies, then only rebuild the file if the
   3106     # signature has changed.
   3107     my($builder) = $self->{builder};
   3108     $level += 2;
   3109 
   3110     my(@deps) = (@{$self->{dep}}, @{$self->{sources}});
   3111     my($rdeps) = \@deps;
   3112 
   3113     if ($param::random) {
   3114 	# If requested, build in a random order, instead of the
   3115 	# order that the dependencies were listed.
   3116 	my(%rdeps);
   3117 	map { $rdeps{$_,'*' x int(rand 10)} = $_ } @deps;
   3118 	$rdeps = [values(%rdeps)];
   3119     }
   3120 
   3121     $self->{status} = '';
   3122 
   3123     my $dep;
   3124     for $dep (@$rdeps) {
   3125 	if ((build $dep) eq 'errors') {
   3126 	    # Propagate dependent errors to target.
   3127 	    # but try to build all dependents regardless of errors.
   3128 	    $self->{status} = 'errors';
   3129 	}
   3130     }
   3131 
   3132     # If any dependents had errors, then we abort.
   3133     if ($self->{status} eq 'errors') {
   3134 	$level -= 2;
   3135 	return 'errors';
   3136     }
   3137 
   3138     # Compute the final signature of the file, based on
   3139     # the static dependencies (in order), dynamic dependencies,
   3140     # output path name, and (non-substituted) build script.
   3141     my($sig) = 'sig'->collect(map('sig'->signature($_->rfile), @deps),
   3142 			    $builder->includes($self),
   3143 			    $builder->scriptsig);
   3144 
   3145     # May have gotten errors during computation of dynamic
   3146     # dependency signature, above.
   3147     $level -= 2;
   3148     return 'errors' if $self->{status} eq 'errors';
   3149 
   3150     if (@param::rpath && $self->derived_exists) {
   3151 	# There is no local file of this name, but there is one
   3152 	# under a Repository directory.
   3153 
   3154 	if ('sig'->current($self->rfile, $sig)) {
   3155 	    # The Repository copy is current (its signature matches
   3156 	    # our calculated signature).
   3157 	    if ($self->local) {
   3158 		# ...but they want a local copy, so provide it.
   3159 		main::showcom("Local copy of ${\$self->path} from " .
   3160 			      "${\$self->rpath}");
   3161 		futil::install($self->rpath, $self);
   3162 		'sig'->bsig($self, $sig);
   3163 	    }
   3164 	    return $self->{status} = 'handled';
   3165 	}
   3166 
   3167 	# The signatures don't match, implicitly because something
   3168 	# on which we depend exists locally.  Get rid of the reference
   3169 	# to the Repository file; we'll build this (and anything that
   3170 	# depends on it) locally.
   3171 	$self->no_rfile;
   3172     }
   3173 
   3174     # Then check for currency.
   3175     if (! 'sig'->current($self, $sig)) {
   3176 	# We have to build/derive the file.
   3177 	print((' ' x $level), "Rebuilding ", $self->path, ": out of date.\n")
   3178 		if $param::depends;
   3179 	# First check to see if the built file is cached.
   3180 	if ($builder->cachin($self, $sig)) {
   3181 	    'sig'->bsig($self, $sig);
   3182 	    return $self->{status} = 'built';
   3183 	} elsif ($builder->action($self)) {
   3184 	    $builder->cachout($self, $sig);
   3185 	    'sig'->bsig($self, $sig);
   3186 	    return $self->{status} = 'built';
   3187 	} else {
   3188 	    die("$0: errors constructing ${\$self->path}\n")
   3189 		unless $param::kflag;
   3190 	    return $self->{status} = 'errors';
   3191 	}
   3192     } else {
   3193 	# Push this out to the cache if we've been asked to (-C option).
   3194 	# Don't normally do this because it slows us down.
   3195 	# In a fully built system, no accesses to the cache directory
   3196 	# are required to check any files. This is a win if cache is
   3197 	# heavily shared. Enabling this option puts the directory in the
   3198 	# loop. Useful only when you wish to recreate a cache from a build.
   3199 	if ($param::cachesync) {
   3200 	    $builder->cachout($self, $sig);
   3201 	    'sig'->bsig($self, $sig);
   3202 	}
   3203 	return $self->{status} = 'handled';
   3204     }
   3205 }
   3206 
   3207 # Bind an action to a file, with the specified sources. No return value.
   3208 sub bind {
   3209     my($self, $builder, @sources) = @_;
   3210     if ($self->{builder} && !$self->{builder}->compatible($builder)) {
   3211 	# Even if not "compatible", we can still check to see if the
   3212 	# derivation is identical. It should be identical if the builder is
   3213 	# the same and the sources are the same.
   3214 	if ("$self->{builder} @{$self->{sources}}" ne "$builder @sources") {
   3215 	    $main::errors++;
   3216 	    my($_foo1, $script1, $line1, $sub1) = @{$self->creator};
   3217 	    my($_foo2, $script2, $line2, $sub2) = script::caller_info;
   3218 	    my $err = "\t${\$self->path}\n" .
   3219 		      "\tbuilt (at least) two different ways:\n" .
   3220 		      "\t\t$script1, line $line1:  $sub1\n" .
   3221 		      "\t\t$script2, line $line2:  $sub2\n";
   3222 	    die $err;
   3223 	}
   3224 	return;
   3225     }
   3226     if ($param::wflag) {
   3227 	my($script, $line, $sub);
   3228 	(undef, $script, $line, $sub) = script::caller_info;
   3229 	$self->{script} = '' if ! defined $self->{script};
   3230 	$self->{script} .= "; " if $self->{script};
   3231 	$self->{script} .= qq($sub in "$script", line $line);
   3232     }
   3233     $self->{builder} = $builder;
   3234     push(@{$self->{sources}}, @sources);
   3235     @{$self->{dep}} = () if ! defined $self->{dep};
   3236     $self->{conscript} = $priv::self->{script};
   3237 }
   3238 
   3239 sub is_under {
   3240     $_[0]->{dir}->is_under($_[1]);
   3241 }
   3242 
   3243 sub relpath {
   3244     my $dirpath = $_[0]->relpath($_[1]->{dir});
   3245     if (! $dirpath) {
   3246 	return $_[1]->{entry};
   3247     } else {
   3248 	File::Spec->catfile($dirpath, $_[1]->{entry});
   3249     }
   3250 }
   3251 
   3252 # Return the signature array for this file.
   3253 # This probably belongs in its own "sigarray" package,
   3254 # which would make it easier to optimize performance.
   3255 sub sigarray {
   3256     if ($_[0]->{sigaref}) {
   3257 	return @{$_[0]->{sigaref}};
   3258     }
   3259     my $self = shift;
   3260     # glob2pat based on The Perl Cookbook, p. 180.
   3261     sub glob2pat {
   3262 	my $globstr = shift;
   3263 	my %patmap = (
   3264 	    '*' => '.*',
   3265 	    '?' => '.',
   3266 	    '[' => '[',
   3267 	    ']' => ']',
   3268 	    '/' => "\Q$dir::SEPARATOR",	# Cons-specific modification
   3269 	);
   3270 	$globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
   3271 	return '^' . $globstr . '$';
   3272     }
   3273     my @sigarray;
   3274     my $default;
   3275     my $builder = $self->lfile->{builder};
   3276     if (! $builder) {
   3277 	@sigarray = @$param::sourcesig;
   3278 	$default = [qw(content)];
   3279     } else {
   3280 	if ($builder->{env} && $builder->{env}->{SIGNATURE}) {
   3281 	    @sigarray = @{$builder->{env}->{SIGNATURE}};
   3282 	} else {
   3283 	    my $class = ref $builder;
   3284 	    my $path = $self->path;
   3285 	    warn qq($0: Warning:  Builder package $class did not record\n) .
   3286 		 qq(\tthe calling environment for '$path'.\n) .
   3287 		 qq(\tUnable to use any %SIGNATURE construction variable\n) .
   3288 		 qq(\tfor signature configuration.\n);
   3289 	}
   3290 	$default = [qw(build)];
   3291     }
   3292     my $path = $self->path;
   3293     while (@sigarray) {
   3294 	my($glob, $aref) = splice(@sigarray, 0, 2);
   3295 	my $re = glob2pat($glob);
   3296 	if ($path =~ /$re/) {
   3297 	    $aref = [split(/\s+/, $aref)] if ! ref $aref;
   3298 	    $self->{sigaref} = $aref;
   3299 	    return @$aref;
   3300 	}
   3301     }
   3302     $self->{sigaref} = $default;
   3303     return @{$self->{sigaref}}
   3304 }
   3305 
   3306 # Decide if this file's signature should be the content or build signature.
   3307 sub sigtype {
   3308     if ($_[0]->{sigtype}) {
   3309 	return $_[0]->{sigtype};
   3310     }
   3311     my $self = shift;
   3312     my @sigarray = $self->sigarray;
   3313     my $sigtype;
   3314     if (grep($_ eq "build", @sigarray)) {
   3315 	$sigtype = 'bsig';
   3316     } elsif (grep($_ =~ /content$/, @sigarray)) {
   3317 	$sigtype = 'csig';
   3318     }
   3319     return $self->{sigtype} = $sigtype;
   3320 }
   3321 
   3322 # Return whether this file is configured to use stored
   3323 # signature values from the .consign file.
   3324 sub stored {
   3325     if (! defined $_[0]->{stored}) {
   3326 	$_[0]->{stored} = grep($_ eq "stored-content", $_[0]->sigarray);
   3327     }
   3328     return $_[0]->{stored};
   3329 }
   3330 
   3331 # Generic entry (file or directory) handling.
   3332 # This is an empty subclass for nodes that haven't
   3333 # quite decided whether they're files or dirs.
   3334 # Use file methods until someone blesses them one way or the other.
   3335 package entry;
   3336 
   3337 use vars qw( @ISA );
   3338 
   3339 BEGIN { @ISA = qw(file) }
   3340 
   3341 # File utilities
   3342 package futil;
   3343 
   3344 # Install one file as another.
   3345 # Links them if possible (hard link), otherwise copies.
   3346 # Don't ask why, but the source is a path, the tgt is a file obj.
   3347 sub install {
   3348     my($sp, $tgt) = @_;
   3349     my($tp) = $tgt->path;
   3350     return 1 if $tp eq $sp;
   3351     return 1 if eval { link($sp, $tp) };
   3352     unlink($tp);
   3353     if (! futil::mkdir($tgt->{dir})) {
   3354 	return undef;
   3355     }
   3356     return 1 if eval { link($sp, $tp) };
   3357     futil::copy($sp, $tp);
   3358 }
   3359 
   3360 # Copy one file to another. Arguments are actual file names.
   3361 # Returns undef on failure. Preserves mtime and mode.
   3362 sub copy {
   3363     my ($sp, $tp) = @_;
   3364     my ($mode, $length, $atime, $mtime) = (stat($sp))[2,7,8,9];
   3365 
   3366     # Use Perl standard library module for file copying, which handles
   3367     # binary copies. <schwarze@isa.de> 1998-06-18
   3368     if (! File::Copy::copy($sp, $tp)) {
   3369 	warn qq($0: can\'t install "$sp" to "$tp" ($!)\n); #'
   3370 	return undef;
   3371     }
   3372     # The file has been created, so try both the chmod and utime,
   3373     # first making sure the copy is writable (because permissions
   3374     # affect the ability to modify file times on some operating
   3375     # systems), and then changing permissions back if necessary.
   3376     my $ret = 1;
   3377     my $wmode = $mode | 0700;
   3378     if (! chmod $wmode, $tp) {
   3379 	warn qq($0: can\'t set mode $wmode on file "$tp" ($!)\n); #'
   3380 	$ret = undef;
   3381     }
   3382     if (! utime $atime, $mtime, $tp) {
   3383 	warn qq($0: can\'t set modification time for file "$tp" ($!)\n); #'
   3384 	$ret = undef;
   3385     }
   3386     if ($mode !=  $wmode && ! chmod $mode, $tp) {
   3387 	warn qq($0: can\'t set mode $mode on file "$tp" ($!)\n); #'
   3388 	$ret = undef;
   3389     }
   3390     return $ret;
   3391 }
   3392 
   3393 # Ensure that the specified directory exists.
   3394 # Aborts on failure.
   3395 sub mkdir {
   3396     return 1 if $_[0]->{'exists'};
   3397     if (! futil::mkdir($_[0]->{dir})) { # Recursively make parent.
   3398 	return undef;
   3399     }
   3400     my($path) = $_[0]->path;
   3401     if (!-d $path && !mkdir($path, 0777)) {
   3402 	warn qq($0: can't create directory $path ($!).\n); #'
   3403 	return undef;
   3404     }
   3405     $_[0]->{'exists'} = 1;
   3406 }
   3407 
   3408 
   3409 # Signature package.
   3410 package sig::hash;
   3411 
   3412 use vars qw( $called );
   3413 
   3414 sub init {
   3415     my($dir) = @_;
   3416     my($consign) = $dir->prefix . ".consign";
   3417     my($dhash) = $dir->{consign} = {};
   3418     if (-f $consign) {
   3419 	open(CONSIGN, $consign) || die("$0: can't open $consign ($!)\n");
   3420 	while(<CONSIGN>) {
   3421 	    chop;
   3422 	    my ($file, $sig) = split(/:/,$_);
   3423 	    $dhash->{$file} = $sig;
   3424 	}
   3425 	close(CONSIGN);
   3426     }
   3427     $dhash
   3428 }
   3429 
   3430 # Read the hash entry for a particular file.
   3431 sub in {
   3432     my($dir) = $_[0]->{dir};
   3433     ($dir->{consign} || init($dir))->{$_[0]->{entry}}
   3434 }
   3435 
   3436 # Write the hash entry for a particular file.
   3437 sub out {
   3438     my($file, $sig) = @_;
   3439     my($dir) = $file->{dir};
   3440     ($dir->{consign} || init($dir))->{$file->{entry}} = $sig;
   3441     $sig::hash::dirty{$dir} = $dir;
   3442 }
   3443 
   3444 # Eliminate the hash entry for a particular file.
   3445 sub clear {
   3446     my($file) = @_;
   3447     my($dir) = $file->{dir};
   3448     delete $dir->{consign}->{$file->{entry}} if $dir->{consign};
   3449     $sig::hash::dirty{$dir} = $dir;
   3450 }
   3451 
   3452 # Flush hash entries. Called at end or via ^C interrupt.
   3453 sub END {
   3454     return if $called++; # May be called twice.
   3455     close(CONSIGN); # in case this came in via ^C.
   3456     my $dir;
   3457     for $dir (values %sig::hash::dirty) {
   3458 	my($consign) = $dir->prefix . ".consign";
   3459 	my($constemp) = $consign . ".$$";
   3460 	if (! open(CONSIGN, ">$constemp")) {
   3461 	    die("$0: can't create $constemp ($!)\n");
   3462 	}
   3463 	my($entry, $sig);
   3464 	while (($entry, $sig) = each %{$dir->{consign}}) {
   3465 	    if (! print CONSIGN "$entry:$sig\n") {
   3466 		die("$0: error writing to $constemp ($!)\n");
   3467 	    }
   3468 	}
   3469 	close(CONSIGN);
   3470 	if (! rename($constemp, $consign)) {
   3471 	    if (futil::copy($constemp, $consign)) {
   3472 		unlink($constemp);
   3473 	    } else {
   3474 		die("$0: couldn't rename or copy $constemp to $consign " .
   3475 		    "($!)\n");
   3476 	    }
   3477 	}
   3478     }
   3479 }
   3480 
   3481 
   3482 # Derived file caching.
   3483 package cache;
   3484 
   3485 # Find a file in the cache. Return non-null if the file is in the cache.
   3486 sub in {
   3487     return undef unless $param::cache;
   3488     my($file, $sig) = @_;
   3489     # Add the path to the signature, to make it unique.
   3490     $sig = 'sig'->collect($sig, $file->path) unless $param::mixtargets;
   3491     my($dir) = substr($sig, 0, 1);
   3492     my($cp) = File::Spec->catfile($param::cache, $dir, $sig);
   3493     return -f $cp && futil::install($cp, $file);
   3494 }
   3495 
   3496 # Try to flush a file to the cache, if not already there.
   3497 # If it doesn't make it out, due to an error, then that doesn't
   3498 # really matter.
   3499 sub out {
   3500     return unless $param::cache;
   3501     my($file, $sig) = @_;
   3502     # Add the path to the signature, to make it unique.
   3503     $sig = 'sig'->collect($sig, $file->path) unless $param::mixtargets;
   3504     my($dir) = substr($sig, 0, 1);
   3505     my($sp) = $file->path;
   3506     my($cp) = File::Spec->catfile($param::cache, $dir, $sig);
   3507     my($cdir) = File::Spec->catfile($param::cache, $dir);
   3508     if (! -d $cdir) {
   3509 	mkdir($cdir, 0777) ||
   3510 	    die("$0: can't create cache directory $cdir ($!).\n");
   3511     } elsif (-f $cp) {
   3512 	# Already cached: try to use that instead, to save space.
   3513 	# This can happen if the -cs option is used on a previously
   3514 	# uncached build, or if two builds occur simultaneously.
   3515 	my($lp) = ".$sig";
   3516 	unlink($lp);
   3517 	return if ! eval { link($cp, $lp) };
   3518 	rename($lp, $sp);
   3519 	# Unix98 says, "If the old argument and the new argument both
   3520 	# [refer] to the same existing file, the rename() function
   3521 	# returns successfully and performs no other action."  So, if
   3522 	# $lp and $sp are links (i.e., $cp and $sp are links), $lp is
   3523 	# left, and we must unlink it ourselves.  If the rename failed
   3524 	# for any reason, it is also good form to unlink the temporary
   3525 	# $lp.  Otherwise $lp no longer exists and, barring some race,
   3526 	# the unlink fails silently.
   3527 	unlink($lp);
   3528 	return;
   3529     }
   3530 
   3531     return if eval { link($sp, $cp) };
   3532     return if ! -f $sp; # if nothing to cache.
   3533     if (futil::copy($sp, "$cp.new")) {
   3534 	rename("$cp.new", $cp);
   3535     }
   3536 }
   3537 
   3538 
   3539 # Generic signature handling package.
   3540 # This handles the higher-layer distinction between content and build
   3541 # signatures, relying on an underlying calculation package like
   3542 # "sig::md5"" to provide the signature values themselves.
   3543 package sig;
   3544 
   3545 use vars qw( @ISA );
   3546 
   3547 # Select the underlying package to be used for signature calculation.
   3548 # We play a few namespace games here.  Specifically, we append
   3549 # "sig::" to the beginning of the subclass we're passed.  Then,
   3550 # if the package ends in "::debug", we actually subclass the
   3551 # "sig::debug" package and as a wrapper around the underlying
   3552 # (e.g.) "sig::md5" package that's doing the real calculation.
   3553 sub select {
   3554     my($package, $subclass) = @_;
   3555     my $p = $package . "::" . $subclass;
   3556     my $sigpkg = $p;
   3557     if ($p =~ /(.*)::debug$/) {
   3558 	$sigpkg = $1;
   3559 	$p = 'sig::debug';
   3560     }
   3561     @ISA = ($p);
   3562     $p->init($sigpkg);
   3563 };
   3564 
   3565 # Set or return the build signature of a file.
   3566 # This is computed elsewhere and passed in to us.
   3567 sub bsig {
   3568     my($self, $file, $sig) = @_;
   3569     if (defined $sig) {
   3570 	$file->{'bsig'} = $sig;
   3571 	$self->set($file);
   3572     } elsif (! defined $file->{'bsig'}) {
   3573 	$file->{'bsig'} = '';
   3574     }
   3575     $file->{'bsig'}
   3576 }
   3577 
   3578 # Determine the content signature of a file.
   3579 # This also sets the .consign entry unless the file is in a
   3580 # repository; we don't write into repositories, only read from them.
   3581 sub csig {
   3582     my($self, $file) = @_;
   3583     if (! $file->{'csig'}) {
   3584 	$file->{'csig'} = $self->srcsig($file->path);
   3585 	$self->set($file) if ! $file->is_on_rpath;
   3586     }
   3587     $_[1]->{'csig'}
   3588 }
   3589 
   3590 # Determine the current signature of an already-existing or
   3591 # non-existant file.  Unless a specific signature type (bsig
   3592 # or csig) is requested, this consults the file's signature
   3593 # array to decide whether to return content or build signature,
   3594 # and whether to use a cached value from a .consign file.
   3595 sub signature {
   3596     my($self, $file, $sigtype) = @_;
   3597     $sigtype = $file->sigtype if ! $sigtype;
   3598     #open(TTY, ">/dev/tty");
   3599     #print TTY $file->path, ": $sigtype\n";
   3600     #close(TTY);
   3601     my($path) = $file->path;
   3602     my($time) = (stat($path))[9];
   3603     if ($time) {
   3604 	if ($file->{$sigtype}) {
   3605 	    return $file->{$sigtype};
   3606 	}
   3607 	if ($file->is_on_rpath || $file->stored) {
   3608 	    if ('sig'->fetch($file) && $file->{$sigtype}) {
   3609 		if ($file->{'sigtime'} == $time ||
   3610 		    ! $param::rep_sig_times_ok
   3611 		    && $file->is_on_rpath) {
   3612 		    return $file->{$sigtype};
   3613 		}
   3614 	    }
   3615 	    $file->{$sigtype} = undef;
   3616 	}
   3617 	if ($file->is_on_rpath || ! File::Spec->file_name_is_absolute($path)) {
   3618 	    my $sig = '';
   3619 	    if ($sigtype eq 'bsig') { $sig = $self->bsig($file); }
   3620 	    elsif ($sigtype eq 'csig') { $sig = $self->csig($file); }
   3621 	    return $sig;
   3622 	}
   3623 	# This file is not in a repository or under the local directory
   3624 	# structure.  In the canonical case, it's a utility that will be
   3625 	# executed by a command.  Historically, Cons has returned the
   3626 	# name of the command concatenated with the modification time.
   3627 	# Note that this is *not* the path ("cc" not "/bin/cc"), so it
   3628 	# would lose in the unlikely event that a different copy of the
   3629 	# utility was used that happened to have the same modification
   3630 	# time (due to living in a different directory on the PATH, for
   3631 	# example).  The obvious "fix" of using the path like so, however:
   3632 	#	return $path . $time;
   3633 	# is wrong.  In a multi-machine build environment, different
   3634 	# systems may have the same utility in different locations (due
   3635 	# to different NFS mount points, for example), which would
   3636 	# cause a lot of unnecessary builds if we used the full path.
   3637 	# A better solution to strengthen this signature would be to
   3638 	# also concatenate the size of the file, but that would cause
   3639 	# unnecessary rebuilds when coming from .consign files that used
   3640 	# the old scheme.  All of which is to merely explain why we're
   3641 	# leaving this as it has been, but documenting it here in case
   3642 	# there's reason to change it in the future.
   3643 	return $file->{entry} . $time;
   3644     }
   3645     return $file->{$sigtype} = '';
   3646 }
   3647 
   3648 sub bsignature {
   3649     my($self, $file) = @_;
   3650     my($path) = $file->path;
   3651     my($time) = (stat($path))[9];
   3652     if ($time) {
   3653 	if ($file->{'bsig'}) {
   3654 	    return $file->{'bsig'};
   3655 	}
   3656 	if ('sig'->fetch($file, 'bsig') && $file->{'bsig'}) {
   3657 		if ($file->{'sigtime'} == $time ||
   3658 		    ! $param::rep_sig_times_ok
   3659 		    && $file->is_on_rpath) {
   3660 		    return $file->{'bsig'};
   3661 		}
   3662 	}
   3663 	if ($file->is_on_rpath || ! File::Spec->file_name_is_absolute($path)) {
   3664 	    return $self->bsig($file);
   3665 	}
   3666 	return $path . $time;
   3667     }
   3668     return $file->{'bsig'} = '';
   3669 }
   3670 
   3671 # Invalidate a file's signature, also clearing its .consign entry.
   3672 sub invalidate {
   3673     my($self, $file) = @_;
   3674     delete $file->{'sigtime'};
   3675     delete $file->{'bsig'};
   3676     delete $file->{'csig'};
   3677     sig::hash::clear($file);
   3678 }
   3679 
   3680 # Store the signature for a file.
   3681 sub set {
   3682     my($self, $file) = @_;
   3683     my $sig = (stat($file->path))[9];
   3684     $sig .= " " . ($file->{'bsig'} || '-');
   3685     $sig .= " " . $file->{'csig'} if $file->{'csig'};
   3686     sig::hash::out($file, $sig);
   3687 }
   3688 
   3689 # Fetch the signature(s) for a file.
   3690 # Returns whether there was a signature to fetch.
   3691 sub fetch {
   3692     my($self, $file, @kw) = @_;
   3693     @kw = ('bsig', 'csig') if ! @kw;
   3694     my $sig = sig::hash::in($file) || '';
   3695     my($sigtime, $bsig, $csig) = split(/ /, $sig);
   3696     $file->{'sigtime'} = $sigtime;
   3697     $file->{'bsig'} = $bsig || '' if grep($_ eq 'bsig', @kw);
   3698     $file->{'csig'} = $csig || '' if grep($_ eq 'csig', @kw);
   3699     $file->{'bsig'} = '' if $file->{'bsig'} eq '-';
   3700     return $sig ne '';
   3701 }
   3702 
   3703 # MD5-based signature package.
   3704 package sig::md5;
   3705 
   3706 use vars qw( $md5 );
   3707 
   3708 # Initialize MD5 signature calculation by finding an appropriate
   3709 # module and creating the proper object.
   3710 sub init {
   3711     my $self = shift;
   3712     my @md5_modules = qw(Digest::MD5 MD5 Digest::Perl::MD5);
   3713     # We used to find the right module more simply, using $_ as the
   3714     # loop iterator and just doing:
   3715     #
   3716     #		eval "use $_";
   3717     #		$module = $_, $last if ! $@;
   3718     #
   3719     # in the loop.  Empirically, though, this doesn't pass back the
   3720     # right value in $module on some ActiveState versions.  (Maybe
   3721     # it's something to do with the eval in a for loop, I dunno.)
   3722     # Work around it by using $_ to pass the value out of the loop,
   3723     # which seems to work everywhere.
   3724     my $module;
   3725     for $module (@md5_modules) {
   3726 	eval "use $module";
   3727 	$_ = $module, last if ! $@;
   3728     }
   3729     $module = $_;
   3730     die "Cannot find any MD5 module from:  @md5_modules" if $@;
   3731 
   3732     $md5 = new $module;
   3733 }
   3734 
   3735 # Is the provided signature equal to the signature of the current
   3736 # instantiation of the target (and does the target exist)?
   3737 sub current {
   3738     my($self, $file, $sig, $sigtype) = @_;
   3739     $self->bsignature($file) eq $sig;
   3740 }
   3741 
   3742 # Return an aggregate signature for a list of signature values.
   3743 sub collect {
   3744     my($self, @sigs) = @_;
   3745     # The following sequence is faster than calling the hex interface.
   3746     $md5->reset();
   3747     $md5->add(join('', $param::salt, @sigs));
   3748     unpack("H*", $md5->digest());
   3749 }
   3750 
   3751 # Directly compute a file signature as the MD5 checksum of the
   3752 # bytes in the file.
   3753 sub srcsig {
   3754     my($self, $path) = @_;
   3755     $md5->reset();
   3756     open(FILE, $path) || return '';
   3757     binmode(FILE);
   3758     $md5->addfile(\*FILE);
   3759     close(FILE);
   3760     unpack("H*", $md5->digest());
   3761 }
   3762 
   3763 # Compute the signature of a command string.
   3764 # For MD5, this is just the string itself, since MD5 will condense
   3765 # the string contents into the ultimate signature.  Other signature
   3766 # schemes may need to figure this out differently.
   3767 sub cmdsig {
   3768     my($self, $sig) = @_;
   3769     return $sig
   3770 }
   3771 
   3772 # Generic debug package for signature calculation.
   3773 # Because of the way we're called by sig::select() and then use
   3774 # the specified value to set up @ISA, this package is essentially a
   3775 # factory that creates packages like sig::md5::debug, etc., on the fly.
   3776 package sig::debug;
   3777 
   3778 use vars qw( @ISA $sigpkg $outfh );
   3779 
   3780 local *FH;
   3781 
   3782 sub init {
   3783     my $self = shift;
   3784     $sigpkg = shift;
   3785     @ISA = ($sigpkg);
   3786     $sigpkg->init();
   3787     my $file = $ENV{CONS_SIG_DEBUG};
   3788     if ($file) {
   3789 	if (! open(FH, ">$file")) {
   3790 	    die "Cannot open $file: $!";
   3791 	}
   3792 	$outfh = \*FH;
   3793     } else {
   3794 	$outfh = \*STDOUT;
   3795     }
   3796 }
   3797 
   3798 sub current {
   3799     my($self, $file, $sig, $sigtype) = @_;
   3800     my $fsig = $self->bsignature($file);
   3801     my $sub = "${sigpkg}::current";
   3802     my $sep = "\n" . ' ' x (length($sub) + 1 - 3);
   3803     print $outfh "$sub(|$fsig|${sep}eq |$sig|)\n";
   3804     return $fsig eq $sig;
   3805 }
   3806 
   3807 sub collect {
   3808     my($self, @sigs) = @_;
   3809     my $sig = $sigpkg->collect(@sigs);
   3810     my $sub = "${sigpkg}::collect";
   3811     my $sep = ",\n" . ' ' x (length($sub) + 1);
   3812     my $buf = join($sep, @sigs);
   3813     $buf = $param::salt . $sep . $buf if $param::salt;
   3814     print $outfh "$sub($buf)\n\t=> |$sig|\n";
   3815     return $sig;
   3816 }
   3817 
   3818 sub srcsig {
   3819     my($self, $path) = @_;
   3820     my $sig = $sigpkg->srcsig($path);
   3821     print $outfh "${sigpkg}::srcsig($path)\n\t=> |$sig|\n";
   3822     return $sig;
   3823 }
   3824 
   3825 __END__;
   3826 
   3827 =head1 NAME
   3828 
   3829 Cons - A Software Construction System
   3830 
   3831 =head1 DESCRIPTION
   3832 
   3833 A guide and reference for version 2.3.1
   3834 
   3835 Copyright (c) 1996-2001 Free Software Foundation, Inc.
   3836 
   3837 This program is free software; you can redistribute it and/or modify
   3838 it under the terms of the GNU General Public License as published by
   3839 the Free Software Foundation; either version 2 of the License, or
   3840 (at your option) any later version.
   3841 
   3842 This program is distributed in the hope that it will be useful,
   3843 but WITHOUT ANY WARRANTY; without even the implied warranty of
   3844 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   3845 GNU General Public License for more details.
   3846 
   3847 You should have received a copy of the GNU General Public License
   3848 along with this program; see the file COPYING.  If not, write to
   3849 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   3850 Boston, MA 02111-1307, USA.
   3851 
   3852 =head1 Introduction
   3853 
   3854 B<Cons> is a system for constructing, primarily, software, but is quite
   3855 different from previous software construction systems. Cons was designed
   3856 from the ground up to deal easily with the construction of software spread
   3857 over multiple source directories. Cons makes it easy to create build scripts
   3858 that are simple, understandable and maintainable. Cons ensures that complex
   3859 software is easily and accurately reproducible.
   3860 
   3861 Cons uses a number of techniques to accomplish all of this. Construction
   3862 scripts are just Perl scripts, making them both easy to comprehend and very
   3863 flexible. Global scoping of variables is replaced with an import/export
   3864 mechanism for sharing information between scripts, significantly improving
   3865 the readability and maintainability of each script. B<Construction
   3866 environments> are introduced: these are Perl objects that capture the
   3867 information required for controlling the build process. Multiple
   3868 environments are used when different semantics are required for generating
   3869 products in the build tree. Cons implements automatic dependency analysis
   3870 and uses this to globally sequence the entire build. Variant builds are
   3871 easily produced from a single source tree. Intelligent build subsetting is
   3872 possible, when working on localized changes. Overrides can be setup to
   3873 easily override build instructions without modifying any scripts. MD5
   3874 cryptographic B<signatures> are associated with derived files, and are used
   3875 to accurately determine whether a given file needs to be rebuilt.
   3876 
   3877 While offering all of the above, and more, Cons remains simple and easy to
   3878 use. This will, hopefully, become clear as you read the remainder of this
   3879 document.
   3880 
   3881 
   3882 =head1 Why Cons? Why not Make?
   3883 
   3884 Cons is a B<make> replacement. In the following paragraphs, we look at a few
   3885 of the undesirable characteristics of make--and typical build environments
   3886 based on make--that motivated the development of Cons.
   3887 
   3888 =head2 Build complexity
   3889 
   3890 Traditional make-based systems of any size tend to become quite complex. The
   3891 original make utility and its derivatives have contributed to this tendency
   3892 in a number of ways. Make is not good at dealing with systems that are
   3893 spread over multiple directories. Various work-arounds are used to overcome
   3894 this difficulty; the usual choice is for make to invoke itself recursively
   3895 for each sub-directory of a build. This leads to complicated code, in which
   3896 it is often unclear how a variable is set, or what effect the setting of a
   3897 variable will have on the build as a whole. The make scripting language has
   3898 gradually been extended to provide more possibilities, but these have
   3899 largely served to clutter an already overextended language. Often, builds
   3900 are done in multiple passes in order to provide appropriate products from
   3901 one directory to another directory. This represents a further increase in
   3902 build complexity.
   3903 
   3904 
   3905 =head2 Build reproducibility
   3906 
   3907 The bane of all makes has always been the correct handling of
   3908 dependencies. Most often, an attempt is made to do a reasonable job of
   3909 dependencies within a single directory, but no serious attempt is made to do
   3910 the job between directories. Even when dependencies are working correctly,
   3911 make's reliance on a simple time stamp comparison to determine whether a
   3912 file is out of date with respect to its dependents is not, in general,
   3913 adequate for determining when a file should be rederived. If an external
   3914 library, for example, is rebuilt and then ``snapped'' into place, the
   3915 timestamps on its newly created files may well be earlier than the last
   3916 local build, since it was built before it became visible.
   3917 
   3918 
   3919 =head2 Variant builds
   3920 
   3921 Make provides only limited facilities for handling variant builds. With the
   3922 proliferation of hardware platforms and the need for debuggable
   3923 vs. optimized code, the ability to easily create these variants is
   3924 essential. More importantly, if variants are created, it is important to
   3925 either be able to separate the variants or to be able to reproduce the
   3926 original or variant at will. With make it is very difficult to separate the
   3927 builds into multiple build directories, separate from the source. And if
   3928 this technique isn't used, it's also virtually impossible to guarantee at
   3929 any given time which variant is present in the tree, without resorting to a
   3930 complete rebuild.
   3931 
   3932 
   3933 =head2 Repositories
   3934 
   3935 Make provides only limited support for building software from code that
   3936 exists in a central repository directory structure.  The VPATH feature of
   3937 GNU make (and some other make implementations) is intended to provide this,
   3938 but doesn't work as expected: it changes the path of target file to the
   3939 VPATH name too early in its analysis, and therefore searches for all
   3940 dependencies in the VPATH directory.  To ensure correct development builds,
   3941 it is important to be able to create a file in a local build directory and
   3942 have any files in a code repository (a VPATH directory, in make terms) that
   3943 depend on the local file get rebuilt properly.  This isn't possible with
   3944 VPATH, without coding a lot of complex repository knowledge directly into
   3945 the makefiles.
   3946 
   3947 
   3948 =head1 Keeping it simple
   3949 
   3950 A few of the difficulties with make have been cited above. In this and
   3951 subsequent sections, we shall introduce Cons and show how these issues are
   3952 addressed.
   3953 
   3954 =head2 Perl scripts
   3955 
   3956 Cons is Perl-based. That is, Cons scripts--F<Conscript> and F<Construct>
   3957 files, the equivalent to F<Makefile> or F<makefile>--are all written in
   3958 Perl. This provides an immediate benefit: the language for writing scripts
   3959 is a familiar one. Even if you don't happen to be a Perl programmer, it
   3960 helps to know that Perl is basically just a simple declarative language,
   3961 with a well-defined flow of control, and familiar semantics. It has
   3962 variables that behave basically the way you would expect them to,
   3963 subroutines, flow of control, and so on. There is no special syntax
   3964 introduced for Cons. The use of Perl as a scripting language simplifies
   3965 the task of expressing the appropriate solution to the often complex
   3966 requirements of a build.
   3967 
   3968 
   3969 =head2 Hello, World!
   3970 
   3971 To ground the following discussion, here's how you could build the B<Hello,
   3972 World!> C application with Cons:
   3973 
   3974 
   3975 
   3976   $env = new cons();
   3977   Program $env 'hello', 'hello.c';
   3978 
   3979 If you install this script in a directory, naming the script F<Construct>,
   3980 and create the F<hello.c> source file in the same directory, then you can
   3981 type C<cons hello> to build the application:
   3982 
   3983 
   3984 
   3985   % cons hello
   3986   cc -c hello.c -o hello.o
   3987   cc -o hello hello.o
   3988 
   3989 
   3990 =head2 Construction environments
   3991 
   3992 A key simplification of Cons is the idea of a B<construction environment>. A
   3993 construction environment is an B<object> characterized by a set of key/value
   3994 pairs and a set of B<methods>. In order to tell Cons how to build something,
   3995 you invoke the appropriate method via an appropriate construction
   3996 environment. Consider the following example:
   3997 
   3998 
   3999 
   4000   $env = new cons(
   4001 	CC	=>	'gcc',
   4002 	LIBS	=>	'libworld.a'
   4003   );
   4004 
   4005   Program $env 'hello', 'hello.c';
   4006 
   4007 In this case, rather than using the default construction environment, as is,
   4008 we have overridden the value of C<CC> so that the GNU C Compiler equivalent
   4009 is used, instead. Since this version of B<Hello, World!> requires a library,
   4010 F<libworld.a>, we have specified that any program linked in this environment
   4011 should be linked with that library. If the library exists already, well and
   4012 good, but if not, then we'll also have to include the statement:
   4013 
   4014 
   4015 
   4016   Library $env 'libworld', 'world.c';
   4017 
   4018 Now if you type C<cons hello>, the library will be built before the program
   4019 is linked, and, of course, C<gcc> will be used to compile both modules:
   4020 
   4021 
   4022 
   4023   % cons hello
   4024   gcc -c hello.c -o hello.o
   4025   gcc -c world.c -o world.o
   4026   ar r libworld.a world.o
   4027   ar: creating libworld.a
   4028   ranlib libworld.a
   4029   gcc -o hello hello.o libworld.a
   4030 
   4031 
   4032 =head2 Automatic and complete dependency analysis
   4033 
   4034 With Cons, dependencies are handled automatically. Continuing the previous
   4035 example, note that when we modify F<world.c>, F<world.o> is recompiled,
   4036 F<libworld.a> recreated, and F<hello> relinked:
   4037 
   4038 
   4039 
   4040   % vi world.c
   4041     [EDIT]
   4042   % cons hello
   4043   gcc -c world.c -o world.o
   4044   ar r libworld.a world.o
   4045   ar: creating libworld.a
   4046   ranlib libworld.a
   4047   gcc -o hello hello.o libworld.a
   4048 
   4049 This is a relatively simple example: Cons ``knows'' F<world.o> depends upon
   4050 F<world.c>, because the dependency is explicitly set up by the C<Library>
   4051 method. It also knows that F<libworld.a> depends upon F<world.o> and that
   4052 F<hello> depends upon F<libworld.a>, all for similar reasons.
   4053 
   4054 Now it turns out that F<hello.c> also includes the interface definition
   4055 file, F<world.h>:
   4056 
   4057 
   4058 
   4059   % emacs world.h
   4060     [EDIT]
   4061   % cons hello
   4062   gcc -c hello.c -o hello.o
   4063   gcc -o hello hello.o libworld.a
   4064 
   4065 How does Cons know that F<hello.c> includes F<world.h>, and that F<hello.o>
   4066 must therefore be recompiled? For now, suffice it to say that when
   4067 considering whether or not F<hello.o> is up-to-date, Cons invokes a scanner
   4068 for its dependency, F<hello.c>. This scanner enumerates the files included
   4069 by F<hello.c> to come up with a list of further dependencies, beyond those
   4070 made explicit by the Cons script. This process is recursive: any files
   4071 included by included files will also be scanned.
   4072 
   4073 Isn't this expensive? The answer is--it depends. If you do a full build of a
   4074 large system, the scanning time is insignificant. If you do a rebuild of a
   4075 large system, then Cons will spend a fair amount of time thinking about it
   4076 before it decides that nothing has to be done (although not necessarily more
   4077 time than make!). The good news is that Cons makes it very easy to
   4078 intelligently subset your build, when you are working on localized changes.
   4079 
   4080 
   4081 =head2 Automatic global build sequencing
   4082 
   4083 Because Cons does full and accurate dependency analysis, and does this
   4084 globally, for the entire build, Cons is able to use this information to take
   4085 full control of the B<sequencing> of the build. This sequencing is evident
   4086 in the above examples, and is equivalent to what you would expect for make,
   4087 given a full set of dependencies. With Cons, this extends trivially to
   4088 larger, multi-directory builds. As a result, all of the complexity involved
   4089 in making sure that a build is organized correctly--including multi-pass
   4090 hierarchical builds--is eliminated. We'll discuss this further in the next
   4091 sections.
   4092 
   4093 =head1 Building large trees--still just as simple
   4094 
   4095 
   4096 =head2 A hierarchy of build scripts
   4097 
   4098 A larger build, in Cons, is organized by creating a hierarchy of B<build
   4099 scripts>. At the top of the tree is a script called F<Construct>. The rest
   4100 of the scripts, by convention, are each called F<Conscript>. These scripts
   4101 are connected together, very simply, by the C<Build>, C<Export>, and
   4102 C<Import> commands.
   4103 
   4104 
   4105 =head2 The Build command
   4106 
   4107 The C<Build> command takes a list of F<Conscript> file names, and arranges
   4108 for them to be included in the build. For example:
   4109 
   4110   Build qw(
   4111 	drivers/display/Conscript
   4112 	drivers/mouse/Conscript
   4113 	parser/Conscript
   4114 	utilities/Conscript
   4115   );
   4116 
   4117 This is a simple two-level hierarchy of build scripts: all the subsidiary
   4118 F<Conscript> files are mentioned in the top-level F<Construct> file. Notice
   4119 that not all directories in the tree necessarily have build scripts
   4120 associated with them.
   4121 
   4122 This could also be written as a multi-level script. For example, the
   4123 F<Construct> file might contain this command:
   4124 
   4125   Build qw(
   4126 	parser/Conscript
   4127 	drivers/Conscript
   4128 	utilities/Conscript
   4129   );
   4130 
   4131 and the F<Conscript> file in the F<drivers> directory might contain this:
   4132 
   4133   Build qw(
   4134 	display/Conscript
   4135 	mouse/Conscript
   4136   );
   4137 
   4138 Experience has shown that the former model is a little easier to understand,
   4139 since the whole construction tree is laid out in front of you, at the
   4140 top-level. Hybrid schemes are also possible. A separately maintained
   4141 component that needs to be incorporated into a build tree, for example,
   4142 might hook into the build tree in one place, but define its own construction
   4143 hierarchy.
   4144 
   4145 By default, Cons does not change its working directory to the directory
   4146 containing a subsidiary F<Conscript> file it is including.  This behavior
   4147 can be enabled for a build by specifying, in the top-level F<Construct>
   4148 file:
   4149 
   4150   Conscript_chdir 1;
   4151 
   4152 When enabled, Cons will change to the subsidiary F<Conscript> file's
   4153 containing directory while reading in that file, and then change back
   4154 to the top-level directory once the file has been processed.
   4155 
   4156 It is expected that this behavior will become the default in some future
   4157 version of Cons.  To prepare for this transition, builds that expect
   4158 Cons to remain at the top of the build while it reads in a subsidiary
   4159 F<Conscript> file should explicitly disable this feature as follows:
   4160 
   4161   Conscript_chdir 0;
   4162 
   4163 
   4164 =head2 Relative, top-relative, and absolute file names
   4165 
   4166 You may have noticed that the file names specified to the Build command are
   4167 relative to the location of the script it is invoked from. This is generally
   4168 true for other filename arguments to other commands, too, although we might
   4169 as well mention here that if you begin a file name with a hash mark, ``#'',
   4170 then that file is interpreted relative to the top-level directory (where the
   4171 F<Construct> file resides). And, not surprisingly, if you begin it with ``/'',
   4172 then it is considered to be an absolute pathname. This is true even on
   4173 systems which use a back slash rather than a forward slash to name absolute
   4174 paths.
   4175 
   4176 (There is another file prefix, ``!'', that is interpreted specially by
   4177 Cons.  See discussion of the C<Link> command, below, for details.)
   4178 
   4179 
   4180 =head2 Using modules in build scripts
   4181 
   4182 You may pull modules into each F<Conscript> file using the normal Perl
   4183 C<use> or C<require> statements:
   4184 
   4185   use English;
   4186   require My::Module;
   4187 
   4188 Each C<use> or C<require> only affects the one F<Conscript> file in which
   4189 it appears.  To use a module in multiple F<Conscript> files, you must
   4190 put a C<use> or C<require> statement in each one that needs the module.
   4191 
   4192 
   4193 =head2 Scope of variables
   4194 
   4195 The top-level F<Construct> file and all F<Conscript> files begin life in
   4196 a common, separate Perl package.  B<Cons> controls the symbol table for
   4197 the package so that, the symbol table for each script is empty, except
   4198 for the F<Construct> file, which gets some of the command line arguments.
   4199 All of the variables that are set or used, therefore, are set by the
   4200 script itself--not by some external script.
   4201 
   4202 Variables can be explicitly B<imported> by a script from its parent
   4203 script. To import a variable, it must have been B<exported> by the parent
   4204 and initialized (otherwise an error will occur).
   4205 
   4206 
   4207 =head2 The Export command
   4208 
   4209 The C<Export> command is used as in the following example:
   4210 
   4211   $env = new cons();
   4212   $INCLUDE = "#export/include";
   4213   $LIB = "#export/lib";
   4214   Export qw( env INCLUDE LIB );
   4215   Build qw( util/Conscript );
   4216 
   4217 The values of the simple variables mentioned in the C<Export> list will be
   4218 squirreled away by any subsequent C<Build> commands. The C<Export> command
   4219 will only export Perl B<scalar> variables, that is, variables whose name
   4220 begins with C<$>. Other variables, objects, etc. can be exported by
   4221 reference--but all scripts will refer to the same object, and this object
   4222 should be considered to be read-only by the subsidiary scripts and by the
   4223 original exporting script. It's acceptable, however, to assign a new value
   4224 to the exported scalar variable--that won't change the underlying variable
   4225 referenced. This sequence, for example, is OK:
   4226 
   4227   $env = new cons();
   4228   Export qw( env INCLUDE LIB );
   4229   Build qw( util/Conscript );
   4230   $env = new cons(CFLAGS => '-O');
   4231   Build qw( other/Conscript );
   4232 
   4233 It doesn't matter whether the variable is set before or after the C<Export>
   4234 command. The important thing is the value of the variable at the time the
   4235 C<Build> command is executed. This is what gets squirreled away. Any
   4236 subsequent C<Export> commands, by the way, invalidate the first: you must
   4237 mention all the variables you wish to export on each C<Export> command.
   4238 
   4239 
   4240 =head2 The Import command
   4241 
   4242 Variables exported by the C<Export> command can be imported into subsidiary
   4243 scripts by the C<Import> command. The subsidiary script always imports
   4244 variables directly from the superior script. Consider this example:
   4245 
   4246   Import qw( env INCLUDE );
   4247 
   4248 This is only legal if the parent script exported both C<$env> and
   4249 C<$INCLUDE>. It also must have given each of these variables values. It is
   4250 OK for the subsidiary script to only import a subset of the exported
   4251 variables (in this example, C<$LIB>, which was exported by the previous
   4252 example, is not imported).
   4253 
   4254 All the imported variables are automatically re-exported, so the sequence:
   4255 
   4256   Import qw ( env INCLUDE );
   4257   Build qw ( beneath-me/Conscript );
   4258 
   4259 will supply both C<$env> and C<$INCLUDE> to the subsidiary file. If only
   4260 C<$env> is to be exported, then the following will suffice:
   4261 
   4262   Import qw ( env INCLUDE );
   4263   Export qw ( env );
   4264   Build qw ( beneath-me/Conscript );
   4265 
   4266 Needless to say, the variables may be modified locally before invoking
   4267 C<Build> on the subsidiary script.
   4268 
   4269 
   4270 =head2 Build script evaluation order
   4271 
   4272 The only constraint on the ordering of build scripts is that superior
   4273 scripts are evaluated before their inferior scripts. The top-level
   4274 F<Construct> file, for instance, is evaluated first, followed by any
   4275 inferior scripts. This is all you really need to know about the evaluation
   4276 order, since order is generally irrelevant. Consider the following C<Build>
   4277 command:
   4278 
   4279   Build qw(
   4280 	drivers/display/Conscript
   4281 	drivers/mouse/Conscript
   4282 	parser/Conscript
   4283 	utilities/Conscript
   4284   );
   4285 
   4286 We've chosen to put the script names in alphabetical order, simply because
   4287 that's the most convenient for maintenance purposes. Changing the order will
   4288 make no difference to the build.
   4289 
   4290 
   4291 =head1 A Model for sharing files
   4292 
   4293 
   4294 =head2 Some simple conventions
   4295 
   4296 In any complex software system, a method for sharing build products needs to
   4297 be established. We propose a simple set of conventions which are trivial to
   4298 implement with Cons, but very effective.
   4299 
   4300 The basic rule is to require that all build products which need to be shared
   4301 between directories are shared via an intermediate directory. We have
   4302 typically called this F<export>, and, in a C environment, provided
   4303 conventional sub-directories of this directory, such as F<include>, F<lib>,
   4304 F<bin>, etc.
   4305 
   4306 These directories are defined by the top-level F<Construct> file. A simple
   4307 F<Construct> file for a B<Hello, World!> application, organized using
   4308 multiple directories, might look like this:
   4309 
   4310   # Construct file for Hello, World!
   4311 
   4312   # Where to put all our shared products.
   4313   $EXPORT = '#export';
   4314 
   4315   Export qw( CONS INCLUDE LIB BIN );
   4316 
   4317   # Standard directories for sharing products.
   4318   $INCLUDE = "$EXPORT/include";
   4319   $LIB = "$EXPORT/lib";
   4320   $BIN = "$EXPORT/bin";
   4321 
   4322   # A standard construction environment.
   4323   $CONS = new cons (
   4324 	CPPPATH => $INCLUDE,	# Include path for C Compilations
   4325 	LIBPATH => $LIB,	# Library path for linking programs
   4326 	LIBS => '-lworld',	# List of standard libraries
   4327   );
   4328 
   4329   Build qw(
   4330 	hello/Conscript
   4331 	world/Conscript
   4332   );
   4333 
   4334 The F<world> directory's F<Conscript> file looks like this:
   4335 
   4336   # Conscript file for directory world
   4337   Import qw( CONS INCLUDE LIB );
   4338 
   4339   # Install the products of this directory
   4340   Install $CONS $LIB, 'libworld.a';
   4341   Install $CONS $INCLUDE, 'world.h';
   4342 
   4343   # Internal products
   4344   Library $CONS 'libworld.a', 'world.c';
   4345 
   4346 and the F<hello> directory's F<Conscript> file looks like this:
   4347 
   4348   # Conscript file for directory hello
   4349   Import qw( CONS BIN );
   4350 
   4351   # Exported products
   4352   Install $CONS $BIN, 'hello';
   4353 
   4354   # Internal products
   4355   Program $CONS 'hello', 'hello.c';
   4356 
   4357 To construct a B<Hello, World!> program with this directory structure, go to
   4358 the top-level directory, and invoke C<cons> with the appropriate
   4359 arguments. In the following example, we tell Cons to build the directory
   4360 F<export>. To build a directory, Cons recursively builds all known products
   4361 within that directory (only if they need rebuilding, of course). If any of
   4362 those products depend upon other products in other directories, then those
   4363 will be built, too.
   4364 
   4365   % cons export
   4366   Install world/world.h as export/include/world.h
   4367   cc -Iexport/include -c hello/hello.c -o hello/hello.o
   4368   cc -Iexport/include -c world/world.c -o world/world.o
   4369   ar r world/libworld.a world/world.o
   4370   ar: creating world/libworld.a
   4371   ranlib world/libworld.a
   4372   Install world/libworld.a as export/lib/libworld.a
   4373   cc -o hello/hello hello/hello.o -Lexport/lib -lworld
   4374   Install hello/hello as export/bin/hello
   4375 
   4376 
   4377 =head2 Clean, understandable, location-independent scripts
   4378 
   4379 You'll note that the two F<Conscript> files are very clean and
   4380 to-the-point. They simply specify products of the directory and how to build
   4381 those products. The build instructions are minimal: they specify which
   4382 construction environment to use, the name of the product, and the name of
   4383 the inputs. Note also that the scripts are location-independent: if you wish
   4384 to reorganize your source tree, you are free to do so: you only have to
   4385 change the F<Construct> file (in this example), to specify the new locations
   4386 of the F<Conscript> files. The use of an export tree makes this goal easy.
   4387 
   4388 Note, too, how Cons takes care of little details for you. All the F<export>
   4389 directories, for example, were made automatically. And the installed files
   4390 were really hard-linked into the respective export directories, to save
   4391 space and time. This attention to detail saves considerable work, and makes
   4392 it even easier to produce simple, maintainable scripts.
   4393 
   4394 
   4395 =head1 Separating source and build trees
   4396 
   4397 It's often desirable to keep any derived files from the build completely
   4398 separate from the source files. This makes it much easier to keep track of
   4399 just what is a source file, and also makes it simpler to handle B<variant>
   4400 builds, especially if you want the variant builds to co-exist.
   4401 
   4402 
   4403 =head2 Separating build and source directories using the Link command
   4404 
   4405 Cons provides a simple mechanism that handles all of these requirements. The
   4406 C<Link> command is invoked as in this example:
   4407 
   4408   Link 'build' => 'src';
   4409 
   4410 The specified directories are ``linked'' to the specified source
   4411 directory. Let's suppose that you setup a source directory, F<src>, with the
   4412 sub-directories F<world> and F<hello> below it, as in the previous
   4413 example. You could then substitute for the original build lines the
   4414 following:
   4415 
   4416   Build qw(
   4417 	build/world/Conscript
   4418 	build/hello/Conscript
   4419   );
   4420 
   4421 Notice that you treat the F<Conscript> file as if it existed in the build
   4422 directory. Now if you type the same command as before, you will get the
   4423 following results:
   4424 
   4425   % cons export
   4426   Install build/world/world.h as export/include/world.h
   4427   cc -Iexport/include -c build/hello/hello.c -o build/hello/hello.o
   4428   cc -Iexport/include -c build/world/world.c -o build/world/world.o
   4429   ar r build/world/libworld.a build/world/world.o
   4430   ar: creating build/world/libworld.a
   4431   ranlib build/world/libworld.a
   4432   Install build/world/libworld.a as export/lib/libworld.a
   4433   cc -o build/hello/hello build/hello/hello.o -Lexport/lib -lworld
   4434   Install build/hello/hello as export/bin/hello
   4435 
   4436 Again, Cons has taken care of the details for you. In particular, you will
   4437 notice that all the builds are done using source files and object files from
   4438 the build directory. For example, F<build/world/world.o> is compiled from
   4439 F<build/world/world.c>, and F<export/include/world.h> is installed from
   4440 F<build/world/world.h>. This is accomplished on most systems by the simple
   4441 expedient of ``hard'' linking the required files from each source directory
   4442 into the appropriate build directory.
   4443 
   4444 The links are maintained correctly by Cons, no matter what you do to the
   4445 source directory. If you modify a source file, your editor may do this ``in
   4446 place'' or it may rename it first and create a new file. In the latter case,
   4447 any hard link will be lost. Cons will detect this condition the next time
   4448 the source file is needed, and will relink it appropriately.
   4449 
   4450 You'll also notice, by the way, that B<no> changes were required to the
   4451 underlying F<Conscript> files. And we can go further, as we shall see in the
   4452 next section.
   4453 
   4454 =head2 Explicit references to the source directory
   4455 
   4456 When using the C<Link> command on some operating systems or with some
   4457 tool chains, it's sometimes useful to have a command actually use
   4458 the path name to the source directory, not the build directory.  For
   4459 example, on systems that must copy, not "hard link," the F<src/> and
   4460 F<build/> copies of C<Linked> files, using the F<src/> path of a file
   4461 name might make an editor aware that a syntax error must be fixed in the
   4462 source directory, not the build directory.
   4463 
   4464 You can tell Cons that you want to use the "source path" for a file by
   4465 preceding the file name with a ``!'' (exclamation point).  For example,
   4466 if we add a ``!'' to the beginning of a source file:
   4467 
   4468   Program $env "foo", "!foo.c";	# Notice initial ! on foo.c
   4469 
   4470 Cons will compile the target as follows:
   4471 
   4472   cc -c src/foo.c -o build/foo.o
   4473   cc -o build/foo build/foo.o
   4474 
   4475 Notice that Cons has compiled the program from the the F<src/foo.c>
   4476 source file.  Without the initial ``!'', Cons would have compiled the
   4477 program using the F<build/foo.c> path name.
   4478 
   4479 
   4480 
   4481 =head1 Variant builds
   4482 
   4483 
   4484 =head2 Hello, World! for baNaNa and peAcH OS's
   4485 
   4486 Variant builds require just another simple extension. Let's take as an
   4487 example a requirement to allow builds for both the baNaNa and peAcH
   4488 operating systems. In this case, we are using a distributed file system,
   4489 such as NFS to access the particular system, and only one or the other of
   4490 the systems has to be compiled for any given invocation of C<cons>. Here's
   4491 one way we could set up the F<Construct> file for our B<Hello, World!>
   4492 application:
   4493 
   4494   # Construct file for Hello, World!
   4495 
   4496   die qq(OS must be specified) unless $OS = $ARG{OS};
   4497   die qq(OS must be "peach" or "banana")
   4498 	if $OS ne "peach" && $OS ne "banana";
   4499 
   4500   # Where to put all our shared products.
   4501   $EXPORT = "#export/$OS";
   4502 
   4503   Export qw( CONS INCLUDE LIB BIN );
   4504 
   4505   # Standard directories for sharing products.
   4506   $INCLUDE = "$EXPORT/include";
   4507   $LIB = "$EXPORT/lib";
   4508   $BIN = "$EXPORT/bin";
   4509 
   4510   # A standard construction environment.
   4511   $CONS = new cons (
   4512 	CPPPATH => $INCLUDE,	# Include path for C Compilations
   4513 	LIBPATH => $LIB,	# Library path for linking programs
   4514 	LIBS => '-lworld',	# List of standard libraries
   4515   );
   4516 
   4517   # $BUILD is where we will derive everything.
   4518   $BUILD = "#build/$OS";
   4519 
   4520   # Tell cons where the source files for $BUILD are.
   4521   Link $BUILD => 'src';
   4522 
   4523   Build (
   4524 	"$BUILD/hello/Conscript",
   4525 	"$BUILD/world/Conscript",
   4526   );
   4527 
   4528 Now if we login to a peAcH system, we can build our B<Hello, World!>
   4529 application for that platform:
   4530 
   4531   % cons export OS=peach
   4532   Install build/peach/world/world.h as export/peach/include/world.h
   4533   cc -Iexport/peach/include -c build/peach/hello/hello.c -o build/peach/hello/hello.o
   4534   cc -Iexport/peach/include -c build/peach/world/world.c -o build/peach/world/world.o
   4535   ar r build/peach/world/libworld.a build/peach/world/world.o
   4536   ar: creating build/peach/world/libworld.a
   4537   ranlib build/peach/world/libworld.a
   4538   Install build/peach/world/libworld.a as export/peach/lib/libworld.a
   4539   cc -o build/peach/hello/hello build/peach/hello/hello.o -Lexport/peach/lib -lworld
   4540   Install build/peach/hello/hello as export/peach/bin/hello
   4541 
   4542 
   4543 =head2 Variations on a theme
   4544 
   4545 Other variations of this model are possible. For example, you might decide
   4546 that you want to separate out your include files into platform dependent and
   4547 platform independent files. In this case, you'd have to define an
   4548 alternative to C<$INCLUDE> for platform-dependent files. Most F<Conscript>
   4549 files, generating purely platform-independent include files, would not have
   4550 to change.
   4551 
   4552 You might also want to be able to compile your whole system with debugging
   4553 or profiling, for example, enabled. You could do this with appropriate
   4554 command line options, such as C<DEBUG=on>. This would then be translated
   4555 into the appropriate platform-specific requirements to enable debugging
   4556 (this might include turning off optimization, for example). You could
   4557 optionally vary the name space for these different types of systems, but, as
   4558 we'll see in the next section, it's not B<essential> to do this, since Cons
   4559 is pretty smart about rebuilding things when you change options.
   4560 
   4561 
   4562 =head1 Signatures
   4563 
   4564 Cons uses file B<signatures> to decide if a derived file is out-of-date
   4565 and needs rebuilding.  In essence, if the contents of a file change,
   4566 or the manner in which the file is built changes, the file's signature
   4567 changes as well.  This allows Cons to decide with certainty when a file
   4568 needs rebuilding, because Cons can detect, quickly and reliably, whether
   4569 any of its dependency files have been changed.
   4570 
   4571 
   4572 =head2 MD5 content and build signatures
   4573 
   4574 Cons uses the B<MD5> (B<Message Digest 5>) algorithm to compute file
   4575 signatures.  The MD5 algorithm computes a strong cryptographic checksum
   4576 for any given input string.  Cons can, based on configuration, use two
   4577 different MD5 signatures for a given file:
   4578 
   4579 The B<content signature> of a file is an MD5 checksum of the file's
   4580 contents.  Consequently, when the contents of a file change, its content
   4581 signature changes as well.
   4582 
   4583 The B<build signature> of a file is a combined MD5 checksum of:
   4584 
   4585 =over 4
   4586 
   4587 the signatures of all the input files used to build the file
   4588 
   4589 the signatures of all dependency files discovered by source scanners
   4590 (for example, C<.h> files)
   4591 
   4592 the signatures of all dependency files specified explicitly via the
   4593 C<Depends> method)
   4594 
   4595 the command-line string used to build the file
   4596 
   4597 =back
   4598 
   4599 The build signature is, in effect, a digest of all the dependency
   4600 information for the specified file.  Consequently, a file's build
   4601 signature changes whenever any part of its dependency information
   4602 changes: a new file is added, the contents of a file on which it depends
   4603 change, there's a change to the command line used to build the file (or
   4604 any of its dependency files), etc.
   4605 
   4606 For example, in the previous section, the build signature of the
   4607 F<world.o> file will include:
   4608 
   4609 =over 4
   4610 
   4611 the signature of the F<world.c> file
   4612 
   4613 the signatures of any header files that Cons detects are included,
   4614 directly or indirectly, by F<world.c>
   4615 
   4616 the text of the actual command line was used to generate F<world.o>
   4617 
   4618 =back
   4619 
   4620 Similarly, the build signature of the F<libworld.a> file will include
   4621 all the signatures of its constituents (and hence, transitively, the
   4622 signatures of B<their> constituents), as well as the command line that
   4623 created the file.
   4624 
   4625 Note that there is no need for a derived file to depend upon any
   4626 particular F<Construct> or F<Conscript> file.  If changes to these files
   4627 affect a file, then this will be automatically reflected in its build
   4628 signature, since relevant parts of the command line are included in the
   4629 signature. Unrelated F<Construct> or F<Conscript> changes will have no
   4630 effect.
   4631 
   4632 
   4633 =head2 Storing signatures in .consign files
   4634 
   4635 Before Cons exits, it stores the calculated signatures for all of the
   4636 files it built or examined in F<.consign> files, one per directory.
   4637 Cons uses this stored information on later invocations to decide if
   4638 derived files need to be rebuilt.
   4639 
   4640 After the previous example was compiled, the F<.consign> file in the
   4641 F<build/peach/world> directory looked like this:
   4642 
   4643   world.h:985533370 - d181712f2fdc07c1f05d97b16bfad904
   4644   world.o:985533372 2a0f71e0766927c0532977b0d2158981
   4645   world.c:985533370 - c712f77189307907f4189b5a7ab62ff3
   4646   libworld.a:985533374 69e568fc5241d7d25be86d581e1fb6aa
   4647 
   4648 After the file name and colon, the first number is a timestamp of the
   4649 file's modification time (on UNIX systems, this is typically the number
   4650 of seconds since January 1st, 1970).  The second value is the build
   4651 signature of the file (or ``-'' in the case of files with no build
   4652 signature--that is, source files).  The third value, if any, is the
   4653 content signature of the file.
   4654 
   4655 
   4656 =head2 Using build signatures to decide when to rebuild files
   4657 
   4658 When Cons is deciding whether to build or rebuild a derived file, it
   4659 first computes the file's current build signature.  If the file doesn't
   4660 exist, it must obviously be built.
   4661 
   4662 If, however, the file already exists, Cons next compares the
   4663 modification timestamp of the file against the timestamp value in
   4664 the F<.consign> file.  If the timestamps match, Cons compares the
   4665 newly-computed build signature against the build signature in the
   4666 F<.consign> file.  If the timestamps do not match or the build
   4667 signatures do not match, the derived file is rebuilt.
   4668 
   4669 After the file is built or rebuilt, Cons arranges to store the
   4670 newly-computed build signature in the F<.consign> file when it exits.
   4671 
   4672 
   4673 =head2 Signature example
   4674 
   4675 The use of these signatures is an extremely simple, efficient, and
   4676 effective method of improving--dramatically--the reproducibility of a
   4677 system.
   4678 
   4679 We'll demonstrate this with a simple example:
   4680 
   4681   # Simple "Hello, World!" Construct file
   4682   $CFLAGS = '-g' if $ARG{DEBUG} eq 'on';
   4683   $CONS = new cons(CFLAGS => $CFLAGS);
   4684   Program $CONS 'hello', 'hello.c';
   4685 
   4686 Notice how Cons recompiles at the appropriate times:
   4687 
   4688   % cons hello
   4689   cc -c hello.c -o hello.o
   4690   cc -o hello hello.o
   4691   % cons hello
   4692   cons: "hello" is up-to-date.
   4693   % cons DEBUG=on hello
   4694   cc -g -c hello.c -o hello.o
   4695   cc -o hello hello.o
   4696   % cons DEBUG=on hello
   4697   cons: "hello" is up-to-date.
   4698   % cons hello
   4699   cc -c hello.c -o hello.o
   4700   cc -o hello hello.o
   4701 
   4702 
   4703 =head2 Source-file signature configuration
   4704 
   4705 Cons provides a C<SourceSignature> method that allows you to configure
   4706 how the signature should be calculated for any source file when its
   4707 signature is being used to decide if a dependent file is up-to-date.
   4708 The arguments to the C<SourceSignature> method consist of one or more
   4709 pairs of strings:
   4710 
   4711   SourceSignature 'auto/*.c' => 'content',
   4712 		  '*' => 'stored-content';
   4713 
   4714 The first string in each pair is a pattern to match against derived file
   4715 path names. The pattern is a file-globbing pattern, not a Perl regular
   4716 expression; the pattern <*.l> will match all Lex source files.  The C<*>
   4717 wildcard will match across directory separators; the pattern C<foo/*.c>
   4718 would match all C source files in any subdirectory underneath the C<foo>
   4719 subdirectory.
   4720 
   4721 The second string in each pair contains one of the following keywords to
   4722 specify how signatures should be calculated for source files that match
   4723 the pattern.  The available keywords are:
   4724 
   4725 =over 4
   4726 
   4727 =item content
   4728 
   4729 Use the content signature of the source file when calculating signatures
   4730 of files that depend on it.  This guarantees correct calculation of the
   4731 file's signature for all builds, by telling Cons to read the contents of
   4732 a source file to calculate its content signature each time it is run.
   4733 
   4734 =item stored-content
   4735 
   4736 Use the source file's content signature as stored in the F<.consign>
   4737 file, provided the file's timestamp matches the cached timestamp value
   4738 in the F<.consign> file.  This optimizes performance, with the slight
   4739 risk of an incorrect build if a source file's contents have been changed
   4740 so quickly after its previous update that the timestamp still matches
   4741 the stored timestamp in the F<.consign> file even though the contents
   4742 have changed.
   4743 
   4744 =back
   4745 
   4746 The Cons default behavior of always calculating a source file's
   4747 signature from the file's contents is equivalent to specifying:
   4748 
   4749   SourceSignature '*' => 'content';
   4750 
   4751 The C<*> will match all source files.  The C<content> keyword
   4752 specifies that Cons will read the contents of a source file to calculate
   4753 its signature each time it is run.
   4754 
   4755 A useful global performance optimization is:
   4756 
   4757   SourceSignature '*' => 'stored-content';
   4758 
   4759 This specifies that Cons will use pre-computed content signatures
   4760 from F<.consign> files, when available, rather than re-calculating a
   4761 signature from the the source file's contents each time Cons is run.  In
   4762 practice, this is safe for most build situations, and only a problem
   4763 when source files are changed automatically (by scripts, for example).
   4764 The Cons default, however, errs on the side of guaranteeing a correct
   4765 build in all situations.
   4766 
   4767 Cons tries to match source file path names against the patterns in the
   4768 order they are specified in the C<SourceSignature> arguments:
   4769 
   4770   SourceSignature '/usr/repository/objects/*' => 'stored-content',
   4771 		  '/usr/repository/*' => 'content',
   4772 		  '*.y' => 'content',
   4773 		  '*' => 'stored-content';
   4774 
   4775 In this example, all source files under the F</usr/repository/objects>
   4776 directory will use F<.consign> file content signatures, source files
   4777 anywhere else underneath F</usr/repository> will not use F<.consign>
   4778 signature values, all Yacc source files (C<*.y>) anywhere else will not
   4779 use F<.consign> signature values, and any other source file will use
   4780 F<.consign> signature values.
   4781 
   4782 
   4783 =head2 Derived-file signature configuration
   4784 
   4785 Cons provides a C<SIGNATURE> construction variable that allows you to
   4786 configure how signatures are calculated for any derived file when its
   4787 signature is being used to decide if a dependent file is up-to-date.
   4788 The value of the C<SIGNATURE> construction variable is a Perl array
   4789 reference that holds one or more pairs of strings, like the arguments to
   4790 the C<SourceSignature> method.
   4791 
   4792 The first string in each pair is a pattern to match against derived file
   4793 path names. The pattern is a file-globbing pattern, not a Perl regular
   4794 expression; the pattern `*.obj' will match all (Win32) object files.
   4795 The C<*> wildcard will match across directory separators; the pattern
   4796 `foo/*.a' would match all (UNIX) library archives in any subdirectory
   4797 underneath the foo subdirectory.
   4798 
   4799 The second string in each pair contains one of the following keywords
   4800 to specify how signatures should be calculated for derived files that
   4801 match the pattern.  The available keywords are the same as for the
   4802 C<SourceSignature> method, with an additional keyword:
   4803 
   4804 =over 4
   4805 
   4806 =item build
   4807 
   4808 Use the build signature of the derived file when calculating signatures
   4809 of files that depend on it.  This guarantees correct builds by forcing
   4810 Cons to rebuild any and all files that depend on the derived file.
   4811 
   4812 =item content
   4813 
   4814 Use the content signature of the derived file when calculating signatures
   4815 of files that depend on it.  This guarantees correct calculation of the
   4816 file's signature for all builds, by telling Cons to read the contents of
   4817 a derived file to calculate its content signature each time it is run.
   4818 
   4819 =item stored-content
   4820 
   4821 Use the derived file's content signature as stored in the F<.consign>
   4822 file, provided the file's timestamp matches the cached timestamp value
   4823 in the F<.consign> file.  This optimizes performance, with the slight
   4824 risk of an incorrect build if a derived file's contents have been
   4825 changed so quickly after a Cons build that the file's timestamp still
   4826 matches the stored timestamp in the F<.consign> file.
   4827 
   4828 =back
   4829 
   4830 The Cons default behavior (as previously described) for using
   4831 derived-file signatures is equivalent to:
   4832 
   4833   $env = new cons(SIGNATURE => ['*' => 'build']);
   4834 
   4835 The C<*> will match all derived files.  The C<build> keyword specifies
   4836 that all derived files' build signatures will be used when calculating
   4837 whether a dependent file is up-to-date.
   4838 
   4839 A useful alternative default C<SIGNATURE> configuration for many sites:
   4840 
   4841   $env = new cons(SIGNATURE => ['*' => 'content']);
   4842 
   4843 In this configuration, derived files have their signatures calculated
   4844 from the file contents.  This adds slightly to Cons' workload, but has
   4845 the useful effect of "stopping" further rebuilds if a derived file is
   4846 rebuilt to exactly the same file contents as before, which usually
   4847 outweighs the additional computation Cons must perform.
   4848 
   4849 For example, changing a comment in a C file and recompiling should
   4850 generate the exact same object file (assuming the compiler doesn't
   4851 insert a timestamp in the object file's header).  In that case,
   4852 specifying C<content> or C<stored-content> for the signature calculation
   4853 will cause Cons to recognize that the object file did not actually
   4854 change as a result of being rebuilt, and libraries or programs that
   4855 include the object file will not be rebuilt.  When C<build> is
   4856 specified, however, Cons will only "know" that the object file was
   4857 rebuilt, and proceed to rebuild any additional files that include the
   4858 object file.
   4859 
   4860 Note that Cons tries to match derived file path names against the
   4861 patterns in the order they are specified in the C<SIGNATURE> array
   4862 reference:
   4863 
   4864   $env = new cons(SIGNATURE => ['foo/*.o' => 'build',
   4865 				'*.o' => 'content',
   4866 				'*.a' => 'stored-content',
   4867 				'*' => 'content']);
   4868 
   4869 In this example, all object files underneath the F<foo> subdirectory
   4870 will use build signatures, all other object files (including object
   4871 files underneath other subdirectories!) will use F<.consign> file
   4872 content signatures, libraries will use F<.consign> file build
   4873 signatures, and all other derived files will use content signatures.
   4874 
   4875 
   4876 =head2 Debugging signature calculation
   4877 
   4878 Cons provides a C<-S> option that can be used to specify what internal
   4879 Perl package Cons should use to calculate signatures.  The default Cons
   4880 behavior is equivalent to specifying C<-S md5> on the command line.
   4881 
   4882 The only other package (currently) available is an C<md5::debug>
   4883 package that prints out detailed information about the MD5 signature
   4884 calculations performed by Cons:
   4885 
   4886   % cons -S md5::debug hello
   4887   sig::md5::srcsig(hello.c)
   4888           => |52d891204c62fe93ecb95281e1571938|
   4889   sig::md5::collect(52d891204c62fe93ecb95281e1571938)
   4890           => |fb0660af4002c40461a2f01fbb5ffd03|
   4891   sig::md5::collect(52d891204c62fe93ecb95281e1571938,
   4892                     fb0660af4002c40461a2f01fbb5ffd03,
   4893                     cc   -c %< -o %>)
   4894           => |f7128da6c3fe3c377dc22ade70647b39|
   4895   sig::md5::current(||
   4896                  eq |f7128da6c3fe3c377dc22ade70647b39|)
   4897   cc -c hello.c -o hello.o
   4898   sig::md5::collect()
   4899           => |d41d8cd98f00b204e9800998ecf8427e|
   4900   sig::md5::collect(f7128da6c3fe3c377dc22ade70647b39,
   4901                     d41d8cd98f00b204e9800998ecf8427e,
   4902                     cc  -o %> %<  )
   4903           => |a0bdce7fd09e0350e7efbbdb043a00b0|
   4904   sig::md5::current(||
   4905                  eq |a0bdce7fd09e0350e7efbbdb043a00b0|)
   4906   cc -o hello, hello.o
   4907 
   4908 
   4909 =head1 Code Repositories
   4910 
   4911 Many software development organizations will have one or more central
   4912 repository directory trees containing the current source code for one or
   4913 more projects, as well as the derived object files, libraries, and
   4914 executables.  In order to reduce unnecessary recompilation, it is useful to
   4915 use files from the repository to build development software--assuming, of
   4916 course, that no newer dependency file exists in the local build tree.
   4917 
   4918 
   4919 =head2 Repository
   4920 
   4921 Cons provides a mechanism to specify a list of code repositories that will
   4922 be searched, in-order, for source files and derived files not found in the
   4923 local build directory tree.
   4924 
   4925 The following lines in a F<Construct> file will instruct Cons to look first
   4926 under the F</usr/experiment/repository> directory and then under the
   4927 F</usr/product/repository> directory:
   4928 
   4929   Repository qw (
   4930 	/usr/experiment/repository
   4931 	/usr/product/repository
   4932   );
   4933 
   4934 The repository directories specified may contain source files, derived files
   4935 (objects, libraries and executables), or both.  If there is no local file
   4936 (source or derived) under the directory in which Cons is executed, then the
   4937 first copy of a same-named file found under a repository directory will be
   4938 used to build any local derived files.
   4939 
   4940 Cons maintains one global list of repositories directories.  Cons will
   4941 eliminate the current directory, and any non-existent directories, from the
   4942 list.
   4943 
   4944 
   4945 =head2 Finding the Construct file in a Repository
   4946 
   4947 Cons will also search for F<Construct> and F<Conscript> files in the
   4948 repository tree or trees.  This leads to a chicken-and-egg situation,
   4949 though: how do you look in a repository tree for a F<Construct> file if the
   4950 F<Construct> file tells you where the repository is?  To get around this,
   4951 repositories may be specified via C<-R> options on the command line:
   4952 
   4953   % cons -R /usr/experiment/repository -R /usr/product/repository .
   4954 
   4955 Any repository directories specified in the F<Construct> or F<Conscript>
   4956 files will be appended to the repository directories specified by
   4957 command-line C<-R> options.
   4958 
   4959 =head2 Repository source files
   4960 
   4961 If the source code (include the F<Conscript> file) for the library version
   4962 of the I<Hello, World!> C application is in a repository (with no derived
   4963 files), Cons will use the repository source files to create the local object
   4964 files and executable file:
   4965 
   4966   % cons -R /usr/src_only/repository hello
   4967   gcc -c /usr/src_only/repository/hello.c -o hello.o
   4968   gcc -c /usr/src_only/repository/world.c -o world.o
   4969   ar r libworld.a world.o
   4970   ar: creating libworld.a
   4971   ranlib libworld.a
   4972   gcc -o hello hello.o libworld.a
   4973 
   4974 Creating a local source file will cause Cons to rebuild the appropriate
   4975 derived file or files:
   4976 
   4977   % pico world.c
   4978     [EDIT]
   4979   % cons -R /usr/src_only/repository hello
   4980   gcc -c world.c -o world.o
   4981   ar r libworld.a world.o
   4982   ar: creating libworld.a
   4983   ranlib libworld.a
   4984   gcc -o hello hello.o libworld.a
   4985 
   4986 And removing the local source file will cause Cons to revert back to
   4987 building the derived files from the repository source:
   4988 
   4989   % rm world.c
   4990   % cons -R /usr/src_only/repository hello
   4991   gcc -c /usr/src_only/repository/world.c -o world.o
   4992   ar r libworld.a world.o
   4993   ar: creating libworld.a
   4994   ranlib libworld.a
   4995   gcc -o hello hello.o libworld.a
   4996 
   4997 
   4998 =head2 Repository derived files
   4999 
   5000 If a repository tree contains derived files (usually object files,
   5001 libraries, or executables), Cons will perform its normal signature
   5002 calculation to decide whether the repository file is up-to-date or a derived
   5003 file must be built locally.  This means that, in order to ensure correct
   5004 signature calculation, a repository tree must also contain the F<.consign>
   5005 files that were created by Cons when generating the derived files.
   5006 
   5007 This would usually be accomplished by building the software in the
   5008 repository (or, alternatively, in a build directory, and then copying the
   5009 result to the repository):
   5010 
   5011   % cd /usr/all/repository
   5012   % cons hello
   5013   gcc -c hello.c -o hello.o
   5014   gcc -c world.c -o world.o
   5015   ar r libworld.a world.o
   5016   ar: creating libworld.a
   5017   ranlib libworld.a
   5018   gcc -o hello hello.o libworld.a
   5019 
   5020 (This is safe even if the F<Construct> file lists the F</usr/all/repository>
   5021 directory in a C<Repository> command because Cons will remove the current
   5022 directory from the repository list.)
   5023 
   5024 Now if we want to build a copy of the application with our own F<hello.c>
   5025 file, we only need to create the one necessary source file, and use the
   5026 C<-R> option to have Cons use other files from the repository:
   5027 
   5028   % mkdir $HOME/build1
   5029   % cd $HOME/build1
   5030   % ed hello.c
   5031     [EDIT]
   5032   % cons -R /usr/all/repository hello
   5033   gcc -c hello.c -o hello.o
   5034   gcc -o hello hello.o /usr/all/repository/libworld.a
   5035 
   5036 Notice that Cons has not bothered to recreate a local F<libworld.a> library
   5037 (or recompile the F<world.o> module), but instead uses the already-compiled
   5038 version from the repository.
   5039 
   5040 Because the MD5 signatures that Cons puts in the F<.consign> file contain
   5041 timestamps for the derived files, the signature timestamps must match the
   5042 file timestamps for a signature to be considered valid.
   5043 
   5044 Some software systems may alter the timestamps on repository files (by
   5045 copying them, e.g.), in which case Cons will, by default, assume the
   5046 repository signatures are invalid and rebuild files unnecessarily.  This
   5047 behavior may be altered by specifying:
   5048 
   5049   Repository_Sig_Times_OK 0;
   5050 
   5051 This tells Cons to ignore timestamps when deciding whether a signature is
   5052 valid.  (Note that avoiding this sanity check means there must be proper
   5053 control over the repository tree to ensure that the derived files cannot be
   5054 modified without updating the F<.consign> signature.)
   5055 
   5056 
   5057 =head2 Local copies of files
   5058 
   5059 If the repository tree contains the complete results of a build, and we try
   5060 to build from the repository without any files in our local tree, something
   5061 moderately surprising happens:
   5062 
   5063   % mkdir $HOME/build2
   5064   % cd $HOME/build2
   5065   % cons -R /usr/all/repository hello
   5066   cons: "hello" is up-to-date.
   5067 
   5068 Why does Cons say that the F<hello> program is up-to-date when there is no
   5069 F<hello> program in the local build directory?  Because the repository (not
   5070 the local directory) contains the up-to-date F<hello> program, and Cons
   5071 correctly determines that nothing needs to be done to rebuild this
   5072 up-to-date copy of the file.
   5073 
   5074 There are, however, many times in which it is appropriate to ensure that a
   5075 local copy of a file always exists.  A packaging or testing script, for
   5076 example, may assume that certain generated files exist locally.  Instead of
   5077 making these subsidiary scripts aware of the repository directory, the
   5078 C<Local> command may be added to a F<Construct> or F<Conscript> file to
   5079 specify that a certain file or files must appear in the local build
   5080 directory:
   5081 
   5082   Local qw(
   5083 	hello
   5084   );
   5085 
   5086 Then, if we re-run the same command, Cons will make a local copy of the
   5087 program from the repository copy (telling you that it is doing so):
   5088 
   5089   % cons -R /usr/all/repository hello
   5090   Local copy of hello from /usr/all/repository/hello
   5091   cons: "hello" is up-to-date.
   5092 
   5093 Notice that, because the act of making the local copy is not considered a
   5094 "build" of the F<hello> file, Cons still reports that it is up-to-date.
   5095 
   5096 Creating local copies is most useful for files that are being installed into
   5097 an intermediate directory (for sharing with other directories) via the
   5098 C<Install> command.  Accompanying the C<Install> command for a file with a
   5099 companion C<Local> command is so common that Cons provides a
   5100 C<Install_Local> command as a convenient way to do both:
   5101 
   5102   Install_Local $env, '#export', 'hello';
   5103 
   5104 is exactly equivalent to:
   5105 
   5106   Install $env '#export', 'hello';
   5107   Local '#export/hello';
   5108 
   5109 Both the C<Local> and C<Install_Local> commands update the local F<.consign>
   5110 file with the appropriate file signatures, so that future builds are
   5111 performed correctly.
   5112 
   5113 
   5114 =head2 Repository dependency analysis
   5115 
   5116 Due to its built-in scanning, Cons will search the specified repository
   5117 trees for included F<.h> files.  Unless the compiler also knows about the
   5118 repository trees, though, it will be unable to find F<.h> files that only
   5119 exist in a repository.  If, for example, the F<hello.c> file includes the
   5120 F<hello.h> file in its current directory:
   5121 
   5122   % cons -R /usr/all/repository hello
   5123   gcc -c /usr/all/repository/hello.c -o hello.o
   5124   /usr/all/repository/hello.c:1: hello.h: No such file or directory
   5125 
   5126 Solving this problem forces some requirements onto the way construction
   5127 environments are defined and onto the way the C C<#include> preprocessor
   5128 directive is used to include files.
   5129 
   5130 In order to inform the compiler about the repository trees, Cons will add
   5131 appropriate C<-I> flags to the compilation commands.  This means that the
   5132 C<CPPPATH> variable in the construction environment must explicitly specify
   5133 all subdirectories which are to be searched for included files, including the
   5134 current directory.  Consequently, we can fix the above example by changing
   5135 the environment creation in the F<Construct> file as follows:
   5136 
   5137   $env = new cons(
   5138 	CC	=> 'gcc',
   5139 	CPPPATH	=> '.',
   5140 	LIBS	=> 'libworld.a',
   5141   );
   5142 
   5143 Due to the definition of the C<CPPPATH> variable, this yields, when we
   5144 re-execute the command:
   5145 
   5146   % cons -R /usr/all/repository hello
   5147   gcc -c -I. -I/usr/all/repository /usr/all/repository/hello.c -o hello.o
   5148   gcc -o hello hello.o /usr/all/repository/libworld.a
   5149 
   5150 The order of the C<-I> flags replicates, for the C preprocessor, the same
   5151 repository-directory search path that Cons uses for its own dependency
   5152 analysis.  If there are multiple repositories and multiple C<CPPPATH>
   5153 directories, Cons will append the repository directories to the beginning of
   5154 each C<CPPPATH> directory, rapidly multiplying the number of C<-I> flags.
   5155 As an extreme example, a F<Construct> file containing:
   5156 
   5157   Repository qw(
   5158 	/u1
   5159 	/u2
   5160   );
   5161 
   5162   $env = new cons(
   5163 	CPPPATH	=> 'a:b:c',
   5164   );
   5165 
   5166 Would yield a compilation command of:
   5167 
   5168   cc -Ia -I/u1/a -I/u2/a -Ib -I/u1/b -I/u2/b -Ic -I/u1/c -I/u2/c -c hello.c -o hello.o
   5169 
   5170 In order to shorten the command lines as much as possible, Cons will
   5171 remove C<-I> flags for any directories, locally or in the repositories,
   5172 which do not actually exist.  (Note that the C<-I> flags are not included
   5173 in the MD5 signature calculation for the target file, so the target will
   5174 not be recompiled if the compilation command changes due to a directory
   5175 coming into existence.)
   5176 
   5177 Because Cons relies on the compiler's C<-I> flags to communicate the
   5178 order in which repository directories must be searched, Cons' handling
   5179 of repository directories is fundamentally incompatible with using
   5180 double-quotes on the C<#include> directives in any C source code that
   5181 you plan to modify:
   5182 
   5183   #include "file.h"	/* DON'T USE DOUBLE-QUOTES LIKE THIS */
   5184 
   5185 This is because most C preprocessors, when faced with such a directive, will
   5186 always first search the directory containing the source file.  This
   5187 undermines the elaborate C<-I> options that Cons constructs to make the
   5188 preprocessor conform to its preferred search path.
   5189 
   5190 Consequently, when using repository trees in Cons, B<always> use
   5191 angle-brackets for included files in any C source (.c or .h) files that
   5192 you plan to modify locally:
   5193 
   5194   #include <file.h>	/* USE ANGLE-BRACKETS INSTEAD */
   5195 
   5196 Code that will not change can still safely use double quotes on #include
   5197 lines.
   5198 
   5199 
   5200 =head2 Repository_List
   5201 
   5202 Cons provides a C<Repository_List> command to return a list of all
   5203 repository directories in their current search order.  This can be used for
   5204 debugging, or to do more complex Perl stuff:
   5205 
   5206   @list = Repository_List;
   5207   print join(' ', @list), "\n";
   5208 
   5209 
   5210 =head2 Repository interaction with other Cons features
   5211 
   5212 Cons' handling of repository trees interacts correctly with other Cons
   5213 features--which is to say, it generally does what you would expect.
   5214 
   5215 Most notably, repository trees interact correctly, and rather powerfully,
   5216 with the 'Link' command.  A repository tree may contain one or more
   5217 subdirectories for version builds established via C<Link> to a source
   5218 subdirectory.  Cons will search for derived files in the appropriate build
   5219 subdirectories under the repository tree.
   5220 
   5221 
   5222 =head1 Default targets
   5223 
   5224 Until now, we've demonstrated invoking Cons with an explicit target
   5225 to build:
   5226 
   5227   % cons hello
   5228 
   5229 Normally, Cons does not build anything unless a target is specified,
   5230 but specifying '.' (the current directory) will build everything:
   5231 
   5232   % cons		# does not build anything
   5233 
   5234   % cons .		# builds everything under the top-level directory
   5235 
   5236 Adding the C<Default> method to any F<Construct> or F<Conscript> file will add
   5237 the specified targets to a list of default targets.  Cons will build
   5238 these defaults if there are no targets specified on the command line.
   5239 So adding the following line to the top-level F<Construct> file will mimic
   5240 Make's typical behavior of building everything by default:
   5241 
   5242   Default '.';
   5243 
   5244 The following would add the F<hello> and F<goodbye> commands (in the
   5245 same directory as the F<Construct> or F<Conscript> file) to the default list:
   5246 
   5247   Default qw(
   5248 	hello
   5249 	goodbye
   5250   );
   5251 
   5252 The C<Default> method may be used more than once to add targets to the
   5253 default list.
   5254 
   5255 =head1 Selective builds
   5256 
   5257 Cons provides two methods for reducing the size of given build. The first is
   5258 by specifying targets on the command line, and the second is a method for
   5259 pruning the build tree. We'll consider target specification first.
   5260 
   5261 
   5262 =head2 Selective targeting
   5263 
   5264 Like make, Cons allows the specification of ``targets'' on the command
   5265 line. Cons targets may be either files or directories. When a directory is
   5266 specified, this is simply a short-hand notation for every derivable
   5267 product--that Cons knows about--in the specified directory and below. For
   5268 example:
   5269 
   5270   % cons build/hello/hello.o
   5271 
   5272 means build F<hello.o> and everything that F<hello.o> might need. This is
   5273 from a previous version of the B<Hello, World!> program in which F<hello.o>
   5274 depended upon F<export/include/world.h>. If that file is not up-to-date
   5275 (because someone modified F<src/world/world.h)>, then it will be rebuilt,
   5276 even though it is in a directory remote from F<build/hello>.
   5277 
   5278 In this example:
   5279 
   5280   % cons build
   5281 
   5282 Everything in the F<build> directory is built, if necessary. Again, this may
   5283 cause more files to be built. In particular, both F<export/include/world.h>
   5284 and F<export/lib/libworld.a> are required by the F<build/hello> directory,
   5285 and so they will be built if they are out-of-date.
   5286 
   5287 If we do, instead:
   5288 
   5289   % cons export
   5290 
   5291 then only the files that should be installed in the export directory will be
   5292 rebuilt, if necessary, and then installed there. Note that C<cons build>
   5293 might build files that C<cons export> doesn't build, and vice-versa.
   5294 
   5295 
   5296 =head2 No ``special'' targets
   5297 
   5298 With Cons, make-style ``special'' targets are not required. The simplest
   5299 analog with Cons is to use special F<export> directories, instead. Let's
   5300 suppose, for example, that you have a whole series of unit tests that are
   5301 associated with your code. The tests live in the source directory near the
   5302 code. Normally, however, you don't want to build these tests. One solution
   5303 is to provide all the build instructions for creating the tests, and then to
   5304 install the tests into a separate part of the tree. If we install the tests
   5305 in a top-level directory called F<tests>, then:
   5306 
   5307   % cons tests
   5308 
   5309 will build all the tests.
   5310 
   5311   % cons export
   5312 
   5313 will build the production version of the system (but not the tests), and:
   5314 
   5315   % cons build
   5316 
   5317 should probably be avoided (since it will compile tests unnecessarily).
   5318 
   5319 If you want to build just a single test, then you could explicitly name the
   5320 test (in either the F<tests> directory or the F<build> directory). You could
   5321 also aggregate the tests into a convenient hierarchy within the tests
   5322 directory. This hierarchy need not necessarily match the source hierarchy,
   5323 in much the same manner that the include hierarchy probably doesn't match
   5324 the source hierarchy (the include hierarchy is unlikely to be more than two
   5325 levels deep, for C programs).
   5326 
   5327 If you want to build absolutely everything in the tree (subject to whatever
   5328 options you select), you can use:
   5329 
   5330   % cons .
   5331 
   5332 This is not particularly efficient, since it will redundantly walk all the
   5333 trees, including the source tree. The source tree, of course, may have
   5334 buildable objects in it--nothing stops you from doing this, even if you
   5335 normally build in a separate build tree.
   5336 
   5337 
   5338 =head1 Build Pruning
   5339 
   5340 In conjunction with target selection, B<build pruning> can be used to reduce
   5341 the scope of the build. In the previous peAcH and baNaNa example, we have
   5342 already seen how script-driven build pruning can be used to make only half
   5343 of the potential build available for any given invocation of C<cons>. Cons
   5344 also provides, as a convenience, a command line convention that allows you
   5345 to specify which F<Conscript> files actually get ``built''--that is,
   5346 incorporated into the build tree. For example:
   5347 
   5348   % cons build +world
   5349 
   5350 The C<+> argument introduces a Perl regular expression. This must, of
   5351 course, be quoted at the shell level if there are any shell meta-characters
   5352 within the expression. The expression is matched against each F<Conscript>
   5353 file which has been mentioned in a C<Build> statement, and only those
   5354 scripts with matching names are actually incorporated into the build
   5355 tree. Multiple such arguments are allowed, in which case a match against any
   5356 of them is sufficient to cause a script to be included.
   5357 
   5358 In the example, above, the F<hello> program will not be built, since Cons
   5359 will have no knowledge of the script F<hello/Conscript>. The F<libworld.a>
   5360 archive will be built, however, if need be.
   5361 
   5362 There are a couple of uses for build pruning via the command line. Perhaps
   5363 the most useful is the ability to make local changes, and then, with
   5364 sufficient knowledge of the consequences of those changes, restrict the size
   5365 of the build tree in order to speed up the rebuild time. A second use for
   5366 build pruning is to actively prevent the recompilation of certain files that
   5367 you know will recompile due to, for example, a modified header file. You may
   5368 know that either the changes to the header file are immaterial, or that the
   5369 changes may be safely ignored for most of the tree, for testing
   5370 purposes.With Cons, the view is that it is pragmatic to admit this type of
   5371 behavior, with the understanding that on the next full build everything that
   5372 needs to be rebuilt will be. There is no equivalent to a ``make touch''
   5373 command, to mark files as permanently up-to-date. So any risk that is
   5374 incurred by build pruning is mitigated. For release quality work, obviously,
   5375 we recommend that you do not use build pruning (it's perfectly OK to use
   5376 during integration, however, for checking compilation, etc. Just be sure to
   5377 do an unconstrained build before committing the integration).
   5378 
   5379 
   5380 =head1 Temporary overrides
   5381 
   5382 Cons provides a very simple mechanism for overriding aspects of a build. The
   5383 essence is that you write an override file containing one or more
   5384 C<Override> commands, and you specify this on the command line, when you run
   5385 C<cons>:
   5386 
   5387   % cons -o over export
   5388 
   5389 will build the F<export> directory, with all derived files subject to the
   5390 overrides present in the F<over> file. If you leave out the C<-o> option,
   5391 then everything necessary to remove all overrides will be rebuilt.
   5392 
   5393 
   5394 =head2 Overriding environment variables
   5395 
   5396 The override file can contain two types of overrides. The first is incoming
   5397 environment variables. These are normally accessible by the F<Construct>
   5398 file from the C<%ENV> hash variable. These can trivially be overridden in
   5399 the override file by setting the appropriate elements of C<%ENV> (these
   5400 could also be overridden in the user's environment, of course).
   5401 
   5402 
   5403 =head2 The Override command
   5404 
   5405 The second type of override is accomplished with the C<Override> command,
   5406 which looks like this:
   5407 
   5408   Override <regexp>, <var1> => <value1>, <var2> => <value2>, ...;
   5409 
   5410 The regular expression I<regexp> is matched against every derived file that
   5411 is a candidate for the build. If the derived file matches, then the
   5412 variable/value pairs are used to override the values in the construction
   5413 environment associated with the derived file.
   5414 
   5415 Let's suppose that we have a construction environment like this:
   5416 
   5417   $CONS = new cons(
   5418 	COPT => '',
   5419 	CDBG => '-g',
   5420 	CFLAGS => '%COPT %CDBG',
   5421   );
   5422 
   5423 Then if we have an override file F<over> containing this command:
   5424 
   5425   Override '\.o$', COPT => '-O', CDBG => '';
   5426 
   5427 then any C<cons> invocation with C<-o over> that creates F<.o> files via
   5428 this environment will cause them to be compiled with C<-O >and no C<-g>. The
   5429 override could, of course, be restricted to a single directory by the
   5430 appropriate selection of a regular expression.
   5431 
   5432 Here's the original version of the Hello, World! program, built with this
   5433 environment. Note that Cons rebuilds the appropriate pieces when the
   5434 override is applied or removed:
   5435 
   5436   % cons hello
   5437   cc -g -c hello.c -o hello.o
   5438   cc -o hello hello.o
   5439   % cons -o over hello
   5440   cc -O -c hello.c -o hello.o
   5441   cc -o hello hello.o
   5442   % cons -o over hello
   5443   cons: "hello" is up-to-date.
   5444   % cons hello
   5445   cc -g -c hello.c -o hello.o
   5446   cc -o hello hello.o
   5447 
   5448 It's important that the C<Override> command only be used for temporary,
   5449 on-the-fly overrides necessary for development because the overrides are not
   5450 platform independent and because they rely too much on intimate knowledge of
   5451 the workings of the scripts. For temporary use, however, they are exactly
   5452 what you want.
   5453 
   5454 Note that it is still useful to provide, say, the ability to create a fully
   5455 optimized version of a system for production use--from the F<Construct> and
   5456 F<Conscript> files. This way you can tailor the optimized system to the
   5457 platform. Where optimizer trade-offs need to be made (particular files may
   5458 not be compiled with full optimization, for example), then these can be
   5459 recorded for posterity (and reproducibility) directly in the scripts.
   5460 
   5461 
   5462 =head1 More on construction environments
   5463 
   5464 As previously mentioned, a B<construction environment> is an object that
   5465 has a set of keyword/value pairs and a set of methods, and which is used
   5466 to tell Cons how target files should be built.  This section describes
   5467 how Cons uses and expands construction environment values to control its
   5468 build behavior.
   5469 
   5470 =head2 Construction variable expansion
   5471 
   5472 Construction variables from a construction environment are expanded
   5473 by preceding the keyword with a C<%> (percent sign):
   5474 
   5475   Construction variables:
   5476 	XYZZY => 'abracadabra',
   5477 
   5478   The string:  "The magic word is:  %XYZZY!"
   5479   expands to:  "The magic word is:  abracadabra!"
   5480 
   5481 A construction variable name may be surrounded by C<{> and C<}> (curly
   5482 braces), which are stripped as part of the expansion.  This can
   5483 sometimes be necessary to separate a variable expansion from trailing
   5484 alphanumeric characters:
   5485 
   5486   Construction variables:
   5487 	OPT    => 'value1',
   5488 	OPTION => 'value2',
   5489 
   5490   The string:  "%OPT %{OPT}ION %OPTION %{OPTION}"
   5491   expands to:  "value1 value1ION value2 value2"
   5492 
   5493 Construction variable expansion is recursive--that is, a string
   5494 containing C<%->expansions after substitution will be re-expanded until
   5495 no further substitutions can be made:
   5496 
   5497   Construction variables:
   5498 	STRING => 'The result is:  %FOO',
   5499 	FOO    => '%BAR',
   5500 	BAR    => 'final value',
   5501 
   5502   The string:  "The string says:  %STRING"
   5503   expands to:  "The string says:  The result is:  final value"
   5504 
   5505 If a construction variable is not defined in an environment, then the
   5506 null string is substituted:
   5507 
   5508   Construction variables:
   5509 	FOO => 'value1',
   5510 	BAR => 'value2',
   5511 
   5512   The string:  "%FOO <%NO_VARIABLE> %BAR"
   5513   expands to:  "value1 <> value2"
   5514 
   5515 A doubled C<%%> will be replaced by a single C<%>:
   5516 
   5517   The string:  "Here is a percent sign:  %%"
   5518   expands to:  "Here is a percent sign: %"
   5519 
   5520 =head2 Default construction variables
   5521 
   5522 When you specify no arguments when creating a new construction
   5523 environment:
   5524 
   5525   $env = new cons();
   5526 
   5527 Cons creates a reference to a new, default construction
   5528 environment. This contains a number of construction variables and some
   5529 methods. At the present writing, the default construction variables on a
   5530 UNIX system are:
   5531 
   5532   CC            => 'cc',
   5533   CFLAGS        => '',
   5534   CCCOM         => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
   5535   CXX           => '%CC',
   5536   CXXFLAGS      => '%CFLAGS',
   5537   CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS -c %< -o %>',
   5538   INCDIRPREFIX  => '-I',
   5539   INCDIRSUFFIX  => '',
   5540   LINK          => '%CXX',
   5541   LINKCOM       => '%LINK %LDFLAGS -o %> %< %_LDIRS %LIBS',
   5542   LINKMODULECOM => '%LD -r -o %> %<',
   5543   LIBDIRPREFIX  => '-L',
   5544   LIBDIRSUFFIX  => '',
   5545   AR		=> 'ar',
   5546   ARFLAGS	=> 'r',
   5547   ARCOM		=> ['%AR %ARFLAGS %> %<', '%RANLIB %>'],
   5548   RANLIB	=> 'ranlib',
   5549   AS		=> 'as',
   5550   ASFLAGS	=> '',
   5551   ASCOM		=> '%AS %ASFLAGS %< -o %>',
   5552   LD		=> 'ld',
   5553   LDFLAGS	=> '',
   5554   PREFLIB	=> 'lib',
   5555   SUFLIB	=> '.a',
   5556   SUFLIBS	=> '.so:.a',
   5557   SUFOBJ	=> '.o',
   5558   SIGNATURE     => [ '*' => 'build' ],
   5559   ENV		=> { 'PATH' => '/bin:/usr/bin' },
   5560 
   5561 
   5562 And on a Win32 system (Windows NT), the default construction variables
   5563 are (unless the default rule style is set using the B<DefaultRules>
   5564 method):
   5565 
   5566   CC		=> 'cl',
   5567   CFLAGS	=> '/nologo',
   5568   CCCOM		=> '%CC %CFLAGS %_IFLAGS /c %< /Fo%>',
   5569   CXXCOM        => '%CXX %CXXFLAGS %_IFLAGS /c %< /Fo%>',
   5570   INCDIRPREFIX  => '/I',
   5571   INCDIRSUFFIX  => '',
   5572   LINK          => 'link',
   5573   LINKCOM       => '%LINK %LDFLAGS /out:%> %< %_LDIRS %LIBS',
   5574   LINKMODULECOM => '%LD /r /o %> %<',
   5575   LIBDIRPREFIX  => '/LIBPATH:',
   5576   LIBDIRSUFFIX  => '',
   5577   AR            => 'lib',
   5578   ARFLAGS       => '/nologo ',
   5579   ARCOM         => "%AR %ARFLAGS /out:%> %<",
   5580   RANLIB        => '',
   5581   LD            => 'link',
   5582   LDFLAGS       => '/nologo ',
   5583   PREFLIB       => '',
   5584   SUFEXE	=> '.exe',
   5585   SUFLIB	=> '.lib',
   5586   SUFLIBS	=> '.dll:.lib',
   5587   SUFOBJ	=> '.obj',
   5588   SIGNATURE     => [ '*' => 'build' ],
   5589 
   5590 These variables are used by the various methods associated with the
   5591 environment. In particular, any method that ultimately invokes an external
   5592 command will substitute these variables into the final command, as
   5593 appropriate. For example, the C<Objects> method takes a number of source
   5594 files and arranges to derive, if necessary, the corresponding object
   5595 files:
   5596 
   5597   Objects $env 'foo.c', 'bar.c';
   5598 
   5599 This will arrange to produce, if necessary, F<foo.o> and F<bar.o>. The
   5600 command invoked is simply C<%CCCOM>, which expands, through substitution,
   5601 to the appropriate external command required to build each object. The
   5602 substitution rules will be discussed in detail in the next section.
   5603 
   5604 The construction variables are also used for other purposes. For example,
   5605 C<CPPPATH> is used to specify a colon-separated path of include
   5606 directories. These are intended to be passed to the C preprocessor and are
   5607 also used by the C-file scanning machinery to determine the dependencies
   5608 involved in a C Compilation.
   5609 
   5610 Variables beginning with underscore are created by various methods,
   5611 and should normally be considered ``internal'' variables. For example,
   5612 when a method is called which calls for the creation of an object from
   5613 a C source, the variable C<_IFLAGS> is created: this corresponds to the
   5614 C<-I> switches required by the C compiler to represent the directories
   5615 specified by C<CPPPATH>.
   5616 
   5617 Note that, for any particular environment, the value of a variable is set
   5618 once, and then never reset (to change a variable, you must create a new
   5619 environment. Methods are provided for copying existing environments for this
   5620 purpose). Some internal variables, such as C<_IFLAGS> are created on demand,
   5621 but once set, they remain fixed for the life of the environment.
   5622 
   5623 The C<CFLAGS>, C<LDFLAGS>, and C<ARFLAGS> variables all supply a place
   5624 for passing options to the compiler, loader, and archiver, respectively.
   5625 
   5626 The C<INCDIRPREFIX> and C<INCDIRSUFFIX> variables specify option
   5627 strings to be appended to the beginning and end, respectively, of each
   5628 include directory so that the compiler knows where to find F<.h> files.
   5629 Similarly, the C<LIBDIRPREFIX> and C<LIBDIRSUFFIX> variables specify the
   5630 option string to be appended to the beginning of and end, respectively,
   5631 of each directory that the linker should search for libraries.
   5632 
   5633 Another variable, C<ENV>, is used to determine the system environment during
   5634 the execution of an external command. By default, the only environment
   5635 variable that is set is C<PATH>, which is the execution path for a UNIX
   5636 command. For the utmost reproducibility, you should really arrange to set
   5637 your own execution path, in your top-level F<Construct> file (or perhaps by
   5638 importing an appropriate construction package with the Perl C<use>
   5639 command). The default variables are intended to get you off the ground.
   5640 
   5641 =head2 Expanding variables in construction commands
   5642 
   5643 Within a construction command, construction variables will be expanded
   5644 according to the rules described above.  In addition to normal variable
   5645 expansion from the construction environment, construction commands also
   5646 expand the following pseudo-variables to insert the specific input and
   5647 output files in the command line that will be executed:
   5648 
   5649 =over 10
   5650 
   5651 =item %>
   5652 
   5653 The target file name.  In a multi-target command, this expands to the
   5654 first target mentioned.)
   5655 
   5656 =item %0
   5657 
   5658 Same as C<%E<gt>>.
   5659 
   5660 =item %1, %2, ..., %9
   5661 
   5662 These refer to the first through ninth input file, respectively.
   5663 
   5664 =item %E<lt>
   5665 
   5666 The full set of input file names. If any of these have been used
   5667 anywhere else in the current command line (via C<%1>, C<%2>, etc.), then
   5668 those will be deleted from the list provided by C<%E<lt>>. Consider the
   5669 following command found in a F<Conscript> file in the F<test> directory:
   5670 
   5671   Command $env 'tgt', qw(foo bar baz), qq(
   5672 	echo %< -i %1 > %>
   5673 	echo %< -i %2 >> %>
   5674 	echo %< -i %3 >> %>
   5675   );
   5676 
   5677 If F<tgt> needed to be updated, then this would result in the execution of
   5678 the following commands, assuming that no remapping has been established for
   5679 the F<test> directory:
   5680 
   5681   echo test/bar test/baz -i test/foo > test/tgt
   5682   echo test/foo test/baz -i test/bar >> test/tgt
   5683   echo test/foo test/bar -i test/baz >> test/tgt
   5684 
   5685 =back
   5686 
   5687 Any of the above pseudo-variables may be followed immediately by one of
   5688 the following suffixes to select a portion of the expanded path name:
   5689 
   5690   :a    the absolute path to the file name
   5691   :b    the directory plus the file name stripped of any suffix
   5692   :d    the directory
   5693   :f    the file name
   5694   :s    the file name suffix
   5695   :F    the file name stripped of any suffix
   5696   :S    the absolute path path to a Linked source file
   5697 
   5698 Continuing with the above example, C<%E<lt>:f> would expand to C<foo bar baz>,
   5699 and C<%E<gt>:d> would expand to C<test>.
   5700 
   5701 There are additional C<%> elements which affect the command line(s):
   5702 
   5703 =over 10
   5704 
   5705 =item %[ %]
   5706 
   5707 It is possible to programmatically rewrite part of the command by
   5708 enclosing part of it between C<%[> and C<%]>.  This will call the
   5709 construction variable named as the first word enclosed in the brackets
   5710 as a Perl code reference; the results of this call will be used to
   5711 replace the contents of the brackets in the command line.  For example,
   5712 given an existing input file named F<tgt.in>:
   5713 
   5714   @keywords = qw(foo bar baz);
   5715   $env = new cons(X_COMMA => sub { join(",", @_) });
   5716   Command $env 'tgt', 'tgt.in', qq(
   5717 	echo '# Keywords: %[X_COMMA @keywords %]' > %>
   5718 	cat %< >> %>
   5719   );
   5720 
   5721 This will execute:
   5722 
   5723   echo '# Keywords: foo,bar,baz' > tgt
   5724   cat tgt.in >> tgt
   5725 
   5726 =item %( %)
   5727 
   5728 Cons includes the text of the command line in the MD5 signature for a
   5729 build, so that targets get rebuilt if you change the command line (to
   5730 add or remove an option, for example).  Command-line text in between
   5731 C<%(> and C<%)>, however, will be ignored for MD5 signature calculation.
   5732 
   5733 Internally, Cons uses C<%(> and C<%)> around include and library
   5734 directory options (C<-I> and C<-L> on UNIX systems, C</I> and
   5735 C</LIBPATH> on Windows NT) to avoid rebuilds just because the directory
   5736 list changes.  Rebuilds occur only if the changed directory list causes
   5737 any included I<files> to change, and a changed include file is detected
   5738 by the MD5 signature calculation on the actual file contents.
   5739 
   5740 =back
   5741 
   5742 =head2 Expanding construction variables in file names
   5743 
   5744 Cons expands construction variables in the source and target file names
   5745 passed to the various construction methods according to the expansion
   5746 rules described above:
   5747 
   5748   $env = new cons(
   5749 	DESTDIR	=>	'programs',
   5750 	SRCDIR	=>	'src',
   5751   );
   5752   Program $env '%DESTDIR/hello', '%SRCDIR/hello.c';
   5753 
   5754 This allows for flexible configuration, through the construction
   5755 environment, of directory names, suffixes, etc.
   5756 
   5757 
   5758 =head1 Build actions
   5759 
   5760 Cons supports several types of B<build actions> that can be performed
   5761 to construct one or more target files.  Usually, a build action is
   5762 a construction command--that is, a command-line string that invokes
   5763 an external command.  Cons can also execute Perl code embedded in a
   5764 command-line string, and even supports an experimental ability to build
   5765 a target file by executing a Perl code reference directly.
   5766 
   5767 A build action is usually specified as the value of a construction
   5768 variable:
   5769 
   5770   $env = new cons(
   5771 	CCCOM         => '%CC %CFLAGS %_IFLAGS -c %< -o %>',
   5772 	LINKCOM       => '[perl] &link_executable("%>", "%<")',
   5773 	ARCOM         => sub { my($env, $target, @sources) = @_;
   5774 				 # code to create an archive
   5775 				}
   5776   );
   5777 
   5778 A build action may be associated directly with one or more target files
   5779 via the C<Command> method; see below.
   5780 
   5781 =head2 Construction commands
   5782 
   5783 A construction command goes through expansion of construction variables
   5784 and C<%-> pseudo-variables, as described above, to create the actual
   5785 command line that Cons will execute to generate the target file or
   5786 files.
   5787 
   5788 After substitution occurs, strings of white space are converted into
   5789 single blanks, and leading and trailing white space is eliminated. It
   5790 is therefore currently not possible to introduce variable length white
   5791 space in strings passed into a command.
   5792 
   5793 If a multi-line command string is provided, the commands are executed
   5794 sequentially. If any of the commands fails, then none of the rest are
   5795 executed, and the target is not marked as updated, i.e. a new signature is
   5796 not stored for the target.
   5797 
   5798 Normally, if all the commands succeed, and return a zero status (or whatever
   5799 platform-specific indication of success is required), then a new signature
   5800 is stored for the target. If a command erroneously reports success even
   5801 after a failure, then Cons will assume that the target file created by that
   5802 command is accurate and up-to-date.
   5803 
   5804 The first word of each command string, after expansion, is assumed to be an
   5805 executable command looked up on the C<PATH> environment variable (which is,
   5806 in turn, specified by the C<ENV> construction variable). If this command is
   5807 found on the path, then the target will depend upon it: the command will
   5808 therefore be automatically built, as necessary. It's possible to write
   5809 multi-part commands to some shells, separated by semi-colons. Only the first
   5810 command word will be depended upon, however, so if you write your command
   5811 strings this way, you must either explicitly set up a dependency (with the
   5812 C<Depends> method), or be sure that the command you are using is a system
   5813 command which is expected to be available. If it isn't available, you will,
   5814 of course, get an error.
   5815 
   5816 Cons normally prints a command before executing it.  This behavior is
   5817 suppressed if the first character of the command is C<@>.  Note that
   5818 you may need to separate the C<@> from the command name or escape it to
   5819 prevent C<@cmd> from looking like an array to Perl quote operators that
   5820 perform interpolation:
   5821 
   5822   # The first command line is incorrect,
   5823   # because "@cp" looks like an array
   5824   # to the Perl qq// function.
   5825   # Use the second form instead.
   5826   Command $env 'foo', 'foo.in', qq(
   5827 	@cp %< tempfile
   5828 	@ cp tempfile %>
   5829   );
   5830 
   5831 If there are shell meta characters anywhere in the expanded command line,
   5832 such as C<E<lt>>, C<E<gt>>, quotes, or semi-colon, then the command
   5833 will actually be executed by invoking a shell. This means that a command
   5834 such as:
   5835 
   5836   cd foo
   5837 
   5838 alone will typically fail, since there is no command C<cd> on the path. But
   5839 the command string:
   5840 
   5841   cd $<:d; tar cf $>:f $<:f
   5842 
   5843 when expanded will still contain the shell meta character semi-colon, and a
   5844 shell will be invoked to interpret the command. Since C<cd> is interpreted
   5845 by this sub-shell, the command will execute as expected.
   5846 
   5847 =head2 Perl expressions
   5848 
   5849 If any command (even one within a multi-line command) begins with
   5850 C<[perl]>, the remainder of that command line will be evaluated by the
   5851 running Perl instead of being forked by the shell.  If an error occurs
   5852 in parsing the Perl code, or if the Perl expression returns 0 or undef,
   5853 the command will be considered to have failed.  For example, here is a
   5854 simple command which creates a file C<foo> directly from Perl:
   5855 
   5856   $env = new cons();
   5857   Command $env 'foo',
   5858     qq([perl] open(FOO,'>foo');print FOO "hi\\n"; close(FOO); 1);
   5859 
   5860 Note that when the command is executed, you are in the same package as
   5861 when the F<Construct> or F<Conscript> file was read, so you can call
   5862 Perl functions you've defined in the same F<Construct> or F<Conscript>
   5863 file in which the C<Command> appears:
   5864 
   5865   $env = new cons();
   5866   sub create_file {
   5867 	my $file = shift;
   5868 	open(FILE, ">$file");
   5869 	print FILE "hi\n";
   5870 	close(FILE);
   5871 	return 1;
   5872   }
   5873   Command $env 'foo', "[perl] &create_file('%>')";
   5874 
   5875 The Perl string will be used to generate the signature for the derived
   5876 file, so if you change the string, the file will be rebuilt.  The contents
   5877 of any subroutines you call, however, are not part of the signature,
   5878 so if you modify a called subroutine such as C<create_file> above,
   5879 the target will I<not> be rebuilt.  Caveat user.
   5880 
   5881 =head2 Perl code references [EXPERIMENTAL]
   5882 
   5883 Cons supports the ability to create a derived file by directly executing
   5884 a Perl code reference.  This feature is considered EXPERIMENTAL and
   5885 subject to change in the future.
   5886 
   5887 A code reference may either be a named subroutine referenced by the
   5888 usual C<\&> syntax:
   5889 
   5890   sub build_output {
   5891 	my($env, $target, @sources) = @_;
   5892 	print "build_output building $target\n";
   5893 	open(OUT, ">$target");
   5894 	foreach $src (@sources) {
   5895 	    if (! open(IN, "<$src")) {
   5896 		print STDERR "cannot open '$src': $!\n";
   5897 		return undef;
   5898 	    }
   5899 	    print OUT, <IN>;
   5900 	}
   5901 	close(OUT);
   5902 	return 1;
   5903   }
   5904   Command $env 'output', \&build_output;
   5905 
   5906 or the code reference may be an anonymous subroutine:
   5907 
   5908   Command $env 'output', sub {
   5909 	my($env, $target, @sources) = @_;
   5910 	print "building $target\n";
   5911 	open(FILE, ">$target");
   5912 	print FILE "hello\n";
   5913 	close(FILE);
   5914 	return 1;
   5915   };
   5916 
   5917 To build the target file, the referenced subroutine is passed, in order:
   5918 the construction environment used to generate the target; the path
   5919 name of the target itself; and the path names of all the source files
   5920 necessary to build the target file.
   5921 
   5922 The code reference is expected to generate the target file, of course,
   5923 but may manipulate the source and target files in any way it chooses.
   5924 The code reference must return a false value (C<undef> or C<0>) if
   5925 the build of the file failed.  Any true value indicates a successful
   5926 build of the target.
   5927 
   5928 Building target files using code references is considered EXPERIMENTAL
   5929 due to the following current limitations:
   5930 
   5931 =over 4
   5932 
   5933 Cons does I<not> print anything to indicate the code reference is being
   5934 called to build the file.  The only way to give the user any indication
   5935 is to have the code reference explicitly print some sort of "building"
   5936 message, as in the above examples.
   5937 
   5938 Cons does not generate any signatures for code references, so if the
   5939 code in the reference changes, the target will I<not> be rebuilt.
   5940 
   5941 Cons has no public method to allow a code reference to extract
   5942 construction variables.  This would be good to allow generalization of
   5943 code references based on the current construction environment, but would
   5944 also complicate the problem of generating meaningful signatures for code
   5945 references.
   5946 
   5947 =back
   5948 
   5949 Support for building targets via code references has been released in
   5950 this version to encourage experimentation and the seeking of possible
   5951 solutions to the above limitations.
   5952 
   5953 
   5954 =head1 Default construction methods
   5955 
   5956 The list of default construction methods includes the following:
   5957 
   5958 
   5959 =head2 The C<new> constructor
   5960 
   5961 The C<new> method is a Perl object constructor. That is, it is not invoked
   5962 via a reference to an existing construction environment B<reference>, but,
   5963 rather statically, using the name of the Perl B<package> where the
   5964 constructor is defined. The method is invoked like this:
   5965 
   5966   $env = new cons(<overrides>);
   5967 
   5968 The environment you get back is blessed into the package C<cons>, which
   5969 means that it will have associated with it the default methods described
   5970 below. Individual construction variables can be overridden by providing
   5971 name/value pairs in an override list. Note that to override any command
   5972 environment variable (i.e. anything under C<ENV>), you will have to override
   5973 all of them. You can get around this difficulty by using the C<copy> method
   5974 on an existing construction environment.
   5975 
   5976 
   5977 =head2 The C<clone> method
   5978 
   5979 The C<clone> method creates a clone of an existing construction environment,
   5980 and can be called as in the following example:
   5981 
   5982   $env2 = $env1->clone(<overrides>);
   5983 
   5984 You can provide overrides in the usual manner to create a different
   5985 environment from the original. If you just want a new name for the same
   5986 environment (which may be helpful when exporting environments to existing
   5987 components), you can just use simple assignment.
   5988 
   5989 
   5990 =head2 The C<copy> method
   5991 
   5992 The C<copy> method extracts the externally defined construction variables
   5993 from an environment and returns them as a list of name/value
   5994 pairs. Overrides can also be provided, in which case, the overridden values
   5995 will be returned, as appropriate. The returned list can be assigned to a
   5996 hash, as shown in the prototype, below, but it can also be manipulated in
   5997 other ways:
   5998 
   5999   %env = $env1->copy(<overrides>);
   6000 
   6001 The value of C<ENV>, which is itself a hash, is also copied to a new hash,
   6002 so this may be changed without fear of affecting the original
   6003 environment. So, for example, if you really want to override just the
   6004 C<PATH> variable in the default environment, you could do the following:
   6005 
   6006   %cons = new cons()->copy();
   6007   $cons{ENV}{PATH} = "<your path here>";
   6008   $cons = new cons(%cons);
   6009 
   6010 This will leave anything else that might be in the default execution
   6011 environment undisturbed.
   6012 
   6013 
   6014 =head2 The C<Install> method
   6015 
   6016 The C<Install> method arranges for the specified files to be installed in
   6017 the specified directory. The installation is optimized: the file is not
   6018 copied if it can be linked. If this is not the desired behavior, you will
   6019 need to use a different method to install the file. It is called as follows:
   6020 
   6021   Install $env <directory>, <names>;
   6022 
   6023 Note that, while the files to be installed may be arbitrarily named,
   6024 only the last component of each name is used for the installed target
   6025 name. So, for example, if you arrange to install F<foo/bar> in F<baz>,
   6026 this will create a F<bar> file in the F<baz> directory (not F<foo/bar>).
   6027 
   6028 
   6029 =head2 The C<InstallAs> method
   6030 
   6031 The C<InstallAs> method arranges for the specified source file(s) to be
   6032 installed as the specified target file(s). Multiple files should be
   6033 specified as a file list. The installation is optimized: the file is not
   6034 copied if it can be linked. If this is not the desired behavior, you will
   6035 need to use a different method to install the file. It is called as follows:
   6036 
   6037 C<InstallAs> works in two ways:
   6038 
   6039 Single file install:
   6040 
   6041   InstallAs $env TgtFile, SrcFile;
   6042 
   6043 Multiple file install:
   6044 
   6045   InstallAs $env ['tgt1', 'tgt2'], ['src1', 'src2'];
   6046 
   6047 Or, even as:
   6048 
   6049   @srcs = qw(src1 src2 src3);
   6050   @tgts = qw(tgt1 tgt2 tgt3);
   6051   InstallAs $env [@tgts], [@srcs];
   6052 
   6053 Both the target and the sources lists should be of the same length.
   6054 
   6055 =head2 The C<Precious> method
   6056 
   6057 The C<Precious> method asks cons not to delete the specified file or
   6058 list of files before building them again.  It is invoked as:
   6059 
   6060   Precious <files>;
   6061 
   6062 This is especially useful for allowing incremental updates to libraries
   6063 or debug information files which are updated rather than rebuilt anew each
   6064 time.  Cons will still delete the files when the C<-r> flag is specified.
   6065 
   6066 =head2 The C<AfterBuild> method
   6067 
   6068 The C<AfterBuild> method evaluates the specified perl string after
   6069 building the given file or files (or finding that they are up to date).
   6070 The eval will happen once per specified file.  C<AfterBuild> is called
   6071 as follows:
   6072 
   6073   AfterBuild $env 'foo.o', qq(print "foo.o is up to date!\n");
   6074 
   6075 The perl string is evaluated in the C<script> package, and has access
   6076 to all variables and subroutines defined in the F<Conscript> file in
   6077 which the C<AfterBuild> method is called.
   6078 
   6079 =head2 The C<Command> method
   6080 
   6081 The C<Command> method is a catchall method which can be used to arrange for
   6082 any build action to be executed to update the target. For this command, a
   6083 target file and list of inputs is provided. In addition, a build action
   6084 is specified as the last argument.  The build action is typically a
   6085 command line or lines, but may also contain Perl code to be executed;
   6086 see the section above on build actions for details.
   6087 
   6088 The C<Command> method is called as follows:
   6089 
   6090   Command $env <target>, <inputs>, <build action>;
   6091 
   6092 The target is made dependent upon the list of input files specified, and the
   6093 inputs must be built successfully or Cons will not attempt to build the
   6094 target.
   6095 
   6096 To specify a command with multiple targets, you can specify a reference to a
   6097 list of targets. In Perl, a list reference can be created by enclosing a
   6098 list in square brackets. Hence the following command:
   6099 
   6100   Command $env ['foo.h', 'foo.c'], 'foo.template', q(
   6101 	gen %1
   6102   );
   6103 
   6104 could be used in a case where the command C<gen> creates two files, both
   6105 F<foo.h> and F<foo.c>.
   6106 
   6107 
   6108 =head2 The C<Objects> method
   6109 
   6110 The C<Objects> method arranges to create the object files that correspond to
   6111 the specified source files. It is invoked as shown below:
   6112 
   6113   @files = Objects $env <source or object files>;
   6114 
   6115 Under Unix, source files ending in F<.s> and F<.c> are currently
   6116 supported, and will be compiled into a name of the same file ending
   6117 in F<.o>. By default, all files are created by invoking the external
   6118 command which results from expanding the C<CCCOM> construction variable,
   6119 with C<%E<lt>> and C<%E<gt>> set to the source and object files,
   6120 respectively. (See the section above on construction variable expansion
   6121 for details).  The variable C<CPPPATH> is also used when scanning source
   6122 files for dependencies. This is a colon separated list of pathnames, and
   6123 is also used to create the construction variable C<_IFLAGS,> which will
   6124 contain the appropriate list of -C<I> options for the compilation. Any
   6125 relative pathnames in C<CPPPATH> is interpreted relative to the
   6126 directory in which the associated construction environment was created
   6127 (absolute and top-relative names may also be used). This variable is
   6128 used by C<CCCOM>. The behavior of this command can be modified by
   6129 changing any of the variables which are interpolated into C<CCCOM>, such
   6130 as C<CC>, C<CFLAGS>, and, indirectly, C<CPPPATH>. It's also possible
   6131 to replace the value of C<CCCOM>, itself. As a convenience, this file
   6132 returns the list of object filenames.
   6133 
   6134 
   6135 =head2 The C<Program> method
   6136 
   6137 The C<Program> method arranges to link the specified program with the
   6138 specified object files. It is invoked in the following manner:
   6139 
   6140   Program $env <program name>, <source or object files>;
   6141 
   6142 The program name will have the value of the C<SUFEXE> construction
   6143 variable appended (by default, C<.exe> on Win32 systems, nothing on Unix
   6144 systems) if the suffix is not already present.
   6145 
   6146 Source files may be specified in place of objects files--the C<Objects>
   6147 method will be invoked to arrange the conversion of all the files into
   6148 object files, and hence all the observations about the C<Objects> method,
   6149 above, apply to this method also.
   6150 
   6151 The actual linking of the program will be handled by an external command
   6152 which results from expanding the C<LINKCOM> construction variable, with
   6153 C<%E<lt>> set to the object files to be linked (in the order presented),
   6154 and C<%E<gt>> set to the target. (See the section above on construction
   6155 variable expansion for details.)  The user may set additional variables
   6156 in the construction environment, including C<LINK>, to define which
   6157 program to use for linking, C<LIBPATH>, a colon-separated list of
   6158 library search paths, for use with library specifications of the form
   6159 I<-llib>, and C<LIBS>, specifying the list of libraries to link against
   6160 (in either I<-llib> form or just as pathnames. Relative pathnames in
   6161 both C<LIBPATH> and C<LIBS> are interpreted relative to the directory
   6162 in which the associated construction environment is created (absolute
   6163 and top-relative names may also be used). Cons automatically sets up
   6164 dependencies on any libraries mentioned in C<LIBS>: those libraries will
   6165 be built before the command is linked.
   6166 
   6167 
   6168 =head2 The C<Library> method
   6169 
   6170 The C<Library> method arranges to create the specified library from the
   6171 specified object files. It is invoked as follows:
   6172 
   6173   Library $env <library name>, <source or object files>;
   6174 
   6175 The library name will have the value of the C<SUFLIB> construction
   6176 variable appended (by default, C<.lib> on Win32 systems, C<.a> on Unix
   6177 systems) if the suffix is not already present.
   6178 
   6179 Source files may be specified in place of objects files--the C<Objects>
   6180 method will be invoked to arrange the conversion of all the files into
   6181 object files, and hence all the observations about the C<Objects> method,
   6182 above, apply to this method also.
   6183 
   6184 The actual creation of the library will be handled by an external
   6185 command which results from expanding the C<ARCOM> construction variable,
   6186 with C<%E<lt>> set to the library members (in the order presented),
   6187 and C<%E<gt>> to the library to be created.  (See the section above
   6188 on construction variable expansion for details.)  The user may set
   6189 variables in the construction environment which will affect the
   6190 operation of the command. These include C<AR>, the archive program
   6191 to use, C<ARFLAGS>, which can be used to modify the flags given to
   6192 the program specified by C<AR>, and C<RANLIB>, the name of a archive
   6193 index generation program, if needed (if the particular need does not
   6194 require the latter functionality, then C<ARCOM> must be redefined to not
   6195 reference C<RANLIB>).
   6196 
   6197 The C<Library> method allows the same library to be specified in multiple
   6198 method invocations. All of the contributing objects from all the invocations
   6199 (which may be from different directories) are combined and generated by a
   6200 single archive command. Note, however, that if you prune a build so that
   6201 only part of a library is specified, then only that part of the library will
   6202 be generated (the rest will disappear!).
   6203 
   6204 
   6205 =head2 The C<Module> method
   6206 
   6207 The C<Module> method is a combination of the C<Program> and C<Command>
   6208 methods. Rather than generating an executable program directly, this command
   6209 allows you to specify your own command to actually generate a module. The
   6210 method is invoked as follows:
   6211 
   6212   Module $env <module name>, <source or object files>, <construction command>;
   6213 
   6214 This command is useful in instances where you wish to create, for example,
   6215 dynamically loaded modules, or statically linked code libraries.
   6216 
   6217 
   6218 =head2 The C<Depends> method
   6219 
   6220 The C<Depends> method allows you to specify additional dependencies for a
   6221 target.  It is invoked as follows:
   6222 
   6223   Depends $env <target>, <dependencies>;
   6224 
   6225 This may be occasionally useful, especially in cases where no scanner exists
   6226 (or is writable) for particular types of files. Normally, dependencies are
   6227 calculated automatically from a combination of the explicit dependencies set
   6228 up by the method invocation or by scanning source files.
   6229 
   6230 A set of identical dependencies for multiple targets may be specified
   6231 using a reference to a list of targets. In Perl, a list reference can
   6232 be created by enclosing a list in square brackets. Hence the following
   6233 command:
   6234 
   6235   Depends $env ['foo', 'bar'], 'input_file_1', 'input_file_2';
   6236 
   6237 specifies that both the F<foo> and F<bar> files depend on the listed
   6238 input files.
   6239 
   6240 
   6241 =head2 The C<RuleSet> method
   6242 
   6243 The C<RuleSet> method returns the construction variables for building
   6244 various components with one of the rule sets supported by Cons.  The
   6245 currently supported rule sets are:
   6246 
   6247 =over 4
   6248 
   6249 =item msvc
   6250 
   6251 Rules for the Microsoft Visual C++ compiler suite.
   6252 
   6253 =item unix
   6254 
   6255 Generic rules for most UNIX-like compiler suites.
   6256 
   6257 =back
   6258 
   6259 On systems with more than one available compiler suite, this allows you
   6260 to easily create side-by-side environments for building software with
   6261 multiple tools:
   6262 
   6263     $msvcenv = new cons(RuleSet("msvc"));
   6264     $cygnusenv = new cons(RuleSet("unix"));
   6265 
   6266 In the future, this could also be extended to other platforms that
   6267 have different default rule sets.
   6268 
   6269 
   6270 =head2 The C<DefaultRules> method
   6271 
   6272 The C<DefaultRules> method sets the default construction variables that
   6273 will be returned by the C<new> method to the specified arguments:
   6274 
   6275   DefaultRules(CC     => 'gcc',
   6276 	       CFLAGS => '',
   6277 	       CCCOM  => '%CC %CFLAGS %_IFLAGS -c %< -o %>');
   6278   $env = new cons();
   6279   # $env now contains *only* the CC, CFLAGS,
   6280   # and CCCOM construction variables
   6281 
   6282 Combined with the C<RuleSet> method, this also provides an easy way
   6283 to set explicitly the default build environment to use some supported
   6284 toolset other than the Cons defaults:
   6285 
   6286     # use a UNIX-like tool suite (like cygwin) on Win32
   6287     DefaultRules(RuleSet('unix'));
   6288     $env = new cons();
   6289 
   6290 Note that the C<DefaultRules> method completely replaces the default
   6291 construction environment with the specified arguments, it does not
   6292 simply override the existing defaults.  To override one or more
   6293 variables in a supported C<RuleSet>, append the variables and values:
   6294 
   6295   DefaultRules(RuleSet('unix'), CFLAGS => '-O3');
   6296   $env1 = new cons();
   6297   $env2 = new cons();
   6298   # both $env1 and $env2 have 'unix' defaults
   6299   # with CFLAGS set to '-O3'
   6300 
   6301 
   6302 =head2 The C<Ignore> method
   6303 
   6304 The C<Ignore> method allows you to ignore explicitly dependencies that
   6305 Cons infers on its own.  It is invoked as follows:
   6306 
   6307   Ignore <patterns>;
   6308 
   6309 This can be used to avoid recompilations due to changes in system header
   6310 files or utilities that are known to not affect the generated targets.
   6311 
   6312 If, for example, a program is built in an NFS-mounted directory on
   6313 multiple systems that have different copies of F<stdio.h>, the differences
   6314 will affect the signatures of all derived targets built from source files
   6315 that C<#include E<lt>stdio.hE<gt>>.  This will cause all those targets to
   6316 be rebuilt when changing systems.  If this is not desirable behavior, then
   6317 the following line will remove the dependencies on the F<stdio.h> file:
   6318 
   6319   Ignore '^/usr/include/stdio\.h$';
   6320 
   6321 Note that the arguments to the C<Ignore> method are regular expressions,
   6322 so special characters must be escaped and you may wish to anchor the
   6323 beginning or end of the expression with C<^> or C<$> characters.
   6324 
   6325 
   6326 =head2 The C<Salt> method
   6327 
   6328 The C<Salt> method adds a constant value to the signature calculation
   6329 for every derived file.  It is invoked as follows:
   6330 
   6331   Salt $string;
   6332 
   6333 Changing the Salt value will force a complete rebuild of every derived
   6334 file.  This can be used to force rebuilds in certain desired
   6335 circumstances.  For example,
   6336 
   6337   Salt `uname -s`;
   6338 
   6339 Would force a complete rebuild of every derived file whenever the
   6340 operating system on which the build is performed (as reported by C<uname
   6341 -s>) changes.
   6342 
   6343 
   6344 =head2 The C<UseCache> method
   6345 
   6346 The C<UseCache> method instructs Cons to maintain a cache of derived
   6347 files, to be shared among separate build trees of the same project.
   6348 
   6349   UseCache("cache/<buildname>") || warn("cache directory not found");
   6350 
   6351 
   6352 =head2 The C<SourcePath> method
   6353 
   6354 The C<SourcePath> mathod returns the real source path name of a file,
   6355 as opposed to the path name within a build directory.  It is invoked
   6356 as follows:
   6357 
   6358   $path = SourcePath <buildpath>;
   6359 
   6360 
   6361 =head2 The C<ConsPath> method
   6362 
   6363 The C<ConsPath> method returns true if the supplied path is a derivable
   6364 file, and returns undef (false) otherwise.
   6365 It is invoked as follows:
   6366 
   6367   $result = ConsPath <path>;
   6368 
   6369 
   6370 =head2 The C<SplitPath> method
   6371 
   6372 The C<SplitPath> method looks up multiple path names in a string separated
   6373 by the default path separator for the operating system (':' on UNIX
   6374 systems, ';' on Windows NT), and returns the fully-qualified names.
   6375 It is invoked as follows:
   6376 
   6377   @paths = SplitPath <pathlist>;
   6378 
   6379 The C<SplitPath> method will convert  names prefixed '#' to the
   6380 appropriate top-level build name (without the '#') and will convert
   6381 relative names to top-level names.
   6382 
   6383 
   6384 =head2 The C<DirPath> method
   6385 
   6386 The C<DirPath> method returns the build path name(s) of a directory or
   6387 list of directories.  It is invoked as follows:
   6388 
   6389   $cwd = DirPath <paths>;
   6390 
   6391 The most common use for the C<DirPath> method is:
   6392 
   6393   $cwd = DirPath '.';
   6394 
   6395 to fetch the path to the current directory of a subsidiary F<Conscript>
   6396 file.
   6397 
   6398 
   6399 =head2 The C<FilePath> method
   6400 
   6401 The C<FilePath> method returns the build path name(s) of a file or
   6402 list of files.  It is invoked as follows:
   6403 
   6404   $file = FilePath <path>;
   6405 
   6406 
   6407 =head2 The C<Help> method
   6408 
   6409 The C<Help> method specifies help text that will be displayed when the
   6410 user invokes C<cons -h>.  This can be used to provide documentation
   6411 of specific targets, values, build options, etc. for the build tree.
   6412 It is invoked as follows:
   6413 
   6414   Help <helptext>;
   6415 
   6416 The C<Help> method may only be called once, and should typically be
   6417 specified in the top-level F<Construct> file.
   6418 
   6419 
   6420 =head1 Extending Cons
   6421 
   6422 
   6423 =head2 Overriding construction variables
   6424 
   6425 There are several ways of extending Cons, which vary in degree of
   6426 difficulty. The simplest method is to define your own construction
   6427 environment, based on the default environment, but modified to reflect your
   6428 particular needs. This will often suffice for C-based applications. You can
   6429 use the C<new> constructor, and the C<clone> and C<copy> methods to create
   6430 hybrid environments. These changes can be entirely transparent to the
   6431 underlying F<Conscript> files.
   6432 
   6433 
   6434 =head2 Adding new methods
   6435 
   6436 For slightly more demanding changes, you may wish to add new methods to the
   6437 C<cons> package. Here's an example of a very simple extension,
   6438 C<InstallScript>, which installs a tcl script in a requested location, but
   6439 edits the script first to reflect a platform-dependent path that needs to be
   6440 installed in the script:
   6441 
   6442   # cons::InstallScript - Create a platform dependent version of a shell
   6443   # script by replacing string ``#!your-path-here'' with platform specific
   6444   # path $BIN_DIR.
   6445 
   6446   sub cons::InstallScript {
   6447 	my ($env, $dst, $src) = @_;
   6448 	Command $env $dst, $src, qq(
   6449 		sed s+your-path-here+$BIN_DIR+ %< > %>
   6450 		chmod oug+x %>
   6451 	);
   6452   }
   6453 
   6454 Notice that this method is defined directly in the C<cons> package (by
   6455 prefixing the name with C<cons::>). A change made in this manner will be
   6456 globally visible to all environments, and could be called as in the
   6457 following example:
   6458 
   6459   InstallScript $env "$BIN/foo", "foo.tcl";
   6460 
   6461 For a small improvement in generality, the C<BINDIR> variable could be
   6462 passed in as an argument or taken from the construction environment--as
   6463 C<%BINDIR>.
   6464 
   6465 
   6466 =head2 Overriding methods
   6467 
   6468 Instead of adding the method to the C<cons> name space, you could define a
   6469 new package which inherits existing methods from the C<cons> package and
   6470 overrides or adds others. This can be done using Perl's inheritance
   6471 mechanisms.
   6472 
   6473 The following example defines a new package C<cons::switch> which
   6474 overrides the standard C<Library> method. The overridden method builds
   6475 linked library modules, rather than library archives. A new
   6476 constructor is provided. Environments created with this constructor
   6477 will have the new library method; others won't.
   6478 
   6479   package cons::switch;
   6480   BEGIN {@ISA = 'cons'}
   6481 
   6482   sub new {
   6483 	shift;
   6484 	bless new cons(@_);
   6485   }
   6486 
   6487   sub Library {
   6488 	my($env) = shift;
   6489 	my($lib) = shift;
   6490 	my(@objs) = Objects $env @_;
   6491 	Command $env $lib, @objs, q(
   6492 		%LD -r %LDFLAGS %< -o %>
   6493 	);
   6494   }
   6495 
   6496 This functionality could be invoked as in the following example:
   6497 
   6498   $env = new cons::switch(@overrides);
   6499   ...
   6500   Library $env 'lib.o', 'foo.c', 'bar.c';
   6501 
   6502 
   6503 =head1 Invoking Cons
   6504 
   6505 The C<cons> command is usually invoked from the root of the build tree. A
   6506 F<Construct> file must exist in that directory. If the C<-f> argument is
   6507 used, then an alternate F<Construct> file may be used (and, possibly, an
   6508 alternate root, since C<cons> will cd to F<Construct> file's containing
   6509 directory).
   6510 
   6511 If C<cons> is invoked from a child of the root of the build tree with
   6512 the C<-t> argument, it will walk up the directory hierarchy looking for a
   6513 F<Construct> file.  (An alternate name may still be specified with C<-f>.)
   6514 The targets supplied on the command line will be modified to be relative
   6515 to the discovered F<Construct> file.  For example, from a directory
   6516 containing a top-level F<Construct> file, the following invocation:
   6517 
   6518   % cd libfoo/subdir
   6519   % cons -t target
   6520 
   6521 is exactly equivalent to:
   6522 
   6523   % cons libfoo/subdir/target
   6524 
   6525 If there are any C<Default> targets specified in the directory hierarchy's
   6526 F<Construct> or F<Conscript> files, only the default targets at or below
   6527 the directory from which C<cons -t> was invoked will be built.
   6528 
   6529 The command is invoked as follows:
   6530 
   6531   cons <arguments> -- <construct-args>
   6532 
   6533 where I<arguments> can be any of the following, in any order:
   6534 
   6535 =over 10
   6536 
   6537 =item I<target>
   6538 
   6539 Build the specified target. If I<target> is a directory, then recursively
   6540 build everything within that directory.
   6541 
   6542 =item I<+pattern>
   6543 
   6544 Limit the F<Conscript> files considered to just those that match I<pattern>,
   6545 which is a Perl regular expression. Multiple C<+> arguments are accepted.
   6546 
   6547 =item I<name>=<val>
   6548 
   6549 Sets I<name> to value I<val> in the C<ARG> hash passed to the top-level
   6550 F<Construct> file.
   6551 
   6552 =item C<-cc>
   6553 
   6554 Show command that would have been executed, when retrieving from cache. No
   6555 indication that the file has been retrieved is given; this is useful for
   6556 generating build logs that can be compared with real build logs.
   6557 
   6558 =item C<-cd>
   6559 
   6560 Disable all caching. Do not retrieve from cache nor flush to cache.
   6561 
   6562 =item C<-cr>
   6563 
   6564 Build dependencies in random order. This is useful when building multiple
   6565 similar trees with caching enabled.
   6566 
   6567 =item C<-cs>
   6568 
   6569 Synchronize existing build targets that are found to be up-to-date with
   6570 cache. This is useful if caching has been disabled with -cc or just recently
   6571 enabled with UseCache.
   6572 
   6573 =item C<-d>
   6574 
   6575 Enable dependency debugging.
   6576 
   6577 =item C<-f> <file>
   6578 
   6579 Use the specified file instead of F<Construct> (but first change to
   6580 containing directory of I<file>).
   6581 
   6582 =item C<-h>
   6583 
   6584 Show a help message local to the current build if one such is defined, and
   6585 exit.
   6586 
   6587 =item C<-k>
   6588 
   6589 Keep going as far as possible after errors.
   6590 
   6591 =item C<-o> <file>
   6592 
   6593 Read override file I<file>.
   6594 
   6595 =item C<-p>
   6596 
   6597 Show construction products in specified trees. No build is attempted.
   6598 
   6599 =item C<-pa>
   6600 
   6601 Show construction products and associated actions. No build is attempted.
   6602 
   6603 =item C<-pw>
   6604 
   6605 Show products and where they are defined. No build is attempted.
   6606 
   6607 =item C<-q>
   6608 
   6609 Make the build quiet.  Multiple C<-q> options may be specified.
   6610 
   6611 A single C<-q> options suppress messages about Installing and Removing
   6612 targets.
   6613 
   6614 Two C<-q> options suppress build command lines and target up-to-date
   6615 messages.
   6616 
   6617 =item C<-r>
   6618 
   6619 Remove construction products associated with <targets>. No build is
   6620 attempted.
   6621 
   6622 =item C<-R> <repos>
   6623 
   6624 Search for files in I<repos>.  Multiple B<-R> I<repos> directories are
   6625 searched in the order specified.
   6626 
   6627 =item C<-S> <pkg>
   6628 
   6629 Use the sig::<pkg> package to calculate.  Supported <pkg> values
   6630 include "md5" for MD5 signature calculation and "md5::debug" for debug
   6631 information about MD5 signature calculation.
   6632 
   6633 If the specified package ends in <::debug>, signature debug information
   6634 will be printed to the file name specified in the C<CONS_SIG_DEBUG>
   6635 environment variable, or to standard output if the environment variable
   6636 is not set.
   6637 
   6638 =item C<-t>
   6639 
   6640 Traverse up the directory hierarchy looking for a F<Construct> file,
   6641 if none exists in the current directory.  Targets will be modified to
   6642 be relative to the F<Construct> file.
   6643 
   6644 Internally, C<cons> will change its working directory to the directory
   6645 which contains the top-level F<Construct> file and report:
   6646 
   6647   cons: Entering directory `top-level-directory'
   6648 
   6649 This message indicates to an invoking editor (such as emacs) or build
   6650 environment that Cons will now report all file names relative to the
   6651 top-level directory.  This message can not be suppressed with the C<-q>
   6652 option.
   6653 
   6654 =item C<-v>
   6655 
   6656 Show C<cons> version and continue processing.
   6657 
   6658 =item C<-V>
   6659 
   6660 Show C<cons> version and exit.
   6661 
   6662 =item C<-wf> <file>
   6663 
   6664 Write all filenames considered into I<file>.
   6665 
   6666 =item C<-x>
   6667 
   6668 Show a help message similar to this one, and exit.
   6669 
   6670 =back
   6671 
   6672 And I<construct-args> can be any arguments that you wish to process in the
   6673 F<Construct> file. Note that there should be a B<--> separating the arguments
   6674 to cons and the arguments that you wish to process in the F<Construct> file.
   6675 
   6676 Processing of I<construct-args> can be done by any standard package like
   6677 B<Getopt> or its variants, or any user defined package. B<cons> will pass in
   6678 the I<construct-args> as B<@ARGV> and will not attempt to interpret anything
   6679 after the B<-->.
   6680 
   6681   % cons -R /usr/local/repository -d os=solaris +driver -- -c test -f DEBUG
   6682 
   6683 would pass the following to cons
   6684 
   6685   -R /usr/local/repository -d os=solaris +driver
   6686 
   6687 and the following, to the top level F<Construct> file as B<@ARGV>
   6688 
   6689   -c test -f DEBUG
   6690 
   6691 Note that C<cons -r .> is equivalent to a full recursive C<make clean>,
   6692 but requires no support in the F<Construct> file or any F<Conscript>
   6693 files. This is most useful if you are compiling files into source
   6694 directories (if you separate the F<build> and F<export> directories,
   6695 then you can just remove the directories).
   6696 
   6697 The options C<-p>, C<-pa>, and C<-pw> are extremely useful for use as an aid
   6698 in reading scripts or debugging them. If you want to know what script
   6699 installs F<export/include/foo.h>, for example, just type:
   6700 
   6701   % cons -pw export/include/foo.h
   6702 
   6703 
   6704 =head1 Using and writing dependency scanners
   6705 
   6706 QuickScan allows simple target-independent scanners to be set up for
   6707 source files. Only one QuickScan scanner may be associated with any given
   6708 source file and environment, although the same scanner may (and should)
   6709 be used for multiple files of a given type.
   6710 
   6711 A QuickScan scanner is only ever invoked once for a given source file,
   6712 and it is only invoked if the file is used by some target in the tree
   6713 (i.e., there is a dependency on the source file).
   6714 
   6715 QuickScan is invoked as follows:
   6716 
   6717   QuickScan CONSENV CODEREF, FILENAME [, PATH]
   6718 
   6719 The subroutine referenced by CODEREF is expected to return a list of
   6720 filenames included directly by FILE. These filenames will, in turn, be
   6721 scanned. The optional PATH argument supplies a lookup path for finding
   6722 FILENAME and/or files returned by the user-supplied subroutine.  The PATH
   6723 may be a reference to an array of lookup-directory names, or a string of
   6724 names separated by the system's separator character (':' on UNIX systems,
   6725 ';' on Windows NT).
   6726 
   6727 The subroutine is called once for each line in the file, with $_ set to the
   6728 current line. If the subroutine needs to look at additional lines, or, for
   6729 that matter, the entire file, then it may read them itself, from the
   6730 filehandle SCAN. It may also terminate the loop, if it knows that no further
   6731 include information is available, by closing the filehandle.
   6732 
   6733 Whether or not a lookup path is provided, QuickScan first tries to lookup
   6734 the file relative to the current directory (for the top-level file
   6735 supplied directly to QuickScan), or from the directory containing the
   6736 file which referenced the file. This is not very general, but seems good
   6737 enough--especially if you have the luxury of writing your own utilities
   6738 and can control the use of the search path in a standard way.
   6739 
   6740 Here's a real example, taken from a F<Construct> file here:
   6741 
   6742   sub cons::SMFgen {
   6743       my($env, @tables) = @_;
   6744       foreach $t (@tables) {
   6745 	  $env->QuickScan(sub { /\b\S*?\.smf\b/g }, "$t.smf",
   6746 			  $env->{SMF_INCLUDE_PATH});
   6747 	  $env->Command(["$t.smdb.cc","$t.smdb.h","$t.snmp.cc",
   6748 			 "$t.ami.cc", "$t.http.cc"], "$t.smf",
   6749 			q(smfgen %( %SMF_INCLUDE_OPT %) %<));
   6750       }
   6751   }
   6752 
   6753 The subroutine above finds all names of the form <name>.smf in the
   6754 file. It will return the names even if they're found within comments,
   6755 but that's OK (the mechanism is forgiving of extra files; they're just
   6756 ignored on the assumption that the missing file will be noticed when
   6757 the program, in this example, smfgen, is actually invoked).
   6758 
   6759 [NOTE that the form C<$env-E<gt>QuickScan ...>  and C<$env-E<gt>Command
   6760 ...> should not be necessary, but, for some reason, is required
   6761 for this particular invocation. This appears to be a bug in Perl or
   6762 a misunderstanding on my part; this invocation style does not always
   6763 appear to be necessary.]
   6764 
   6765 Here is another way to build the same scanner. This one uses an
   6766 explicit code reference, and also (unnecessarily, in this case) reads
   6767 the whole file itself:
   6768 
   6769   sub myscan {
   6770       my(@includes);
   6771       do {
   6772 	  push(@includes, /\b\S*?\.smf\b/g);
   6773       } while <SCAN>;
   6774       @includes
   6775   }
   6776 
   6777 Note that the order of the loop is reversed, with the loop test at the
   6778 end. This is because the first line is already read for you. This scanner
   6779 can be attached to a source file by:
   6780 
   6781   QuickScan $env \&myscan, "$_.smf";
   6782 
   6783 This final example, which scans a different type of input file, takes
   6784 over the file scanning rather than being called for each input line:
   6785 
   6786   $env->QuickScan(
   6787       sub { my(@includes) = ();
   6788 	  do {
   6789 	     push(@includes, $3)
   6790 		 if /^(#include|import)\s+(\")(.+)(\")/ && $3
   6791 	  } while <SCAN>;
   6792 	  @includes
   6793       },
   6794       "$idlFileName",
   6795       "$env->{CPPPATH};$BUILD/ActiveContext/ACSCLientInterfaces"
   6796   );
   6797 
   6798 =head1 SUPPORT AND SUGGESTIONS
   6799 
   6800 Cons is maintained by the user community.  To subscribe, send mail to
   6801 B<cons-discuss-request@gnu.org> with body B<subscribe>.
   6802 
   6803 Please report any suggestions through the B<cons-discuss@gnu.org> mailing
   6804 list.
   6805 
   6806 =head1 BUGS
   6807 
   6808 Sure to be some. Please report any bugs through the B<bug-cons@gnu.org>
   6809 mailing list.
   6810 
   6811 =head1 INFORMATION ABOUT CONS
   6812 
   6813 Information about CONS can be obtained from the official cons web site
   6814 B<http://www.dsmit.com/cons/> or its mirrors listed there.
   6815 
   6816 The cons maintainers can be contacted by email at
   6817 B<cons-maintainers@gnu.org>
   6818 
   6819 =head1 AUTHORS
   6820 
   6821 Originally by Bob Sidebotham. Then significantly enriched by the members
   6822 of the Cons community B<cons-discuss@gnu.org>.
   6823 
   6824 The Cons community would like to thank Ulrich Pfeifer for the original pod
   6825 documentation derived from the F<cons.html> file. Cons documentation is now
   6826 a part of the program itself.
   6827 
   6828 =cut