⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cons

📁 quakeIII源码这个不用我多说吧
💻
📖 第 1 页 / 共 5 页
字号:

# Every builder must now have at least an associated environment,
# so we can find its sigarray and calculate the proper signature.
sub find {
    my($class, $env) = @_;
    $builder{$env} || do {
	my $self = { env => $env };
	$builder{$env} = bless $self, $class;
    }
}

# Null signature for dynamic includes.
sub includes { () }

# Null signature for build script.
sub scriptsig { () }

# Not compatible with any other builder, by default.
sub compatible { 0 }


# Builder module for the Install command.
package build::install;

use vars qw( @ISA );

BEGIN { @ISA = qw(build) }

# Caching not supported for Install: generally install is trivial anyway,
# and we don't want to clutter the cache.
sub cachin { undef }
sub cachout { }

# Do the installation.
sub action {
    my($self, $tgt) = @_;
    my($src) = $tgt->{sources}[0];
    main::showcom("Install ${\$src->rpath} as ${\$tgt->path}")
	if ($param::install && $param::quiet < 1);
    return unless $param::build;
    futil::install($src->rpath, $tgt);
    return 1;
}


# Builder module for generic UNIX commands.
package build::command;

use vars qw( @ISA %com );

BEGIN { @ISA = qw(build) }

sub find {
    my($class, $env, $cmd, $package) = @_;
    my($act) = action::new($env, $cmd);
    $package ||= '';
    $com{$env,$act,$package} || do {
	my $self = { env => $env, act => $act, 'package' => $package };
	$com{$env,$act,$package} = bless $self, $class;
    }
}

# Default cache in function.
sub cachin {
    my($self, $tgt, $sig) = @_;
    if (cache::in($tgt, $sig)) {
	if ($param::cachecom) {
	    $self->{act}->show($self->{env}, $tgt);
	} else {
	    printf("Retrieved %s from cache\n", $tgt->path)
		if ($param::quiet < 1);
	}
	return 1;
    }
    return undef;
}

# Default cache out function.
sub cachout {
    my($self, $tgt, $sig) = @_;
    cache::out($tgt, $sig);
}

# Build the target using the previously specified commands.
sub action {
    my($self, $tgt) = @_;
    $self->{act}->execute($self->{env}, $tgt, $self->{'package'});
}

# Return script signature.
sub scriptsig {
    $_[0]->{act}->scriptsig
}


# Create a linked module.
package build::command::link;

use vars qw( @ISA );

BEGIN { @ISA = qw(build::command) }

# Find an appropriate linker.
sub find {
    my($class, $env, $command) = @_;
    if (!exists $env->{_LDIRS}) {
	my($ldirs) = '';
	my($wd) = $env->{_cwd};
	my($pdirs) = $env->{LIBPATH};
	if (! defined $pdirs) {
	    $pdirs = [ ];
	} elsif (ref($pdirs) ne 'ARRAY') {
	    $pdirs = [ split(/$main::PATH_SEPARATOR/o, $pdirs) ];
	}
	my($dir, $dpath);
	for $dir (map($wd->lookupdir($env->_subst($_)), @$pdirs)) {
	    $dpath = $dir->path;
	    # Add the (presumably local) directory to the -L flags
	    # if we're not using repositories, the directory exists,
	    # or it's Linked to a source directory (that is, it *will*
	    # exist by the time the link occurs).
	    $ldirs .= " ".$env->{LIBDIRPREFIX}.$dpath.$env->{LIBDIRSUFFIX}
			if ! @param::rpath || -d $dpath || $dir->is_linked;
	    next if File::Spec->file_name_is_absolute($dpath);
	    if (@param::rpath) {
		my $d;
		if ($dpath eq $dir::CURDIR) {
		    foreach $d (map($_->path, @param::rpath)) {
			$ldirs .= " " . $env->{LIBDIRPREFIX} .
				  $d . $env->{LIBDIRSUFFIX};
		    }
		} else {
		    my($rpath);
		    foreach $d (map($_->path, @param::rpath)) {
			$rpath = File::Spec->catfile($d, $dpath);
			$ldirs .= " ". $env->{LIBDIRPREFIX} .
				  $rpath . $env->{LIBDIRSUFFIX} if -d $rpath;
		    }
		}
	    }
	}
	$env->{_LDIRS} = "%($ldirs%)";
    }

    # Introduce a new magic _LIBS symbol which allows to use the
    # Unix-style -lNAME syntax for Win32 only. -lNAME will be replaced
    # with %{PREFLIB}NAME%{SUFLIB}. <schwarze@isa.de> 1998-06-18

    if ($main::_WIN32 && !exists $env->{_LIBS}) {
	my $libs;
	my $name;
	for $name (split(' ', $env->_subst($env->{LIBS} || ''))) {
	    if ($name =~ /^-l(.*)/) {
		$name = "$env->{PREFLIB}$1$env->{SUFLIB}";
	    }
	    $libs .= ' ' . $name;
	}
	$env->{_LIBS} = $libs ? "%($libs%)" : '';
    }
    bless find build::command($env, $command);
}

# Called from file::build. Make sure any libraries needed by the
# environment are built, and return the collected signatures
# of the libraries in the path.
sub includes {
    return $_[0]->{'bsig'} if exists $_[0]->{'bsig'};
    my($self, $tgt) = @_;
    my($env) = $self->{env};
    my($ewd) = $env->{_cwd};
    my $ldirs = $env->{LIBPATH};
    if (! defined $ldirs) {
	$ldirs = [ ];
    } elsif (ref($ldirs) ne 'ARRAY') {
	$ldirs = [ split(/$main::PATH_SEPARATOR/o, $ldirs) ];
    }
    my @lpath = map($ewd->lookupdir($_), @$ldirs);
    my(@sigs);
    my(@names);

    # Pass %LIBS symbol through %-substituition
    # <schwarze@isa.de> 1998-06-18
    @names = split(' ', $env->_subst($env->{LIBS} || ''));
    my $name;
    for $name (@names) {
	my ($lpath, @allnames);
	if ($name =~ /^-l(.*)/) {
	    # -l style names are looked up on LIBPATH, using all
	    # possible lib suffixes in the same search order the
	    # linker uses (according to SUFLIBS).
	    # Recognize new PREFLIB symbol, which should be 'lib' on
	    # Unix, and empty on Win32. TODO: What about shared
	    # library suffixes?  <schwarze@isa.de> 1998-05-13
	   @allnames = map("$env->{PREFLIB}$1$_",
			   split(/:/, $env->{SUFLIBS}));
	    $lpath = \@lpath;
	} else {
	    @allnames = ($name);
	    # On Win32, all library names are looked up in LIBPATH
	    # <schwarze@isa.de> 1998-05-13
	    if ($main::_WIN32) {
		$lpath = [$dir::top, @lpath];
	    }
	    else {
		$lpath = [$dir::top];
	    }
	}
	my $dir;
	DIR: for $dir (@$lpath) {
	    my $n;
	    for $n (@allnames) {
		my($lib) = $dir->lookup_accessible($n);
		if ($lib) {
		    last DIR if $lib->ignore;
		    if ((build $lib) eq 'errors') {
			$tgt->{status} = 'errors';
			return undef;
		    }
		    push(@sigs, 'sig'->signature($lib));
		    last DIR;
		}
	    }
	}
    }
    $self->{'bsig'} = 'sig'->collect(@sigs);
}

# Always compatible with other such builders, so the user
# can define a single program or module from multiple places.
sub compatible {
    my($self, $other) = @_;
    ref($other) eq "build::command::link";
}

# Link a program.
package build::command::linkedmodule;

use vars qw( @ISA );

BEGIN { @ISA = qw(build::command) }

# Always compatible with other such builders, so the user
# can define a single linked module from multiple places.
sub compatible {
    my($self, $other) = @_;
    ref($other) eq "build::command::linkedmodule";
}

# Builder for a C module
package build::command::cc;

use vars qw( @ISA );

BEGIN { @ISA = qw(build::command) }

sub find {
    $_[1]->{_cc} || do {
	my($class, $env) = @_;
	my($cpppath) = $env->_subst($env->{CPPPATH});
	my($cscanner) = find scan::cpp($env->{_cwd}, $cpppath);
	$env->{_IFLAGS} = "%(" . $cscanner->iflags($env) . "%)";
	my($self) = find build::command($env, $env->{CCCOM});
	$self->{scanner} = $cscanner;
	bless $env->{_cc} = $self;
    }
}

# Invoke the associated	 C scanner to get signature of included files.
sub includes {
    my($self, $tgt) = @_;
    $self->{scanner}->includes($tgt, $tgt->{sources}[0]);
}

# Builder for a C++ module
package build::command::cxx;

use vars qw( @ISA );

BEGIN { @ISA = qw(build::command) }

sub find {
    $_[1]->{_cxx} || do {
	my($class, $env) = @_;
	my($cpppath) = $env->_subst($env->{CPPPATH});
	my($cscanner) = find scan::cpp($env->{_cwd}, $cpppath);
	$env->{_IFLAGS} = "%(" . $cscanner->iflags($env) . "%)";
	my($self) = find build::command($env, $env->{CXXCOM});
	$self->{scanner} = $cscanner;
	bless $env->{_cxx} = $self;
    }
}

# Invoke the associated	 C scanner to get signature of included files.
sub includes {
    my($self, $tgt) = @_;
    $self->{scanner}->includes($tgt, $tgt->{sources}[0]);
}

# Builder for a user command (cons::Command).  We assume that a user
# command might be built and implement the appropriate dependencies on
# the command itself (actually, just on the first word of the command
# line).
package build::command::user;

use vars qw( @ISA );

BEGIN { @ISA = qw(build::command) }

sub includes {
    my($self, $tgt) = @_;
    my($sig) = '';

    # Check for any quick scanners attached to source files.
    my $dep;
    for $dep (@{$tgt->{dep}}, @{$tgt->{sources}}) {
	my($scanner) = $dep->{'srcscan',$self->{env}};
	if ($scanner) {
	    $sig .= $scanner->includes($tgt, $dep);
	}
    }

    # XXX Optimize this to not use ignored paths.
    if (! exists $self->{_comsig}) {
	my($env) = $self->{env};
	$self->{_comsig} = '';
	my($com, $dir);
      com:
	for $com ($self->{act}->commands) {
	    my($pdirs) = $env->{ENV}->{PATH};
	    if (! defined $pdirs) {
		$pdirs = [ ];
	    } elsif (ref($pdirs) ne 'ARRAY') {
		$pdirs = [ split(/$main::PATH_SEPARATOR/o, $pdirs) ];
	    }
	    for $dir (map($dir::top->lookupdir($_), @$pdirs)) {
		my($prog) = $dir->lookup_accessible($com);
		if ($prog) { # XXX Not checking execute permission.
		    if ((build $prog) eq 'errors') {
			$tgt->{status} = 'errors';
			return $sig;
		    }
		    next com if $prog->ignore;
		    $self->{_comsig} .= 'sig'->signature($prog);
		    next com;
		}
	    }
	}
    }

    return $self->{_comsig} . $sig
}


# Builder for a library module (archive).
# We assume that a user command might be built and implement the
# appropriate dependencies on the command itself.
package build::command::library;

use vars qw( @ISA );

BEGIN { @ISA = qw(build::command) }

sub find {
    my($class, $env) = @_;
    bless find build::command($env, $env->{ARCOM})
}

# Always compatible with other library builders, so the user
# can define a single library from multiple places.
sub compatible {
    my($self, $other) = @_;
    ref($other) eq "build::command::library";
}

# A multi-target builder.
# This allows multiple targets to be associated with a single build
# script, without forcing all the code to be aware of multiple targets.
package build::multiple;

sub new {
    my($class, $builder, $tgts) = @_;
    bless { 'builder' => $builder, 'env' => $builder->{env}, 'tgts' => $tgts };
}

sub scriptsig {
    my($self, $tgt) = @_;
    $self->{builder}->scriptsig($tgt);
}

sub includes {
    my($self, $tgt) = @_;
    $self->{builder}->includes($tgt);
}

sub compatible {
    my($self, $tgt) = @_;
    $self->{builder}->compatible($tgt);
}

sub cachin {
    my($self, $tgt, $sig) = @_;
    $self->{builder}->cachin($tgt, $sig);
}

sub cachout {
    my($self, $tgt, $sig) = @_;
    $self->{builder}->cachout($tgt, $sig);
}

sub action {
    my($self, $invoked_tgt) = @_;
    return $self->{built} if exists $self->{built};

    # Make sure all targets in the group are unlinked before building any.
    my($tgts) = $self->{tgts};
    my $tgt;
    for $tgt (@$tgts) {
	futil::mkdir($tgt->{dir});
	unlink($tgt->path) if ! $tgt->precious;
    }

    # Now do the action to build all the targets. For consistency
    # we always call the action on the first target, just so that
    # $> is deterministic.
    $self->{built} = $self->{builder}->action($tgts->[0]);

    # Now "build" all the other targets (except for the one
    # we were called with). This guarantees that the signature
    # of each target is updated appropriately. We force the
    # targets to be built even if they have been previously
    # considered and found to be OK; the only effect this

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -