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

📄 pcons-2.3.1

📁 quakeIII源码这个不用我多说吧
💻 1
📖 第 1 页 / 共 5 页
字号:
# Return caller info about the method being invoked.
# This is everything from the Perl "caller" builtin function,
# including which Construct/Conscript file, line number,
# subroutine name, etc.
sub caller_info
{
    my ($lev) = 1;
    my (@frame);
    do
    {
        @frame = caller ++$lev;
        if (defined($frame[3]) && $frame[3] eq '(eval)')
        {
            @frame = caller --$lev;
            if ($caller_dir_path)
            {
                $frame[1] = File::Spec->catfile($caller_dir_path, $frame[1]);
            }
            return @frame;
        }
    } while ($frame[3]);
    return;
}

# Link a directory to another. This simply means set up the *source*
# for the directory to be the other directory.
sub Link
{
    dir::link(@_);
}

# Add directories to the repository search path for files.
# Strip our current directory from the list so Repository
# (or -R options) can be used from within the repository.
sub Repository
{
    my ($my_dir) = Cwd::cwd();
    my $dir;
    foreach $dir (@_)
    {

        # The following more direct call isn't available in
        # Cwd.pm until some time after 5.003...
        #	my($d) = Cwd::abs_path($dir);
        chdir($dir);
        my ($d) = Cwd::cwd();
        chdir($my_dir);

        #
        next if !$d || !-d $d || $d eq $my_dir;

        # We know we can get away with passing undef to lookupdir
        # as the directory because $dir is an absolute path.
        push (@param::rpath, dir::lookupdir(undef, $dir));
        push @INC, $d;
    }
}

# Return the list of Repository directories specified.
sub Repository_List
{
    map($_->path, @param::rpath);
}

# Specify whether the .consign signature times in repository files are,
# in fact, consistent with the times on the files themselves.
sub Repository_Sig_Times_OK
{
    $param::rep_sig_times_ok = shift;
}

sub SourceSignature
{
    $param::sourcesig = [@_];
}

# Specify whether we should chdir to the containing directories
# of Conscript files.
sub Conscript_chdir
{
    $param::conscript_chdir = shift;
}

# Specify files/targets that must be present and built locally,
# even if they exist already-built in a Repository.
sub Local
{
    my (@files) = map($dir::cwd->lookupfile($_), @_);
    map($_->local(1), @files);
}

# Export variables to any scripts invoked from this one.
sub Export
{
    my (@illegal) = grep($special_var{$_}, @_);
    if (@illegal)
    {
        die qq($0: cannot Export special Perl variables: @illegal\n);
    }
    @{$priv::self->{exports}} = grep(!defined $special_var{$_}, @_);
}

# Import variables from the export list of the caller
# of the current script.
sub Import
{
    my (@illegal) = grep($special_var{$_}, @_);
    if (@illegal)
    {
        die qq($0: cannot Import special Perl variables: @illegal\n);
    }
    my ($parent)  = $priv::self->{parent};
    my ($imports) = $priv::self->{imports};
    @{$priv::self->{exports}} = keys %$imports;
    my ($var);
    foreach $var (grep(!defined $special_var{$_}, @_))
    {
        if (!exists $imports->{$var})
        {
            my ($path) = $parent->{script}->path;
            die qq($0: variable "$var" not exported by file "$path"\n);
        }
        if (!defined $imports->{$var})
        {
            my $path = $parent->{script}->path;
            my $err  =
              "$0: variable \"$var\" exported but not "
              . "defined by file \"$path\"\n";
            die $err;
        }
        ${"script::$var"} = $imports->{$var};
    }
}

# Build an inferior script. That is, arrange to read and execute
# the specified script, passing to it any exported variables from
# the current script.
sub Build
{
    my (@files) = map($dir::cwd->lookupfile($_), @_);
    my (%imports) = map { $_ => ${"script::$_"} } @{$priv::self->{exports}};
    my $file;
    for $file (@files)
    {
        next if $param::include && $file->path !~ /$param::include/o;
        my ($self) = {
                       'script'  => $file,
                       'parent'  => $priv::self,
                       'imports' => \%imports
                       };
        bless $self;    # may want to bless into class of parent in future
        push (@priv::scripts, $self);
    }
}

# Set up regexps dependencies to ignore. Should only be called once.
sub Ignore
{
    die ("Ignore called more than once\n") if $param::ignore;
    $param::ignore = join ("|", map("($_)", @_)) if @_;
}

# Specification of default targets.
sub Default
{
    push (@param::default_targets, map($dir::cwd->lookup($_)->path, @_));
}

# Local Help.  Should only be called once.
sub Help
{
    if ($param::localhelp)
    {
        print "@_\n";
        exit 2;
    }
}

# For windows platforms which use unix tool sets, the msvc defaults may
# not be useful. Also, in the future, other platforms (Mac?) may have the
# same problem.
sub RuleSet
{
    my $style    = shift;
    my @rulesets = sort keys %param::rulesets;
    die "Unknown style for rules: $style.\n"
      . "Supported rules are: ("
      . join (" ", @rulesets) . ")"
      unless eval(join ("||", map("\$style eq '$_'", @rulesets)));
    return @param::base, @{$param::rulesets{$style}};
}

sub DefaultRules
{
    @param::defaults = ();
    push @param::defaults, @_;
}

# Return the build name(s) of a file or file list.
sub FilePath
{
    wantarray 
      ? map($dir::cwd->lookupfile($_)->path, @_)
      : $dir::cwd->lookupfile($_[0])->path;
}

# Return the build name(s) of a directory or directory list.
sub DirPath
{
    wantarray 
      ? map($dir::cwd->lookupdir($_)->path, @_)
      : $dir::cwd->lookupdir($_[0])->path;
}

# Split the search path provided into components. Look each up
# relative to the current directory.
# The usual path separator problems abound; for now we'll use :
sub SplitPath
{
    my ($dirs) = @_;
    if (ref($dirs) ne "ARRAY")
    {
        $dirs = [split (/$main::PATH_SEPARATOR/o, $dirs)];
    }
    map { DirPath($_) } @$dirs;
}

# Return true if the supplied path is available as a source file
# or is buildable (by rules seen to-date in the build).
sub ConsPath
{
    my ($path) = @_;
    my ($file) = $dir::cwd->lookup($path);
    return $file->accessible;
}

# Return the source path of the supplied path.
sub SourcePath
{
    wantarray 
      ? map($dir::cwd->lookupfile($_)->rsrcpath, @_)
      : $dir::cwd->lookupfile($_[0])->rsrcpath;
}

# Search up the tree for the specified cache directory, starting with
# the current directory. Returns undef if not found, 1 otherwise.
# If the directory is found, then caching is enabled. The directory
# must be readable and writable. If the argument "mixtargets" is provided,
# then targets may be mixed in the cache (two targets may share the same
# cache file--not recommended).
sub UseCache($@)
{
    my ($dir, @args) = @_;

    # NOTE: it's important to process arguments here regardless of whether
    # the cache is disabled temporarily, since the mixtargets option affects
    # the salt for derived signatures.
    for (@args)
    {
        if ($_ eq "mixtargets")
        {

            # When mixtargets is enabled, we salt the target signatures.
            # This is done purely to avoid a scenario whereby if
            # mixtargets is turned on or off after doing builds, and
            # if cache synchronization with -cs is used, then
            # cache files may be shared in the cache itself (linked
            # under more than one name in the cache). This is not bad,
            # per se, but simply would mean that a cache cleaning algorithm
            # that looked for a link count of 1 would never find those
            # particular files; they would always appear to be in use.
            $param::salt       = 'M' . $param::salt;
            $param::mixtargets = 1;
        }
        else
        {
            die qq($0: UseCache unrecognized option "$_"\n);
        }
    }
    if ($param::cachedisable)
    {
        warn("Note: caching disabled by -cd flag\n");
        return 1;
    }
    my ($depth) = 15;
    while ($depth-- && !-d $dir)
    {
        $dir = File::Spec->catdir($dir::UPDIR, $dir);
    }
    if (-d $dir)
    {
        $param::cache = $dir;
        return 1;
    }
    return undef;
}

# Salt the signature generator. The salt (a number of string) is added
# into the signature of each derived file. Changing the salt will
# force recompilation of all derived files.
sub Salt($)
{

    # We append the value, so that UseCache and Salt may be used
    # in either order without changing the signature calculation.
    $param::salt .= $_[0];
}

# Mark files (or directories) to not be removed before building.
sub Precious
{
    map($_->{precious} = 1, map($dir::cwd->lookup($_), @_));
}

# These methods are callable from Conscript files, via a cons
# object. Procs beginning with _ are intended for internal use.
package cons;

use vars qw( %envcache );

# This is passed the name of the base environment to instantiate.
# Overrides to the base environment may also be passed in
# as key/value pairs.
sub new
{
    my ($package) = shift;
    my ($env) = {@param::defaults, @_};
    @{$env->{_envcopy}} = %$env;    # Note: we never change PATH
    $env->{_cwd} = $dir::cwd;       # Save directory of environment for
    bless $env, $package;           # any deferred name interpretation.
}

# Clone an environment.
# Note that the working directory will be the initial directory
# of the original environment.
sub clone
{
    my ($env) = shift;
    my $clone = {@{$env->{_envcopy}}, @_};
    @{$clone->{_envcopy}} = %$clone;    # Note: we never change PATH
    $clone->{_cwd} = $env->{_cwd};
    bless $clone, ref $env;
}

# Create a flattened hash representing the environment.
# It also contains a copy of the PATH, so that the path
# may be modified if it is converted back to a hash.
sub copy
{
    my ($env) = shift;
    (@{$env->{_envcopy}}, 'ENV' => {%{$env->{ENV}}}, @_);
}

# Resolve which environment to actually use for a given
# target. This is just used for simple overrides.
sub _resolve
{
    return $_[0] if !$param::overrides;
    my ($env, $tgt) = @_;
    my ($path) = $tgt->path;
    my $re;
    for $re (@param::overrides)
    {
        next if $path !~ /$re/;

        # Found one. Return a combination of the original environment
        # and the override.
        my ($ovr) = $param::overrides{$re};
        return $envcache{$env, $re} if $envcache{$env, $re};
        my ($newenv) = {@{$env->{_envcopy}}, @$ovr};
        @{$newenv->{_envcopy}} = %$env;
        $newenv->{_cwd} = $env->{_cwd};
        return $envcache{$env, $re} = bless $newenv, ref $env;
    }
    return $env;
}

# Substitute construction environment variables into a string.
# Internal function/method.
sub _subst
{
    my ($env, $str) = @_;
    if (!defined $str)
    {
        return undef;
    }
    elsif (ref($str) eq "ARRAY")
    {
        return [map($env->_subst($_), @$str)];
    }
    else
    {

        # % expansion.  %% gets converted to % later, so expand any
        # %keyword construction that doesn't have a % in front of it,
        # modulo multiple %% pairs in between.
        # In Perl 5.005 and later, we could actually do this in one regex
        # using a conditional expression as follows,
        #	while ($str =~ s/($pre)\%(\{)?([_a-zA-Z]\w*)(?(2)\})/"$1".
        #                      $env->{$3}/ge) {}
        # The following two-step approach is backwards-compatible
        # to (at least) Perl5.003.
        my $pre = '^|[^\%](?:\%\%)*';
        while (($str =~ s/($pre)\%([_a-zA-Z]\w*)/$1.($env->{$2}||'')/ge)
               || ($str =~ s/($pre)\%\{([_a-zA-Z]\w*)\}/$1.($env->{$2}||'')/ge))
        {
        }
        return $str;
    }
}

sub AfterBuild
{
    my ($env)           = shift;
    my ($perl_eval_str) = pop (@_);
    my $file;
    for $file (map($dir::cwd->lookup($_), @_))
    {
        $file->{after_build_func} = $perl_eval_str;

    }
}

sub Install
{
    my ($env)    = shift;
    my ($tgtdir) = $dir::cwd->lookupdir($env->_subst(shift));
    my $file;
    for $file (map($dir::cwd->lookupfile($env->_subst($_)), @_))
    {
        my ($tgt) = $tgtdir->lookupfile($file->{entry});
        $tgt->bind(find build::install($env), $file);
    }
}

sub InstallAs
{
    my $env     = shift;
    my $tgt     = shift;
    my $src     = shift;
    my @sources = ();
    my @targets = ();

    if (ref $tgt)
    {
        die "InstallAs: Source is a file and target is a list!\n"

⌨️ 快捷键说明

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