uid issue
This commit is contained in:
BIN
devtools/bin.zip
Normal file
BIN
devtools/bin.zip
Normal file
Binary file not shown.
BIN
devtools/bin/FileSystem_Stdio.dll
Normal file
BIN
devtools/bin/FileSystem_Stdio.dll
Normal file
Binary file not shown.
22
devtools/bin/buildshaderlist.pl
Normal file
22
devtools/bin/buildshaderlist.pl
Normal file
@ -0,0 +1,22 @@
|
||||
use File::DosGlob;
|
||||
@ARGV = map {
|
||||
my @g = File::DosGlob::glob($_) if /[*?]/;
|
||||
@g ? @g : $_;
|
||||
} @ARGV;
|
||||
|
||||
open FILE, ">__tmpshaderlist.txt";
|
||||
|
||||
foreach $arg (@ARGV)
|
||||
{
|
||||
if( $arg =~ m/\.fxc$/i || $arg =~ m/\.vsh$/i || $arg =~ m/\.psh$/i )
|
||||
{
|
||||
print $arg . "\n";
|
||||
print FILE $arg . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
close FILE;
|
||||
|
||||
system "buildshaders.bat __tmpshaderlist";
|
||||
|
||||
unlink "__tmpshaderlist.txt";
|
116
devtools/bin/checkshaderchecksums.pl
Normal file
116
devtools/bin/checkshaderchecksums.pl
Normal file
@ -0,0 +1,116 @@
|
||||
use String::CRC32;
|
||||
BEGIN {use File::Basename; push @INC, dirname($0); }
|
||||
require "valve_perl_helpers.pl";
|
||||
|
||||
sub GetShaderType
|
||||
{
|
||||
my $shadername = shift;
|
||||
my $shadertype;
|
||||
if( $shadername =~ m/\.vsh/i )
|
||||
{
|
||||
$shadertype = "vsh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.psh/i )
|
||||
{
|
||||
$shadertype = "psh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.fxc/i )
|
||||
{
|
||||
$shadertype = "fxc";
|
||||
}
|
||||
else
|
||||
{
|
||||
die;
|
||||
}
|
||||
return $shadertype;
|
||||
}
|
||||
|
||||
sub GetShaderSrc
|
||||
{
|
||||
my $shadername = shift;
|
||||
if ( $shadername =~ m/^(.*)-----/i )
|
||||
{
|
||||
return $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $shadername;
|
||||
}
|
||||
}
|
||||
|
||||
sub GetShaderType
|
||||
{
|
||||
my $shadername = shift;
|
||||
my $shadertype;
|
||||
if( $shadername =~ m/\.vsh/i )
|
||||
{
|
||||
$shadertype = "vsh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.psh/i )
|
||||
{
|
||||
$shadertype = "psh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.fxc/i )
|
||||
{
|
||||
$shadertype = "fxc";
|
||||
}
|
||||
else
|
||||
{
|
||||
die;
|
||||
}
|
||||
return $shadertype;
|
||||
}
|
||||
|
||||
sub GetShaderBase
|
||||
{
|
||||
my $shadername = shift;
|
||||
if ( $shadername =~ m/-----(.*)$/i )
|
||||
{
|
||||
return $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $shadertype = &GetShaderType( $shadername );
|
||||
$shadername =~ s/\.$shadertype//i;
|
||||
return $shadername;
|
||||
}
|
||||
}
|
||||
|
||||
$g_x360 = 0;
|
||||
$g_vcsext = ".vcs";
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
$inputbase = shift;
|
||||
|
||||
if( $inputbase =~ m/-x360/ )
|
||||
{
|
||||
$g_x360 = 1;
|
||||
$g_vcsext = ".360.vcs";
|
||||
}
|
||||
else
|
||||
{
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# rip the txt off the end if it's there.
|
||||
$inputbase =~ s/\.txt//i;
|
||||
|
||||
my @srcfiles = &LoadShaderListFile( $inputbase );
|
||||
|
||||
foreach $srcfile ( @srcfiles )
|
||||
{
|
||||
my $shadertype = &GetShaderType( $srcfile );
|
||||
my $shaderbase = &GetShaderBase( $srcfile );
|
||||
my $shadersrc = &GetShaderSrc( $srcfile );
|
||||
my $vcsFileName = "..\\..\\..\\game\\platform\\shaders\\$shadertype\\$shaderbase" . $g_vcsext;
|
||||
# print "shadersrc: $shadersrc vcsFileName: $vcsFileName\n";
|
||||
|
||||
if( $g_x360 && ( $shaderbase =~ m/_ps20$/i ) )
|
||||
{
|
||||
next; # skip _ps20 files for 360
|
||||
}
|
||||
|
||||
&CheckCRCAgainstTarget( $shadersrc, $vcsFileName, 1 );
|
||||
}
|
92
devtools/bin/copyshaderincfiles.pl
Normal file
92
devtools/bin/copyshaderincfiles.pl
Normal file
@ -0,0 +1,92 @@
|
||||
BEGIN {use File::Basename; push @INC, dirname($0); }
|
||||
require "valve_perl_helpers.pl";
|
||||
use Cwd;
|
||||
use String::CRC32;
|
||||
|
||||
my $txtfilename = shift;
|
||||
my $arg = shift;
|
||||
|
||||
my $is360 = 0;
|
||||
my $platformextension = "";
|
||||
if( $arg =~ m/-x360/i )
|
||||
{
|
||||
$is360 = 1;
|
||||
$platformextension = ".360";
|
||||
}
|
||||
|
||||
# Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist.
|
||||
my $changelistnumber = `valve_p4_create_changelist.cmd ..\\..\\..\\game\\platform\\shaders \"Shader Auto Checkout VCS\"`;
|
||||
# Get rid of the newline
|
||||
$changelistnumber =~ s/\n//g;
|
||||
|
||||
my $changelistarg = "";
|
||||
if( $changelistnumber != 0 )
|
||||
{
|
||||
$changelistarg = "-c $changelistnumber"
|
||||
}
|
||||
|
||||
open TXTFILE, "<$txtfilename";
|
||||
|
||||
my $src;
|
||||
my $dst;
|
||||
while( $src = <TXTFILE> )
|
||||
{
|
||||
# get rid of comments
|
||||
$src =~ s,//.*,,g;
|
||||
|
||||
# skip blank lines
|
||||
if( $src =~ m/^\s*$/ )
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# Get rid of newlines.
|
||||
$src =~ s/\n//g;
|
||||
|
||||
# Save off the shader source filename.
|
||||
my $dst = $src;
|
||||
|
||||
$dst =~ s/_tmp//gi;
|
||||
|
||||
# Does the dst exist?
|
||||
my $dstexists = -e $dst;
|
||||
my $srcexists = -e $src;
|
||||
# What are the time stamps for the src and dst?
|
||||
my $srcmodtime = ( stat $src )[9];
|
||||
my $dstmodtime = ( stat $dst )[9];
|
||||
|
||||
if( $dstexists && !$srcexists )
|
||||
{
|
||||
printf STDERR "$src doesn't exist, deleting $dst\n";
|
||||
unlink $dst;
|
||||
}
|
||||
|
||||
# Open for edit or add if different than what is in perforce already.
|
||||
if( !$dstexists || ( $srcmodtime != $dstmodtime ) )
|
||||
{
|
||||
# Make the target writable if it exists
|
||||
if( $dstexists )
|
||||
{
|
||||
MakeFileWritable( $dst );
|
||||
}
|
||||
|
||||
my $dir = $dst;
|
||||
$dir =~ s,([^/\\]*$),,; # rip the filename off the end
|
||||
my $filename = $1;
|
||||
|
||||
# create the target directory if it doesn't exist
|
||||
if( !$dstexists )
|
||||
{
|
||||
&MakeDirHier( $dir, 0777 );
|
||||
}
|
||||
|
||||
# copy the file to its targets. . . we want to see STDERR here if there is an error.
|
||||
my $cmd = "copy $src $dst > nul";
|
||||
# print STDERR "$cmd\n";
|
||||
system $cmd;
|
||||
|
||||
MakeFileReadOnly( $dst );
|
||||
}
|
||||
}
|
||||
|
||||
close TXTFILE;
|
179
devtools/bin/copyshaders.pl
Normal file
179
devtools/bin/copyshaders.pl
Normal file
@ -0,0 +1,179 @@
|
||||
BEGIN {use File::Basename; push @INC, dirname($0); }
|
||||
require "valve_perl_helpers.pl";
|
||||
use Cwd;
|
||||
use String::CRC32;
|
||||
|
||||
sub ReadInputFileWithIncludes
|
||||
{
|
||||
local( $filename ) = shift;
|
||||
|
||||
local( *INPUT );
|
||||
local( $output );
|
||||
|
||||
open INPUT, "<$filename" || die;
|
||||
|
||||
local( $line );
|
||||
local( $linenum ) = 1;
|
||||
while( $line = <INPUT> )
|
||||
{
|
||||
if( $line =~ m/\#include\s+\"(.*)\"/i )
|
||||
{
|
||||
$output.= ReadInputFileWithIncludes( $1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$output .= $line;
|
||||
}
|
||||
}
|
||||
|
||||
close INPUT;
|
||||
return $output;
|
||||
}
|
||||
|
||||
sub PatchCRC
|
||||
{
|
||||
my $filename = shift;
|
||||
my $crc = shift;
|
||||
# print STDERR "*** PatchCRC( $filename, $crc )\n";
|
||||
local( *FP );
|
||||
open FP, "+<$filename" || die;
|
||||
binmode( FP );
|
||||
seek FP, 6 * 4, 0;
|
||||
my $uInt = "I";
|
||||
if ( ( $filename =~ m/\.ps3\./ ) || ( $filename =~ m/\.360\./ ) )
|
||||
{
|
||||
# print STDERR "*** PatchCRC found ps3 or 360\n";
|
||||
$uInt = "N";
|
||||
}
|
||||
print FP pack $uInt, $crc;
|
||||
close FP;
|
||||
}
|
||||
|
||||
my $txtfilename = shift;
|
||||
my $arg = shift;
|
||||
|
||||
my $is360 = 0;
|
||||
my $isPS3 = 0;
|
||||
my $platformextension = "";
|
||||
if( $arg =~ m/-x360/i )
|
||||
{
|
||||
$is360 = 1;
|
||||
$platformextension = ".360";
|
||||
}
|
||||
elsif( $arg =~ m/-ps3/i )
|
||||
{
|
||||
$isPS3 = 1;
|
||||
$platformextension = ".ps3";
|
||||
}
|
||||
|
||||
# Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist.
|
||||
my $changelistnumber = `valve_p4_create_changelist.cmd ..\\..\\..\\game\\platform\\shaders \"Shader Auto Checkout VCS\"`;
|
||||
# Get rid of the newline
|
||||
$changelistnumber =~ s/\n//g;
|
||||
|
||||
my $changelistarg = "";
|
||||
if( $changelistnumber != 0 )
|
||||
{
|
||||
$changelistarg = "-c $changelistnumber"
|
||||
}
|
||||
|
||||
open TXTFILE, "<$txtfilename";
|
||||
|
||||
my $src;
|
||||
my $dst;
|
||||
while( $src = <TXTFILE> )
|
||||
{
|
||||
# get rid of comments
|
||||
$src =~ s,//.*,,g;
|
||||
|
||||
# skip blank lines
|
||||
if( $src =~ m/^\s*$/ )
|
||||
{
|
||||
next;
|
||||
}
|
||||
|
||||
# Get rid of newlines.
|
||||
$src =~ s/\n//g;
|
||||
|
||||
# Save off the shader source filename.
|
||||
my $shadersrcfilename = $src;
|
||||
$shadersrcfilename =~ s/-----.*$//;
|
||||
# use only target basename.
|
||||
$src =~ s/^.*-----//;
|
||||
|
||||
# where the binary vcs file is
|
||||
my $spath = "";
|
||||
|
||||
if ( $shadersrcfilename =~ m@\.fxc@i )
|
||||
{
|
||||
$spath = "shaders\\fxc\\";
|
||||
}
|
||||
if ( $shadersrcfilename =~ m@\.vsh@i )
|
||||
{
|
||||
$spath = "shaders\\vsh\\";
|
||||
}
|
||||
if ( $shadersrcfilename =~ m@\.psh@i )
|
||||
{
|
||||
$spath = "shaders\\psh\\";
|
||||
}
|
||||
|
||||
# make the source have path and extension
|
||||
$src = $spath . $src . $platformextension . ".vcs";
|
||||
|
||||
# build the dest filename.
|
||||
$dst = $src;
|
||||
|
||||
$dst =~ s/shaders\\/..\\..\\..\\game\\platform\\shaders\\/i;
|
||||
|
||||
# Does the dst exist?
|
||||
my $dstexists = -e $dst;
|
||||
my $srcexists = -e $src;
|
||||
# What are the time stamps for the src and dst?
|
||||
my $srcmodtime = ( stat $src )[9];
|
||||
my $dstmodtime = ( stat $dst )[9];
|
||||
|
||||
# Write $dst to a file so that we can do perforce stuff to it later.
|
||||
local( *VCSLIST );
|
||||
open VCSLIST, ">>vcslist.txt" || die;
|
||||
print VCSLIST $dst . "\n";
|
||||
close VCSLIST;
|
||||
|
||||
# Open for edit or add if different than what is in perforce already.
|
||||
if( !$dstexists || ( $srcmodtime != $dstmodtime ) )
|
||||
{
|
||||
if ( $srcexists && $shadersrcfilename =~ m@\.fxc@i )
|
||||
{
|
||||
# Get the CRC for the source file.
|
||||
my $srccode = ReadInputFileWithIncludes( $shadersrcfilename );
|
||||
my $crc = crc32( $srccode );
|
||||
|
||||
# Patch the source VCS file with the CRC32 of the source code used to build that file.
|
||||
PatchCRC( $src, $crc );
|
||||
}
|
||||
|
||||
# Make the target vcs writable if it exists
|
||||
if( $dstexists )
|
||||
{
|
||||
MakeFileWritable( $dst );
|
||||
}
|
||||
|
||||
my $dir = $dst;
|
||||
$dir =~ s,([^/\\]*$),,; # rip the filename off the end
|
||||
my $filename = $1;
|
||||
|
||||
# create the target directory if it doesn't exist
|
||||
if( !$dstexists )
|
||||
{
|
||||
&MakeDirHier( $dir, 0777 );
|
||||
}
|
||||
|
||||
# copy the file to its targets. . . we want to see STDERR here if there is an error.
|
||||
my $cmd = "copy $src $dst > nul";
|
||||
# print STDERR "$cmd\n";
|
||||
system $cmd;
|
||||
|
||||
MakeFileReadOnly( $dst );
|
||||
}
|
||||
}
|
||||
|
||||
close TXTFILE;
|
110
devtools/bin/fix_particle_operator_names.pl
Normal file
110
devtools/bin/fix_particle_operator_names.pl
Normal file
@ -0,0 +1,110 @@
|
||||
#!perl
|
||||
use File::Find;
|
||||
|
||||
&BuildRemapTable;
|
||||
|
||||
find(\&convert, "." );
|
||||
|
||||
|
||||
sub convert
|
||||
{
|
||||
return unless (/\.pcf$/i);
|
||||
return if (/^tmp\.pcf$/i);
|
||||
return if (/^tmp2\.pcf$/i);
|
||||
return if (/360\.pcf$/i);
|
||||
print STDERR "process ", $File::Find::name," ($_) dir=",`cd`," \n";
|
||||
my $fname=$_;
|
||||
print `p4 edit $fname`;
|
||||
print `dmxconvert -i $_ -o tmp.pcf -oe keyvalues2`;
|
||||
open(TMP, "tmp.pcf" ) || return;
|
||||
open(OUT, ">tmp2.pcf" ) || die;
|
||||
while(<TMP>)
|
||||
{
|
||||
s/[\n\r]//g;
|
||||
if ( (/^(\s*\"functionName\"\s*\"string\"\s*\")(.*)\"(.*)$/) &&
|
||||
length($map{$2}) )
|
||||
{
|
||||
$_=$1.$map{$2}.'"'.$3;
|
||||
}
|
||||
if ( (/^(\s*\"name\"\s*\"string\"\s*\")(.*)\"(.*)$/) &&
|
||||
length($map{$2}) )
|
||||
{
|
||||
$_=$1.$map{$2}.'"'.$3;
|
||||
}
|
||||
print OUT "$_\n";
|
||||
}
|
||||
close OUT;
|
||||
close TMP;
|
||||
print `dmxconvert -i tmp2.pcf -o $fname -ie keyvalues2 -oe binary`;
|
||||
unlink "tmp.pcf";
|
||||
unlink "tmp2.pcf";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub BuildRemapTable
|
||||
{
|
||||
$map{"alpha_fade"}= "Alpha Fade and Decay";
|
||||
$map{"alpha_fade_in_random"}= "Alpha Fade In Random";
|
||||
$map{"alpha_fade_out_random"}= "Alpha Fade Out Random";
|
||||
$map{"basic_movement"}= "Movement Basic";
|
||||
$map{"color_fade"}= "Color Fade";
|
||||
$map{"controlpoint_light"}= "Color Light From Control Point";
|
||||
$map{"Dampen Movement Relative to Control Point"}= "Movement Dampen Relative to Control Point";
|
||||
$map{"Distance Between Control Points Scale"}= "Remap Distance Between Two Control Points to Scalar";
|
||||
$map{"Distance to Control Points Scale"}= "Remap Distance to Control Point to Scalar";
|
||||
$map{"lifespan_decay"}= "Lifespan Decay";
|
||||
$map{"lock to bone"}= "Movement Lock to Bone";
|
||||
$map{"postion_lock_to_controlpoint"}= "Movement Lock to Control Point";
|
||||
$map{"maintain position along path"}= "Movement Maintain Position Along Path";
|
||||
$map{"Match Particle Velocities"}= "Movement Match Particle Velocities";
|
||||
$map{"Max Velocity"}= "Movement Max Velocity";
|
||||
$map{"noise"}= "Noise Scalar";
|
||||
$map{"vector noise"}= "Noise Vector";
|
||||
$map{"oscillate_scalar"}= "Oscillate Scalar";
|
||||
$map{"oscillate_vector"}= "Oscillate Vector";
|
||||
$map{"Orient Rotation to 2D Direction"}= "Rotation Orient to 2D Direction";
|
||||
$map{"radius_scale"}= "Radius Scale";
|
||||
$map{"Random Cull"}= "Cull Random";
|
||||
$map{"remap_scalar"}= "Remap Scalar";
|
||||
$map{"rotation_movement"}= "Rotation Basic";
|
||||
$map{"rotation_spin"}= "Rotation Spin Roll";
|
||||
$map{"rotation_spin yaw"}= "Rotation Spin Yaw";
|
||||
$map{"alpha_random"}= "Alpha Random";
|
||||
$map{"color_random"}= "Color Random";
|
||||
$map{"create from parent particles"}= "Position From Parent Particles";
|
||||
$map{"Create In Hierarchy"}= "Position In CP Hierarchy";
|
||||
$map{"random position along path"}= "Position Along Path Random";
|
||||
$map{"random position on model"}= "Position on Model Random";
|
||||
$map{"sequential position along path"}= "Position Along Path Sequential";
|
||||
$map{"position_offset_random"}= "Position Modify Offset Random";
|
||||
$map{"position_warp_random"}= "Position Modify Warp Random";
|
||||
$map{"position_within_box"}= "Position Within Box Random";
|
||||
$map{"position_within_sphere"}= "Position Within Sphere Random";
|
||||
$map{"Inherit Velocity"}= "Velocity Inherit from Control Point";
|
||||
$map{"Initial Repulsion Velocity"}= "Velocity Repulse from World";
|
||||
$map{"Initial Velocity Noise"}= "Velocity Noise";
|
||||
$map{"Initial Scalar Noise"}= "Remap Noise to Scalar";
|
||||
$map{"Lifespan from distance to world"}= "Lifetime from Time to Impact";
|
||||
$map{"Pre-Age Noise"}= "Lifetime Pre-Age Noise";
|
||||
$map{"lifetime_random"}= "Lifetime Random";
|
||||
$map{"radius_random"}= "Radius Random";
|
||||
$map{"random yaw"}= "Rotation Yaw Random";
|
||||
$map{"Randomly Flip Yaw"}= "Rotation Yaw Flip Random";
|
||||
$map{"rotation_random"}= "Rotation Random";
|
||||
$map{"rotation_speed_random"}= "Rotation Speed Random";
|
||||
$map{"sequence_random"}= "Sequence Random";
|
||||
$map{"second_sequence_random"}= "Sequence Two Random";
|
||||
$map{"trail_length_random"}= "Trail Length Random";
|
||||
$map{"velocity_random"}= "Velocity Random";
|
||||
}
|
||||
|
1185
devtools/bin/fxc_prep.pl
Normal file
1185
devtools/bin/fxc_prep.pl
Normal file
File diff suppressed because it is too large
Load Diff
BIN
devtools/bin/linux/ccache
Normal file
BIN
devtools/bin/linux/ccache
Normal file
Binary file not shown.
BIN
devtools/bin/linux/vpc
Normal file
BIN
devtools/bin/linux/vpc
Normal file
Binary file not shown.
BIN
devtools/bin/osx/vpc
Normal file
BIN
devtools/bin/osx/vpc
Normal file
Binary file not shown.
96
devtools/bin/osx32/breakpad_build_symbols.py
Normal file
96
devtools/bin/osx32/breakpad_build_symbols.py
Normal file
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import datetime
|
||||
import getopt
|
||||
import glob
|
||||
import os
|
||||
import pickle
|
||||
import shutil
|
||||
import sys
|
||||
import zipfile
|
||||
import re
|
||||
import subprocess as sp
|
||||
|
||||
import pdb
|
||||
|
||||
def ShowUsage():
|
||||
print "breakpad_build_symbols.py [options] bindirectory symboldirectory]"
|
||||
print "-f/--force Force rebuild of .sym files."
|
||||
|
||||
#
|
||||
# Set program defaults.
|
||||
#
|
||||
g_bForce = False
|
||||
|
||||
def main():
|
||||
global g_bForce
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt( sys.argv[1:], "f", [ "force" ] )
|
||||
|
||||
except getopt.GetoptError, e:
|
||||
print ""
|
||||
print "Argument error: ", e
|
||||
print ""
|
||||
ShowUsage()
|
||||
sys.exit(1)
|
||||
|
||||
for o, a in opts:
|
||||
if o in ( "-f", "--force" ):
|
||||
g_bForce = True
|
||||
|
||||
# now look for all files in the specified path
|
||||
print "building symbols for %s to %s" % ( args[ 0 ], args[ 1 ] )
|
||||
|
||||
dump_syms = os.getcwd() + "/dump_syms"
|
||||
|
||||
rebuildcount = 0
|
||||
visitcount = 0
|
||||
for root, dirs, files in os.walk(args[ 0 ]):
|
||||
for name in dirs:
|
||||
dsymdirname = os.path.join(root, name)
|
||||
#print "checking %s" % dsymdirname
|
||||
if dsymdirname[-5:] == '.dSYM':
|
||||
visitcount += 1
|
||||
dylibfiletime = os.path.getmtime( dsymdirname )
|
||||
# get the first line
|
||||
command = dump_syms + " -g " + dsymdirname
|
||||
p = sp.Popen( command, stdout=sp.PIPE, stderr=sp.PIPE, shell=True )
|
||||
firstline = p.communicate()[ 0 ];
|
||||
#line syntax
|
||||
# MODULE mac x86 59C9A56A5EB38C85A185BA60877C89610 engine.dylib
|
||||
tokens = firstline.split()
|
||||
if ( len( tokens ) != 5 ):
|
||||
continue
|
||||
rawlibname = tokens[ 4 ]
|
||||
# print "shortname %s\n" % rawlibname
|
||||
symdir = args[1] + "/" + tokens[ 4 ] + "/" + tokens[ 3 ]
|
||||
if not os.path.isdir( symdir ):
|
||||
os.makedirs( symdir )
|
||||
symfile = symdir + "/" + rawlibname + ".sym"
|
||||
if ( os.path.exists( symfile ) ):
|
||||
# check time stamp
|
||||
symfilefiletime = os.path.getmtime( symfile )
|
||||
symfilesize = os.path.getsize( symfile )
|
||||
# print " %s %d %d" % (symfile, dylibfiletime, symfilefiletime)
|
||||
if ( symfilefiletime >= dylibfiletime and not g_bForce and symfilesize > 0 ):
|
||||
continue
|
||||
|
||||
# do full processing
|
||||
command = dump_syms + " " + dsymdirname
|
||||
p = sp.Popen( command, stdout=sp.PIPE, stderr=sp.PIPE, shell=True )
|
||||
symbols = p.communicate()[ 0 ]
|
||||
print " :%s" % symfile
|
||||
# print " %s" % symbols
|
||||
fd = open( symfile, 'wb' )
|
||||
fd.write( symbols )
|
||||
fd.close()
|
||||
# force time stamp
|
||||
os.utime( symfile, ( dylibfiletime, dylibfiletime ) )
|
||||
rebuildcount += 1
|
||||
|
||||
print " rebuilt %d out of %d symbol files" % ( rebuildcount, visitcount )
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
10
devtools/bin/osx32/breakpad_makesymbols.sh
Normal file
10
devtools/bin/osx32/breakpad_makesymbols.sh
Normal file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# rm -rf /tmp/symbols/
|
||||
./breakpad_build_symbols.py ~/Perforce/perforce_1666/yahn_mac/Steam/main/src/ /tmp/symbols
|
||||
./breakpad_build_symbols.py ~/Perforce/perforce_1666/yahn_mac/Steam/main/client/osx32/ /tmp/symbols
|
||||
#./breakpad_build_symbols.py ~/Perforce/perforce_1666/yahn_mac/Steam/main/client/ /tmp/symbols
|
||||
#./breakpad_build_symbols.py ~/Perforce/perforce_1666/yahn_staging/game/ /tmp/symbols
|
||||
./breakpad_build_symbols.py ~/Perforce/perforce_1666/yahn_staging/src/ /tmp/symbols
|
||||
rsync -r /tmp/symbols/ socorro-test:./symbols
|
||||
|
BIN
devtools/bin/osx32/ccache
Normal file
BIN
devtools/bin/osx32/ccache
Normal file
Binary file not shown.
BIN
devtools/bin/osx32/dump_syms
Normal file
BIN
devtools/bin/osx32/dump_syms
Normal file
Binary file not shown.
BIN
devtools/bin/osx32/ipcclient
Normal file
BIN
devtools/bin/osx32/ipcclient
Normal file
Binary file not shown.
BIN
devtools/bin/osx32/protoserviceplugin
Normal file
BIN
devtools/bin/osx32/protoserviceplugin
Normal file
Binary file not shown.
3
devtools/bin/osx32/xcode_ccache_wrapper
Normal file
3
devtools/bin/osx32/xcode_ccache_wrapper
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
exec $(dirname $0)/ccache ${DT_TOOLCHAIN_DIR}/usr/bin/clang -Qunused-arguments $@
|
294
devtools/bin/p4autocheckout.pl
Normal file
294
devtools/bin/p4autocheckout.pl
Normal file
@ -0,0 +1,294 @@
|
||||
#!perl
|
||||
use strict;
|
||||
|
||||
BEGIN {use File::Basename; push @INC, dirname($0); }
|
||||
require "valve_perl_helpers.pl";
|
||||
|
||||
sub PrintCleanPerforceOutput
|
||||
{
|
||||
my $line;
|
||||
while( $line = shift )
|
||||
{
|
||||
if( $line =~ m/currently opened/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
if( $line =~ m/already opened for edit/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
if( $line =~ m/also opened/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
if( $line =~ m/add of existing file/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
print $line;
|
||||
}
|
||||
}
|
||||
|
||||
# HACK!!!! Need to pass something in to do this rather than hard coding.
|
||||
sub NormalizePerforceFilename
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
# remove newlines.
|
||||
$line =~ s/\n//;
|
||||
# downcase.
|
||||
$line =~ tr/[A-Z]/[a-z]/;
|
||||
# backslash to forwardslash
|
||||
$line =~ s,\\,/,g;
|
||||
|
||||
# for inc files HACK!
|
||||
$line =~ s/^.*(fxctmp9.*)/$1/i;
|
||||
$line =~ s/^.*(vshtmp9.*)/$1/i;
|
||||
|
||||
# for vcs files. HACK!
|
||||
$line =~ s,^.*game/platform/shaders/,,i;
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
# COMMAND-LINE ARGUMENTS
|
||||
my $x360 = 0;
|
||||
my $ps3 = 0;
|
||||
my $filename = shift;
|
||||
if( $filename =~ m/-x360/i )
|
||||
{
|
||||
$x360 = 1;
|
||||
$filename = shift;
|
||||
}
|
||||
elsif( $filename =~ m/-ps3/i )
|
||||
{
|
||||
$ps3 = 1;
|
||||
$filename = shift;
|
||||
}
|
||||
my $changelistname = shift;
|
||||
my $perforcebasepath = shift;
|
||||
my $diffpath = join " ", @ARGV;
|
||||
|
||||
#print STDERR "\$filename: $filename\n";
|
||||
#print STDERR "\$changelistname: $changelistname\n";
|
||||
#print STDERR "\$perforcebasepath: $perforcebasepath\n";
|
||||
#print STDERR "\$diffpath: $diffpath\n";
|
||||
|
||||
# Read the input file list before changing to the perforce directory.
|
||||
open FILELIST, "<$filename";
|
||||
my @inclist = <FILELIST>;
|
||||
close FILELIST;
|
||||
|
||||
# change from the perforce directory so that our client will be correct from here out.
|
||||
#print STDERR "chdir $perforcebasepath\n";
|
||||
chdir $perforcebasepath || die "can't cd to $perforcebasepath";
|
||||
|
||||
#print "inclist before @inclist\n";
|
||||
# get rid of newlines and fix slashes
|
||||
@inclist =
|
||||
map
|
||||
{
|
||||
$_ =~ s,_tmp,,g; # remove _tmp so that we check out in the proper directory
|
||||
$_ =~ s,\\,/,g; # backslash to forwardslash
|
||||
$_ =~ s/\n//g; # remove newlines
|
||||
$_ =~ tr/[A-Z]/[a-z]/; # downcase
|
||||
# $_ =~ s,.*platform/shaders/,,i;
|
||||
# $_ =~ s,$perforcebasepath/,,i;
|
||||
$_ =~ s,../../../game/platform/shaders/,,i; # hack. . .really want something here that works generically.
|
||||
$_
|
||||
} @inclist;
|
||||
#print "inclist after @inclist\n";
|
||||
|
||||
my $prevline;
|
||||
my @outlist;
|
||||
foreach $_ ( sort( @inclist ) )
|
||||
{
|
||||
next if( defined( $prevline ) && $_ eq $prevline );
|
||||
$prevline = $_;
|
||||
push @outlist, $_;
|
||||
}
|
||||
@inclist = @outlist;
|
||||
|
||||
#print "\@inclist: @inclist\n";
|
||||
|
||||
# Get list of files on the client
|
||||
# -sl Every unopened file, along with the status of
|
||||
# 'same, 'diff', or 'missing' as compared to its
|
||||
# revision in the depot.
|
||||
my @unopenedlist = &RunCommand( "p4 diff -sl $diffpath" );
|
||||
|
||||
#print "\@unopenedlist: @unopenedlist\n";
|
||||
|
||||
my %sameunopened;
|
||||
my %diffunopened;
|
||||
my %missingunopened;
|
||||
|
||||
my $line;
|
||||
foreach $line ( @unopenedlist )
|
||||
{
|
||||
my $same = 0;
|
||||
my $diff = 0;
|
||||
my $missing = 0;
|
||||
if( $line =~ s/^same //i )
|
||||
{
|
||||
$same = 1;
|
||||
}
|
||||
elsif( $line =~ s/^diff //i )
|
||||
{
|
||||
$diff = 1;
|
||||
}
|
||||
elsif( $line =~ s/^missing //i )
|
||||
{
|
||||
$missing = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
die "checkoutincfiles.pl don't understand p4 diff -sl results: $line\n";
|
||||
}
|
||||
|
||||
# clean up the filename
|
||||
# print "before: $line\n" if $line =~ m/aftershock_vs20/i;
|
||||
$line = NormalizePerforceFilename( $line );
|
||||
# print "after: \"$line\"\n" if $line =~ m/aftershock_vs20/i;
|
||||
# if( $line =~ m/aftershock/i )
|
||||
# {
|
||||
# print "unopenedlist: $line same: $same diff: $diff missing: $missing\n";
|
||||
# }
|
||||
|
||||
# Save off the results for each line so that we can query them later.
|
||||
if( $same )
|
||||
{
|
||||
$sameunopened{$line} = 1;
|
||||
}
|
||||
elsif( $diff )
|
||||
{
|
||||
$diffunopened{$line} = 1;
|
||||
}
|
||||
elsif( $missing )
|
||||
{
|
||||
$missingunopened{$line} = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
# -sr Opened files that are the same as the revision in the
|
||||
# depot.
|
||||
my @openedbutsame = &RunCommand( "p4 diff -sr $diffpath" );
|
||||
|
||||
my %sameopened;
|
||||
|
||||
foreach $line ( @openedbutsame )
|
||||
{
|
||||
if( $line =~ m/not opened on this client/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
# clean up the filename
|
||||
# print "before: $line\n" if $line =~ m/aftershock_vs20/i;
|
||||
$line = NormalizePerforceFilename( $line );
|
||||
# print "after: $line\n" if $line =~ m/aftershock_vs20/i;
|
||||
# if( $line =~ m/aftershock/i )
|
||||
# {
|
||||
# print STDERR "sameopened: $line\n";
|
||||
# }
|
||||
$sameopened{$line} = 1;
|
||||
}
|
||||
|
||||
my @sameunopened;
|
||||
my @revert;
|
||||
my @edit;
|
||||
my @add;
|
||||
|
||||
foreach $line ( @inclist )
|
||||
{
|
||||
if( defined( $sameunopened{$line} ) )
|
||||
{
|
||||
push @sameunopened, $line;
|
||||
}
|
||||
elsif( defined( $sameopened{$line} ) )
|
||||
{
|
||||
push @revert, $line;
|
||||
}
|
||||
elsif( defined( $diffunopened{$line} ) )
|
||||
{
|
||||
push @edit, $line;
|
||||
}
|
||||
elsif( defined( $missingunopened{$line} ) )
|
||||
{
|
||||
printf STDERR "p4autocheckout.pl: $line missing\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
push @add, $line;
|
||||
}
|
||||
}
|
||||
|
||||
#print "\@sameunopened = @sameunopened\n";
|
||||
#print "\@revert = @revert\n";
|
||||
#print "\@edit = @edit\n";
|
||||
#print "\@add = @add\n";
|
||||
|
||||
# Get the changelist number for the named changelist if we are actually going to edit or add anything.
|
||||
# We don't need it for deleting.
|
||||
my $changelistarg = "";
|
||||
# Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist.
|
||||
my $changelistnumber = `valve_p4_create_changelist.cmd . \"$changelistname\"`;
|
||||
# Get rid of the newline
|
||||
$changelistnumber =~ s/\n//g;
|
||||
|
||||
#print STDERR "changelistnumber: $changelistnumber\n";
|
||||
|
||||
if( $changelistnumber != 0 )
|
||||
{
|
||||
$changelistarg = "-c $changelistnumber"
|
||||
}
|
||||
|
||||
#my %sameunopened;
|
||||
#my %diffunopened;
|
||||
#my %missingunopened;
|
||||
#my %sameopened;
|
||||
|
||||
if( scalar @edit )
|
||||
{
|
||||
while( scalar @edit )
|
||||
{
|
||||
# Grab 10 files at a time so that we don't blow cmd.exe line limits.
|
||||
my @files = splice @edit, 0, 10;
|
||||
my $cmd = "p4 edit $changelistarg @files";
|
||||
# print STDERR $cmd . "\n";
|
||||
my @results = &RunCommand( $cmd );
|
||||
# print STDERR @results;
|
||||
&PrintCleanPerforceOutput( @results );
|
||||
}
|
||||
}
|
||||
|
||||
if( scalar @revert )
|
||||
{
|
||||
while( scalar @revert )
|
||||
{
|
||||
# Grab 10 files at a time so that we don't blow cmd.exe line limits.
|
||||
my @files = splice @revert, 0, 10;
|
||||
my $cmd = "p4 revert @files";
|
||||
# print STDERR $cmd . "\n";
|
||||
my @results = &RunCommand( $cmd );
|
||||
&PrintCleanPerforceOutput( @results );
|
||||
}
|
||||
}
|
||||
|
||||
if( scalar @add )
|
||||
{
|
||||
while( scalar @add )
|
||||
{
|
||||
# Grab 10 files at a time so that we don't blow cmd.exe line limits.
|
||||
my @files = splice @add, 0, 10;
|
||||
my $cmd = "p4 add $changelistarg @files";
|
||||
# print STDERR $cmd . "\n";
|
||||
my @results = &RunCommand( $cmd );
|
||||
# print STDERR "@results\n";
|
||||
&PrintCleanPerforceOutput( @results );
|
||||
}
|
||||
}
|
||||
|
129
devtools/bin/p4revertshadertargets.pl
Normal file
129
devtools/bin/p4revertshadertargets.pl
Normal file
@ -0,0 +1,129 @@
|
||||
use strict;
|
||||
|
||||
BEGIN {use File::Basename; push @INC, dirname($0); }
|
||||
require "valve_perl_helpers.pl";
|
||||
|
||||
my $dynamic_compile = defined $ENV{"dynamic_shaders"} && $ENV{"dynamic_shaders"} != 0;
|
||||
|
||||
# ----------------------------------------------
|
||||
# COMMAND-LINE ARGS
|
||||
# ----------------------------------------------
|
||||
my $g_x360 = 0;
|
||||
my $g_ps3 = 0;
|
||||
my $g_tmpfolder = "";
|
||||
my $g_vcsext = ".vcs";
|
||||
my $g_SrcDir = ".";
|
||||
my $inputbase;
|
||||
my $g_SourceDir;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
$inputbase = shift;
|
||||
|
||||
if( $inputbase =~ m/-source/ )
|
||||
{
|
||||
$g_SourceDir = shift;
|
||||
}
|
||||
elsif( $inputbase =~ m/-x360/ )
|
||||
{
|
||||
$g_x360 = 1;
|
||||
$g_tmpfolder = "_360";
|
||||
$g_vcsext = ".360.vcs";
|
||||
}
|
||||
elsif( $inputbase =~ m/-ps3/ )
|
||||
{
|
||||
$g_ps3 = 1;
|
||||
$g_tmpfolder = "_ps3";
|
||||
$g_vcsext = ".ps3.vcs";
|
||||
}
|
||||
else
|
||||
{
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------
|
||||
# Load the list of shaders that we care about.
|
||||
# ----------------------------------------------
|
||||
my @srcfiles = &LoadShaderListFile( $inputbase );
|
||||
|
||||
my %incHash;
|
||||
my %vcsHash;
|
||||
my $shader;
|
||||
foreach $shader ( @srcfiles )
|
||||
{
|
||||
my $shadertype = &LoadShaderListFile_GetShaderType( $shader );
|
||||
my $shaderbase = &LoadShaderListFile_GetShaderBase( $shader );
|
||||
my $shadersrc = &LoadShaderListFile_GetShaderSrc( $shader );
|
||||
if( $shadertype eq "fxc" || $shadertype eq "vsh" )
|
||||
{
|
||||
# We only generate inc files for fxc and vsh files.
|
||||
my $incFileName = "$shadertype" . "tmp9" . $g_tmpfolder . "/" . $shaderbase . "\.inc";
|
||||
$incFileName =~ tr/A-Z/a-z/;
|
||||
$incHash{$incFileName} = 1;
|
||||
}
|
||||
|
||||
my $vcsFileName = "$shadertype/$shaderbase" . $g_vcsext;
|
||||
$vcsFileName =~ tr/A-Z/a-z/;
|
||||
$vcsHash{$vcsFileName} = 1;
|
||||
}
|
||||
|
||||
# ----------------------------------------------
|
||||
# Get the list of inc files to consider for reverting
|
||||
# ----------------------------------------------
|
||||
sub RevertIntegratedFiles
|
||||
{
|
||||
my $path = shift;
|
||||
my $fileHashRef = shift;
|
||||
|
||||
my $cmd = "p4 fstat $path";
|
||||
my @fstat = &RunCommand( $cmd );
|
||||
|
||||
my $depotFile;
|
||||
my $action;
|
||||
my @openedforintegrate;
|
||||
|
||||
my $line;
|
||||
foreach $line ( @fstat )
|
||||
{
|
||||
if( $line =~ m,depotFile (.*)\n, )
|
||||
{
|
||||
$depotFile = &NormalizePerforceFilename( $1 );
|
||||
}
|
||||
elsif( $line =~ m,action (.*)\n, )
|
||||
{
|
||||
$action = $1;
|
||||
}
|
||||
elsif( $line =~ m,^\s*$, )
|
||||
{
|
||||
if( defined $action && defined $fileHashRef->{$depotFile} && $action =~ m/integrate/i )
|
||||
{
|
||||
push @openedforintegrate, $depotFile;
|
||||
}
|
||||
undef $depotFile;
|
||||
undef $action;
|
||||
}
|
||||
}
|
||||
|
||||
if( scalar( @openedforintegrate ) )
|
||||
{
|
||||
my $cmd = "p4 revert @openedforintegrate";
|
||||
# print "$cmd\n";
|
||||
my @revertOutput = &RunCommand( $cmd );
|
||||
&PrintCleanPerforceOutput( @revertOutput );
|
||||
}
|
||||
}
|
||||
|
||||
my $path = "vshtmp9" . $g_tmpfolder . "/... fxctmp9" . $g_tmpfolder . "/...";
|
||||
&RevertIntegratedFiles( $path, \%incHash );
|
||||
|
||||
if( !$dynamic_compile )
|
||||
{
|
||||
&MakeDirHier( "../../../game/platform/shaders" );
|
||||
|
||||
# Might be in a different client for the vcs files, so chdir to the correct place.
|
||||
chdir "../../../game/platform/shaders" || die;
|
||||
|
||||
my $path = "...";
|
||||
&RevertIntegratedFiles( $path, \%vcsHash );
|
||||
}
|
333
devtools/bin/psh_prep.pl
Normal file
333
devtools/bin/psh_prep.pl
Normal file
@ -0,0 +1,333 @@
|
||||
use String::CRC32;
|
||||
BEGIN {use File::Basename; push @INC, dirname($0); }
|
||||
require "valve_perl_helpers.pl";
|
||||
|
||||
sub BuildDefineOptions
|
||||
{
|
||||
local( $output );
|
||||
local( $combo ) = shift;
|
||||
local( $i );
|
||||
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
|
||||
{
|
||||
local( $val ) = ( $combo % ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 ) ) + $dynamicDefineMin[$i];
|
||||
$output .= "/D$dynamicDefineNames[$i]=$val ";
|
||||
$combo = $combo / ( $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1 );
|
||||
}
|
||||
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
|
||||
{
|
||||
local( $val ) = ( $combo % ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 ) ) + $staticDefineMin[$i];
|
||||
$output .= "/D$staticDefineNames[$i]=$val ";
|
||||
$combo = $combo / ( $staticDefineMax[$i] - $staticDefineMin[$i] + 1 );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
sub CalcNumCombos
|
||||
{
|
||||
local( $i, $numCombos );
|
||||
$numCombos = 1;
|
||||
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
|
||||
{
|
||||
$numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
|
||||
}
|
||||
for( $i = 0; $i < scalar( @staticDefineNames ); $i++ )
|
||||
{
|
||||
$numCombos *= $staticDefineMax[$i] - $staticDefineMin[$i] + 1;
|
||||
}
|
||||
return $numCombos;
|
||||
}
|
||||
|
||||
sub CalcNumDynamicCombos
|
||||
{
|
||||
local( $i, $numCombos );
|
||||
$numCombos = 1;
|
||||
for( $i = 0; $i < scalar( @dynamicDefineNames ); $i++ )
|
||||
{
|
||||
$numCombos *= $dynamicDefineMax[$i] - $dynamicDefineMin[$i] + 1;
|
||||
}
|
||||
return $numCombos;
|
||||
}
|
||||
|
||||
$g_dx9 = 1;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
$psh_filename = shift;
|
||||
|
||||
if( $psh_filename =~ m/-source/ )
|
||||
{
|
||||
$g_SourceDir = shift;
|
||||
}
|
||||
elsif( $psh_filename =~ m/-x360/ )
|
||||
{
|
||||
$g_x360 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
$psh_filename =~ s/-----.*$//;
|
||||
|
||||
|
||||
# Get the shader binary version number from a header file.
|
||||
open FILE, "<$g_SourceDir\\public\\materialsystem\\shader_vcs_version.h" || die;
|
||||
while( $line = <FILE> )
|
||||
{
|
||||
if( $line =~ m/^\#define\s+SHADER_VCS_VERSION_NUMBER\s+(\d+)\s*$/ )
|
||||
{
|
||||
$shaderVersion = $1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if( !defined $shaderVersion )
|
||||
{
|
||||
die "couldn't get shader version from shader_vcs_version.h";
|
||||
}
|
||||
close FILE;
|
||||
|
||||
|
||||
|
||||
local( @staticDefineNames );
|
||||
local( @staticDefineMin );
|
||||
local( @staticDefineMax );
|
||||
local( @dynamicDefineNames );
|
||||
local( @dynamicDefineMin );
|
||||
local( @dynamicDefineMax );
|
||||
|
||||
# Parse the combos.
|
||||
open PSH, "<$psh_filename";
|
||||
while( <PSH> )
|
||||
{
|
||||
last if( !m,^;, );
|
||||
s,^;\s*,,;
|
||||
if( m/\s*STATIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
|
||||
{
|
||||
local( $name, $min, $max );
|
||||
$name = $1;
|
||||
$min = $2;
|
||||
$max = $3;
|
||||
# print "\"STATIC: $name\" \"$min..$max\"\n";
|
||||
if (/\[(.*)\]/)
|
||||
{
|
||||
$platforms=$1;
|
||||
next if ( ($g_x360) && (!($platforms=~/XBOX/i)) );
|
||||
next if ( (!$g_x360) && (!($platforms=~/PC/i)) );
|
||||
}
|
||||
push @staticDefineNames, $name;
|
||||
push @staticDefineMin, $min;
|
||||
push @staticDefineMax, $max;
|
||||
}
|
||||
elsif( m/\s*DYNAMIC\s*\:\s*\"(.*)\"\s+\"(\d+)\.\.(\d+)\"/ )
|
||||
{
|
||||
local( $name, $min, $max );
|
||||
$name = $1;
|
||||
$min = $2;
|
||||
$max = $3;
|
||||
# print "\"DYNAMIC: $name\" \"$min..$max\"\n";
|
||||
if (/\[(.*)\]/)
|
||||
{
|
||||
$platforms=$1;
|
||||
next if ( ($g_x360) && (!($platforms=~/XBOX/i)) );
|
||||
next if ( (!$g_x360) && (!($platforms=~/PC/i)) );
|
||||
}
|
||||
push @dynamicDefineNames, $name;
|
||||
push @dynamicDefineMin, $min;
|
||||
push @dynamicDefineMax, $max;
|
||||
}
|
||||
}
|
||||
close PSH;
|
||||
|
||||
$numCombos = &CalcNumCombos();
|
||||
$numDynamicCombos = &CalcNumDynamicCombos();
|
||||
print "$psh_filename\n";
|
||||
#print "$numCombos combos\n";
|
||||
#print "$numDynamicCombos dynamic combos\n";
|
||||
|
||||
if( $g_x360 )
|
||||
{
|
||||
$pshtmp = "pshtmp9_360";
|
||||
}
|
||||
elsif( $g_dx9 )
|
||||
{
|
||||
$pshtmp = "pshtmp9";
|
||||
}
|
||||
else
|
||||
{
|
||||
$pshtmp = "pshtmp8";
|
||||
}
|
||||
$basename = $psh_filename;
|
||||
$basename =~ s/\.psh$//i;
|
||||
|
||||
for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ )
|
||||
{
|
||||
my $tempFilename = "shader$shaderCombo.o";
|
||||
unlink $tempFilename;
|
||||
|
||||
if( $g_x360 )
|
||||
{
|
||||
$cmd = "psa /D_X360=1 /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL";
|
||||
}
|
||||
else
|
||||
{
|
||||
$cmd = "$g_SourceDir\\dx9sdk\\utilities\\psa /Foshader$shaderCombo.o /nologo " . &BuildDefineOptions( $shaderCombo ) . "$psh_filename > NIL";
|
||||
}
|
||||
|
||||
if( !stat $pshtmp )
|
||||
{
|
||||
mkdir $pshtmp, 0777 || die $!;
|
||||
}
|
||||
|
||||
# print $cmd . "\n";
|
||||
system $cmd || die $!;
|
||||
|
||||
# Make sure a file got generated because sometimes the die above won't happen on compile errors.
|
||||
my $filesize = (stat $tempFilename)[7];
|
||||
if ( !$filesize )
|
||||
{
|
||||
die "Error compiling shader$shaderCombo.o";
|
||||
}
|
||||
|
||||
push @outputHeader, @hdr;
|
||||
}
|
||||
|
||||
$basename =~ s/\.fxc//gi;
|
||||
push @outputHeader, "static PrecompiledShaderByteCode_t " . $basename . "_pixel_shaders[" . $numCombos . "] = \n";
|
||||
push @outputHeader, "{\n";
|
||||
local( $j );
|
||||
for( $j = 0; $j < $numCombos; $j++ )
|
||||
{
|
||||
local( $thing ) = "pixelShader_" . $basename . "_" . $j;
|
||||
push @outputHeader, "\t{ " . "$thing, sizeof( $thing ) },\n";
|
||||
}
|
||||
push @outputHeader, "};\n";
|
||||
|
||||
push @outputHeader, "struct $basename" . "PixelShader_t : public PrecompiledShader_t\n";
|
||||
push @outputHeader, "{\n";
|
||||
push @outputHeader, "\t$basename" . "PixelShader_t()\n";
|
||||
push @outputHeader, "\t{\n";
|
||||
push @outputHeader, "\t\tm_nFlags = 0;\n";
|
||||
push @outputHeader, "\t\tm_pByteCode = " . $basename . "_pixel_shaders;\n";
|
||||
push @outputHeader, "\t\tm_nShaderCount = $numCombos;\n";
|
||||
#push @outputHeader, "\t\tm_nDynamicCombos = m_nShaderCount;\n";
|
||||
push @outputHeader, "\t\t// NOTE!!! psh_prep.pl shaders are always static combos!\n";
|
||||
push @outputHeader, "\t\tm_nDynamicCombos = 1;\n";
|
||||
push @outputHeader, "\t\tm_pName = \"$basename\";\n";
|
||||
if( $basename =~ /vs\d\d/ ) # hack
|
||||
{
|
||||
push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_VERTEX_SHADER, this );\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
push @outputHeader, "\t\tGetShaderDLL()->InsertPrecompiledShader( PRECOMPILED_PIXEL_SHADER, this );\n";
|
||||
}
|
||||
push @outputHeader, "\t}\n";
|
||||
push @outputHeader, "\tvirtual const PrecompiledShaderByteCode_t &GetByteCode( int shaderID )\n";
|
||||
push @outputHeader, "\t{\n";
|
||||
push @outputHeader, "\t\treturn m_pByteCode[shaderID];\n";
|
||||
push @outputHeader, "\t}\n";
|
||||
push @outputHeader, "};\n";
|
||||
|
||||
push @outputHeader, "static $basename" . "PixelShader_t $basename" . "_PixelShaderInstance;\n";
|
||||
|
||||
|
||||
&MakeDirHier( "shaders/psh" );
|
||||
|
||||
my $vcsName = "";
|
||||
if( $g_x360 )
|
||||
{
|
||||
$vcsName = $basename . ".360.vcs";
|
||||
}
|
||||
else
|
||||
{
|
||||
$vcsName = $basename . ".vcs";
|
||||
}
|
||||
|
||||
open COMPILEDSHADER, ">shaders/psh/$vcsName" || die;
|
||||
binmode( COMPILEDSHADER );
|
||||
|
||||
#
|
||||
# Write out the part of the header that we know. . we'll write the rest after writing the object code.
|
||||
#
|
||||
|
||||
#print $numCombos . "\n";
|
||||
|
||||
# Pack arguments
|
||||
my $sInt = "i";
|
||||
my $uInt = "I";
|
||||
if ( $g_x360 )
|
||||
{
|
||||
# Change arguments to "big endian long"
|
||||
$sInt = "N";
|
||||
$uInt = "N";
|
||||
}
|
||||
|
||||
open PSH, "<$psh_filename";
|
||||
my $crc = crc32( *PSH );
|
||||
close PSH;
|
||||
#print STDERR "crc for $psh_filename: $crc\n";
|
||||
|
||||
# version
|
||||
print COMPILEDSHADER pack $sInt, 4;
|
||||
# totalCombos
|
||||
print COMPILEDSHADER pack $sInt, $numCombos;
|
||||
# dynamic combos
|
||||
print COMPILEDSHADER pack $sInt, $numDynamicCombos;
|
||||
# flags
|
||||
print COMPILEDSHADER pack $uInt, 0x0; # nothing here for now.
|
||||
# centroid mask
|
||||
print COMPILEDSHADER pack $uInt, 0;
|
||||
# reference size for diffs
|
||||
print COMPILEDSHADER pack $uInt, 0;
|
||||
# crc32 of the source code
|
||||
print COMPILEDSHADER pack $uInt, $crc;
|
||||
|
||||
my $beginningOfDir = tell COMPILEDSHADER;
|
||||
|
||||
# Write out a blank directionary. . we'll fill it in later.
|
||||
for( $i = 0; $i < $numCombos; $i++ )
|
||||
{
|
||||
# offset from beginning of file.
|
||||
print COMPILEDSHADER pack $sInt, 0;
|
||||
# size
|
||||
print COMPILEDSHADER pack $sInt, 0;
|
||||
}
|
||||
|
||||
my $startByteCode = tell COMPILEDSHADER;
|
||||
my @byteCodeStart;
|
||||
my @byteCodeSize;
|
||||
|
||||
# Write out the shader object code.
|
||||
for( $shaderCombo = 0; $shaderCombo < $numCombos; $shaderCombo++ )
|
||||
{
|
||||
my $filename = "shader$shaderCombo\.o";
|
||||
my $filesize = (stat $filename)[7];
|
||||
|
||||
$byteCodeStart[$shaderCombo] = tell COMPILEDSHADER;
|
||||
$byteCodeSize[$shaderCombo] = $filesize;
|
||||
open SHADERBYTECODE, "<$filename";
|
||||
binmode SHADERBYTECODE;
|
||||
|
||||
my $bin;
|
||||
my $numread = read SHADERBYTECODE, $bin, $filesize;
|
||||
# print "filename: $filename numread: $numread filesize: $filesize\n";
|
||||
close SHADERBYTECODE;
|
||||
unlink $filename;
|
||||
|
||||
print COMPILEDSHADER $bin;
|
||||
}
|
||||
|
||||
# Seek back to the directory and write it out.
|
||||
seek COMPILEDSHADER, $beginningOfDir, 0;
|
||||
for( $i = 0; $i < $numCombos; $i++ )
|
||||
{
|
||||
# offset from beginning of file.
|
||||
print COMPILEDSHADER pack $sInt, $byteCodeStart[$i];
|
||||
# size
|
||||
print COMPILEDSHADER pack $sInt, $byteCodeSize[$i];
|
||||
}
|
||||
|
||||
close COMPILEDSHADER;
|
||||
|
||||
|
36
devtools/bin/shaderinfo.pl
Normal file
36
devtools/bin/shaderinfo.pl
Normal file
@ -0,0 +1,36 @@
|
||||
#! perl
|
||||
|
||||
my $fname=shift || die "format is shaderinfo blah.vcs";
|
||||
|
||||
open(SHADER, $fname) || die "can't open $fname";
|
||||
binmode SHADER;
|
||||
|
||||
read(SHADER,$header,20);
|
||||
($ver,$ntotal,$ndynamic,$flags,$centroidmask)=unpack("LLLLL",$header);
|
||||
|
||||
#print "Version $ver total combos=$ntotal, num dynamic combos=$ndynamic,\n flags=$flags, centroid mask=$centroidmask\n";
|
||||
|
||||
read(SHADER,$refsize,4);
|
||||
$refsize=unpack("L",$refsize);
|
||||
#print "Size of reference shader for diffing=$refsize\n";
|
||||
|
||||
seek(SHADER,$refsize,1);
|
||||
|
||||
$nskipped_combos=0;
|
||||
for(1..$ntotal)
|
||||
{
|
||||
read(SHADER,$combodata,8);
|
||||
($ofs,$combosize)=unpack("LL",$combodata);
|
||||
if ( $ofs == 0xffffffff)
|
||||
{
|
||||
$nskipped_combos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
#print "$nskipped_combos skipped, for an actual total of ",$ntotal-$nskipped_combos,"\n";
|
||||
#print "Real to skipped ratio = ",($ntotal-$nskipped_combos)/$ntotal,"\n";
|
||||
# csv output - name, real combos, virtual combos, dynamic combos
|
||||
my $real_combos=$ntotal-$nskipped_combos;
|
||||
print "$fname,$real_combos,$ntotal,$ndynamic\n";
|
54
devtools/bin/splitdiff3.pl
Normal file
54
devtools/bin/splitdiff3.pl
Normal file
@ -0,0 +1,54 @@
|
||||
$infilename = shift;
|
||||
$outfilename1 = shift;
|
||||
$outfilename2 = shift;
|
||||
open INPUT, $infilename || die;
|
||||
@input = <INPUT>;
|
||||
close INPUT;
|
||||
|
||||
open MERGEDMINE, ">$outfilename1" || die;
|
||||
open MERGEDTHEIRS, ">$outfilename2" || die;
|
||||
|
||||
for( $i = 0; $i < scalar( @input ); $i++ )
|
||||
{
|
||||
$line = $input[$i];
|
||||
|
||||
if( $line =~ m/^(.*)<<<<<<</ )
|
||||
{
|
||||
$first = 1;
|
||||
$second = 0;
|
||||
print MERGEDMINE $1;
|
||||
print MERGEDTHEIRS $1;
|
||||
next;
|
||||
}
|
||||
# Make sure that we are in a split block so that comments with ======= don't mess us up.
|
||||
if( $line =~ m/^(.*)=======$/ && $first == 1 )
|
||||
{
|
||||
$first = 0;
|
||||
$second = 1;
|
||||
print MERGEDMINE $1;
|
||||
next;
|
||||
}
|
||||
if( $line =~ m/^(.*)>>>>>>>/ )
|
||||
{
|
||||
$first = $second = 0;
|
||||
print MERGEDTHEIRS $1;
|
||||
next;
|
||||
}
|
||||
|
||||
if( $first )
|
||||
{
|
||||
print MERGEDMINE $line;
|
||||
}
|
||||
elsif( $second )
|
||||
{
|
||||
print MERGEDTHEIRS $line;
|
||||
}
|
||||
else
|
||||
{
|
||||
print MERGEDMINE $line;
|
||||
print MERGEDTHEIRS $line;
|
||||
}
|
||||
}
|
||||
|
||||
close MERGEDMINE;
|
||||
close MERGEDTHEIRS;
|
15
devtools/bin/texttoarray.pl
Normal file
15
devtools/bin/texttoarray.pl
Normal file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env perl
|
||||
open( HANDLE,shift) || die;
|
||||
undef $/;
|
||||
binmode HANDLE;
|
||||
$data=<HANDLE>;
|
||||
$ctr=0;
|
||||
$out.=sprintf("static unsigned char %s[] = {\n ", shift);
|
||||
for($i=0;$i<length($data);$i++)
|
||||
{
|
||||
$out.=sprintf("0x%02x,", unpack("C", substr($data,$i,1)) );
|
||||
$out.="\n " if ( ( $ctr % 20) == 19);
|
||||
$ctr++;
|
||||
}
|
||||
$out.="0x00\n};\n";
|
||||
print $out;
|
BIN
devtools/bin/tier0.dll
Normal file
BIN
devtools/bin/tier0.dll
Normal file
Binary file not shown.
6
devtools/bin/uniqifylist.pl
Normal file
6
devtools/bin/uniqifylist.pl
Normal file
@ -0,0 +1,6 @@
|
||||
foreach $_ (sort <> )
|
||||
{
|
||||
next if( defined( $prevline ) && $_ eq $prevline );
|
||||
$prevline = $_;
|
||||
print;
|
||||
}
|
325
devtools/bin/updateshaders.pl
Normal file
325
devtools/bin/updateshaders.pl
Normal file
@ -0,0 +1,325 @@
|
||||
use String::CRC32;
|
||||
BEGIN {use File::Basename; push @INC, dirname($0); }
|
||||
require "valve_perl_helpers.pl";
|
||||
|
||||
$dynamic_compile = defined $ENV{"dynamic_shaders"} && $ENV{"dynamic_shaders"} != 0;
|
||||
|
||||
$depnum = 0;
|
||||
$baseSourceDir = ".";
|
||||
|
||||
my %dep;
|
||||
|
||||
sub GetAsmShaderDependencies_R
|
||||
{
|
||||
local( $shadername ) = shift;
|
||||
local( *SHADER );
|
||||
|
||||
open SHADER, "<$shadername";
|
||||
while( <SHADER> )
|
||||
{
|
||||
if( m/^\s*\#\s*include\s+\"(.*)\"/ )
|
||||
{
|
||||
# make sure it isn't in there already.
|
||||
if( !defined( $dep{$1} ) )
|
||||
{
|
||||
$dep{$1} = 1;
|
||||
GetAsmShaderDependencies_R( $1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
close SHADER;
|
||||
}
|
||||
|
||||
sub GetAsmShaderDependencies
|
||||
{
|
||||
local( $shadername ) = shift;
|
||||
undef %dep;
|
||||
GetAsmShaderDependencies_R( $shadername );
|
||||
# local( $i );
|
||||
# foreach $i ( keys( %dep ) )
|
||||
# {
|
||||
# print "$shadername depends on $i\n";
|
||||
# }
|
||||
return keys( %dep );
|
||||
}
|
||||
|
||||
sub GetShaderType
|
||||
{
|
||||
my $shadername = shift;
|
||||
my $shadertype;
|
||||
if( $shadername =~ m/\.vsh/i )
|
||||
{
|
||||
$shadertype = "vsh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.psh/i )
|
||||
{
|
||||
$shadertype = "psh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.fxc/i )
|
||||
{
|
||||
$shadertype = "fxc";
|
||||
}
|
||||
else
|
||||
{
|
||||
die;
|
||||
}
|
||||
return $shadertype;
|
||||
}
|
||||
|
||||
sub GetShaderSrc
|
||||
{
|
||||
my $shadername = shift;
|
||||
if ( $shadername =~ m/^(.*)-----/i )
|
||||
{
|
||||
return $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $shadername;
|
||||
}
|
||||
}
|
||||
|
||||
sub GetShaderBase
|
||||
{
|
||||
my $shadername = shift;
|
||||
if ( $shadername =~ m/-----(.*)$/i )
|
||||
{
|
||||
return $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $shadertype = &GetShaderType( $shadername );
|
||||
$shadername =~ s/\.$shadertype//i;
|
||||
return $shadername;
|
||||
}
|
||||
}
|
||||
|
||||
sub DoAsmShader
|
||||
{
|
||||
my $argstring = shift;
|
||||
my $shadername = &GetShaderSrc( $argstring );
|
||||
my $shaderbase = &GetShaderBase( $argstring );
|
||||
my $shadertype = &GetShaderType( $argstring );
|
||||
my $incfile = "";
|
||||
if( $shadertype eq "fxc" || $shadertype eq "vsh" )
|
||||
{
|
||||
$incfile = $shadertype . "tmp9" . $g_tmpfolder . "\\$shaderbase.inc ";
|
||||
}
|
||||
|
||||
my $vcsfile = $shaderbase . $g_vcsext;
|
||||
my $bWillCompileVcs = 1;
|
||||
if( ( $shadertype eq "fxc") && $dynamic_compile )
|
||||
{
|
||||
$bWillCompileVcs = 0;
|
||||
}
|
||||
if( $shadercrcpass{$argstring} )
|
||||
{
|
||||
$bWillCompileVcs = 0;
|
||||
}
|
||||
|
||||
if( $bWillCompileVcs )
|
||||
{
|
||||
&output_makefile_line( $incfile . "shaders\\$shadertype\\$vcsfile: $shadername ..\\..\\devtools\\bin\\updateshaders.pl ..\\..\\devtools\\bin\\" . $shadertype . "_prep.pl" . " @dep\n") ;
|
||||
}
|
||||
else
|
||||
{
|
||||
# psh files don't need a rule at this point since they don't have inc files and we aren't compiling a vcs.
|
||||
if( $shadertype eq "fxc" || $shadertype eq "vsh" )
|
||||
{
|
||||
&output_makefile_line( $incfile . ": $shadername ..\\..\\devtools\\bin\\updateshaders.pl ..\\..\\devtools\\bin\\" . $shadertype . "_prep.pl" . " @dep\n") ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $x360switch = "";
|
||||
my $ps3switch = "";
|
||||
my $moreswitches = "";
|
||||
if( !$bWillCompileVcs && $shadertype eq "fxc" )
|
||||
{
|
||||
$moreswitches .= "-novcs ";
|
||||
}
|
||||
if( $g_x360 )
|
||||
{
|
||||
$x360switch = "-x360";
|
||||
|
||||
if( $bWillCompileVcs && ( $shaderbase =~ m/_ps20$/i ) )
|
||||
{
|
||||
$moreswitches .= "-novcs ";
|
||||
$bWillCompileVcs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( $g_ps3 )
|
||||
{
|
||||
$ps3switch = "-ps3";
|
||||
|
||||
if( $bWillCompileVcs && ( $shaderbase =~ m/_ps20$/i ) )
|
||||
{
|
||||
$moreswitches .= "-novcs ";
|
||||
$bWillCompileVcs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
# if we are psh and we are compiling the vcs, we don't need this rule.
|
||||
if( !( $shadertype eq "psh" && !$bWillCompileVcs ) )
|
||||
{
|
||||
&output_makefile_line( "\tperl $g_SourceDir\\devtools\\bin\\" . $shadertype . "_prep.pl $moreswitches $x360switch $ps3switch -source \"$g_SourceDir\" $argstring\n") ;
|
||||
}
|
||||
|
||||
if( $bWillCompileVcs )
|
||||
{
|
||||
&output_makefile_line( "\techo $shadername>> filestocopy.txt\n") ;
|
||||
my $dep;
|
||||
foreach $dep( @dep )
|
||||
{
|
||||
&output_makefile_line( "\techo $dep>> filestocopy.txt\n") ;
|
||||
}
|
||||
}
|
||||
&output_makefile_line( "\n") ;
|
||||
}
|
||||
|
||||
if( scalar( @ARGV ) == 0 )
|
||||
{
|
||||
die "Usage updateshaders.pl shaderprojectbasename\n\tie: updateshaders.pl stdshaders_dx6\n";
|
||||
}
|
||||
|
||||
$g_x360 = 0;
|
||||
$g_ps3 = 0;
|
||||
$g_tmpfolder = "_tmp";
|
||||
$g_vcsext = ".vcs";
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
$inputbase = shift;
|
||||
|
||||
if( $inputbase =~ m/-source/ )
|
||||
{
|
||||
$g_SourceDir = shift;
|
||||
}
|
||||
elsif( $inputbase =~ m/-x360/ )
|
||||
{
|
||||
$g_x360 = 1;
|
||||
$g_tmpfolder = "_360_tmp";
|
||||
$g_vcsext = ".360.vcs";
|
||||
}
|
||||
elsif( $inputbase =~ m/-ps3/ )
|
||||
{
|
||||
$g_ps3 = 1;
|
||||
$g_tmpfolder = "_ps3_tmp";
|
||||
$g_vcsext = ".ps3.vcs";
|
||||
}
|
||||
elsif( $inputbase =~ m/-execute/ )
|
||||
{
|
||||
$g_execute = 1;
|
||||
}
|
||||
elsif( $inputbase =~ m/-nv3x/ )
|
||||
{
|
||||
$nv3x = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
my @srcfiles = &LoadShaderListFile( $inputbase );
|
||||
|
||||
open MAKEFILE, ">makefile\.$inputbase";
|
||||
open COPYFILE, ">makefile\.$inputbase\.copy";
|
||||
open INCLIST, ">inclist.txt";
|
||||
open VCSLIST, ">vcslist.txt";
|
||||
|
||||
# make a default dependency that depends on all of the shaders.
|
||||
&output_makefile_line( "default: ") ;
|
||||
foreach $shader ( @srcfiles )
|
||||
{
|
||||
my $shadertype = &GetShaderType( $shader );
|
||||
my $shaderbase = &GetShaderBase( $shader );
|
||||
my $shadersrc = &GetShaderSrc( $shader );
|
||||
if( $shadertype eq "fxc" || $shadertype eq "vsh" )
|
||||
{
|
||||
# We only generate inc files for fxc and vsh files.
|
||||
my $incFileName = "$shadertype" . "tmp9" . $g_tmpfolder . "\\" . $shaderbase . "\.inc";
|
||||
&output_makefile_line( " $incFileName" );
|
||||
&output_inclist_line( "$incFileName\n" );
|
||||
}
|
||||
|
||||
my $vcsfile = $shaderbase . $g_vcsext;
|
||||
|
||||
my $compilevcs = 1;
|
||||
if( $shadertype eq "fxc" && $dynamic_compile )
|
||||
{
|
||||
$compilevcs = 0;
|
||||
}
|
||||
# Do not compile ps2.0 shaders on PS3/X360
|
||||
if( ( $g_x360 || $g_ps3 ) && ( $shaderbase =~ m/_ps20$/i ) )
|
||||
{
|
||||
$compilevcs = 0;
|
||||
}
|
||||
if( $compilevcs )
|
||||
{
|
||||
my $vcsFileName = "..\\..\\..\\game\\platform\\shaders\\$shadertype\\$shaderbase" . $g_vcsext;
|
||||
# We want to check for perforce operations even if the crc matches in the event that a file has been manually reverted and needs to be checked out again.
|
||||
&output_vcslist_line( "$vcsFileName\n" );
|
||||
$shadercrcpass{$shader} = &CheckCRCAgainstTarget( $shadersrc, $vcsFileName, 0 );
|
||||
if( $shadercrcpass{$shader} )
|
||||
{
|
||||
$compilevcs = 0;
|
||||
}
|
||||
}
|
||||
if( $compilevcs )
|
||||
{
|
||||
&output_makefile_line( " shaders\\$shadertype\\$vcsfile" );
|
||||
# emit a list of vcs files to copy to the target since we want to build them.
|
||||
&output_copyfile_line( GetShaderSrc($shader) . "-----" . GetShaderBase($shader) . "\n" );
|
||||
}
|
||||
}
|
||||
&output_makefile_line( "\n\n") ;
|
||||
|
||||
# Insert all of our vertex shaders and depencencies
|
||||
$lastshader = "";
|
||||
foreach $shader ( @srcfiles )
|
||||
{
|
||||
my $currentshader = &GetShaderSrc( $shader );
|
||||
if ( $lastshader ne $currentshader )
|
||||
{
|
||||
$lastshader = $currentshader;
|
||||
@dep = &GetAsmShaderDependencies( $lastshader );
|
||||
}
|
||||
&DoAsmShader( $shader );
|
||||
}
|
||||
close VCSLIST;
|
||||
close INCLIST;
|
||||
close COPYFILE;
|
||||
close MAKEFILE;
|
||||
|
||||
# nuke the copyfile if it is zero length
|
||||
if( ( stat "makefile\.$inputbase\.copy" )[7] == 0 )
|
||||
{
|
||||
unlink "makefile\.$inputbase\.copy";
|
||||
}
|
||||
|
||||
sub output_makefile_line
|
||||
{
|
||||
local ($_)=@_;
|
||||
print MAKEFILE $_;
|
||||
}
|
||||
|
||||
sub output_copyfile_line
|
||||
{
|
||||
local ($_)=@_;
|
||||
print COPYFILE $_;
|
||||
}
|
||||
|
||||
sub output_vcslist_line
|
||||
{
|
||||
local ($_)=@_;
|
||||
print VCSLIST $_;
|
||||
}
|
||||
|
||||
sub output_inclist_line
|
||||
{
|
||||
local ($_)=@_;
|
||||
print INCLIST $_;
|
||||
}
|
||||
|
65
devtools/bin/valve_p4_create_changelist.cmd
Normal file
65
devtools/bin/valve_p4_create_changelist.cmd
Normal file
@ -0,0 +1,65 @@
|
||||
@echo off
|
||||
|
||||
:: // This will make all new env variables local to this script
|
||||
setlocal
|
||||
|
||||
:: // Make sure we have 2 args
|
||||
if .%2.==.. (
|
||||
echo *** [valve_p4_create_changelist] Error calling command! No file or changelist specified for checkout! Usage: valve_p4_create_changelist.cmd fileOrPath "Description"
|
||||
endlocal
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: // Get file info
|
||||
set valveTmpPathOnly="%~d1%~p1"
|
||||
if "%valveTmpPathOnly%"=="" (
|
||||
echo *** [valve_p4_create_changelist] Error! Can't parse file or path "%1"!
|
||||
endlocal
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:: // Change directories so that the p4 set commands give use useful data
|
||||
pushd %valveTmpPathOnly%
|
||||
|
||||
:: // Find user
|
||||
for /f "tokens=2 delims== " %%A in ('p4.exe set ^| find /i "P4USER="') do set valveP4User=%%A
|
||||
if "%valveP4User%"=="" goto RegularCheckout
|
||||
rem //echo User="%valveP4User%"
|
||||
|
||||
:: // Find client
|
||||
for /f "tokens=2 delims== " %%A in ('p4.exe set ^| find /i "P4CLIENT="') do set valveP4Client=%%A
|
||||
if "%valveP4Client%"=="" goto RegularCheckout
|
||||
rem //echo Client="%valveP4Client%"
|
||||
|
||||
:: // Search for existing changelist that matches command line arg
|
||||
set valveP4ChangelistName=%2%
|
||||
set valveP4ChangelistName=%valveP4ChangelistName:~1,-1%
|
||||
for /f "tokens=2 delims= " %%A in ('p4.exe changes -u %valveP4User% -s pending -c %valveP4Client% ^| sort /r ^| find /i "'%valveP4ChangelistName%"') do set valveP4ChangelistNumber=%%A
|
||||
if NOT "%valveP4ChangelistNumber%"=="" goto HaveChangelist
|
||||
|
||||
:: // We didn't find a matching changelist but we did figure enough out to create a new changelist
|
||||
rem //echo Creating New Changelist
|
||||
for /f "tokens=2 delims= " %%A in ('^( echo Change: new ^& echo Client: %valveP4Client% ^& echo User: %valveP4User% ^& echo Status: new ^& echo Description: %valveP4ChangelistName%^&echo.^) ^| p4.exe change -i') do set valveP4ChangelistNumberJustCreated=%%A
|
||||
if "%valveP4ChangelistNumberJustCreated%"=="" goto RegularCheckout
|
||||
|
||||
:: // Now search for the changelist number even though we already have it to try to clean up after the race condition when it's hit
|
||||
:: // This way, if more than one changelist is created in parallel, this will hopefully cause them to be checked out into the same changelist and the empty one deleted
|
||||
for /f "tokens=2 delims= " %%A in ('p4.exe changes -u %valveP4User% -s pending -c %valveP4Client% ^| sort /r ^| find /i "'%valveP4ChangelistName%"') do set valveP4ChangelistNumber=%%A
|
||||
if "%valveP4ChangelistNumber%"=="" goto RegularCheckout
|
||||
|
||||
if NOT "%valveP4ChangelistNumber%"=="%valveP4ChangelistNumberJustCreated%" p4.exe change -d %valveP4ChangelistNumberJustCreated% 2>&1 >nul
|
||||
|
||||
:: // We have a changelist number
|
||||
:HaveChangelist
|
||||
echo %valveP4ChangelistNumber%
|
||||
goto End
|
||||
|
||||
:: // Can't find or create the changelist, output 0
|
||||
:RegularCheckout
|
||||
echo 0
|
||||
goto End
|
||||
|
||||
:End
|
||||
popd
|
||||
endlocal
|
||||
exit /b 0
|
93
devtools/bin/valve_p4_edit_to_changelist.cmd
Normal file
93
devtools/bin/valve_p4_edit_to_changelist.cmd
Normal file
@ -0,0 +1,93 @@
|
||||
@echo off
|
||||
|
||||
:: // This will make all new env variables local to this script
|
||||
setlocal
|
||||
|
||||
:: // If called with the start command, we need to exit, so also make sure you pass EXIT as the third param!
|
||||
:: // Also, if you modify this script, make sure that endlocal and exit are within ()'s so valveExitArg works!
|
||||
:: // Type 'help set' at a command prompt if you don't understand why.
|
||||
if NOT "%3"=="EXIT" set valveExitArg=/b
|
||||
|
||||
:: // Make sure we have 2 args
|
||||
if .%2.==.. (
|
||||
echo *** [valve_p4_edit_to_changelist] Error calling command! No file or changelist specified for checkout! Usage: valve_p4_edit_to_changelist.cmd file "Description" [EXIT]
|
||||
endlocal
|
||||
exit %valveExitArg% 1
|
||||
)
|
||||
|
||||
:: // Get file info
|
||||
set valveTmpFileName="%~n1%~x1"
|
||||
set valveTmpFullFilePath="%~f1"
|
||||
set valveTmpPathOnly="%~d1%~p1"
|
||||
|
||||
if "%valveTmpFileName%"=="" (
|
||||
echo *** [valve_p4_edit_to_changelist] Error! Can't parse filename "%1"!
|
||||
endlocal
|
||||
exit %valveExitArg% 1
|
||||
)
|
||||
|
||||
if "%valveTmpFullFilePath%"=="" (
|
||||
echo *** [valve_p4_edit_to_changelist] Error! Can't parse filename "%1"!
|
||||
endlocal
|
||||
exit %valveExitArg% 1
|
||||
)
|
||||
|
||||
if "%valveTmpPathOnly%"=="" (
|
||||
echo *** [valve_p4_edit_to_changelist] Error! Can't parse filename "%1"!
|
||||
endlocal
|
||||
exit %valveExitArg% 1
|
||||
)
|
||||
|
||||
:: // Change directories so that the p4 set commands give use useful data
|
||||
pushd %valveTmpPathOnly%
|
||||
|
||||
:: // Find user
|
||||
for /f "tokens=2 delims== " %%A in ('p4.exe set ^| find /i "P4USER="') do set valveP4User=%%A
|
||||
if "%valveP4User%"=="" goto RegularCheckout
|
||||
rem //echo User="%valveP4User%"
|
||||
|
||||
:: // Find client
|
||||
for /f "tokens=2 delims== " %%A in ('p4.exe set ^| find /i "P4CLIENT="') do set valveP4Client=%%A
|
||||
if "%valveP4Client%"=="" goto RegularCheckout
|
||||
rem //echo Client="%valveP4Client%"
|
||||
|
||||
:: // Search for existing changelist that matches command line arg
|
||||
set valveP4ChangelistName=%2%
|
||||
set valveP4ChangelistName=%valveP4ChangelistName:~1,-1%
|
||||
for /f "tokens=2 delims= " %%A in ('p4.exe changes -u %valveP4User% -s pending -c %valveP4Client% ^| sort /r ^| find /i "'%valveP4ChangelistName%"') do set valveP4ChangelistNumber=%%A
|
||||
if NOT "%valveP4ChangelistNumber%"=="" goto HaveChangelist
|
||||
|
||||
:: // We didn't find a matching changelist but we did figure enough out to create a new changelist
|
||||
rem //echo Creating New Changelist
|
||||
for /f "tokens=2 delims= " %%A in ('^( echo Change: new ^& echo Client: %valveP4Client% ^& echo User: %valveP4User% ^& echo Status: new ^& echo Description: %valveP4ChangelistName%^&echo.^) ^| p4.exe change -i') do set valveP4ChangelistNumberJustCreated=%%A
|
||||
if "%valveP4ChangelistNumberJustCreated%"=="" goto RegularCheckout
|
||||
|
||||
:: // Now search for the changelist number even though we already have it to try to clean up after the race condition when it's hit
|
||||
:: // This way, if more than one changelist is created in parallel, this will hopefully cause them to be checked out into the same changelist and the empty one deleted
|
||||
for /f "tokens=2 delims= " %%A in ('p4.exe changes -u %valveP4User% -s pending -c %valveP4Client% ^| sort /r ^| find /i "'%valveP4ChangelistName%"') do set valveP4ChangelistNumber=%%A
|
||||
if "%valveP4ChangelistNumber%"=="" goto RegularCheckout
|
||||
|
||||
if NOT "%valveP4ChangelistNumber%"=="%valveP4ChangelistNumberJustCreated%" p4.exe change -d %valveP4ChangelistNumberJustCreated% 2>&1 >nul
|
||||
|
||||
:: // We have a changelist number
|
||||
:HaveChangelist
|
||||
set valveP4ChangelistArg=-c %valveP4ChangelistNumber%
|
||||
rem //echo valveP4ChangelistArg="%valveP4ChangelistArg%"
|
||||
rem //echo ChangelistNumber="%valveP4ChangelistNumber%"
|
||||
rem //echo ChangelistName="%valveP4ChangelistName%"
|
||||
|
||||
:: // Check the file out
|
||||
:RegularCheckout
|
||||
if "%VALVE_WAIT_ON_P4%"=="" (
|
||||
p4.exe edit %valveP4ChangelistArg% %valveTmpFullFilePath% 2>&1 | find /v /i "- currently opened for edit" | find /v /i "- also opened by" | find /v /i "- file(s) not on client" | find /v /i "- can't change from"
|
||||
) ELSE (
|
||||
:: // Filter out largely benign messages unless we're explicitly waiting on p4 results a la buildbot
|
||||
p4.exe edit %valveP4ChangelistArg% %valveTmpFullFilePath% 2>&1 | find /v /i "- also opened by"
|
||||
)
|
||||
|
||||
goto End
|
||||
|
||||
:End
|
||||
popd
|
||||
( endlocal
|
||||
exit %valveExitArg% 0 )
|
554
devtools/bin/valve_perl_helpers.pl
Normal file
554
devtools/bin/valve_perl_helpers.pl
Normal file
@ -0,0 +1,554 @@
|
||||
sub BackToForwardSlash
|
||||
{
|
||||
my( $path ) = shift;
|
||||
$path =~ s,\\,/,g;
|
||||
return $path;
|
||||
}
|
||||
|
||||
sub RemoveFileName
|
||||
{
|
||||
my( $in ) = shift;
|
||||
$in = &BackToForwardSlash( $in );
|
||||
$in =~ s,/[^/]*$,,;
|
||||
return $in;
|
||||
}
|
||||
|
||||
sub RemovePath
|
||||
{
|
||||
my( $in ) = shift;
|
||||
$in = &BackToForwardSlash( $in );
|
||||
$in =~ s,^(.*)/([^/]*)$,$2,;
|
||||
return $in;
|
||||
}
|
||||
|
||||
sub MakeDirHier
|
||||
{
|
||||
my( $in ) = shift;
|
||||
# print "MakeDirHier( $in )\n";
|
||||
$in = &BackToForwardSlash( $in );
|
||||
my( @path );
|
||||
while( $in =~ m,/, ) # while $in still has a slash
|
||||
{
|
||||
my( $end ) = &RemovePath( $in );
|
||||
push @path, $end;
|
||||
# print $in . "\n";
|
||||
$in = &RemoveFileName( $in );
|
||||
}
|
||||
my( $i );
|
||||
my( $numelems ) = scalar( @path );
|
||||
my( $curpath );
|
||||
for( $i = $numelems - 1; $i >= 0; $i-- )
|
||||
{
|
||||
$curpath .= "/" . $path[$i];
|
||||
my( $dir ) = $in . $curpath;
|
||||
if( !stat $dir )
|
||||
{
|
||||
# print "mkdir $dir\n";
|
||||
mkdir $dir, 0777;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub FileExists
|
||||
{
|
||||
my $filename = shift;
|
||||
my @statresult = stat $filename;
|
||||
my $iswritable = @statresult != 0;
|
||||
return $iswritable;
|
||||
}
|
||||
|
||||
sub MakeFileWritable
|
||||
{
|
||||
my $filename = shift;
|
||||
if ( &FileExists( $filename ) )
|
||||
{
|
||||
chmod 0666, $filename || die;
|
||||
}
|
||||
}
|
||||
|
||||
sub MakeFileReadOnly
|
||||
{
|
||||
my $filename = shift;
|
||||
chmod 0444, $filename || die;
|
||||
}
|
||||
|
||||
# Run a command and get stdout and stderr to an array
|
||||
sub RunCommand
|
||||
{
|
||||
my $cmd = shift;
|
||||
# print STDERR "command: $cmd\n";
|
||||
system "$cmd > cmdout.txt 2>&1" || die;
|
||||
local( *FILE );
|
||||
open FILE, "<cmdout.txt" || die;
|
||||
my @output = <FILE>;
|
||||
# print STDERR "command output: @output\n";
|
||||
close FILE;
|
||||
unlink "cmdout.txt" || die;
|
||||
return @output;
|
||||
}
|
||||
|
||||
sub PerforceEditOrAdd
|
||||
{
|
||||
return;
|
||||
my $filename = shift;
|
||||
my $changelistarg = shift;
|
||||
|
||||
# Is the file on the client?
|
||||
my $cmd = "p4 fstat \"$filename\"";
|
||||
my @p4output = &RunCommand( $cmd );
|
||||
my $p4output = join "", @p4output;
|
||||
if( $p4output =~ m/no such file/ )
|
||||
{
|
||||
# not on client. . add
|
||||
my $cmd = "p4 add $changelistarg $filename";
|
||||
my @p4output = &RunCommand( $cmd );
|
||||
my $p4output = join "", @p4output;
|
||||
if( $p4output =~ m/opened for add/ )
|
||||
{
|
||||
print $p4output;
|
||||
return;
|
||||
}
|
||||
print "ERROR: $p4output";
|
||||
return;
|
||||
}
|
||||
|
||||
# The file is known to be on the client at this point.
|
||||
|
||||
# Is it open for edit?
|
||||
if( $p4output =~ m/action edit/ )
|
||||
{
|
||||
# Is is open for edit, let's see if it's still different.
|
||||
# check for opened files that are not different from the revision in the depot.
|
||||
my $cmd = "p4 diff -sr \"$filename\"";
|
||||
my @p4output = &RunCommand( $cmd );
|
||||
my $outputstring = join "", @p4output;
|
||||
# check for empty string
|
||||
if( !( $outputstring =~ m/^\s*$/ ) )
|
||||
{
|
||||
my $cmd = "p4 revert \"$filename\"";
|
||||
my @p4output = &RunCommand( $cmd );
|
||||
my $outputstring = join "", @p4output;
|
||||
print $outputstring;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# check for unopened files that are different from the revision in the depot.
|
||||
my $cmd = "p4 diff -se \"$filename\"";
|
||||
my @p4output = &RunCommand( $cmd );
|
||||
my $outputstring = join "", @p4output;
|
||||
# check for empty string
|
||||
if( $outputstring =~ m/^\s*$/ )
|
||||
{
|
||||
&MakeFileReadOnly( $filename );
|
||||
return;
|
||||
}
|
||||
|
||||
# We need to edit the file since it is known to be different here.
|
||||
my $cmd = "p4 edit $changelistarg \"$filename\"";
|
||||
my @p4output = &RunCommand( $cmd );
|
||||
|
||||
my $line;
|
||||
foreach $line ( @p4output )
|
||||
{
|
||||
if( $line =~ m/not on client/ )
|
||||
{
|
||||
#print "notonclient...";
|
||||
print "ERROR: @p4output\n";
|
||||
return;
|
||||
}
|
||||
if( $line =~ m/currently opened for edit/ )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if( $line =~ m/opened for edit/ )
|
||||
{
|
||||
print $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub FileIsWritable
|
||||
{
|
||||
local( $filename ) = shift;
|
||||
local( @statresult ) = stat $filename;
|
||||
local( $mode, $iswritable );
|
||||
$mode = oct( $statresult[2] );
|
||||
$iswritable = ( $mode & 2 ) != 0;
|
||||
return $iswritable;
|
||||
}
|
||||
|
||||
sub TouchFile
|
||||
{
|
||||
my $filename = shift;
|
||||
if( !&FileExists( $filename ) )
|
||||
{
|
||||
if( !open FILE, ">$filename" )
|
||||
{
|
||||
die;
|
||||
}
|
||||
close FILE;
|
||||
}
|
||||
my $now = time;
|
||||
local( *FILE );
|
||||
utime $now, $now, $filename;
|
||||
}
|
||||
|
||||
sub FileExistsInPerforce
|
||||
{
|
||||
my $filename = shift;
|
||||
my @output = &RunCommand( "p4 fstat $filename" );
|
||||
my $line;
|
||||
foreach $line (@output)
|
||||
{
|
||||
if( $line =~ m/no such file/ )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub PerforceWriteFile
|
||||
{
|
||||
my $filename = shift;
|
||||
my $filecontents = shift;
|
||||
# my $changelistname = shift;
|
||||
|
||||
# Get the changelist number for the Shader Auto Checkout changelist. Will create the changelist if it doesn't exist.
|
||||
# my $changelistnumber = `valve_p4_create_changelist.cmd . \"$changelistname\"`;
|
||||
# Get rid of the newline
|
||||
# $changelistnumber =~ s/\n//g;
|
||||
|
||||
# my $changelistarg = "";
|
||||
# if( $changelistnumber != 0 )
|
||||
# {
|
||||
# $changelistarg = "-c $changelistnumber"
|
||||
# }
|
||||
|
||||
# Make the target vcs writable if it exists
|
||||
MakeFileWritable( $filename );
|
||||
|
||||
# Write the file.
|
||||
local( *FP );
|
||||
open FP, ">$filename";
|
||||
print FP $filecontents;
|
||||
close FP;
|
||||
|
||||
# Do whatever needs to happen with perforce for this file.
|
||||
# &PerforceEditOrAdd( $filename, $changelistarg );
|
||||
}
|
||||
|
||||
sub WriteFile
|
||||
{
|
||||
my $filename = shift;
|
||||
my $filecontents = shift;
|
||||
|
||||
# Make the target vcs writable if it exists
|
||||
MakeFileWritable( $filename );
|
||||
|
||||
# Write the file.
|
||||
local( *FP );
|
||||
open FP, ">$filename";
|
||||
print FP $filecontents;
|
||||
close FP;
|
||||
}
|
||||
|
||||
sub PrintCleanPerforceOutput
|
||||
{
|
||||
my $line;
|
||||
while( $line = shift )
|
||||
{
|
||||
if( $line =~ m/currently opened/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
if( $line =~ m/already opened for edit/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
if( $line =~ m/also opened/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
if( $line =~ m/add of existing file/i )
|
||||
{
|
||||
next;
|
||||
}
|
||||
print $line;
|
||||
}
|
||||
}
|
||||
|
||||
# HACK!!!! Need to pass something in to do this rather than hard coding.
|
||||
sub NormalizePerforceFilename
|
||||
{
|
||||
my $line = shift;
|
||||
|
||||
# remove newlines.
|
||||
$line =~ s/\n//;
|
||||
# downcase.
|
||||
$line =~ tr/[A-Z]/[a-z]/;
|
||||
# backslash to forwardslash
|
||||
$line =~ s,\\,/,g;
|
||||
|
||||
# for inc files HACK!
|
||||
$line =~ s/^.*(fxctmp9.*)/$1/i;
|
||||
$line =~ s/^.*(vshtmp9.*)/$1/i;
|
||||
|
||||
# for vcs files. HACK!
|
||||
$line =~ s,^.*game/platform/shaders/,,i;
|
||||
|
||||
return $line;
|
||||
}
|
||||
|
||||
sub MakeSureFileExists
|
||||
{
|
||||
local( $filename ) = shift;
|
||||
local( $testexists ) = shift;
|
||||
local( $testwrite ) = shift;
|
||||
|
||||
local( @statresult ) = stat $filename;
|
||||
if( !@statresult && $testexists )
|
||||
{
|
||||
die "$filename doesn't exist!\n";
|
||||
}
|
||||
local( $mode, $iswritable );
|
||||
$mode = oct( $statresult[2] );
|
||||
$iswritable = ( $mode & 2 ) != 0;
|
||||
if( !$iswritable && $testwrite )
|
||||
{
|
||||
die "$filename isn't writable!\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub LoadShaderListFile_GetShaderType
|
||||
{
|
||||
my $shadername = shift;
|
||||
my $shadertype;
|
||||
if( $shadername =~ m/\.vsh/i )
|
||||
{
|
||||
$shadertype = "vsh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.psh/i )
|
||||
{
|
||||
$shadertype = "psh";
|
||||
}
|
||||
elsif( $shadername =~ m/\.fxc/i )
|
||||
{
|
||||
$shadertype = "fxc";
|
||||
}
|
||||
else
|
||||
{
|
||||
die;
|
||||
}
|
||||
return $shadertype;
|
||||
}
|
||||
|
||||
sub LoadShaderListFile_GetShaderSrc
|
||||
{
|
||||
my $shadername = shift;
|
||||
if ( $shadername =~ m/^(.*)-----/i )
|
||||
{
|
||||
return $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $shadername;
|
||||
}
|
||||
}
|
||||
|
||||
sub LoadShaderListFile_GetShaderBase
|
||||
{
|
||||
my $shadername = shift;
|
||||
if ( $shadername =~ m/-----(.*)$/i )
|
||||
{
|
||||
return $1;
|
||||
}
|
||||
else
|
||||
{
|
||||
my $shadertype = &LoadShaderListFile_GetShaderType( $shadername );
|
||||
$shadername =~ s/\.$shadertype//i;
|
||||
return $shadername;
|
||||
}
|
||||
}
|
||||
|
||||
sub LoadShaderListFile
|
||||
{
|
||||
my $inputbase = shift;
|
||||
|
||||
my @srcfiles;
|
||||
&MakeSureFileExists( "$inputbase.txt", 1, 0 );
|
||||
|
||||
open SHADERLISTFILE, "<$inputbase.txt" || die;
|
||||
my $line;
|
||||
while( $line = <SHADERLISTFILE> )
|
||||
{
|
||||
$line =~ s/\/\/.*$//; # remove comments "//..."
|
||||
$line =~ s/^\s*//; # trim leading whitespace
|
||||
$line =~ s/\s*$//; # trim trailing whitespace
|
||||
next if( $line =~ m/^\s*$/ );
|
||||
if( $line =~ m/\.fxc/ || $line =~ m/\.vsh/ || $line =~ m/\.psh/ )
|
||||
{
|
||||
my $shaderbase = &LoadShaderListFile_GetShaderBase( $line );
|
||||
|
||||
if( $ENV{"DIRECTX_FORCE_MODEL"} =~ m/^30$/i ) # forcing all shaders to be ver. 30
|
||||
{
|
||||
my $targetbase = $shaderbase;
|
||||
$targetbase =~ s/_ps2x/_ps30/i;
|
||||
$targetbase =~ s/_ps20b/_ps30/i;
|
||||
$targetbase =~ s/_ps20/_ps30/i;
|
||||
$targetbase =~ s/_vs20/_vs30/i;
|
||||
$targetbase =~ s/_vsxx/_vs30/i;
|
||||
push @srcfiles, ( $line . "-----" . $targetbase );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( $shaderbase =~ m/_ps2x/i )
|
||||
{
|
||||
my $targetbase = $shaderbase;
|
||||
$targetbase =~ s/_ps2x/_ps20/i;
|
||||
push @srcfiles, ( $line . "-----" . $targetbase );
|
||||
|
||||
$targetbase = $shaderbase;
|
||||
$targetbase =~ s/_ps2x/_ps20b/i;
|
||||
push @srcfiles, ( $line . "-----" . $targetbase );
|
||||
}
|
||||
elsif( $shaderbase =~ m/_vsxx/i )
|
||||
{
|
||||
my $targetbase = $shaderbase;
|
||||
$targetbase =~ s/_vsxx/_vs20/i;
|
||||
push @srcfiles, ( $line . "-----" . $targetbase );
|
||||
}
|
||||
else
|
||||
{
|
||||
push @srcfiles, ( $line . "-----" . $shaderbase );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close SHADERLISTFILE;
|
||||
return @srcfiles;
|
||||
}
|
||||
|
||||
sub ReadInputFileWithIncludes
|
||||
{
|
||||
local( $filename ) = shift;
|
||||
# print STDERR "ReadInputFileWithIncludes: $filename\n";
|
||||
|
||||
local( *INPUT );
|
||||
local( $output );
|
||||
|
||||
# print STDERR "before open\n";
|
||||
open INPUT, "<$filename" || die;
|
||||
# print STDERR "after open\n";
|
||||
|
||||
local( $line );
|
||||
while( $line = <INPUT> )
|
||||
{
|
||||
# print STDERR $line;
|
||||
if( $line =~ m/\#include\s+\"(.*)\"/i )
|
||||
{
|
||||
$output.= ReadInputFileWithIncludes( $1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$output .= $line;
|
||||
}
|
||||
}
|
||||
|
||||
close INPUT;
|
||||
return $output;
|
||||
}
|
||||
|
||||
sub GetCRCFromSourceFile
|
||||
{
|
||||
my $filename = shift;
|
||||
my $data = &ReadInputFileWithIncludes( $filename );
|
||||
# print STDERR $data;
|
||||
$crc = crc32( $data );
|
||||
# print STDERR "GetCRCFromSourceFile: $crc\n";
|
||||
return $crc;
|
||||
}
|
||||
|
||||
sub GetCRCFromVCSFile
|
||||
{
|
||||
my $filename = shift;
|
||||
# print STDERR "GetCRCFromVCSFile $filename\n";
|
||||
local( *FP );
|
||||
open FP, "<$filename" || die "GetCRCFromVCSFile: can't open file $filename\n";
|
||||
binmode( FP );
|
||||
|
||||
# unpack arguments
|
||||
my $sInt = "i";
|
||||
my $uInt = "I";
|
||||
if ( ( $filename =~ m/\.360\./ ) || ( $filename =~ m/\.ps3\./ ) )
|
||||
{
|
||||
# Change arguments to "big endian long"
|
||||
$sInt = "N";
|
||||
$uInt = "N";
|
||||
}
|
||||
|
||||
my $header;
|
||||
read FP, $header, 7 * 4 || die "updateshaders.pl:GetCRCFromVCSFile: can't read header for $filename\n";
|
||||
my $version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc;
|
||||
($version,$numCombos,$numDynamicCombos,$flags,$centroidMask,$refSize,$crc) = unpack "$sInt$sInt$sInt$uInt$uInt$uInt$uInt", $header;
|
||||
unless( $version == 4 || $version == 5 || $version == 6 )
|
||||
{
|
||||
print STDERR "ERROR: GetCRCFromVCSFile: $filename is version $version\n";
|
||||
return 0;
|
||||
}
|
||||
# print STDERR "version: $version\n";
|
||||
# print STDERR "numCombos: $numCombos\n";
|
||||
# print STDERR "numDynamicCombos: $numDynamicCombos\n";
|
||||
# print STDERR "flags: $flags\n";
|
||||
# print STDERR "centroidMask: $centroidMask\n";
|
||||
# print STDERR "refSize: $refSize\n";
|
||||
# print STDERR "GetCRCFromVCSFile: $crc\n";
|
||||
close( FP );
|
||||
return $crc;
|
||||
}
|
||||
|
||||
sub CheckCRCAgainstTarget
|
||||
{
|
||||
my $srcFileName = shift;
|
||||
my $vcsFileName = shift;
|
||||
my $warn = shift;
|
||||
|
||||
# Make sure both files exist.
|
||||
# print STDERR "$srcFileName doesn't exist\n" if( !( -e $srcFileName ) );
|
||||
# print STDERR "$vcsFileName doesn't exist\n" if( !( -e $vcsFileName ) );
|
||||
if( !( -e $srcFileName ) )
|
||||
{
|
||||
if( $warn )
|
||||
{
|
||||
print "$srcFileName missing\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if( !( -e $vcsFileName ) )
|
||||
{
|
||||
if( $warn )
|
||||
{
|
||||
print "$vcsFileName missing\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
# print STDERR "CheckCRCAgainstTarget( $srcFileName, $vcsFileName );\n";
|
||||
# print STDERR "vcsFileName: $vcsFileName\n";
|
||||
# print STDERR "vcsFileName: $srcFileName\n";
|
||||
my $vcsCRC = &GetCRCFromVCSFile( $vcsFileName );
|
||||
my $srcCRC = &GetCRCFromSourceFile( $srcFileName );
|
||||
if( $warn && ( $vcsCRC != $srcCRC ) )
|
||||
{
|
||||
print "$vcsFileName checksum ($vcsCRC) != $srcFileName checksum: ($srcCRC)\n";
|
||||
}
|
||||
|
||||
# return 0; # use this to skip crc checking.
|
||||
# if( $vcsCRC == $srcCRC )
|
||||
# {
|
||||
# print STDERR "CRC passed for $srcFileName $vcsFileName $vcsCRC\n";
|
||||
# }
|
||||
return $vcsCRC == $srcCRC;
|
||||
}
|
||||
|
||||
1;
|
49
devtools/bin/vpc
Normal file
49
devtools/bin/vpc
Normal file
@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
|
||||
OS=`uname`
|
||||
SCRIPTPATH=`dirname $0`
|
||||
FORCEARG=""
|
||||
|
||||
case $OS in
|
||||
"Darwin")
|
||||
BINNAME=vpc_osx
|
||||
;;
|
||||
"Linux")
|
||||
BINNAME=vpc_linux
|
||||
;;
|
||||
*)
|
||||
echo "Couldn't find appropriate VPC binary, fix the script."
|
||||
exit -1
|
||||
;;
|
||||
esac
|
||||
|
||||
CWD=`pwd`
|
||||
cd $SCRIPTPATH/../../utils/vpc/vpc
|
||||
# ask make if we need to do any work, returns 0 if we don't,
|
||||
# non zero if we do.
|
||||
make -q
|
||||
RC=$?
|
||||
if [ $RC -eq 1 ]; then
|
||||
FORCEARG="/f"
|
||||
elif [ $RC -eq 2 ]; then
|
||||
FORCEARG="/f"
|
||||
make clean
|
||||
fi
|
||||
make -j4
|
||||
if [ $? -ne 0 ]; then
|
||||
exit -1
|
||||
fi
|
||||
if [ $RC -ne 0 ]; then
|
||||
cp -vf ../../devtools/bin/$BINNAME $CWD/$SCRIPTPATH
|
||||
fi
|
||||
|
||||
cd $CWD
|
||||
|
||||
if [ $OS == "Darwin" ]; then
|
||||
$SCRIPTPATH/$BINNAME $FORCEARG $@
|
||||
elif [ $OS == "Linux" ]; then
|
||||
$SCRIPTPATH/$BINNAME $FORCEARG $@
|
||||
else
|
||||
echo "Couldn't find appropriate VPC binary, fix the script."
|
||||
exit -1
|
||||
fi
|
BIN
devtools/bin/vpc.dll
Normal file
BIN
devtools/bin/vpc.dll
Normal file
Binary file not shown.
676
devtools/bin/vpc2linuxmake.pl
Normal file
676
devtools/bin/vpc2linuxmake.pl
Normal file
@ -0,0 +1,676 @@
|
||||
#!perl
|
||||
use IO::File;
|
||||
use File::Basename;
|
||||
use File::Find;
|
||||
use Cwd;
|
||||
use Cwd 'abs_path';
|
||||
|
||||
|
||||
|
||||
$nprocs=`grep vendor_id /proc/cpuinfo | wc -l `;
|
||||
$nprocs=~s/[\n\r]//g;
|
||||
print "$nprocs processors found\n";
|
||||
|
||||
#find where to include master make file from
|
||||
$srcdir=getcwd;
|
||||
die "can't determine path to src"
|
||||
unless ($srcdir=~s@/src.*$@/src@);
|
||||
|
||||
|
||||
find( { wanted=> \&handle_vpc_file } ,"$srcdir"); # search through all directories for .vpc files
|
||||
|
||||
@MAINTARGETS=("all", "clean", "objs");
|
||||
@TARGETS=("all", "clean", "objs", "tags");
|
||||
|
||||
|
||||
|
||||
# now, write a master makefile in each dir, and a master-master makefile in ~/src
|
||||
foreach $dir ( keys %dir_written )
|
||||
{
|
||||
open( MAKEOUT,">$dir/Makefile" ) || die "can't write $dir/Makefile";
|
||||
foreach $target ( @TARGETS )
|
||||
{
|
||||
print MAKEOUT ".PHONY: $target\n\n";
|
||||
print MAKEOUT "$target:\n";
|
||||
foreach $_ (split(/,/,$dir_written{$dir}) )
|
||||
{
|
||||
print MAKEOUT "\tmake -j $nprocs -f $_ $target\n" if length($_);
|
||||
}
|
||||
}
|
||||
close MAKEOUT;
|
||||
}
|
||||
|
||||
# now, write a master makefile in ~/src
|
||||
open( MAKEOUT,">$srcdir/Makefile" ) || die "can't write master makefile to $srcdir";
|
||||
foreach $target ( @MAINTARGETS )
|
||||
{
|
||||
print MAKEOUT ".PHONY: $target\n\n";
|
||||
print MAKEOUT "$target:\n";
|
||||
foreach $dir ( keys %dir_written )
|
||||
{
|
||||
if ($target ne "clean" )
|
||||
{
|
||||
print MAKEOUT "\tmake -j $nprocs -C $dir $target\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print MAKEOUT "\tmake -C $dir $target\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
print MAKEOUT "\n\nmakefiles:\n\tperl $srcdir/devtools/bin/vpc2linuxmake.pl\n";
|
||||
print MAKEOUT "\ntags:\n\tctags --languages=c++ -eR\n";
|
||||
|
||||
close MAKEOUT;
|
||||
|
||||
sub handle_vpc_file
|
||||
{
|
||||
# called for each file in the callers dir tree
|
||||
my $dir=$File::Find::dir;
|
||||
return if ( $dir=~/vpc_scripts/i );
|
||||
if ( /_base\.vpc$/i )
|
||||
{
|
||||
unless ( /hk_base\.vpc$/i )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
return if (/_inc\.vpc/i);
|
||||
|
||||
if (/\.vpc$/)
|
||||
{
|
||||
(%ignore_file,@DEFINES, @CPPFILES, @CXXFILES,@CFILES, @LITERAL_LIBFILES,@LIBFILES, %define_seen,%macros,%include_seen,@INCLUDEDIRS)=undef;
|
||||
undef $buildforlinux;
|
||||
undef $conf_type;
|
||||
undef $gccflags;
|
||||
$OptimizeLevel=3;
|
||||
|
||||
|
||||
# some defines to ignore in vpc files when generating linux include files
|
||||
|
||||
$define_seen{'WIN32'}=1;
|
||||
$define_seen{'_WIN32'}=1;
|
||||
$define_seen{'_WINDOWS'}=1;
|
||||
$define_seen{'_USRDLL'}=1;
|
||||
$define_seen{'DEBUG'}=1;
|
||||
$define_seen{'_DEBUG'}=1;
|
||||
$define_seen{'NDEBUG'}=1;
|
||||
$define_seen{'_CRT_SECURE_NO_DEPRECATE'}=1;
|
||||
$define_seen{'_CRT_NONSTDC_NO_DEPRECATE'}=1;
|
||||
$define_seen{'fopen'}=1;
|
||||
|
||||
# print STDERR "parsing project $pname\n";
|
||||
&ParseVPC($_);
|
||||
|
||||
$pname=lc($pname);
|
||||
$pname=~s/\s+/_/g;
|
||||
$pname=~s/[\(\)]//g;
|
||||
# if anything seen, output a makefile
|
||||
if ( $buildforlinux && ( @CPPFILES || @CXXFILES || @CFILES || @LIBFILES ) )
|
||||
{
|
||||
print STDERR "writing project $pname\n";
|
||||
$projdir=getcwd;
|
||||
$projdir=~s@/$@@;
|
||||
$dir_written{$projdir}.=",$pname.mak";
|
||||
&WriteMakefile("$projdir/$pname.mak");
|
||||
&WriteCodeBlocksProj("$projdir/$pname.cbp");
|
||||
}
|
||||
else
|
||||
{
|
||||
die "no .lib or source files found in .vpc" if ( $buildforlinux );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub WriteCodeBlocksProj
|
||||
{
|
||||
local($_)=@_;
|
||||
|
||||
open(CBPROJ,">$_") || die "can't write $_";
|
||||
|
||||
print CBPROJ <<HEADER
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="$pname" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Release">
|
||||
|
||||
</Target>
|
||||
</Build>
|
||||
HEADER
|
||||
;
|
||||
|
||||
foreach $fl (@CPPFILES)
|
||||
{
|
||||
push @cppfiles2, $fl unless ( $ignore_file{$fl} > 0 );
|
||||
}
|
||||
|
||||
foreach $fl (@CXXFILES)
|
||||
{
|
||||
push @cxxfiles2, $fl unless ( $ignore_file{$fl} > 0 );
|
||||
}
|
||||
|
||||
printf CBPROJ "\t\t<Compiler>\n";
|
||||
|
||||
foreach $_ (@DEFINES)
|
||||
{
|
||||
print CBPROJ "\t\t\t<Add option=\"-DSWDS\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-D_LINUX\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-fpermissive\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-Dstricmp=strcasecmp\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-D_stricmp=strcasecmp\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-D_strnicmp=strncasecmp\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-Dstrnicmp=strncasecmp\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-D_snprintf=snprintf\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-D_vsnprintf=vsnprintf\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-D_alloca=alloca\" />\n";
|
||||
print CBPROJ "\t\t\t<Add option=\"-Dstrcmpi=strcasecmp\" />\n";
|
||||
|
||||
print CBPROJ "\t\t\t<Add option=\"-D$_\" />\n";
|
||||
}
|
||||
|
||||
foreach $_ (@INCLUDEDIRS)
|
||||
{
|
||||
print CBPROJ "\t\t\t<Add directory=\"$_\" />\n";
|
||||
}
|
||||
|
||||
printf CBPROJ "\t\t</Compiler>\n";
|
||||
|
||||
@CPPFILES = sort(@CPPFILES);
|
||||
@CXXFILES = sort(@CXXFILES);
|
||||
@CFILES = sort(@CFILES);
|
||||
|
||||
# now, output obj dependencies
|
||||
foreach $_ (@CPPFILES, @CFILES, @CXXFILES)
|
||||
{
|
||||
unless (( $ignore_file{$_} > 0 ) || ( length($_) < 2 ) )
|
||||
{
|
||||
($filename,$dir,$suffix) = fileparse($_,qr/\.[^.]*/);
|
||||
|
||||
print CBPROJ "\t\t<Unit filename=\"".$dir . $filename. ".cpp\" />\n";
|
||||
}
|
||||
}
|
||||
|
||||
print CBPROJ <<FOOTER
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
||||
FOOTER
|
||||
;
|
||||
|
||||
close CBPROJ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub WriteMakefile
|
||||
{
|
||||
local($_)=@_;
|
||||
|
||||
open(MAKEFILE,">$_") || die "can't write $_";
|
||||
print MAKEFILE "NAME=$pname\n\n";
|
||||
print MAKEFILE "SRCROOT=$srcdir\n";
|
||||
print MAKEFILE "PROJDIR=$projdir\n";
|
||||
print MAKEFILE "CONFTYPE=$conf_type\n";
|
||||
print MAKEFILE "PROJECT_SPECIFIC_GCCFLAGS = $gccflags\n";
|
||||
|
||||
if ( int($OptimizeLevel) )
|
||||
{
|
||||
print MAKEFILE "OLEVEL=-O$OptimizeLevel\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print MAKEFILE "OLEVEL=\n";
|
||||
}
|
||||
if (@DEFINES)
|
||||
{
|
||||
print MAKEFILE "DEFINES= -D",join(" -D", @DEFINES),"\n";
|
||||
}
|
||||
if (@INCLUDEDIRS)
|
||||
{
|
||||
print MAKEFILE "INCLUDEDIRS= -I",join(" -I", @INCLUDEDIRS),"\n";
|
||||
}
|
||||
undef @cppfiles2;
|
||||
undef @cxxfiles2;
|
||||
foreach $fl (@CPPFILES)
|
||||
{
|
||||
if ( length($fl) )
|
||||
{
|
||||
print "warning file $fl does not exist\n" unless( -e $fl);
|
||||
push @cppfiles2, $fl unless ( $ignore_file{$fl} > 0 );
|
||||
}
|
||||
}
|
||||
foreach $fl (@CXXFILES)
|
||||
{
|
||||
push @cxxfiles2, $fl unless ( $ignore_file{$fl} > 0 );
|
||||
}
|
||||
|
||||
if (@cppfiles2)
|
||||
{
|
||||
print MAKEFILE "CPPFILES= \\\n ", join(" \\\n ",@cppfiles2), "\n";
|
||||
}
|
||||
if (@cxxfiles2)
|
||||
{
|
||||
print MAKEFILE "CXXFILES= \\\n ", join(" \\\n ",@cxxfiles2), "\n";
|
||||
}
|
||||
if (@CFILES)
|
||||
{
|
||||
print MAKEFILE "CFILES= \\\n ", join(" \\\n ",@CFILES), "\n";
|
||||
}
|
||||
if (@LIBFILES)
|
||||
{
|
||||
undef @LIBNAMES;
|
||||
print MAKEFILE "\nLIBFILES= \\\n";
|
||||
unless( $pname=~/(tier0)|(mathlib)|(tier1)/i)
|
||||
{
|
||||
print MAKEFILE " $srcdir/lib/linux/tier1_486.a \\\n"
|
||||
}
|
||||
foreach $lib (@LIBFILES)
|
||||
{
|
||||
my @DLLNAMES=("tier0", "vstdlib", "steam_api");
|
||||
unless ( $ignore_file{$lib} > 0 )
|
||||
{
|
||||
$lib=lc($lib);
|
||||
my ($filename,$dir,$suffix) = fileparse($lib,qr/\.[^.]*/);
|
||||
my $dll=0;
|
||||
foreach $dllname (@DLLNAMES)
|
||||
{
|
||||
$dll=1 if ( $dllname eq $filename);
|
||||
}
|
||||
if ( $dll )
|
||||
{
|
||||
$lib=~s@^(.*)\.lib@$1_i486.so@i;
|
||||
$lib=~s@/lib/.*/([^/]+)@/linux/$1@g;
|
||||
}
|
||||
else
|
||||
{
|
||||
$lib=~s/\.lib/_486.a/i;
|
||||
$lib=~s@/lib/(\S+)/@/lib/linux/@g;
|
||||
}
|
||||
push @LIBNAMES, $lib;
|
||||
}
|
||||
}
|
||||
foreach $lib (@LITERAL_LIBFILES)
|
||||
{
|
||||
unless ( $ignore_file{$lib} > 0 )
|
||||
{
|
||||
$lib=~s/\\/\//g;
|
||||
$lib=~s@/linux/([a-zA-Z_0-9\.]+)$@/linux/$1@;
|
||||
$lib=~s@^.*/linux/([a-zA-Z_0-9]+)\.so$@$1.so@;
|
||||
push @LIBNAMES, $lib;
|
||||
}
|
||||
}
|
||||
# now, sort libs for link order
|
||||
foreach $lib ( sort bypriority @LIBNAMES )
|
||||
{
|
||||
print MAKEFILE " $lib \\\n";
|
||||
}
|
||||
print MAKEFILE "\n\n";
|
||||
}
|
||||
|
||||
if ( $conf_type eq "dll" )
|
||||
{
|
||||
print MAKEFILE "OUTPUT_SO_FILE=$srcdir/linux/$pname","_i486.so\n\n";
|
||||
}
|
||||
elsif ( $conf_type eq "exe" )
|
||||
{
|
||||
if ( $macros{'OUTBINNAME'} eq "" )
|
||||
{
|
||||
die "Missing OUTBINNAME macro";
|
||||
}
|
||||
|
||||
print MAKEFILE "OUTPUT_EXECUTABLE=$srcdir/linux/$macros{'OUTBINNAME'}\n\n";
|
||||
}
|
||||
|
||||
print MAKEFILE "\n\n\# include base make file\ninclude $srcdir/devtools/makefile_base_linux.mak\n";
|
||||
|
||||
# now, output obj dependencies
|
||||
foreach $_ (@CPPFILES, @CFILES)
|
||||
{
|
||||
unless (( $ignore_file{$_} > 0 ) || ( length($_) < 2 ) )
|
||||
{
|
||||
($filename) = fileparse($_,qr/\.[^.]*/);
|
||||
print MAKEFILE getcwd,"/obj/$filename.o : $_\n\t\$(DO_CC)\n";
|
||||
}
|
||||
}
|
||||
foreach $_ (@CXXFILES)
|
||||
{
|
||||
unless (( $ignore_file{$_} > 0 ) || ( length($_) < 2 ) )
|
||||
{
|
||||
($filename) = fileparse($_,qr/\.[^.]*/);
|
||||
print MAKEFILE getcwd,"/obj/$filename.oxx : $_\n\t\$(DO_CC)\n";
|
||||
}
|
||||
}
|
||||
|
||||
close MAKEFILE;
|
||||
}
|
||||
|
||||
sub bypriority
|
||||
{
|
||||
# sort libs for gcc linkgoodness
|
||||
$priority{"mathlib"}="0005";
|
||||
$priority{"tier1"}="0010";
|
||||
$priority{"tier2"}="0020";
|
||||
$priority{"tier3"}="0030";
|
||||
|
||||
my ($filenamea) = fileparse($a,qr/\.[^.]*/);
|
||||
my ($filenameb) = fileparse($b,qr/\.[^.]*/);
|
||||
$filenamea =~ s/_.86.*$//; # lose _i486
|
||||
$filenameb =~ s/_.86.*$//;
|
||||
my $pa=$priority{$filenamea} || 1000;
|
||||
my $pb=$priority{$filenameb} || 1000;
|
||||
return $pb cmp $pa;
|
||||
}
|
||||
|
||||
sub ParseVPC
|
||||
{
|
||||
local($fname)=@_;
|
||||
&startreading($fname);
|
||||
while(&nextvpcline)
|
||||
{
|
||||
# print "$_\n";
|
||||
if ( (/^\$linux/i) )
|
||||
{
|
||||
&skipblock(0,\&handlelinuxline);
|
||||
}
|
||||
if ( (/^\$configuration/i) )
|
||||
{
|
||||
&skipblock(0,\&handleconfigline);
|
||||
}
|
||||
elsif (/^\s*\$project/i)
|
||||
{
|
||||
&parseproject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub massageline
|
||||
{
|
||||
# strip leading and trailing spaces and carriage returns and comments from vpc lines
|
||||
s/[\n\r]//g;
|
||||
s@//.*$@@g;
|
||||
s@^\s*@@g;
|
||||
s@\s*$@@g;
|
||||
}
|
||||
|
||||
sub submacros
|
||||
{
|
||||
# replace all macros within a line
|
||||
my $mac;
|
||||
foreach $mac (keys %macros)
|
||||
{
|
||||
s/\$$mac/$macros{$mac}/g;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub startreading
|
||||
{
|
||||
# initialize recursive file reader
|
||||
my( $fname)=@_;
|
||||
$curfile=IO::File->new($fname) || die "can't open $fname";
|
||||
}
|
||||
|
||||
sub nextvpcline
|
||||
{
|
||||
# get the next line from the file, handling line continuations, macro substitution, and $include
|
||||
# return 0 if out of lines
|
||||
my $ret=0;
|
||||
if ( $_ = <$curfile> )
|
||||
{
|
||||
$ret=1;
|
||||
&massageline;
|
||||
while(s@\\$@ @)
|
||||
{
|
||||
my $old=$_;
|
||||
$_=<$curfile>;
|
||||
&massageline;
|
||||
$_=$old.$_;
|
||||
}
|
||||
s@\s+@ @g;
|
||||
my $old=$_;
|
||||
&submacros;
|
||||
# now, parse
|
||||
if (/\$macro (\S+) \"(\S+)\"$/i)
|
||||
{
|
||||
$macros{$1}=$2;
|
||||
return &nextvpcline;
|
||||
}
|
||||
s/\[\$WIN32\]//g;
|
||||
return &nextvpcline if (/\[\$X360\]/);
|
||||
if ( /^\s*[\$\#]include\s+\"(.*)\"/i)
|
||||
{
|
||||
# process $include
|
||||
my $incfile=$1;
|
||||
push @filestack, $curfile;
|
||||
$incfile=~s@\\@/@g;
|
||||
if ( $curfile=IO::File->new($incfile) )
|
||||
{
|
||||
return &nextvpcline;
|
||||
}
|
||||
else
|
||||
{
|
||||
print STDERR "can't open include file $incfile, ignoring\n";
|
||||
$curfile=pop(@filestack);
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$curfile->close;
|
||||
if (@filestack)
|
||||
{
|
||||
$curfile=pop(@filestack);
|
||||
return &nextvpcline;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub skipblock
|
||||
{
|
||||
# skip a named block in the key values, handling nested {} pairs
|
||||
my($empty_ok, $callback)=@_;
|
||||
my $lnstat=&nextvpcline;
|
||||
die "parse error eof in block" if ( (! $lnstat) && ( ! $empty_ok) );
|
||||
|
||||
my $nest=0;
|
||||
if (/^\{/)
|
||||
{
|
||||
$nest++;
|
||||
}
|
||||
else
|
||||
{
|
||||
die "no start block found, $_ found instead" unless($empty_ok);
|
||||
}
|
||||
while ($nest)
|
||||
{
|
||||
die "prematur eof" unless &nextvpcline;
|
||||
&$callback($_) if ( $callback );
|
||||
$nest++ if (/^\{/);
|
||||
$nest-- if (/^\}/);
|
||||
}
|
||||
}
|
||||
|
||||
sub parseproject
|
||||
{
|
||||
# handle a project block, picking up files mentioned
|
||||
$pname="";
|
||||
if (/^\s*\$project\s*(.*)$/i)
|
||||
{
|
||||
$pname=$1;
|
||||
$pname=~s@\"@@g;
|
||||
}
|
||||
local($_);
|
||||
my $nest=0;
|
||||
&nextvpcline || die "empty project?";
|
||||
$nest++ if (/^\s*\{/);
|
||||
while($nest )
|
||||
{
|
||||
&nextvpcline || die "premature eof in project?";
|
||||
$nest++ if (/^\{/);
|
||||
$nest-- if (/^\}/);
|
||||
&CheckForFileLine($_);
|
||||
}
|
||||
}
|
||||
|
||||
sub CheckForFileLine
|
||||
{
|
||||
local($_)=@_;
|
||||
if (/^\s*\-\$File\s+(.*$)/i)
|
||||
{
|
||||
foreach $_ (split(/ /,$1))
|
||||
{
|
||||
s/\"//g;
|
||||
$ignore_file{&process_path($_)} = 1;
|
||||
}
|
||||
}
|
||||
|
||||
elsif (/^\s*\$File\s+(.*$)/i)
|
||||
{
|
||||
foreach $_ (split(/ /,$1))
|
||||
{
|
||||
s/\"//g;
|
||||
&handlefile($_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub handlefile
|
||||
{
|
||||
# given a project file (.cpp, etc), figure out what to do with it
|
||||
local($_)=@_;
|
||||
|
||||
# hardcoded exclusions for linux
|
||||
return if (/dx9sdk/i);
|
||||
return if (/_360/i);
|
||||
return if (/xbox_console.cpp/i);
|
||||
return if (/xbox_system.cpp/i);
|
||||
return if (/xbox_win32stubs.cpp/i);
|
||||
return if (/binkw32/i || /binkxenon/i );
|
||||
|
||||
if (/\.cpp$/)
|
||||
{
|
||||
push @CPPFILES,process_path($_);
|
||||
}
|
||||
if (/\.cxx$/)
|
||||
{
|
||||
push @CXXFILES,process_path($_);
|
||||
}
|
||||
elsif (/\.c$/)
|
||||
{
|
||||
push @CFILES,process_path($_);
|
||||
}
|
||||
elsif (/\.lib$/)
|
||||
{
|
||||
push @LIBFILES,process_path($_);
|
||||
}
|
||||
elsif (/\.a$/)
|
||||
{
|
||||
push @LITERAL_LIBFILES, process_path($_);
|
||||
}
|
||||
elsif (/\.so$/)
|
||||
{
|
||||
push @LITERAL_LIBFILES, process_path($_);
|
||||
}
|
||||
}
|
||||
|
||||
sub process_path
|
||||
{
|
||||
local($_)=@_;
|
||||
s@\\@/@g;
|
||||
if ( (! -e $_) && ( -e lc($_)) )
|
||||
{
|
||||
# print STDERR "$_ does not exist try lc($_)\n";
|
||||
$_=lc($_);
|
||||
}
|
||||
my $ap=abs_path($_);
|
||||
if ( (! length($ap) ) && length($_))
|
||||
{
|
||||
# print "abs path of $_ is empty. bad dir?\n";
|
||||
}
|
||||
$_=$ap;
|
||||
s@i686@i486@g;
|
||||
if ( (! -e $_) && ( -e lc($_)) )
|
||||
{
|
||||
# print STDERR "$_ does not exist try lc($_)\n";
|
||||
$_=lc($_);
|
||||
}
|
||||
# kill ..s for prettyness
|
||||
s@/[^/]+/\.\./@/@g;
|
||||
if (! -e $_)
|
||||
{
|
||||
# print STDERR "$_ does not exist\n";
|
||||
}
|
||||
return $_;
|
||||
}
|
||||
|
||||
sub handlelinuxline
|
||||
{
|
||||
local($_)=@_;
|
||||
$buildforlinux = 1 if ( /^\s*\$buildforlinux.*1/i);
|
||||
$OptimizeLevel= $1 if (/^\s*\$OptimizerLevel\s+(\d+)/i);
|
||||
$buildforlinux = 1 if ( /^\s*\$buildforlinux.*1/i);
|
||||
$gccflags = $1 if (/^\s*\$ProjectSpecificGCCFLags\s+\"(\S+)\"/i);
|
||||
&CheckForFileLine($_); # allows linux-specific file includes and excludes
|
||||
&handleconfigline($_); # allow linux-specific #defines
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub CheckPreprocessorDefs
|
||||
{
|
||||
local($_)=@_;
|
||||
if (/^\s*\$PreprocessorDefinitions\s+\"(.*)\"/i)
|
||||
{
|
||||
foreach $_ (split(/[;,]/,$1) )
|
||||
{
|
||||
unless( /\$/ || $define_seen{$_} || /fopen/i)
|
||||
{
|
||||
push(@DEFINES,$_);
|
||||
$define_seen{$_}=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sub handleconfigline
|
||||
{
|
||||
# handle a line within a $Configuration block
|
||||
local($_)=@_; # the line
|
||||
if (/^\s*\$AdditionalIncludeDirectories\s+\"(.*)\"/i)
|
||||
{
|
||||
foreach $_ (split(/[;,]/,$1) )
|
||||
{
|
||||
unless( /\$/ || $include_seen{$_} )
|
||||
{
|
||||
push(@INCLUDEDIRS,process_path($_));
|
||||
$include_seen{$_}=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (/^\s*\$ConfigurationType\s*\"(.*)\"/)
|
||||
{
|
||||
undef $conf_type;
|
||||
$conf_type="lib" if ($1 =~ /Static Library/i);
|
||||
$conf_type="dll" if ($1 =~ /Dynamic Library/i);
|
||||
$conf_type="exe" if ($1 =~ /Application/i);
|
||||
print STDERR " unknown conf type $1\n" if (! length($conf_type) );
|
||||
|
||||
}
|
||||
|
||||
&CheckPreprocessorDefs($_);
|
||||
}
|
1106
devtools/bin/vsh_prep.pl
Normal file
1106
devtools/bin/vsh_prep.pl
Normal file
File diff suppressed because it is too large
Load Diff
BIN
devtools/bin/vstdlib.dll
Normal file
BIN
devtools/bin/vstdlib.dll
Normal file
Binary file not shown.
44
devtools/gendbg.sh
Normal file
44
devtools/gendbg.sh
Normal file
@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
|
||||
OBJCOPY=objcopy
|
||||
|
||||
function usage {
|
||||
echo "$0 /path/to/input/file [-o /path/to/output/file ]"
|
||||
echo ""
|
||||
}
|
||||
|
||||
if [ $# == 0 ]; then
|
||||
usage
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [ $(basename $1) == $1 ]; then
|
||||
INFILEDIR=$PWD
|
||||
else
|
||||
INFILEDIR=$(cd ${1%/*} && echo $PWD)
|
||||
fi
|
||||
INFILE=$(basename $1)
|
||||
|
||||
OUTFILEDIR=$INFILEDIR
|
||||
OUTFILE=$INFILE.dbg
|
||||
|
||||
while getopts "o:" opt; do
|
||||
case $opt in
|
||||
o)
|
||||
OUTFILEDIR=$(cd ${OPTARG%/*} && echo $PWD)
|
||||
OUTFILE=$(basename $OPTARG)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$OUTFILEDIR" != "$INFILEDIR" ]; then
|
||||
INFILE=${INFILEDIR}/${INFILE}
|
||||
OUTFILE=${OUTFILEDIR}/${OUTFILE}
|
||||
fi
|
||||
|
||||
pushd "$INFILEDIR"
|
||||
$OBJCOPY "$INFILE" "$OUTFILE"
|
||||
$OBJCOPY --add-gnu-debuglink="$OUTFILE" "$INFILE"
|
||||
popd
|
||||
|
||||
|
869
devtools/makefile_base_posix.mak
Normal file
869
devtools/makefile_base_posix.mak
Normal file
@ -0,0 +1,869 @@
|
||||
#
|
||||
# Base makefile for Linux and OSX
|
||||
#
|
||||
# !!!!! Note to future editors !!!!!
|
||||
#
|
||||
# before you make changes, make sure you grok:
|
||||
# 1. the difference between =, :=, +=, and ?=
|
||||
# 2. how and when this base makefile gets included in the generated makefile(s)
|
||||
# ( see http://www.gnu.org/software/make/manual/make.html#Flavors )
|
||||
#
|
||||
# Command line prefixes:
|
||||
# - errors are ignored
|
||||
# @ command is not printed to stdout before being executed
|
||||
# + command is executed even if Make is invoked in "do not exec" mode
|
||||
|
||||
OS := $(shell uname)
|
||||
HOSTNAME := $(shell hostname)
|
||||
|
||||
IDENTIFY_CURRENT_MAKEFILE_RELATIVE_FUNCTION = $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
|
||||
MAKEFILE_BASE_POSIX_MAK := $(call IDENTIFY_CURRENT_MAKEFILE_RELATIVE_FUNCTION)
|
||||
CROSS_COMPILE_DIR := $(realpath $(dir $(MAKEFILE_BASE_POSIX_MAK))../../cross_compile)
|
||||
|
||||
ifeq ($(MAKE_VERBOSE),1)
|
||||
QUIET_PREFIX =
|
||||
QUIET_ECHO_POSTFIX =
|
||||
else
|
||||
QUIET_PREFIX = @
|
||||
QUIET_ECHO_POSTFIX = > /dev/null
|
||||
|
||||
# Use abbreviated progress messages in the schema compiler.
|
||||
VALVE_SCHEMA_QUIET = 1
|
||||
export VALVE_SCHEMA_QUIET
|
||||
endif
|
||||
|
||||
BASENAME := basename
|
||||
CAT := cat
|
||||
CP := cp
|
||||
CUT := cut
|
||||
DIRNAME := dirname
|
||||
ECHO := echo
|
||||
ETAGS := etags
|
||||
EXPR := expr
|
||||
FALSE := false
|
||||
FGREP := fgrep
|
||||
FIND := find
|
||||
GREP := grep
|
||||
ICONV := iconv
|
||||
MKDIR := mkdir
|
||||
PWD := PWD
|
||||
PWD_TOOL := pwd
|
||||
RM := rm
|
||||
SED := sed
|
||||
SLEEP := sleep
|
||||
TAIL := tail
|
||||
TOUCH := touch
|
||||
TR := tr
|
||||
TRUE := true
|
||||
UNAME := uname
|
||||
WHICH := which
|
||||
|
||||
ECHO_LF = $(ECHO) -e
|
||||
|
||||
BUILD_DEBUG_ECHO = $(TRUE)
|
||||
#uncomment or define ENABLE_BUILD_DEBUG=1 on the make commandline to debug build phases and dependency updates
|
||||
# ENABLE_BUILD_DEBUG = 1
|
||||
ifneq "$(ENABLE_BUILD_DEBUG)" ""
|
||||
BUILD_DEBUG_ECHO = $(ECHO)
|
||||
endif
|
||||
|
||||
# SPEW_UPDATED_DEPENDENCIES spews the list of dependencies whose current timestamps invalidate this rule.
|
||||
# This is only done when ENABLE_BUILD_DEBUG is 1
|
||||
ifeq ("$(ENABLE_BUILD_DEBUG)","1")
|
||||
SPEW_DEPENDENCY_CHUNK = \
|
||||
SpewDependencyChunk () \
|
||||
{ \
|
||||
$(BUILD_DEBUG_ECHO) " $${1}"; \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
SPEW_UPDATED_DEPENDENCIES = \
|
||||
$(QUIET_PREFIX) \
|
||||
{ \
|
||||
$(BUILD_DEBUG_ECHO) "[SPEW_UPDATED_DEPENDENCIES] rule \"$@\" triggered by files:" && \
|
||||
$(BUILD_DEBUG_ECHO) " $?"; \
|
||||
}
|
||||
else
|
||||
SPEW_UPDATED_DEPENDENCIES = $(QUIET_PREFIX) $(TRUE)
|
||||
endif
|
||||
|
||||
-include $(SRCROOT)/devtools/steam_def.mak
|
||||
|
||||
# To build with clang, set the following in your environment:
|
||||
# CC = clang
|
||||
# CXX = clang++
|
||||
|
||||
ifeq ($(CFG), release)
|
||||
# With gcc 4.6.3, engine.so went from 7,383,765 to 8,429,109 when building with -O3.
|
||||
# There also was no speed difference running at 1280x1024. May 2012, mikesart.
|
||||
# -fno-omit-frame-pointer: need this for stack traces with perf.
|
||||
OptimizerLevel_CompilerSpecific = -O2 -fno-strict-aliasing -ffast-math -fno-omit-frame-pointer
|
||||
else
|
||||
OptimizerLevel_CompilerSpecific = -O0
|
||||
#-O1 -finline-functions
|
||||
endif
|
||||
|
||||
# CPPFLAGS == "c/c++ *preprocessor* flags" - not "cee-plus-plus flags"
|
||||
ARCH_FLAGS =
|
||||
BUILDING_MULTI_ARCH = 0
|
||||
CPPFLAGS = $(DEFINES) $(FORCEINCLUDES) $(addprefix -I, $(abspath $(INCLUDEDIRS) ))
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),linux64)
|
||||
CPPFLAGS += -fPIC
|
||||
endif
|
||||
|
||||
|
||||
CFLAGS = $(ARCH_FLAGS) $(CPPFLAGS) $(WARN_FLAGS) -fvisibility=$(SymbolVisibility) $(OptimizerLevel) -ffast-math -pipe $(GCC_ExtraCompilerFlags) -Usprintf -Ustrncpy -UPROTECTED_THINGS_ENABLE
|
||||
# In -std=gnu++11 mode we get lots of errors about "error: narrowing conversion". -fpermissive
|
||||
# turns these into warnings in gcc, and -Wno-c++11-narrowing suppresses them entirely in clang 3.1+.
|
||||
|
||||
ifeq ($(OS),Linux)
|
||||
CXXFLAGS = $(CFLAGS) -std=gnu++0x -fpermissive
|
||||
else
|
||||
CXXFLAGS = $(CFLAGS) -std=gnu++11 -stdlib=libc++ -Wno-c++11-narrowing -Wno-dangling-else
|
||||
endif
|
||||
|
||||
DEFINES += -DVPROF_LEVEL=1 -DGNUC
|
||||
# This causes all filesystem interfaces to default to their 64bit versions on
|
||||
# 32bit systems, which means we don't break on filesystems with inodes > 32bit.
|
||||
DEFINES += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
LDFLAGS = $(CFLAGS) $(GCC_ExtraLinkerFlags) $(OptimizerLevel)
|
||||
GENDEP_CXXFLAGS = -MD -MP -MF $(@:.o=.P)
|
||||
MAP_FLAGS =
|
||||
|
||||
ifeq ($(STEAM_BRANCH),1)
|
||||
WARN_FLAGS = -Wall -Wextra -Wshadow -Wno-invalid-offsetof
|
||||
else
|
||||
WARN_FLAGS = -Wno-write-strings -Wno-multichar
|
||||
endif
|
||||
|
||||
WARN_FLAGS += -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers -Wno-sign-compare -Wno-reorder -Wno-invalid-offsetof -Wno-float-equal -Wno-switch -fdiagnostics-show-option -Wformat -Werror=format-security -Wstrict-aliasing=2
|
||||
|
||||
|
||||
ifeq ($(OS),Linux)
|
||||
# We should always specify -Wl,--build-id, as documented at:
|
||||
# http://linux.die.net/man/1/ld and http://fedoraproject.org/wiki/Releases/FeatureBuildId.http://fedoraproject.org/wiki/Releases/FeatureBuildId
|
||||
LDFLAGS += -Wl,--build-id
|
||||
|
||||
UUID_LIB =
|
||||
|
||||
# Set USE_STEAM_RUNTIME to build with the Steam Runtime. Otherwise uses
|
||||
# The toolchain in /valve
|
||||
ifneq ($(USE_STEAM_RUNTIME),1)
|
||||
# dedicated server flags
|
||||
ifeq ($(TARGET_PLATFORM),linux64)
|
||||
VALVE_BINDIR = /valve/bin64/
|
||||
MARCH_TARGET = nocona
|
||||
else
|
||||
VALVE_BINDIR = /valve/bin/
|
||||
MARCH_TARGET = pentium4
|
||||
endif
|
||||
STRIP_FLAGS = -x
|
||||
LIBCPP_EXT = a
|
||||
|
||||
else
|
||||
# linux desktop client flags
|
||||
VALVE_BINDIR =
|
||||
DEFINES +=
|
||||
# If the steam-runtime is available, use it. We should just default to using it when
|
||||
# buildbot and everyone has a bit of time to get it installed.
|
||||
ifneq "$(wildcard /valve/steam-runtime/bin/)" ""
|
||||
# The steam-runtime is incompatible with clang at this point, so disable it
|
||||
# if clang is enabled.
|
||||
ifneq ($(CXX),clang++)
|
||||
VALVE_BINDIR = /valve/steam-runtime/bin/
|
||||
endif
|
||||
endif
|
||||
GCC_VER =
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),linux64)
|
||||
MARCH_TARGET = nocona
|
||||
else
|
||||
MARCH_TARGET = pentium4
|
||||
endif
|
||||
# On dedicated servers, some plugins depend on global variable symbols in addition to functions.
|
||||
# So symbols like _Z16ClearMultiDamagev should show up when you do "nm server_srv.so" in TF2.
|
||||
STRIP_FLAGS = -x
|
||||
|
||||
LIBCPP_EXT = so
|
||||
|
||||
UUID_LIB = -luuid
|
||||
endif
|
||||
|
||||
# We want to make all TLS use the global-dynamic
|
||||
# model, to avoid having to use -fpic but avoid problems with dlopen()
|
||||
# failing due to TLS clashes. This happens in particular when trying
|
||||
# to run the game with primus. Note that -ftls-model=global-dynamic
|
||||
# doesn't work due to undocumented 'features' in gcc that only allow
|
||||
# the TLS model to be 'downgraded' from the default and not upgraded.
|
||||
CFLAGS += -D__thread='__thread __attribute__((tls_model("global-dynamic")))'
|
||||
CXXFLAGS += -D__thread='__thread __attribute__((tls_model("global-dynamic")))'
|
||||
|
||||
ifeq ($(CXX),clang++)
|
||||
# Clang does not support -mfpmath=sse
|
||||
SSE_GEN_FLAGS = -msse2
|
||||
else
|
||||
SSE_GEN_FLAGS = -msse2 -mfpmath=sse
|
||||
endif
|
||||
|
||||
# Turn this on when ready to fix errors that crop up (can merge fixes from console eventually).
|
||||
#WARN_FLAGS += -Werror=return-type
|
||||
ifeq ($(CXX),clang++)
|
||||
# The C-linkage return-type warning (no returning of references) must be disabled after the
|
||||
# return-type error is enabled.
|
||||
WARN_FLAGS += -Wno-return-type-c-linkage
|
||||
# -g0 must be specified because -g2 makes server.so.dbg so huge that the linker sometimes
|
||||
# fails due to memory exhaustion.
|
||||
CFLAGS += -g0
|
||||
endif
|
||||
CCACHE := $(SRCROOT)/devtools/bin/linux/ccache
|
||||
|
||||
ifeq ($(origin GCC_VER), undefined)
|
||||
GCC_VER=-4.6
|
||||
endif
|
||||
ifeq ($(origin AR), default)
|
||||
AR = $(VALVE_BINDIR)ar crs
|
||||
endif
|
||||
ifeq ($(origin CC),default)
|
||||
CC = $(CCACHE) $(VALVE_BINDIR)gcc$(GCC_VER)
|
||||
endif
|
||||
ifeq ($(origin CXX), default)
|
||||
CXX = $(CCACHE) $(VALVE_BINDIR)g++$(GCC_VER)
|
||||
endif
|
||||
# Support ccache with clang. Add -Qunused-arguments to avoid excessive warnings due to
|
||||
# a ccache quirk. Could also upgrade ccache.
|
||||
# http://petereisentraut.blogspot.com/2011/05/ccache-and-clang.html
|
||||
ifeq ($(CC),clang)
|
||||
CC = $(CCACHE) $(VALVE_BINDIR)clang -Qunused-arguments
|
||||
endif
|
||||
ifeq ($(CXX),clang++)
|
||||
CXX = $(CCACHE) $(VALVE_BINDIR)clang++ -Qunused-arguments
|
||||
endif
|
||||
LINK ?= $(CC)
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),linux64)
|
||||
# nocona = pentium4 + 64bit + MMX, SSE, SSE2, SSE3 - no SSSE3 (that's three s's - added in core2)
|
||||
ARCH_FLAGS += -march=$(MARCH_TARGET) -mtune=core2
|
||||
LD_SO = ld-linux-x86-64.so.2
|
||||
LIBSTDCXX := $(shell $(CXX) -print-file-name=libstdc++.$(LIBCPP_EXT))
|
||||
LIBSTDCXXPIC := $(shell $(CXX) -print-file-name=libstdc++.$(LIBCPP_EXT))
|
||||
else
|
||||
|
||||
# core2 = Intel Core2 CPU with 64-bit extensions, MMX, SSE, SSE2, SSE3 and SSSE3 instruction set support.
|
||||
# changed for DOTA since we are running servers on newer hardware
|
||||
ifeq ($(TARGET_PLATFORM_EXT),_client)
|
||||
# on non-server Linux client builds let's be a little more conservative
|
||||
ARCH_FLAGS += -m32 -march=prescott -mtune=core2 $(SSE_GEN_FLAGS)
|
||||
else
|
||||
ARCH_FLAGS += -m32 -march=core2 -mtune=core2 $(SSE_GEN_FLAGS)
|
||||
endif
|
||||
LD_SO = ld-linux.so.2
|
||||
LIBSTDCXX := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.$(LIBCPP_EXT))
|
||||
LIBSTDCXXPIC := $(shell $(CXX) $(ARCH_FLAGS) -print-file-name=libstdc++.$(LIBCPP_EXT))
|
||||
LDFLAGS += -m32
|
||||
endif
|
||||
|
||||
GEN_SYM ?= $(SRCROOT)/devtools/gendbg.sh
|
||||
ifeq ($(CFG),release)
|
||||
STRIP ?= strip $(STRIP_FLAGS) -S
|
||||
# CFLAGS += -ffunction-sections -fdata-sections
|
||||
# LDFLAGS += -Wl,--gc-sections -Wl,--print-gc-sections
|
||||
else
|
||||
STRIP ?= true
|
||||
endif
|
||||
VSIGN ?= true
|
||||
|
||||
LINK_MAP_FLAGS = -Wl,-Map,$(@:.so=).map
|
||||
|
||||
SHLIBLDFLAGS = -shared $(LDFLAGS) -Wl,--no-undefined
|
||||
_WRAP := -Xlinker --wrap=
|
||||
PATHWRAP = $(_WRAP)fopen $(_WRAP)freopen $(_WRAP)open $(_WRAP)creat $(_WRAP)access $(_WRAP)__xstat \
|
||||
$(_WRAP)stat $(_WRAP)lstat $(_WRAP)fopen64 $(_WRAP)open64 $(_WRAP)opendir $(_WRAP)__lxstat \
|
||||
$(_WRAP)chmod $(_WRAP)chown $(_WRAP)lchown $(_WRAP)symlink $(_WRAP)link $(_WRAP)__lxstat64 \
|
||||
$(_WRAP)mknod $(_WRAP)utimes $(_WRAP)unlink $(_WRAP)rename $(_WRAP)utime $(_WRAP)__xstat64 \
|
||||
$(_WRAP)mount $(_WRAP)mkfifo $(_WRAP)mkdir $(_WRAP)rmdir $(_WRAP)scandir $(_WRAP)realpath
|
||||
|
||||
|
||||
LIB_START_EXE = $(PATHWRAP) -static-libgcc -Wl,--start-group
|
||||
LIB_END_EXE = -Wl,--end-group -lm -ldl $(LIBSTDCXX) -lpthread $(UUID_LIB)
|
||||
|
||||
LIB_START_SHLIB = $(PATHWRAP) -static-libgcc -Wl,--start-group
|
||||
LIB_END_SHLIB = -Wl,--end-group -lm -ldl $(LIBSTDCXXPIC) -lpthread $(UUID_LIB) -l:$(LD_SO) -Wl,--version-script=$(SRCROOT)/devtools/version_script.linux.txt
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(OS),Darwin)
|
||||
LDFLAGS += -stdlib=libc++
|
||||
|
||||
OSXVER := $(shell sw_vers -productVersion)
|
||||
CCACHE := $(SRCROOT)/devtools/bin/osx32/ccache
|
||||
DEVELOPER_DIR := $(shell /usr/bin/xcode-select -print-path)
|
||||
XCODEVER := $(shell /usr/bin/xcode-select -version)
|
||||
|
||||
|
||||
USE_DEV_USR_BIN := 0
|
||||
ifeq (,$(findstring 10.7, $(OSXVER)))
|
||||
USE_DEV_USR_BIN := 1
|
||||
endif
|
||||
ifeq (/Developer, $(DEVELOPER_DIR))
|
||||
USE_DEV_USR_BIN := 1
|
||||
endif
|
||||
|
||||
ifeq (1,$(USE_DEV_USR_BIN))
|
||||
COMPILER_BIN_DIR := $(DEVELOPER_DIR)/usr/bin
|
||||
SDK_DIR := $(DEVELOPER_DIR)/SDKs
|
||||
else
|
||||
COMPILER_BIN_DIR := $(DEVELOPER_DIR)/Toolchains/XcodeDefault.xctoolchain/usr/bin
|
||||
SDK_DIR := $(DEVELOPER_DIR)/Platforms/MacOSX.platform/Developer/SDKs
|
||||
endif
|
||||
|
||||
SDKROOT ?= $(SDK_DIR)/MacOSX10.9.sdk
|
||||
|
||||
|
||||
#test to see if you have a compiler in the right place, if you don't abort with an error
|
||||
|
||||
ifeq ($(wildcard $(COMPILER_BIN_DIR)/clang),)
|
||||
$(error Unable to find compiler, install and configure XCode)
|
||||
endif
|
||||
|
||||
ifeq ($(wildcard $(COMPILER_BIN_DIR)/clang++),)
|
||||
$(error Unable to find compiler, install and configure XCode)
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(origin AR), default)
|
||||
AR = libtool -static -o
|
||||
endif
|
||||
ifeq ($(origin CC), default)
|
||||
CC = $(CCACHE) $(COMPILER_BIN_DIR)/clang -Qunused-arguments -Wno-c++11-narrowing -Wno-dangling-else
|
||||
endif
|
||||
ifeq ($(origin CXX), default)
|
||||
CXX = $(CCACHE) $(COMPILER_BIN_DIR)/clang++ -Qunused-arguments -Wno-c++11-narrowing -Wno-dangling-else
|
||||
endif
|
||||
LINK ?= $(CXX)
|
||||
|
||||
ifeq ($(TARGET_PLATFORM),osx64)
|
||||
ARCH_FLAGS += -arch x86_64 -m64 -march=core2
|
||||
else ifeq (,$(findstring -arch x86_64,$(GCC_ExtraCompilerFlags)))
|
||||
ARCH_FLAGS += -arch i386 -m32 -march=prescott -momit-leaf-frame-pointer -mtune=core2
|
||||
else
|
||||
# dirty hack to build a universal binary - don't specify the architecture
|
||||
ARCH_FLAGS += -arch i386 -Xarch_i386 -march=prescott -Xarch_i386 -mtune=core2 -Xarch_i386 -momit-leaf-frame-pointer -Xarch_x86_64 -march=core2
|
||||
endif
|
||||
|
||||
#FIXME: NOTE:Full path specified because the xcode 4.0 preview has a terribly broken dsymutil, so ref the 3.2 one
|
||||
GEN_SYM ?= /usr/bin/dsymutil
|
||||
ifeq ($(CFG),release)
|
||||
STRIP ?= strip -x -S
|
||||
else
|
||||
STRIP ?= true
|
||||
endif
|
||||
VSIGN ?= true
|
||||
|
||||
CPPFLAGS += -I$(SDKROOT)/usr/include/malloc -ftemplate-depth=1024
|
||||
CFLAGS += -isysroot $(SDKROOT) -mmacosx-version-min=10.7 -fasm-blocks -fno-color-diagnostics
|
||||
WARN_FLAGS += -Wno-parentheses -Wno-constant-logical-operand -Wno-deprecated
|
||||
|
||||
LIB_START_EXE = -lm -ldl -lpthread
|
||||
LIB_END_EXE =
|
||||
|
||||
LIB_START_SHLIB =
|
||||
LIB_END_SHLIB =
|
||||
|
||||
SHLIBLDFLAGS = $(LDFLAGS) -bundle -flat_namespace -undefined suppress -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms
|
||||
|
||||
ifeq (lib,$(findstring lib,$(GAMEOUTPUTFILE)))
|
||||
SHLIBLDFLAGS = $(LDFLAGS) -dynamiclib -current_version 1.0 -compatibility_version 1.0 -install_name @rpath/$(basename $(notdir $(GAMEOUTPUTFILE))).dylib $(SystemLibraries) -Wl,-dead_strip -Wl,-no_dead_strip_inits_and_terms
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
#
|
||||
# Profile-directed optimizations.
|
||||
# Note: Last time these were tested 3/5/08, it actually slowed down the server benchmark by 5%!
|
||||
#
|
||||
# First, uncomment these, build, and test. It will generate .gcda and .gcno files where the .o files are.
|
||||
# PROFILE_LINKER_FLAG=-fprofile-arcs
|
||||
# PROFILE_COMPILER_FLAG=-fprofile-arcs
|
||||
#
|
||||
# Then, comment the above flags out again and rebuild with this flag uncommented:
|
||||
# PROFILE_COMPILER_FLAG=-fprofile-use
|
||||
#
|
||||
|
||||
#############################################################################
|
||||
# The compiler command lne for each src code file to compile
|
||||
#############################################################################
|
||||
|
||||
OBJ_DIR = ./obj_$(NAME)_$(TARGET_PLATFORM)$(TARGET_PLATFORM_EXT)/$(CFG)
|
||||
CPP_TO_OBJ = $(CPPFILES:.cpp=.o)
|
||||
CXX_TO_OBJ = $(CPP_TO_OBJ:.cxx=.o)
|
||||
CC_TO_OBJ = $(CXX_TO_OBJ:.cc=.o)
|
||||
MM_TO_OBJ = $(CC_TO_OBJ:.mm=.o)
|
||||
C_TO_OBJ = $(MM_TO_OBJ:.c=.o)
|
||||
OBJS = $(addprefix $(OBJ_DIR)/, $(notdir $(C_TO_OBJ)))
|
||||
|
||||
export OBJ_DIR
|
||||
|
||||
ifeq ($(MAKE_VERBOSE),1)
|
||||
QUIET_PREFIX =
|
||||
QUIET_ECHO_POSTFIX =
|
||||
else
|
||||
QUIET_PREFIX = @
|
||||
QUIET_ECHO_POSTFIX = > /dev/null
|
||||
endif
|
||||
|
||||
ifeq ($(MAKE_CC_VERBOSE),1)
|
||||
CC += -v
|
||||
endif
|
||||
|
||||
ifeq ($(CONFTYPE),lib)
|
||||
LIB_File = $(OUTPUTFILE)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFTYPE),dll)
|
||||
SO_File = $(OUTPUTFILE)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFTYPE),exe)
|
||||
EXE_File = $(OUTPUTFILE)
|
||||
endif
|
||||
|
||||
# we generate dependencies as a side-effect of compilation now
|
||||
GEN_DEP_FILE=
|
||||
|
||||
PRE_COMPILE_FILE =
|
||||
|
||||
POST_COMPILE_FILE =
|
||||
|
||||
ifeq ($(BUILDING_MULTI_ARCH),1)
|
||||
SINGLE_ARCH_CXXFLAGS=$(subst -arch x86_64,,$(CXXFLAGS))
|
||||
COMPILE_FILE = \
|
||||
$(QUIET_PREFIX) \
|
||||
echo "---- $(lastword $(subst /, ,$<)) as MULTIARCH----";\
|
||||
mkdir -p $(OBJ_DIR) && \
|
||||
$(CXX) $(SINGLE_ARCH_CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $< && \
|
||||
$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||
else
|
||||
COMPILE_FILE = \
|
||||
$(QUIET_PREFIX) \
|
||||
echo "---- $(lastword $(subst /, ,$<)) ----";\
|
||||
mkdir -p $(OBJ_DIR) && \
|
||||
$(CXX) $(CXXFLAGS) $(GENDEP_CXXFLAGS) -o $@ -c $<
|
||||
endif
|
||||
|
||||
ifneq "$(origin VALVE_NO_AUTO_P4)" "undefined"
|
||||
P4_EDIT_START = chmod -R +w
|
||||
P4_EDIT_END = || true
|
||||
P4_REVERT_START = true
|
||||
P4_REVERT_END =
|
||||
else
|
||||
ifndef P4_EDIT_CHANGELIST
|
||||
# You can use an environment variable to specify what changelist to check the Linux Binaries out into. Normally the default
|
||||
# setting is best, but here is an alternate example:
|
||||
# export P4_EDIT_CHANGELIST_CMD="echo 1424335"
|
||||
# ?= means that if P4_EDIT_CHANGELIST_CMD is already set it won't be changed.
|
||||
P4_EDIT_CHANGELIST_CMD ?= p4 changes -c `p4 client -o | grep ^Client | cut -f 2` -s pending | fgrep 'POSIX Auto Checkout' | cut -d' ' -f 2 | tail -n 1
|
||||
P4_EDIT_CHANGELIST := $(shell $(P4_EDIT_CHANGELIST_CMD))
|
||||
endif
|
||||
ifeq ($(P4_EDIT_CHANGELIST),)
|
||||
# If we haven't found a changelist to check out to then create one. The name must match the one from a few
|
||||
# lines above or else a new changelist will be created each time.
|
||||
# Warning: the behavior of 'echo' is not consistent. In bash you need the "-e" option in order for \n to be
|
||||
# interpreted as a line-feed, but in dash you do not, and if "-e" is passed along then it is printed, which
|
||||
# confuses p4. So, if you run this command from the bash shell don't forget to add "-e" to the echo command.
|
||||
P4_EDIT_CHANGELIST = $(shell echo "Change: new\nDescription: POSIX Auto Checkout" | p4 change -i | cut -f 2 -d ' ')
|
||||
endif
|
||||
|
||||
P4_EDIT_START := for f in
|
||||
P4_EDIT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - edit -c $(P4_EDIT_CHANGELIST); else p4 edit -c $(P4_EDIT_CHANGELIST) $$f; fi; fi; done $(QUIET_ECHO_POSTFIX)
|
||||
P4_REVERT_START := for f in
|
||||
P4_REVERT_END := ; do if [ -n $$f ]; then if [ -d $$f ]; then find $$f -type f -print | p4 -x - revert; else p4 revert $$f; fi; fi; done $(QUIET_ECHO_POSTFIX)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFTYPE),dll)
|
||||
all: $(OTHER_DEPENDENCIES) $(OBJS) $(GAMEOUTPUTFILE)
|
||||
@echo $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX)
|
||||
else
|
||||
all: $(OTHER_DEPENDENCIES) $(OBJS) $(OUTPUTFILE)
|
||||
@echo $(OUTPUTFILE) $(QUIET_ECHO_POSTFIX)
|
||||
endif
|
||||
|
||||
.PHONY: clean cleantargets cleanandremove rebuild relink RemoveOutputFile SingleFile
|
||||
|
||||
|
||||
rebuild :
|
||||
$(MAKE) -f $(firstword $(MAKEFILE_LIST)) cleanandremove
|
||||
$(MAKE) -f $(firstword $(MAKEFILE_LIST))
|
||||
|
||||
|
||||
# Use the relink target to force to relink the project.
|
||||
relink: RemoveOutputFile all
|
||||
|
||||
RemoveOutputFile:
|
||||
rm -f $(OUTPUTFILE)
|
||||
|
||||
|
||||
# This rule is so you can say "make SingleFile SingleFilename=/home/myname/valve_main/src/engine/language.cpp" and have it only build that file.
|
||||
# It basically just translates the full filename to create a dependency on the appropriate .o file so it'll build that.
|
||||
SingleFile : RemoveSingleFile $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o
|
||||
@echo ""
|
||||
|
||||
RemoveSingleFile:
|
||||
$(QUIET_PREFIX) rm -f $(OBJ_DIR)/$(basename $(notdir $(SingleFilename))).o
|
||||
|
||||
clean:
|
||||
ifneq "$(OBJ_DIR)" ""
|
||||
$(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)"
|
||||
$(QUIET_PREFIX) rm -rf $(OBJ_DIR)
|
||||
endif
|
||||
ifneq "$(OUTPUTFILE)" ""
|
||||
$(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \
|
||||
echo "p4 revert $(OUTPUTFILE)"; \
|
||||
$(P4_REVERT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END); \
|
||||
fi;
|
||||
endif
|
||||
ifneq "$(OTHER_DEPENDENCIES)" ""
|
||||
$(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)"
|
||||
ifneq "$(GAMEOUTPUTFILE)" ""
|
||||
endif
|
||||
$(QUIET_PREFIX) rm -f $(OTHER_DEPENDENCIES)
|
||||
endif
|
||||
ifneq "$(GAMEOUTPUTFILE)" ""
|
||||
$(QUIET_PREFIX) echo "p4 revert $(GAMEOUTPUTFILE)"
|
||||
$(QUIET_PREFIX) $(P4_REVERT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_REVERT_END)
|
||||
endif
|
||||
|
||||
|
||||
# Do the above cleaning, except with p4 edit and rm. Reason being ar crs adds and replaces obj files to the
|
||||
# archive. However if you've renamed or deleted a source file, $(AR) won't remove it. This can leave
|
||||
# us with archive files that have extra unused symbols, and also potentially cause compilation errors
|
||||
# when you rename a file and have many duplicate symbols.
|
||||
cleanandremove:
|
||||
ifneq "$(OBJ_DIR)" ""
|
||||
$(QUIET_PREFIX) echo "rm -rf $(OBJ_DIR)"
|
||||
$(QUIET_PREFIX) -rm -rf $(OBJ_DIR)
|
||||
endif
|
||||
ifneq "$(OUTPUTFILE)" ""
|
||||
$(QUIET_PREFIX) if [ -e $(OUTPUTFILE) ]; then \
|
||||
echo "p4 edit and rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT)"; \
|
||||
$(P4_EDIT_START) $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END); \
|
||||
fi;
|
||||
$(QUIET_PREFIX) -rm -f $(OUTPUTFILE) $(OUTPUTFILE)$(SYM_EXT);
|
||||
endif
|
||||
ifneq "$(OTHER_DEPENDENCIES)" ""
|
||||
$(QUIET_PREFIX) echo "rm -f $(OTHER_DEPENDENCIES)"
|
||||
$(QUIET_PREFIX) -rm -f $(OTHER_DEPENDENCIES)
|
||||
endif
|
||||
ifneq "$(GAMEOUTPUTFILE)" ""
|
||||
$(QUIET_PREFIX) echo "p4 edit and rm -f $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT)"
|
||||
$(QUIET_PREFIX) $(P4_EDIT_START) $(GAMEOUTPUTFILE) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END)
|
||||
$(QUIET_PREFIX) -rm -f $(GAMEOUTPUTFILE)
|
||||
endif
|
||||
|
||||
|
||||
# This just deletes the final targets so it'll do a relink next time we build.
|
||||
cleantargets:
|
||||
$(QUIET_PREFIX) rm -f $(OUTPUTFILE) $(GAMEOUTPUTFILE)
|
||||
|
||||
|
||||
$(LIB_File): $(OTHER_DEPENDENCIES) $(OBJS)
|
||||
$(QUIET_PREFIX) -$(P4_EDIT_START) $(LIB_File) $(P4_EDIT_END);
|
||||
$(QUIET_PREFIX) $(AR) $(LIB_File) $(OBJS) $(LIBFILES);
|
||||
|
||||
SO_GameOutputFile = $(GAMEOUTPUTFILE)
|
||||
|
||||
$(SO_GameOutputFile): $(SO_File)
|
||||
$(QUIET_PREFIX) \
|
||||
$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END) && \
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);\
|
||||
echo "---- COPYING TO $@ [$(CFG)] ----";\
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);
|
||||
$(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE) $(P4_EDIT_END);
|
||||
$(QUIET_PREFIX) -mkdir -p `dirname $(GAMEOUTPUTFILE)` > /dev/null;
|
||||
$(QUIET_PREFIX) cp -v $(OUTPUTFILE) $(GAMEOUTPUTFILE) $(QUIET_ECHO_POSTFIX);
|
||||
$(QUIET_PREFIX) -$(P4_EDIT_START) $(GAMEOUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END);
|
||||
$(QUIET_PREFIX) $(GEN_SYM) $(GAMEOUTPUTFILE);
|
||||
$(QUIET_PREFIX) -$(STRIP) $(GAMEOUTPUTFILE);
|
||||
$(QUIET_PREFIX) $(VSIGN) -signvalve $(GAMEOUTPUTFILE);
|
||||
$(QUIET_PREFIX) if [ "$(IMPORTLIBRARY)" != "" ]; then\
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);\
|
||||
echo "---- COPYING TO IMPORT LIBRARY $(IMPORTLIBRARY) ----";\
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);\
|
||||
$(P4_EDIT_START) $(IMPORTLIBRARY) $(P4_EDIT_END) && \
|
||||
mkdir -p `dirname $(IMPORTLIBRARY)` > /dev/null && \
|
||||
cp -v $(OUTPUTFILE) $(IMPORTLIBRARY); \
|
||||
fi;
|
||||
|
||||
|
||||
$(SO_File): $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES)
|
||||
$(QUIET_PREFIX) \
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);\
|
||||
echo "---- LINKING $@ [$(CFG)] ----";\
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);\
|
||||
\
|
||||
$(LINK) $(LINK_MAP_FLAGS) $(SHLIBLDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_SHLIB) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_SHLIB);
|
||||
$(VSIGN) -signvalve $(OUTPUTFILE);
|
||||
|
||||
|
||||
$(EXE_File) : $(OTHER_DEPENDENCIES) $(OBJS) $(LIBFILENAMES)
|
||||
$(QUIET_PREFIX) \
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);\
|
||||
echo "---- LINKING EXE $@ [$(CFG)] ----";\
|
||||
echo "----" $(QUIET_ECHO_POSTFIX);\
|
||||
\
|
||||
$(P4_EDIT_START) $(OUTPUTFILE) $(P4_EDIT_END);\
|
||||
$(LINK) $(LINK_MAP_FLAGS) $(LDFLAGS) $(PROFILE_LINKER_FLAG) -o $(OUTPUTFILE) $(LIB_START_EXE) $(OBJS) $(LIBFILES) $(SystemLibraries) $(LIB_END_EXE);
|
||||
$(QUIET_PREFIX) -$(P4_EDIT_START) $(OUTPUTFILE)$(SYM_EXT) $(P4_EDIT_END);
|
||||
$(QUIET_PREFIX) $(GEN_SYM) $(OUTPUTFILE);
|
||||
$(QUIET_PREFIX) -$(STRIP) $(OUTPUTFILE);
|
||||
$(QUIET_PREFIX) $(VSIGN) -signvalve $(OUTPUTFILE);
|
||||
|
||||
|
||||
tags:
|
||||
etags -a -C -o $(SRCROOT)/TAGS *.cpp *.cxx *.h *.hxx
|
||||
|
||||
P4EXE ?= p4
|
||||
|
||||
# DETECT_STRING_CHANGE_BETWEEN_BUILDS is a macro that lets you update the timestamp on a file whenever a string changes between invokations of make
|
||||
# This lets us know that our compile flags are consistent with the last time we ran and avoid overbuilding
|
||||
#
|
||||
# Parameters: $(1) = a unique name as a basis for intermediate variables and file names, the exact name will not be used if you want to give it a name used for $(2).
|
||||
# $(2) = extra escaped deref or call that you would invoke to fully evaluate the string in $(1)
|
||||
# A file specified with $(call DETECT_STRING_CHANGE_BETWEEN_BUILDS_TIMESTAMP_FILE,$(1)) will have it's timestamp updated whenever the cached settings change
|
||||
|
||||
# Make string substitions on the value so it can be represented cleanly in an "$(ECHO) > file" operation
|
||||
DETECT_STRING_CHANGE_BETWEEN_BUILDS_STRING_FILTER = $(strip $(subst $$,_dollar,$(subst \\,_bs,$(subst =,_eq,$(subst ',_sq,$(subst ",_dq,$(1)))))))
|
||||
|
||||
DETECT_STRING_CHANGE_BETWEEN_BUILDS_TIMESTAMP_FILE = $(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated
|
||||
|
||||
define DETECT_STRING_CHANGE_BETWEEN_BUILDS
|
||||
|
||||
ifeq "$$(DISABLE_DETECT_STRING_CHANGE_BETWEEN_BUILDS)" ""
|
||||
|
||||
|
||||
include $$(wildcard $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_previous)
|
||||
unexport $(1)_FILTERED_PREV
|
||||
$(1)_FILTERED_CURRENT := $$(call DETECT_STRING_CHANGE_BETWEEN_BUILDS_STRING_FILTER,$(2))
|
||||
unexport $(1)_FILTERED_CURRENT
|
||||
|
||||
ifeq "1" "0"
|
||||
# Invalidate any cached settings whenever the base makefile changes in any way. This is mostly paranoia and we should be able to rely on the second rule by itself
|
||||
$$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_eval:: $(MAKEFILE_BASE_POSIX_MAK) ; \
|
||||
$$(QUIET_PREFIX) \
|
||||
{ \
|
||||
$$(BUILD_DEBUG_ECHO) detect string change between builds $(1) eval base start && \
|
||||
if [ -e "$$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated" ]; then \
|
||||
{ \
|
||||
$$(BUILD_DEBUG_ECHO) "Discarding $(1) cached value due to changes in \"$$^\""; \
|
||||
}; \
|
||||
fi; \
|
||||
$$(RM) -f $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated; \
|
||||
$$(RM) -f $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_previous; \
|
||||
$$(RM) -f $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_eval; \
|
||||
}
|
||||
endif
|
||||
|
||||
ifneq ("$$($(1)_FILTERED_CURRENT)","$$($(1)_FILTERED_PREV)")
|
||||
|
||||
$(1)_WRITE_CHUNK_FUNC = \
|
||||
WriteStringChunkToPrevFile () \
|
||||
{ \
|
||||
$$(ECHO) -n "$$$${1}" >> $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_previous && \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#value changed, write out the new value, touch the updated and eval file
|
||||
$$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_eval:: $(MAKEFILE_BASE_POSIX_MAK) $(COMPILE_DEPENDANT_MAKEFILES)
|
||||
$$(QUIET_PREFIX) $$(BUILD_DEBUG_ECHO) detect string change between builds $(1) eval incremental start
|
||||
$$(SPEW_UPDATED_DEPENDENCIES)
|
||||
$$(QUIET_PREFIX) \
|
||||
{ \
|
||||
{ $$(MKDIR) -p $$(OBJ_DIR)/_detect_string_change_between_builds $$(QUIET_ECHO_POSTFIX) || $(TRUE); } && \
|
||||
$$(BUILD_DEBUG_ECHO) "$(1) changed since last build" && \
|
||||
$$(TOUCH) $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated && \
|
||||
$$(ECHO) -n "$(1)_FILTERED_PREV = " > $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_previous; \
|
||||
}
|
||||
$$(QUIET_PREFIX) $$(call CHUNK_OUT_STRING_FOR_SHELL_LIMITS,$$($(1)_WRITE_CHUNK_FUNC),WriteStringChunkToPrevFile, ,$$($(1)_FILTERED_CURRENT))
|
||||
$$(QUIET_PREFIX) $$(TOUCH) $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_eval
|
||||
|
||||
else
|
||||
|
||||
#value is the same, just touch the eval file
|
||||
$$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_eval:: $(MAKEFILE_BASE_POSIX_MAK) $(COMPILE_DEPENDANT_MAKEFILES)
|
||||
$$(QUIET_PREFIX) $$(BUILD_DEBUG_ECHO) detect string change between builds $(1) eval incremental start
|
||||
$$(SPEW_UPDATED_DEPENDENCIES)
|
||||
$$(QUIET_PREFIX) \
|
||||
{ \
|
||||
{ $$(MKDIR) -p $$(OBJ_DIR)/_detect_string_change_between_builds $$(QUIET_ECHO_POSTFIX) || $(TRUE); } && \
|
||||
$$(BUILD_DEBUG_ECHO) $(1) unchanged since last build && \
|
||||
$$(TOUCH) $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_eval; \
|
||||
}
|
||||
|
||||
endif
|
||||
|
||||
|
||||
$$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated: $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_eval ; \
|
||||
$$(QUIET_PREFIX) \
|
||||
{ \
|
||||
if [ ! -e "$$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated" ]; then \
|
||||
{ \
|
||||
$$(TOUCH) $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated; \
|
||||
}; \
|
||||
fi; \
|
||||
$$(BUILD_DEBUG_ECHO) detect string change between builds $(1) has evaluated; \
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
# if $(DISABLE_DETECT_STRING_CHANGE_BETWEEN_BUILDS) is defined to not do anything, always update the strings when any relevant makefile changes
|
||||
|
||||
$$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated: $(MAKEFILE_BASE_POSIX_MAK) $(COMPILE_DEPENDANT_MAKEFILES) ; \
|
||||
$$(QUIET_PREFIX) \
|
||||
{
|
||||
$$(BUILD_DEBUG_ECHO) detect string change between builds $(1) updated disabled start && \
|
||||
$$(TOUCH) $$(OBJ_DIR)/_detect_string_change_between_builds/$(1)_updated; \
|
||||
}
|
||||
|
||||
endif
|
||||
|
||||
endef
|
||||
|
||||
unexport DETECT_STRING_CHANGE_BETWEEN_BUILDS
|
||||
|
||||
|
||||
# RUN_RECIPE_ACTION_ONCE ensures you run a recipe action exactly one time among many parallel threads
|
||||
# and none of the recipes trying to run it return from the function until the action has completed
|
||||
#
|
||||
# Parameters: $(1) = unique "already run" sentinel file, $(2) = unique mutex directory, $(3) = action to run
|
||||
# The existence of the sentinel is used to note that the action has already run and should not run again. The contents of the file are a shell script to replciate the exit status of the action. You are responsible for ensuring this file is deleted before the action will run again
|
||||
# The existence of the mutex directory causes parallel recipes to spin until it is removed (which automatically happens at the end of the function). You are responsible for ensuring this directory is deleted before any locks can be acquired
|
||||
# "_prebuild_always::" is a good place to remove both files.
|
||||
# You are also responsible for ensuring the base directories for both items exist prior to calling RUN_RECIPE_ACTION_ONCE
|
||||
#
|
||||
# The sentinel file is used because shell scripts cannot promote environment variables to the parent make process, so the filesystem is used to create a boolean flag out of the sentinel file
|
||||
# The mutex directory is used because directory creation is atomic and will return an error if the directory cannot be created (already exists)
|
||||
RUN_RECIPE_ACTION_ONCE = \
|
||||
( \
|
||||
until [ -e $(1) ]; do \
|
||||
{ \
|
||||
$(MKDIR) -p $(2) > /dev/null 2>&1 && \
|
||||
{ \
|
||||
! [ -e $(1) ] && \
|
||||
{ \
|
||||
{ $(3); } && \
|
||||
$(ECHO) "exit 0" > $(1) || \
|
||||
$(ECHO) "exit 1" > $(1); \
|
||||
}; \
|
||||
$(RM) -fr $(2); \
|
||||
} \
|
||||
|| \
|
||||
{ \
|
||||
$(SLEEP) 1; \
|
||||
}; \
|
||||
}; \
|
||||
done; \
|
||||
$(SHELL) $(1); \
|
||||
)
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Standard directory creation targets to ensure we can just touch files we need knowing that their directory exists
|
||||
#
|
||||
|
||||
# Ensure $(OBJ_DIR) exists
|
||||
$(OBJ_DIR)/_create_dir:
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) $(OBJ_DIR)/_create_dir start
|
||||
$(QUIET_PREFIX) $(MKDIR) -p $(OBJ_DIR) $(QUIET_ECHO_POSTFIX)
|
||||
$(QUIET_PREFIX) $(TOUCH) $(OBJ_DIR)/_create_dir
|
||||
|
||||
|
||||
PREBUILD_EVENT_ACTION ?= { $(TRUE); }
|
||||
PREBUILD_EVENT_WRAPPED = \
|
||||
{ \
|
||||
{ \
|
||||
$(BUILD_DEBUG_ECHO) "Pre-Build Event For \"$(NAME)\"" && \
|
||||
$(call PREBUILD_EVENT_ACTION); \
|
||||
} \
|
||||
|| \
|
||||
{ \
|
||||
$(ECHO) "Error executing Pre-Build Event for \"$(NAME)\""; \
|
||||
$(FALSE); \
|
||||
}; \
|
||||
}
|
||||
|
||||
RUN_PREBUILD_EVENT_ONCE = $(call RUN_RECIPE_ACTION_ONCE,"$(OBJ_DIR)/_ran_prebuild_event","$(OBJ_DIR)/_lock_prebuild_event",$(call PREBUILD_EVENT_WRAPPED))
|
||||
|
||||
_prebuild_always::
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _prebuild_always delete prebuild event start
|
||||
$(QUIET_PREFIX) $(RM) -fr $(OBJ_DIR)/_ran_prebuild_event
|
||||
$(QUIET_PREFIX) $(RM) -fr $(OBJ_DIR)/_lock_prebuild_event
|
||||
|
||||
# Analogous to MSVC Pre-Link Event
|
||||
PRELINK_EVENT_ACTION ?= { $(TRUE); }
|
||||
|
||||
$(OBJ_DIR)/_prelink_event: $(LINK_STEP_DEPENDENCIES) | _prebuild_steps _predepgen_steps _precompile_steps
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _prelink_event start
|
||||
$(SPEW_UPDATED_DEPENDENCIES)
|
||||
$(QUIET_PREFIX) \
|
||||
{ \
|
||||
{ \
|
||||
$(call RUN_PREBUILD_EVENT_ONCE) && \
|
||||
$(BUILD_DEBUG_ECHO) "Pre-Link Event For \"$(NAME)\"" && \
|
||||
$(call PRELINK_EVENT_ACTION) && \
|
||||
$(TOUCH) $(OBJ_DIR)/_prelink_event && \
|
||||
$(RM) -f $(OBJ_DIR)/_prelink_event_failed; \
|
||||
} \
|
||||
|| \
|
||||
{ \
|
||||
$(ECHO) "Error executing Pre-Link Event for \"$(NAME)\""; \
|
||||
$(RM) -f $(OBJ_DIR)/_prelink_event; \
|
||||
$(TOUCH) $(OBJ_DIR)/_prelink_event_failed; \
|
||||
$(FALSE); \
|
||||
}; \
|
||||
}
|
||||
|
||||
# Analogous to MSVC Post-Build Event
|
||||
POSTBUILD_EVENT_ACTION ?= { $(TRUE); }
|
||||
|
||||
$(OBJ_DIR)/_postbuild_event: $(ALL_CUSTOM_BUILD_TOOL_OUTPUTS) $(LINK_STEP) $(wildcard $(OBJ_DIR)/_postbuild_event_failed) | _prebuild_steps
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _postbuild_event start
|
||||
$(SPEW_UPDATED_DEPENDENCIES)
|
||||
$(QUIET_PREFIX) \
|
||||
{ \
|
||||
{ \
|
||||
$(call RUN_PREBUILD_EVENT_ONCE) && \
|
||||
$(BUILD_DEBUG_ECHO) "Post-Build Event For \"$(NAME)\"" && \
|
||||
$(call POSTBUILD_EVENT_ACTION) && \
|
||||
$(TOUCH) $(OBJ_DIR)/_postbuild_event && \
|
||||
$(RM) -f $(OBJ_DIR)/_postbuild_event_failed; \
|
||||
} \
|
||||
|| \
|
||||
{ \
|
||||
$(ECHO) "Error executing Post-Build Event for \"$(NAME)\""; \
|
||||
$(RM) -f $(OBJ_DIR)/_postbuild_event; \
|
||||
$(TOUCH) $(OBJ_DIR)/_postbuild_event_failed; \
|
||||
$(FALSE); \
|
||||
}; \
|
||||
}
|
||||
|
||||
# Everything that should run before anything starts generating intermediate files
|
||||
_prebuild_steps: _prebuild_always $(OBJ_DIR)/_create_dir
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _prebuild_steps completed
|
||||
|
||||
# Everything that needs to run before depgen. Running after custom build tools because they can generate cpp's we depend on
|
||||
_predepgen_steps: _prebuild_steps $(ALL_CUSTOM_BUILD_TOOL_OUTPUTS)
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _predepgen_steps completed
|
||||
|
||||
# Everything that needs to finish before compiling cpps.
|
||||
_precompile_steps: _predepgen_steps
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _precompile_steps completed
|
||||
|
||||
# Everything that needs to finish before linking
|
||||
_prelink_steps: $(OBJ_DIR)/_prelink_event
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _prelink_steps completed
|
||||
|
||||
# Everything to do after linking
|
||||
_postbuild_steps: $(OBJ_DIR)/_postbuild_event
|
||||
$(QUIET_PREFIX) $(BUILD_DEBUG_ECHO) _postbuild_steps completed
|
2517
devtools/memlog/memlog.cpp
Normal file
2517
devtools/memlog/memlog.cpp
Normal file
File diff suppressed because it is too large
Load Diff
BIN
devtools/srcsrv/perl/bin/perl58.dll
Normal file
BIN
devtools/srcsrv/perl/bin/perl58.dll
Normal file
Binary file not shown.
237
devtools/srcsrv/perl/lib/Carp.pm
Normal file
237
devtools/srcsrv/perl/lib/Carp.pm
Normal file
@ -0,0 +1,237 @@
|
||||
package Carp;
|
||||
|
||||
our $VERSION = '1.0701';
|
||||
# this file is an utra-lightweight stub. The first time a function is
|
||||
# called, Carp::Heavy is loaded, and the real short/longmessmess_jmp
|
||||
# subs are installed
|
||||
|
||||
our $MaxEvalLen = 0;
|
||||
our $Verbose = 0;
|
||||
our $CarpLevel = 0;
|
||||
our $MaxArgLen = 64; # How much of each argument to print. 0 = all.
|
||||
our $MaxArgNums = 8; # How many arguments to print. 0 = all.
|
||||
|
||||
require Exporter;
|
||||
our @ISA = ('Exporter');
|
||||
our @EXPORT = qw(confess croak carp);
|
||||
our @EXPORT_OK = qw(cluck verbose longmess shortmess);
|
||||
our @EXPORT_FAIL = qw(verbose); # hook to enable verbose mode
|
||||
|
||||
# if the caller specifies verbose usage ("perl -MCarp=verbose script.pl")
|
||||
# then the following method will be called by the Exporter which knows
|
||||
# to do this thanks to @EXPORT_FAIL, above. $_[1] will contain the word
|
||||
# 'verbose'.
|
||||
|
||||
sub export_fail { shift; $Verbose = shift if $_[0] eq 'verbose'; @_ }
|
||||
|
||||
# fixed hooks for stashes to point to
|
||||
sub longmess { goto &longmess_jmp }
|
||||
sub shortmess { goto &shortmess_jmp }
|
||||
# these two are replaced when Carp::Heavy is loaded
|
||||
sub longmess_jmp {
|
||||
local($@, $!);
|
||||
eval { require Carp::Heavy };
|
||||
return $@ if $@;
|
||||
goto &longmess_real;
|
||||
}
|
||||
sub shortmess_jmp {
|
||||
local($@, $!);
|
||||
eval { require Carp::Heavy };
|
||||
return $@ if $@;
|
||||
goto &shortmess_real;
|
||||
}
|
||||
|
||||
sub croak { die shortmess @_ }
|
||||
sub confess { die longmess @_ }
|
||||
sub carp { warn shortmess @_ }
|
||||
sub cluck { warn longmess @_ }
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
carp - warn of errors (from perspective of caller)
|
||||
|
||||
cluck - warn of errors with stack backtrace
|
||||
(not exported by default)
|
||||
|
||||
croak - die of errors (from perspective of caller)
|
||||
|
||||
confess - die of errors with stack backtrace
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Carp;
|
||||
croak "We're outta here!";
|
||||
|
||||
use Carp qw(cluck);
|
||||
cluck "This is how we got here!";
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The Carp routines are useful in your own modules because
|
||||
they act like die() or warn(), but with a message which is more
|
||||
likely to be useful to a user of your module. In the case of
|
||||
cluck, confess, and longmess that context is a summary of every
|
||||
call in the call-stack. For a shorter message you can use C<carp>
|
||||
or C<croak> which report the error as being from where your module
|
||||
was called. There is no guarantee that that is where the error
|
||||
was, but it is a good educated guess.
|
||||
|
||||
You can also alter the way the output and logic of C<Carp> works, by
|
||||
changing some global variables in the C<Carp> namespace. See the
|
||||
section on C<GLOBAL VARIABLES> below.
|
||||
|
||||
Here is a more complete description of how c<carp> and c<croak> work.
|
||||
What they do is search the call-stack for a function call stack where
|
||||
they have not been told that there shouldn't be an error. If every
|
||||
call is marked safe, they give up and give a full stack backtrace
|
||||
instead. In other words they presume that the first likely looking
|
||||
potential suspect is guilty. Their rules for telling whether
|
||||
a call shouldn't generate errors work as follows:
|
||||
|
||||
=over 4
|
||||
|
||||
=item 1.
|
||||
|
||||
Any call from a package to itself is safe.
|
||||
|
||||
=item 2.
|
||||
|
||||
Packages claim that there won't be errors on calls to or from
|
||||
packages explicitly marked as safe by inclusion in C<@CARP_NOT>, or
|
||||
(if that array is empty) C<@ISA>. The ability to override what
|
||||
@ISA says is new in 5.8.
|
||||
|
||||
=item 3.
|
||||
|
||||
The trust in item 2 is transitive. If A trusts B, and B
|
||||
trusts C, then A trusts C. So if you do not override C<@ISA>
|
||||
with C<@CARP_NOT>, then this trust relationship is identical to,
|
||||
"inherits from".
|
||||
|
||||
=item 4.
|
||||
|
||||
Any call from an internal Perl module is safe. (Nothing keeps
|
||||
user modules from marking themselves as internal to Perl, but
|
||||
this practice is discouraged.)
|
||||
|
||||
=item 5.
|
||||
|
||||
Any call to Perl's warning system (eg Carp itself) is safe.
|
||||
(This rule is what keeps it from reporting the error at the
|
||||
point where you call C<carp> or C<croak>.)
|
||||
|
||||
=item 6.
|
||||
|
||||
C<$Carp::CarpLevel> can be set to skip a fixed number of additional
|
||||
call levels. Using this is not recommended because it is very
|
||||
difficult to get it to behave correctly.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Forcing a Stack Trace
|
||||
|
||||
As a debugging aid, you can force Carp to treat a croak as a confess
|
||||
and a carp as a cluck across I<all> modules. In other words, force a
|
||||
detailed stack trace to be given. This can be very helpful when trying
|
||||
to understand why, or from where, a warning or error is being generated.
|
||||
|
||||
This feature is enabled by 'importing' the non-existent symbol
|
||||
'verbose'. You would typically enable it by saying
|
||||
|
||||
perl -MCarp=verbose script.pl
|
||||
|
||||
or by including the string C<MCarp=verbose> in the PERL5OPT
|
||||
environment variable.
|
||||
|
||||
Alternately, you can set the global variable C<$Carp::Verbose> to true.
|
||||
See the C<GLOBAL VARIABLES> section below.
|
||||
|
||||
=head1 GLOBAL VARIABLES
|
||||
|
||||
=head2 $Carp::MaxEvalLen
|
||||
|
||||
This variable determines how many characters of a string-eval are to
|
||||
be shown in the output. Use a value of C<0> to show all text.
|
||||
|
||||
Defaults to C<0>.
|
||||
|
||||
=head2 $Carp::MaxArgLen
|
||||
|
||||
This variable determines how many characters of each argument to a
|
||||
function to print. Use a value of C<0> to show the full length of the
|
||||
argument.
|
||||
|
||||
Defaults to C<64>.
|
||||
|
||||
=head2 $Carp::MaxArgNums
|
||||
|
||||
This variable determines how many arguments to each function to show.
|
||||
Use a value of C<0> to show all arguments to a function call.
|
||||
|
||||
Defaults to C<8>.
|
||||
|
||||
=head2 $Carp::Verbose
|
||||
|
||||
This variable makes C<carp> and C<cluck> generate stack backtraces
|
||||
just like C<cluck> and C<confess>. This is how C<use Carp 'verbose'>
|
||||
is implemented internally.
|
||||
|
||||
Defaults to C<0>.
|
||||
|
||||
=head2 %Carp::Internal
|
||||
|
||||
This says what packages are internal to Perl. C<Carp> will never
|
||||
report an error as being from a line in a package that is internal to
|
||||
Perl. For example:
|
||||
|
||||
$Carp::Internal{ __PACKAGE__ }++;
|
||||
# time passes...
|
||||
sub foo { ... or confess("whatever") };
|
||||
|
||||
would give a full stack backtrace starting from the first caller
|
||||
outside of __PACKAGE__. (Unless that package was also internal to
|
||||
Perl.)
|
||||
|
||||
=head2 %Carp::CarpInternal
|
||||
|
||||
This says which packages are internal to Perl's warning system. For
|
||||
generating a full stack backtrace this is the same as being internal
|
||||
to Perl, the stack backtrace will not start inside packages that are
|
||||
listed in C<%Carp::CarpInternal>. But it is slightly different for
|
||||
the summary message generated by C<carp> or C<croak>. There errors
|
||||
will not be reported on any lines that are calling packages in
|
||||
C<%Carp::CarpInternal>.
|
||||
|
||||
For example C<Carp> itself is listed in C<%Carp::CarpInternal>.
|
||||
Therefore the full stack backtrace from C<confess> will not start
|
||||
inside of C<Carp>, and the short message from calling C<croak> is
|
||||
not placed on the line where C<croak> was called.
|
||||
|
||||
=head2 $Carp::CarpLevel
|
||||
|
||||
This variable determines how many additional call frames are to be
|
||||
skipped that would not otherwise be when reporting where an error
|
||||
occurred on a call to one of C<Carp>'s functions. It is fairly easy
|
||||
to count these call frames on calls that generate a full stack
|
||||
backtrace. However it is much harder to do this accounting for calls
|
||||
that generate a short message. Usually people skip too many call
|
||||
frames. If they are lucky they skip enough that C<Carp> goes all of
|
||||
the way through the call stack, realizes that something is wrong, and
|
||||
then generates a full stack backtrace. If they are unlucky then the
|
||||
error is reported from somewhere misleading very high in the call
|
||||
stack.
|
||||
|
||||
Therefore it is best to avoid C<$Carp::CarpLevel>. Instead use
|
||||
C<@CARP_NOT>, C<%Carp::Internal> and %Carp::CarpInternal>.
|
||||
|
||||
Defaults to C<0>.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
The Carp routines don't handle exception objects currently.
|
||||
If called with a first argument that is a reference, they simply
|
||||
call die() or warn(), as appropriate.
|
||||
|
441
devtools/srcsrv/perl/lib/Exporter.pm
Normal file
441
devtools/srcsrv/perl/lib/Exporter.pm
Normal file
@ -0,0 +1,441 @@
|
||||
package Exporter;
|
||||
|
||||
require 5.006;
|
||||
|
||||
# Be lean.
|
||||
#use strict;
|
||||
#no strict 'refs';
|
||||
|
||||
our $Debug = 0;
|
||||
our $ExportLevel = 0;
|
||||
our $Verbose ||= 0;
|
||||
our $VERSION = '5.60';
|
||||
our (%Cache);
|
||||
# Carp does this now for us, so we can finally live w/o Carp
|
||||
#$Carp::Internal{Exporter} = 1;
|
||||
|
||||
sub as_heavy {
|
||||
require Exporter::Heavy;
|
||||
# Unfortunately, this does not work if the caller is aliased as *name = \&foo
|
||||
# Thus the need to create a lot of identical subroutines
|
||||
my $c = (caller(1))[3];
|
||||
$c =~ s/.*:://;
|
||||
\&{"Exporter::Heavy::heavy_$c"};
|
||||
}
|
||||
|
||||
sub export {
|
||||
goto &{as_heavy()};
|
||||
}
|
||||
|
||||
sub import {
|
||||
my $pkg = shift;
|
||||
my $callpkg = caller($ExportLevel);
|
||||
|
||||
if ($pkg eq "Exporter" and @_ and $_[0] eq "import") {
|
||||
*{$callpkg."::import"} = \&import;
|
||||
return;
|
||||
}
|
||||
|
||||
# We *need* to treat @{"$pkg\::EXPORT_FAIL"} since Carp uses it :-(
|
||||
my($exports, $fail) = (\@{"$pkg\::EXPORT"}, \@{"$pkg\::EXPORT_FAIL"});
|
||||
return export $pkg, $callpkg, @_
|
||||
if $Verbose or $Debug or @$fail > 1;
|
||||
my $export_cache = ($Cache{$pkg} ||= {});
|
||||
my $args = @_ or @_ = @$exports;
|
||||
|
||||
local $_;
|
||||
if ($args and not %$export_cache) {
|
||||
s/^&//, $export_cache->{$_} = 1
|
||||
foreach (@$exports, @{"$pkg\::EXPORT_OK"});
|
||||
}
|
||||
my $heavy;
|
||||
# Try very hard not to use {} and hence have to enter scope on the foreach
|
||||
# We bomb out of the loop with last as soon as heavy is set.
|
||||
if ($args or $fail) {
|
||||
($heavy = (/\W/ or $args and not exists $export_cache->{$_}
|
||||
or @$fail and $_ eq $fail->[0])) and last
|
||||
foreach (@_);
|
||||
} else {
|
||||
($heavy = /\W/) and last
|
||||
foreach (@_);
|
||||
}
|
||||
return export $pkg, $callpkg, ($args ? @_ : ()) if $heavy;
|
||||
local $SIG{__WARN__} =
|
||||
sub {require Carp; &Carp::carp};
|
||||
# shortcut for the common case of no type character
|
||||
*{"$callpkg\::$_"} = \&{"$pkg\::$_"} foreach @_;
|
||||
}
|
||||
|
||||
# Default methods
|
||||
|
||||
sub export_fail {
|
||||
my $self = shift;
|
||||
@_;
|
||||
}
|
||||
|
||||
# Unfortunately, caller(1)[3] "does not work" if the caller is aliased as
|
||||
# *name = \&foo. Thus the need to create a lot of identical subroutines
|
||||
# Otherwise we could have aliased them to export().
|
||||
|
||||
sub export_to_level {
|
||||
goto &{as_heavy()};
|
||||
}
|
||||
|
||||
sub export_tags {
|
||||
goto &{as_heavy()};
|
||||
}
|
||||
|
||||
sub export_ok_tags {
|
||||
goto &{as_heavy()};
|
||||
}
|
||||
|
||||
sub require_version {
|
||||
goto &{as_heavy()};
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Exporter - Implements default import method for modules
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
In module YourModule.pm:
|
||||
|
||||
package YourModule;
|
||||
require Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw(munge frobnicate); # symbols to export on request
|
||||
|
||||
or
|
||||
|
||||
package YourModule;
|
||||
use Exporter 'import'; # gives you Exporter's import() method directly
|
||||
@EXPORT_OK = qw(munge frobnicate); # symbols to export on request
|
||||
|
||||
In other files which wish to use YourModule:
|
||||
|
||||
use ModuleName qw(frobnicate); # import listed symbols
|
||||
frobnicate ($left, $right) # calls YourModule::frobnicate
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The Exporter module implements an C<import> method which allows a module
|
||||
to export functions and variables to its users' namespaces. Many modules
|
||||
use Exporter rather than implementing their own C<import> method because
|
||||
Exporter provides a highly flexible interface, with an implementation optimised
|
||||
for the common case.
|
||||
|
||||
Perl automatically calls the C<import> method when processing a
|
||||
C<use> statement for a module. Modules and C<use> are documented
|
||||
in L<perlfunc> and L<perlmod>. Understanding the concept of
|
||||
modules and how the C<use> statement operates is important to
|
||||
understanding the Exporter.
|
||||
|
||||
=head2 How to Export
|
||||
|
||||
The arrays C<@EXPORT> and C<@EXPORT_OK> in a module hold lists of
|
||||
symbols that are going to be exported into the users name space by
|
||||
default, or which they can request to be exported, respectively. The
|
||||
symbols can represent functions, scalars, arrays, hashes, or typeglobs.
|
||||
The symbols must be given by full name with the exception that the
|
||||
ampersand in front of a function is optional, e.g.
|
||||
|
||||
@EXPORT = qw(afunc $scalar @array); # afunc is a function
|
||||
@EXPORT_OK = qw(&bfunc %hash *typeglob); # explicit prefix on &bfunc
|
||||
|
||||
If you are only exporting function names it is recommended to omit the
|
||||
ampersand, as the implementation is faster this way.
|
||||
|
||||
=head2 Selecting What To Export
|
||||
|
||||
Do B<not> export method names!
|
||||
|
||||
Do B<not> export anything else by default without a good reason!
|
||||
|
||||
Exports pollute the namespace of the module user. If you must export
|
||||
try to use @EXPORT_OK in preference to @EXPORT and avoid short or
|
||||
common symbol names to reduce the risk of name clashes.
|
||||
|
||||
Generally anything not exported is still accessible from outside the
|
||||
module using the ModuleName::item_name (or $blessed_ref-E<gt>method)
|
||||
syntax. By convention you can use a leading underscore on names to
|
||||
informally indicate that they are 'internal' and not for public use.
|
||||
|
||||
(It is actually possible to get private functions by saying:
|
||||
|
||||
my $subref = sub { ... };
|
||||
$subref->(@args); # Call it as a function
|
||||
$obj->$subref(@args); # Use it as a method
|
||||
|
||||
However if you use them for methods it is up to you to figure out
|
||||
how to make inheritance work.)
|
||||
|
||||
As a general rule, if the module is trying to be object oriented
|
||||
then export nothing. If it's just a collection of functions then
|
||||
@EXPORT_OK anything but use @EXPORT with caution. For function and
|
||||
method names use barewords in preference to names prefixed with
|
||||
ampersands for the export lists.
|
||||
|
||||
Other module design guidelines can be found in L<perlmod>.
|
||||
|
||||
=head2 How to Import
|
||||
|
||||
In other files which wish to use your module there are three basic ways for
|
||||
them to load your module and import its symbols:
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<use ModuleName;>
|
||||
|
||||
This imports all the symbols from ModuleName's @EXPORT into the namespace
|
||||
of the C<use> statement.
|
||||
|
||||
=item C<use ModuleName ();>
|
||||
|
||||
This causes perl to load your module but does not import any symbols.
|
||||
|
||||
=item C<use ModuleName qw(...);>
|
||||
|
||||
This imports only the symbols listed by the caller into their namespace.
|
||||
All listed symbols must be in your @EXPORT or @EXPORT_OK, else an error
|
||||
occurs. The advanced export features of Exporter are accessed like this,
|
||||
but with list entries that are syntactically distinct from symbol names.
|
||||
|
||||
=back
|
||||
|
||||
Unless you want to use its advanced features, this is probably all you
|
||||
need to know to use Exporter.
|
||||
|
||||
=head1 Advanced features
|
||||
|
||||
=head2 Specialised Import Lists
|
||||
|
||||
If any of the entries in an import list begins with !, : or / then
|
||||
the list is treated as a series of specifications which either add to
|
||||
or delete from the list of names to import. They are processed left to
|
||||
right. Specifications are in the form:
|
||||
|
||||
[!]name This name only
|
||||
[!]:DEFAULT All names in @EXPORT
|
||||
[!]:tag All names in $EXPORT_TAGS{tag} anonymous list
|
||||
[!]/pattern/ All names in @EXPORT and @EXPORT_OK which match
|
||||
|
||||
A leading ! indicates that matching names should be deleted from the
|
||||
list of names to import. If the first specification is a deletion it
|
||||
is treated as though preceded by :DEFAULT. If you just want to import
|
||||
extra names in addition to the default set you will still need to
|
||||
include :DEFAULT explicitly.
|
||||
|
||||
e.g., Module.pm defines:
|
||||
|
||||
@EXPORT = qw(A1 A2 A3 A4 A5);
|
||||
@EXPORT_OK = qw(B1 B2 B3 B4 B5);
|
||||
%EXPORT_TAGS = (T1 => [qw(A1 A2 B1 B2)], T2 => [qw(A1 A2 B3 B4)]);
|
||||
|
||||
Note that you cannot use tags in @EXPORT or @EXPORT_OK.
|
||||
Names in EXPORT_TAGS must also appear in @EXPORT or @EXPORT_OK.
|
||||
|
||||
An application using Module can say something like:
|
||||
|
||||
use Module qw(:DEFAULT :T2 !B3 A3);
|
||||
|
||||
Other examples include:
|
||||
|
||||
use Socket qw(!/^[AP]F_/ !SOMAXCONN !SOL_SOCKET);
|
||||
use POSIX qw(:errno_h :termios_h !TCSADRAIN !/^EXIT/);
|
||||
|
||||
Remember that most patterns (using //) will need to be anchored
|
||||
with a leading ^, e.g., C</^EXIT/> rather than C</EXIT/>.
|
||||
|
||||
You can say C<BEGIN { $Exporter::Verbose=1 }> to see how the
|
||||
specifications are being processed and what is actually being imported
|
||||
into modules.
|
||||
|
||||
=head2 Exporting without using Exporter's import method
|
||||
|
||||
Exporter has a special method, 'export_to_level' which is used in situations
|
||||
where you can't directly call Exporter's import method. The export_to_level
|
||||
method looks like:
|
||||
|
||||
MyPackage->export_to_level($where_to_export, $package, @what_to_export);
|
||||
|
||||
where $where_to_export is an integer telling how far up the calling stack
|
||||
to export your symbols, and @what_to_export is an array telling what
|
||||
symbols *to* export (usually this is @_). The $package argument is
|
||||
currently unused.
|
||||
|
||||
For example, suppose that you have a module, A, which already has an
|
||||
import function:
|
||||
|
||||
package A;
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw ($b);
|
||||
|
||||
sub import
|
||||
{
|
||||
$A::b = 1; # not a very useful import method
|
||||
}
|
||||
|
||||
and you want to Export symbol $A::b back to the module that called
|
||||
package A. Since Exporter relies on the import method to work, via
|
||||
inheritance, as it stands Exporter::import() will never get called.
|
||||
Instead, say the following:
|
||||
|
||||
package A;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT_OK = qw ($b);
|
||||
|
||||
sub import
|
||||
{
|
||||
$A::b = 1;
|
||||
A->export_to_level(1, @_);
|
||||
}
|
||||
|
||||
This will export the symbols one level 'above' the current package - ie: to
|
||||
the program or module that used package A.
|
||||
|
||||
Note: Be careful not to modify C<@_> at all before you call export_to_level
|
||||
- or people using your package will get very unexplained results!
|
||||
|
||||
=head2 Exporting without inheriting from Exporter
|
||||
|
||||
By including Exporter in your @ISA you inherit an Exporter's import() method
|
||||
but you also inherit several other helper methods which you probably don't
|
||||
want. To avoid this you can do
|
||||
|
||||
package YourModule;
|
||||
use Exporter qw( import );
|
||||
|
||||
which will export Exporter's own import() method into YourModule.
|
||||
Everything will work as before but you won't need to include Exporter in
|
||||
@YourModule::ISA.
|
||||
|
||||
=head2 Module Version Checking
|
||||
|
||||
The Exporter module will convert an attempt to import a number from a
|
||||
module into a call to $module_name-E<gt>require_version($value). This can
|
||||
be used to validate that the version of the module being used is
|
||||
greater than or equal to the required version.
|
||||
|
||||
The Exporter module supplies a default require_version method which
|
||||
checks the value of $VERSION in the exporting module.
|
||||
|
||||
Since the default require_version method treats the $VERSION number as
|
||||
a simple numeric value it will regard version 1.10 as lower than
|
||||
1.9. For this reason it is strongly recommended that you use numbers
|
||||
with at least two decimal places, e.g., 1.09.
|
||||
|
||||
=head2 Managing Unknown Symbols
|
||||
|
||||
In some situations you may want to prevent certain symbols from being
|
||||
exported. Typically this applies to extensions which have functions
|
||||
or constants that may not exist on some systems.
|
||||
|
||||
The names of any symbols that cannot be exported should be listed
|
||||
in the C<@EXPORT_FAIL> array.
|
||||
|
||||
If a module attempts to import any of these symbols the Exporter
|
||||
will give the module an opportunity to handle the situation before
|
||||
generating an error. The Exporter will call an export_fail method
|
||||
with a list of the failed symbols:
|
||||
|
||||
@failed_symbols = $module_name->export_fail(@failed_symbols);
|
||||
|
||||
If the export_fail method returns an empty list then no error is
|
||||
recorded and all the requested symbols are exported. If the returned
|
||||
list is not empty then an error is generated for each symbol and the
|
||||
export fails. The Exporter provides a default export_fail method which
|
||||
simply returns the list unchanged.
|
||||
|
||||
Uses for the export_fail method include giving better error messages
|
||||
for some symbols and performing lazy architectural checks (put more
|
||||
symbols into @EXPORT_FAIL by default and then take them out if someone
|
||||
actually tries to use them and an expensive check shows that they are
|
||||
usable on that platform).
|
||||
|
||||
=head2 Tag Handling Utility Functions
|
||||
|
||||
Since the symbols listed within %EXPORT_TAGS must also appear in either
|
||||
@EXPORT or @EXPORT_OK, two utility functions are provided which allow
|
||||
you to easily add tagged sets of symbols to @EXPORT or @EXPORT_OK:
|
||||
|
||||
%EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);
|
||||
|
||||
Exporter::export_tags('foo'); # add aa, bb and cc to @EXPORT
|
||||
Exporter::export_ok_tags('bar'); # add aa, cc and dd to @EXPORT_OK
|
||||
|
||||
Any names which are not tags are added to @EXPORT or @EXPORT_OK
|
||||
unchanged but will trigger a warning (with C<-w>) to avoid misspelt tags
|
||||
names being silently added to @EXPORT or @EXPORT_OK. Future versions
|
||||
may make this a fatal error.
|
||||
|
||||
=head2 Generating combined tags
|
||||
|
||||
If several symbol categories exist in %EXPORT_TAGS, it's usually
|
||||
useful to create the utility ":all" to simplify "use" statements.
|
||||
|
||||
The simplest way to do this is:
|
||||
|
||||
%EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);
|
||||
|
||||
# add all the other ":class" tags to the ":all" class,
|
||||
# deleting duplicates
|
||||
{
|
||||
my %seen;
|
||||
|
||||
push @{$EXPORT_TAGS{all}},
|
||||
grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS;
|
||||
}
|
||||
|
||||
CGI.pm creates an ":all" tag which contains some (but not really
|
||||
all) of its categories. That could be done with one small
|
||||
change:
|
||||
|
||||
# add some of the other ":class" tags to the ":all" class,
|
||||
# deleting duplicates
|
||||
{
|
||||
my %seen;
|
||||
|
||||
push @{$EXPORT_TAGS{all}},
|
||||
grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}}
|
||||
foreach qw/html2 html3 netscape form cgi internal/;
|
||||
}
|
||||
|
||||
Note that the tag names in %EXPORT_TAGS don't have the leading ':'.
|
||||
|
||||
=head2 C<AUTOLOAD>ed Constants
|
||||
|
||||
Many modules make use of C<AUTOLOAD>ing for constant subroutines to
|
||||
avoid having to compile and waste memory on rarely used values (see
|
||||
L<perlsub> for details on constant subroutines). Calls to such
|
||||
constant subroutines are not optimized away at compile time because
|
||||
they can't be checked at compile time for constancy.
|
||||
|
||||
Even if a prototype is available at compile time, the body of the
|
||||
subroutine is not (it hasn't been C<AUTOLOAD>ed yet). perl needs to
|
||||
examine both the C<()> prototype and the body of a subroutine at
|
||||
compile time to detect that it can safely replace calls to that
|
||||
subroutine with the constant value.
|
||||
|
||||
A workaround for this is to call the constants once in a C<BEGIN> block:
|
||||
|
||||
package My ;
|
||||
|
||||
use Socket ;
|
||||
|
||||
foo( SO_LINGER ); ## SO_LINGER NOT optimized away; called at runtime
|
||||
BEGIN { SO_LINGER }
|
||||
foo( SO_LINGER ); ## SO_LINGER optimized away at compile time.
|
||||
|
||||
This forces the C<AUTOLOAD> for C<SO_LINGER> to take place before
|
||||
SO_LINGER is encountered later in C<My> package.
|
||||
|
||||
If you are writing a package that C<AUTOLOAD>s, consider forcing
|
||||
an C<AUTOLOAD> for any constants explicitly imported by other packages
|
||||
or which are usually used when your package is C<use>d.
|
||||
|
||||
=cut
|
244
devtools/srcsrv/perl/lib/Fcntl.pm
Normal file
244
devtools/srcsrv/perl/lib/Fcntl.pm
Normal file
@ -0,0 +1,244 @@
|
||||
package Fcntl;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Fcntl - load the C Fcntl.h defines
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Fcntl;
|
||||
use Fcntl qw(:DEFAULT :flock);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module is just a translation of the C F<fcntl.h> file.
|
||||
Unlike the old mechanism of requiring a translated F<fcntl.ph>
|
||||
file, this uses the B<h2xs> program (see the Perl source distribution)
|
||||
and your native C compiler. This means that it has a
|
||||
far more likely chance of getting the numbers right.
|
||||
|
||||
=head1 NOTE
|
||||
|
||||
Only C<#define> symbols get translated; you must still correctly
|
||||
pack up your own arguments to pass as args for locking functions, etc.
|
||||
|
||||
=head1 EXPORTED SYMBOLS
|
||||
|
||||
By default your system's F_* and O_* constants (eg, F_DUPFD and
|
||||
O_CREAT) and the FD_CLOEXEC constant are exported into your namespace.
|
||||
|
||||
You can request that the flock() constants (LOCK_SH, LOCK_EX, LOCK_NB
|
||||
and LOCK_UN) be provided by using the tag C<:flock>. See L<Exporter>.
|
||||
|
||||
You can request that the old constants (FAPPEND, FASYNC, FCREAT,
|
||||
FDEFER, FEXCL, FNDELAY, FNONBLOCK, FSYNC, FTRUNC) be provided for
|
||||
compatibility reasons by using the tag C<:Fcompat>. For new
|
||||
applications the newer versions of these constants are suggested
|
||||
(O_APPEND, O_ASYNC, O_CREAT, O_DEFER, O_EXCL, O_NDELAY, O_NONBLOCK,
|
||||
O_SYNC, O_TRUNC).
|
||||
|
||||
For ease of use also the SEEK_* constants (for seek() and sysseek(),
|
||||
e.g. SEEK_END) and the S_I* constants (for chmod() and stat()) are
|
||||
available for import. They can be imported either separately or using
|
||||
the tags C<:seek> and C<:mode>.
|
||||
|
||||
Please refer to your native fcntl(2), open(2), fseek(3), lseek(2)
|
||||
(equal to Perl's seek() and sysseek(), respectively), and chmod(2)
|
||||
documentation to see what constants are implemented in your system.
|
||||
|
||||
See L<perlopentut> to learn about the uses of the O_* constants
|
||||
with sysopen().
|
||||
|
||||
See L<perlfunc/seek> and L<perlfunc/sysseek> about the SEEK_* constants.
|
||||
|
||||
See L<perlfunc/stat> about the S_I* constants.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
our($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $AUTOLOAD);
|
||||
|
||||
require Exporter;
|
||||
use XSLoader ();
|
||||
@ISA = qw(Exporter);
|
||||
BEGIN {
|
||||
$VERSION = "1.06";
|
||||
}
|
||||
|
||||
# Items to export into callers namespace by default
|
||||
# (move infrequently used names to @EXPORT_OK below)
|
||||
@EXPORT =
|
||||
qw(
|
||||
FD_CLOEXEC
|
||||
F_ALLOCSP
|
||||
F_ALLOCSP64
|
||||
F_COMPAT
|
||||
F_DUP2FD
|
||||
F_DUPFD
|
||||
F_EXLCK
|
||||
F_FREESP
|
||||
F_FREESP64
|
||||
F_FSYNC
|
||||
F_FSYNC64
|
||||
F_GETFD
|
||||
F_GETFL
|
||||
F_GETLK
|
||||
F_GETLK64
|
||||
F_GETOWN
|
||||
F_NODNY
|
||||
F_POSIX
|
||||
F_RDACC
|
||||
F_RDDNY
|
||||
F_RDLCK
|
||||
F_RWACC
|
||||
F_RWDNY
|
||||
F_SETFD
|
||||
F_SETFL
|
||||
F_SETLK
|
||||
F_SETLK64
|
||||
F_SETLKW
|
||||
F_SETLKW64
|
||||
F_SETOWN
|
||||
F_SHARE
|
||||
F_SHLCK
|
||||
F_UNLCK
|
||||
F_UNSHARE
|
||||
F_WRACC
|
||||
F_WRDNY
|
||||
F_WRLCK
|
||||
O_ACCMODE
|
||||
O_ALIAS
|
||||
O_APPEND
|
||||
O_ASYNC
|
||||
O_BINARY
|
||||
O_CREAT
|
||||
O_DEFER
|
||||
O_DIRECT
|
||||
O_DIRECTORY
|
||||
O_DSYNC
|
||||
O_EXCL
|
||||
O_EXLOCK
|
||||
O_LARGEFILE
|
||||
O_NDELAY
|
||||
O_NOCTTY
|
||||
O_NOFOLLOW
|
||||
O_NOINHERIT
|
||||
O_NONBLOCK
|
||||
O_RANDOM
|
||||
O_RAW
|
||||
O_RDONLY
|
||||
O_RDWR
|
||||
O_RSRC
|
||||
O_RSYNC
|
||||
O_SEQUENTIAL
|
||||
O_SHLOCK
|
||||
O_SYNC
|
||||
O_TEMPORARY
|
||||
O_TEXT
|
||||
O_TRUNC
|
||||
O_WRONLY
|
||||
);
|
||||
|
||||
# Other items we are prepared to export if requested
|
||||
@EXPORT_OK = qw(
|
||||
DN_ACCESS
|
||||
DN_ATTRIB
|
||||
DN_CREATE
|
||||
DN_DELETE
|
||||
DN_MODIFY
|
||||
DN_MULTISHOT
|
||||
DN_RENAME
|
||||
FAPPEND
|
||||
FASYNC
|
||||
FCREAT
|
||||
FDEFER
|
||||
FDSYNC
|
||||
FEXCL
|
||||
FLARGEFILE
|
||||
FNDELAY
|
||||
FNONBLOCK
|
||||
FRSYNC
|
||||
FSYNC
|
||||
FTRUNC
|
||||
F_GETLEASE
|
||||
F_GETSIG
|
||||
F_NOTIFY
|
||||
F_SETLEASE
|
||||
F_SETSIG
|
||||
LOCK_EX
|
||||
LOCK_MAND
|
||||
LOCK_NB
|
||||
LOCK_READ
|
||||
LOCK_RW
|
||||
LOCK_SH
|
||||
LOCK_UN
|
||||
LOCK_WRITE
|
||||
O_IGNORE_CTTY
|
||||
O_NOATIME
|
||||
O_NOLINK
|
||||
O_NOTRANS
|
||||
SEEK_CUR
|
||||
SEEK_END
|
||||
SEEK_SET
|
||||
S_IFSOCK S_IFBLK S_IFCHR S_IFIFO S_IFWHT S_ENFMT
|
||||
S_IREAD S_IWRITE S_IEXEC
|
||||
S_IRGRP S_IWGRP S_IXGRP S_IRWXG
|
||||
S_IROTH S_IWOTH S_IXOTH S_IRWXO
|
||||
S_IRUSR S_IWUSR S_IXUSR S_IRWXU
|
||||
S_ISUID S_ISGID S_ISVTX S_ISTXT
|
||||
_S_IFMT S_IFREG S_IFDIR S_IFLNK
|
||||
&S_ISREG &S_ISDIR &S_ISLNK &S_ISSOCK &S_ISBLK &S_ISCHR &S_ISFIFO
|
||||
&S_ISWHT &S_ISENFMT &S_IFMT &S_IMODE
|
||||
);
|
||||
# Named groups of exports
|
||||
%EXPORT_TAGS = (
|
||||
'flock' => [qw(LOCK_SH LOCK_EX LOCK_NB LOCK_UN)],
|
||||
'Fcompat' => [qw(FAPPEND FASYNC FCREAT FDEFER FDSYNC FEXCL FLARGEFILE
|
||||
FNDELAY FNONBLOCK FRSYNC FSYNC FTRUNC)],
|
||||
'seek' => [qw(SEEK_SET SEEK_CUR SEEK_END)],
|
||||
'mode' => [qw(S_ISUID S_ISGID S_ISVTX S_ISTXT
|
||||
_S_IFMT S_IFREG S_IFDIR S_IFLNK
|
||||
S_IFSOCK S_IFBLK S_IFCHR S_IFIFO S_IFWHT S_ENFMT
|
||||
S_IRUSR S_IWUSR S_IXUSR S_IRWXU
|
||||
S_IRGRP S_IWGRP S_IXGRP S_IRWXG
|
||||
S_IROTH S_IWOTH S_IXOTH S_IRWXO
|
||||
S_IREAD S_IWRITE S_IEXEC
|
||||
S_ISREG S_ISDIR S_ISLNK S_ISSOCK
|
||||
S_ISBLK S_ISCHR S_ISFIFO
|
||||
S_ISWHT S_ISENFMT
|
||||
S_IFMT S_IMODE
|
||||
)],
|
||||
);
|
||||
|
||||
# Force the constants to become inlined
|
||||
BEGIN {
|
||||
XSLoader::load 'Fcntl', $VERSION;
|
||||
}
|
||||
|
||||
sub S_IFMT { @_ ? ( $_[0] & _S_IFMT() ) : _S_IFMT() }
|
||||
sub S_IMODE { $_[0] & 07777 }
|
||||
|
||||
sub S_ISREG { ( $_[0] & _S_IFMT() ) == S_IFREG() }
|
||||
sub S_ISDIR { ( $_[0] & _S_IFMT() ) == S_IFDIR() }
|
||||
sub S_ISLNK { ( $_[0] & _S_IFMT() ) == S_IFLNK() }
|
||||
sub S_ISSOCK { ( $_[0] & _S_IFMT() ) == S_IFSOCK() }
|
||||
sub S_ISBLK { ( $_[0] & _S_IFMT() ) == S_IFBLK() }
|
||||
sub S_ISCHR { ( $_[0] & _S_IFMT() ) == S_IFCHR() }
|
||||
sub S_ISFIFO { ( $_[0] & _S_IFMT() ) == S_IFIFO() }
|
||||
sub S_ISWHT { ( $_[0] & _S_IFMT() ) == S_IFWHT() }
|
||||
sub S_ISENFMT { ( $_[0] & _S_IFMT() ) == S_IFENFMT() }
|
||||
|
||||
sub AUTOLOAD {
|
||||
(my $constname = $AUTOLOAD) =~ s/.*:://;
|
||||
die "&Fcntl::constant not defined" if $constname eq 'constant';
|
||||
my ($error, $val) = constant($constname);
|
||||
if ($error) {
|
||||
my (undef,$file,$line) = caller;
|
||||
die "$error at $file line $line.\n";
|
||||
}
|
||||
no strict 'refs';
|
||||
*$AUTOLOAD = sub { $val };
|
||||
goto &$AUTOLOAD;
|
||||
}
|
||||
|
||||
1;
|
350
devtools/srcsrv/perl/lib/XSLoader.pm
Normal file
350
devtools/srcsrv/perl/lib/XSLoader.pm
Normal file
@ -0,0 +1,350 @@
|
||||
# Generated from XSLoader.pm.PL (resolved %Config::Config value)
|
||||
|
||||
package XSLoader;
|
||||
|
||||
$VERSION = "0.08";
|
||||
|
||||
#use strict;
|
||||
|
||||
# enable debug/trace messages from DynaLoader perl code
|
||||
# $dl_debug = $ENV{PERL_DL_DEBUG} || 0 unless defined $dl_debug;
|
||||
|
||||
my $dl_dlext = 'dll';
|
||||
|
||||
package DynaLoader;
|
||||
|
||||
# No prizes for guessing why we don't say 'bootstrap DynaLoader;' here.
|
||||
# NOTE: All dl_*.xs (including dl_none.xs) define a dl_error() XSUB
|
||||
boot_DynaLoader('DynaLoader') if defined(&boot_DynaLoader) &&
|
||||
!defined(&dl_error);
|
||||
package XSLoader;
|
||||
|
||||
sub load {
|
||||
package DynaLoader;
|
||||
|
||||
die q{XSLoader::load('Your::Module', $Your::Module::VERSION)} unless @_;
|
||||
|
||||
my($module) = $_[0];
|
||||
|
||||
# work with static linking too
|
||||
my $b = "$module\::bootstrap";
|
||||
goto &$b if defined &$b;
|
||||
|
||||
goto retry unless $module and defined &dl_load_file;
|
||||
|
||||
my @modparts = split(/::/,$module);
|
||||
my $modfname = $modparts[-1];
|
||||
|
||||
my $modpname = join('/',@modparts);
|
||||
my $modlibname = (caller())[1];
|
||||
my $c = @modparts;
|
||||
$modlibname =~ s,[\\/][^\\/]+$,, while $c--; # Q&D basename
|
||||
my $file = "$modlibname/auto/$modpname/$modfname.$dl_dlext";
|
||||
|
||||
# print STDERR "XSLoader::load for $module ($file)\n" if $dl_debug;
|
||||
|
||||
my $bs = $file;
|
||||
$bs =~ s/(\.\w+)?(;\d*)?$/\.bs/; # look for .bs 'beside' the library
|
||||
|
||||
goto retry if not -f $file or -s $bs;
|
||||
|
||||
my $bootname = "boot_$module";
|
||||
$bootname =~ s/\W/_/g;
|
||||
@DynaLoader::dl_require_symbols = ($bootname);
|
||||
|
||||
my $boot_symbol_ref;
|
||||
|
||||
# Many dynamic extension loading problems will appear to come from
|
||||
# this section of code: XYZ failed at line 123 of DynaLoader.pm.
|
||||
# Often these errors are actually occurring in the initialisation
|
||||
# C code of the extension XS file. Perl reports the error as being
|
||||
# in this perl code simply because this was the last perl code
|
||||
# it executed.
|
||||
|
||||
my $libref = dl_load_file($file, 0) or do {
|
||||
require Carp;
|
||||
Carp::croak("Can't load '$file' for module $module: " . dl_error());
|
||||
};
|
||||
push(@DynaLoader::dl_librefs,$libref); # record loaded object
|
||||
|
||||
my @unresolved = dl_undef_symbols();
|
||||
if (@unresolved) {
|
||||
require Carp;
|
||||
Carp::carp("Undefined symbols present after loading $file: @unresolved\n");
|
||||
}
|
||||
|
||||
$boot_symbol_ref = dl_find_symbol($libref, $bootname) or do {
|
||||
require Carp;
|
||||
Carp::croak("Can't find '$bootname' symbol in $file\n");
|
||||
};
|
||||
|
||||
push(@DynaLoader::dl_modules, $module); # record loaded module
|
||||
|
||||
boot:
|
||||
my $xs = dl_install_xsub("${module}::bootstrap", $boot_symbol_ref, $file);
|
||||
|
||||
# See comment block above
|
||||
push(@DynaLoader::dl_shared_objects, $file); # record files loaded
|
||||
return &$xs(@_);
|
||||
|
||||
retry:
|
||||
my $bootstrap_inherit = DynaLoader->can('bootstrap_inherit') ||
|
||||
XSLoader->can('bootstrap_inherit');
|
||||
goto &$bootstrap_inherit;
|
||||
}
|
||||
|
||||
# Versions of DynaLoader prior to 5.6.0 don't have this function.
|
||||
sub bootstrap_inherit {
|
||||
package DynaLoader;
|
||||
|
||||
my $module = $_[0];
|
||||
local *DynaLoader::isa = *{"$module\::ISA"};
|
||||
local @DynaLoader::isa = (@DynaLoader::isa, 'DynaLoader');
|
||||
# Cannot goto due to delocalization. Will report errors on a wrong line?
|
||||
require DynaLoader;
|
||||
DynaLoader::bootstrap(@_);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
XSLoader - Dynamically load C libraries into Perl code
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.08
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package YourPackage;
|
||||
use XSLoader;
|
||||
|
||||
XSLoader::load 'YourPackage', $YourPackage::VERSION;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module defines a standard I<simplified> interface to the dynamic
|
||||
linking mechanisms available on many platforms. Its primary purpose is
|
||||
to implement cheap automatic dynamic loading of Perl modules.
|
||||
|
||||
For a more complicated interface, see L<DynaLoader>. Many (most)
|
||||
features of C<DynaLoader> are not implemented in C<XSLoader>, like for
|
||||
example the C<dl_load_flags>, not honored by C<XSLoader>.
|
||||
|
||||
=head2 Migration from C<DynaLoader>
|
||||
|
||||
A typical module using L<DynaLoader|DynaLoader> starts like this:
|
||||
|
||||
package YourPackage;
|
||||
require DynaLoader;
|
||||
|
||||
our @ISA = qw( OnePackage OtherPackage DynaLoader );
|
||||
our $VERSION = '0.01';
|
||||
bootstrap YourPackage $VERSION;
|
||||
|
||||
Change this to
|
||||
|
||||
package YourPackage;
|
||||
use XSLoader;
|
||||
|
||||
our @ISA = qw( OnePackage OtherPackage );
|
||||
our $VERSION = '0.01';
|
||||
XSLoader::load 'YourPackage', $VERSION;
|
||||
|
||||
In other words: replace C<require DynaLoader> by C<use XSLoader>, remove
|
||||
C<DynaLoader> from C<@ISA>, change C<bootstrap> by C<XSLoader::load>. Do not
|
||||
forget to quote the name of your package on the C<XSLoader::load> line,
|
||||
and add comma (C<,>) before the arguments (C<$VERSION> above).
|
||||
|
||||
Of course, if C<@ISA> contained only C<DynaLoader>, there is no need to have
|
||||
the C<@ISA> assignment at all; moreover, if instead of C<our> one uses the
|
||||
more backward-compatible
|
||||
|
||||
use vars qw($VERSION @ISA);
|
||||
|
||||
one can remove this reference to C<@ISA> together with the C<@ISA> assignment.
|
||||
|
||||
If no C<$VERSION> was specified on the C<bootstrap> line, the last line becomes
|
||||
|
||||
XSLoader::load 'YourPackage';
|
||||
|
||||
=head2 Backward compatible boilerplate
|
||||
|
||||
If you want to have your cake and eat it too, you need a more complicated
|
||||
boilerplate.
|
||||
|
||||
package YourPackage;
|
||||
use vars qw($VERSION @ISA);
|
||||
|
||||
@ISA = qw( OnePackage OtherPackage );
|
||||
$VERSION = '0.01';
|
||||
eval {
|
||||
require XSLoader;
|
||||
XSLoader::load('YourPackage', $VERSION);
|
||||
1;
|
||||
} or do {
|
||||
require DynaLoader;
|
||||
push @ISA, 'DynaLoader';
|
||||
bootstrap YourPackage $VERSION;
|
||||
};
|
||||
|
||||
The parentheses about C<XSLoader::load()> arguments are needed since we replaced
|
||||
C<use XSLoader> by C<require>, so the compiler does not know that a function
|
||||
C<XSLoader::load()> is present.
|
||||
|
||||
This boilerplate uses the low-overhead C<XSLoader> if present; if used with
|
||||
an antic Perl which has no C<XSLoader>, it falls back to using C<DynaLoader>.
|
||||
|
||||
=head1 Order of initialization: early load()
|
||||
|
||||
I<Skip this section if the XSUB functions are supposed to be called from other
|
||||
modules only; read it only if you call your XSUBs from the code in your module,
|
||||
or have a C<BOOT:> section in your XS file (see L<perlxs/"The BOOT: Keyword">).
|
||||
What is described here is equally applicable to the L<DynaLoader|DynaLoader>
|
||||
interface.>
|
||||
|
||||
A sufficiently complicated module using XS would have both Perl code (defined
|
||||
in F<YourPackage.pm>) and XS code (defined in F<YourPackage.xs>). If this
|
||||
Perl code makes calls into this XS code, and/or this XS code makes calls to
|
||||
the Perl code, one should be careful with the order of initialization.
|
||||
|
||||
The call to C<XSLoader::load()> (or C<bootstrap()>) has three side effects:
|
||||
|
||||
=over
|
||||
|
||||
=item *
|
||||
|
||||
if C<$VERSION> was specified, a sanity check is done to ensure that the
|
||||
versions of the F<.pm> and the (compiled) F<.xs> parts are compatible;
|
||||
|
||||
=item *
|
||||
|
||||
the XSUBs are made accessible from Perl;
|
||||
|
||||
=item *
|
||||
|
||||
if a C<BOOT:> section was present in the F<.xs> file, the code there is called.
|
||||
|
||||
=back
|
||||
|
||||
Consequently, if the code in the F<.pm> file makes calls to these XSUBs, it is
|
||||
convenient to have XSUBs installed before the Perl code is defined; for
|
||||
example, this makes prototypes for XSUBs visible to this Perl code.
|
||||
Alternatively, if the C<BOOT:> section makes calls to Perl functions (or
|
||||
uses Perl variables) defined in the F<.pm> file, they must be defined prior to
|
||||
the call to C<XSLoader::load()> (or C<bootstrap()>).
|
||||
|
||||
The first situation being much more frequent, it makes sense to rewrite the
|
||||
boilerplate as
|
||||
|
||||
package YourPackage;
|
||||
use XSLoader;
|
||||
use vars qw($VERSION @ISA);
|
||||
|
||||
BEGIN {
|
||||
@ISA = qw( OnePackage OtherPackage );
|
||||
$VERSION = '0.01';
|
||||
|
||||
# Put Perl code used in the BOOT: section here
|
||||
|
||||
XSLoader::load 'YourPackage', $VERSION;
|
||||
}
|
||||
|
||||
# Put Perl code making calls into XSUBs here
|
||||
|
||||
=head2 The most hairy case
|
||||
|
||||
If the interdependence of your C<BOOT:> section and Perl code is
|
||||
more complicated than this (e.g., the C<BOOT:> section makes calls to Perl
|
||||
functions which make calls to XSUBs with prototypes), get rid of the C<BOOT:>
|
||||
section altogether. Replace it with a function C<onBOOT()>, and call it like
|
||||
this:
|
||||
|
||||
package YourPackage;
|
||||
use XSLoader;
|
||||
use vars qw($VERSION @ISA);
|
||||
|
||||
BEGIN {
|
||||
@ISA = qw( OnePackage OtherPackage );
|
||||
$VERSION = '0.01';
|
||||
XSLoader::load 'YourPackage', $VERSION;
|
||||
}
|
||||
|
||||
# Put Perl code used in onBOOT() function here; calls to XSUBs are
|
||||
# prototype-checked.
|
||||
|
||||
onBOOT;
|
||||
|
||||
# Put Perl initialization code assuming that XS is initialized here
|
||||
|
||||
|
||||
=head1 DIAGNOSTICS
|
||||
|
||||
=over
|
||||
|
||||
=item C<Can't find '%s' symbol in %s>
|
||||
|
||||
B<(F)> The bootstrap symbol could not be found in the extension module.
|
||||
|
||||
=item C<Can't load '%s' for module %s: %s>
|
||||
|
||||
B<(F)> The loading or initialisation of the extension module failed.
|
||||
The detailed error follows.
|
||||
|
||||
=item C<Undefined symbols present after loading %s: %s>
|
||||
|
||||
B<(W)> As the message says, some symbols stay undefined although the
|
||||
extension module was correctly loaded and initialised. The list of undefined
|
||||
symbols follows.
|
||||
|
||||
=item C<XSLoader::load('Your::Module', $Your::Module::VERSION)>
|
||||
|
||||
B<(F)> You tried to invoke C<load()> without any argument. You must supply
|
||||
a module name, and optionally its version.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 LIMITATIONS
|
||||
|
||||
To reduce the overhead as much as possible, only one possible location
|
||||
is checked to find the extension DLL (this location is where C<make install>
|
||||
would put the DLL). If not found, the search for the DLL is transparently
|
||||
delegated to C<DynaLoader>, which looks for the DLL along the C<@INC> list.
|
||||
|
||||
In particular, this is applicable to the structure of C<@INC> used for testing
|
||||
not-yet-installed extensions. This means that running uninstalled extensions
|
||||
may have much more overhead than running the same extensions after
|
||||
C<make install>.
|
||||
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Please report any bugs or feature requests via the perlbug(1) utility.
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<DynaLoader>
|
||||
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Ilya Zakharevich originally extracted C<XSLoader> from C<DynaLoader>.
|
||||
|
||||
CPAN version is currently maintained by SE<eacute>bastien Aperghis-Tramoni
|
||||
E<lt>sebastien@aperghis.netE<gt>.
|
||||
|
||||
Previous maintainer was Michael G Schwern <schwern@pobox.com>.
|
||||
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself.
|
||||
|
||||
=cut
|
BIN
devtools/srcsrv/perl/lib/auto/Data/Dumper/Dumper.dll
Normal file
BIN
devtools/srcsrv/perl/lib/auto/Data/Dumper/Dumper.dll
Normal file
Binary file not shown.
BIN
devtools/srcsrv/perl/lib/auto/fcntl/Fcntl.dll
Normal file
BIN
devtools/srcsrv/perl/lib/auto/fcntl/Fcntl.dll
Normal file
Binary file not shown.
88
devtools/srcsrv/perl/lib/bytes.pm
Normal file
88
devtools/srcsrv/perl/lib/bytes.pm
Normal file
@ -0,0 +1,88 @@
|
||||
package bytes;
|
||||
|
||||
our $VERSION = '1.02';
|
||||
|
||||
$bytes::hint_bits = 0x00000008;
|
||||
|
||||
sub import {
|
||||
$^H |= $bytes::hint_bits;
|
||||
}
|
||||
|
||||
sub unimport {
|
||||
$^H &= ~$bytes::hint_bits;
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
require "bytes_heavy.pl";
|
||||
goto &$AUTOLOAD if defined &$AUTOLOAD;
|
||||
require Carp;
|
||||
Carp::croak("Undefined subroutine $AUTOLOAD called");
|
||||
}
|
||||
|
||||
sub length ($);
|
||||
sub chr ($);
|
||||
sub ord ($);
|
||||
sub substr ($$;$$);
|
||||
sub index ($$;$);
|
||||
sub rindex ($$;$);
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
bytes - Perl pragma to force byte semantics rather than character semantics
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use bytes;
|
||||
... chr(...); # or bytes::chr
|
||||
... index(...); # or bytes::index
|
||||
... length(...); # or bytes::length
|
||||
... ord(...); # or bytes::ord
|
||||
... rindex(...); # or bytes::rindex
|
||||
... substr(...); # or bytes::substr
|
||||
no bytes;
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The C<use bytes> pragma disables character semantics for the rest of the
|
||||
lexical scope in which it appears. C<no bytes> can be used to reverse
|
||||
the effect of C<use bytes> within the current lexical scope.
|
||||
|
||||
Perl normally assumes character semantics in the presence of character
|
||||
data (i.e. data that has come from a source that has been marked as
|
||||
being of a particular character encoding). When C<use bytes> is in
|
||||
effect, the encoding is temporarily ignored, and each string is treated
|
||||
as a series of bytes.
|
||||
|
||||
As an example, when Perl sees C<$x = chr(400)>, it encodes the character
|
||||
in UTF-8 and stores it in $x. Then it is marked as character data, so,
|
||||
for instance, C<length $x> returns C<1>. However, in the scope of the
|
||||
C<bytes> pragma, $x is treated as a series of bytes - the bytes that make
|
||||
up the UTF8 encoding - and C<length $x> returns C<2>:
|
||||
|
||||
$x = chr(400);
|
||||
print "Length is ", length $x, "\n"; # "Length is 1"
|
||||
printf "Contents are %vd\n", $x; # "Contents are 400"
|
||||
{
|
||||
use bytes; # or "require bytes; bytes::length()"
|
||||
print "Length is ", length $x, "\n"; # "Length is 2"
|
||||
printf "Contents are %vd\n", $x; # "Contents are 198.144"
|
||||
}
|
||||
|
||||
chr(), ord(), substr(), index() and rindex() behave similarly.
|
||||
|
||||
For more on the implications and differences between character
|
||||
semantics and byte semantics, see L<perluniintro> and L<perlunicode>.
|
||||
|
||||
=head1 LIMITATIONS
|
||||
|
||||
bytes::substr() does not work as an lvalue().
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<perluniintro>, L<perlunicode>, L<utf8>
|
||||
|
||||
=cut
|
1280
devtools/srcsrv/perl/lib/data/Dumper.pm
Normal file
1280
devtools/srcsrv/perl/lib/data/Dumper.pm
Normal file
File diff suppressed because it is too large
Load Diff
1455
devtools/srcsrv/perl/lib/overload.pm
Normal file
1455
devtools/srcsrv/perl/lib/overload.pm
Normal file
File diff suppressed because it is too large
Load Diff
136
devtools/srcsrv/perl/lib/strict.pm
Normal file
136
devtools/srcsrv/perl/lib/strict.pm
Normal file
@ -0,0 +1,136 @@
|
||||
package strict;
|
||||
|
||||
$strict::VERSION = "1.03";
|
||||
|
||||
my %bitmask = (
|
||||
refs => 0x00000002,
|
||||
subs => 0x00000200,
|
||||
vars => 0x00000400
|
||||
);
|
||||
|
||||
sub bits {
|
||||
my $bits = 0;
|
||||
my @wrong;
|
||||
foreach my $s (@_) {
|
||||
push @wrong, $s unless exists $bitmask{$s};
|
||||
$bits |= $bitmask{$s} || 0;
|
||||
}
|
||||
if (@wrong) {
|
||||
require Carp;
|
||||
Carp::croak("Unknown 'strict' tag(s) '@wrong'");
|
||||
}
|
||||
$bits;
|
||||
}
|
||||
|
||||
my $default_bits = bits(qw(refs subs vars));
|
||||
|
||||
sub import {
|
||||
shift;
|
||||
$^H |= @_ ? bits(@_) : $default_bits;
|
||||
}
|
||||
|
||||
sub unimport {
|
||||
shift;
|
||||
$^H &= ~ (@_ ? bits(@_) : $default_bits);
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
strict - Perl pragma to restrict unsafe constructs
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use strict;
|
||||
|
||||
use strict "vars";
|
||||
use strict "refs";
|
||||
use strict "subs";
|
||||
|
||||
use strict;
|
||||
no strict "vars";
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
If no import list is supplied, all possible restrictions are assumed.
|
||||
(This is the safest mode to operate in, but is sometimes too strict for
|
||||
casual programming.) Currently, there are three possible things to be
|
||||
strict about: "subs", "vars", and "refs".
|
||||
|
||||
=over 6
|
||||
|
||||
=item C<strict refs>
|
||||
|
||||
This generates a runtime error if you
|
||||
use symbolic references (see L<perlref>).
|
||||
|
||||
use strict 'refs';
|
||||
$ref = \$foo;
|
||||
print $$ref; # ok
|
||||
$ref = "foo";
|
||||
print $$ref; # runtime error; normally ok
|
||||
$file = "STDOUT";
|
||||
print $file "Hi!"; # error; note: no comma after $file
|
||||
|
||||
There is one exception to this rule:
|
||||
|
||||
$bar = \&{'foo'};
|
||||
&$bar;
|
||||
|
||||
is allowed so that C<goto &$AUTOLOAD> would not break under stricture.
|
||||
|
||||
|
||||
=item C<strict vars>
|
||||
|
||||
This generates a compile-time error if you access a variable that wasn't
|
||||
declared via C<our> or C<use vars>,
|
||||
localized via C<my()>, or wasn't fully qualified. Because this is to avoid
|
||||
variable suicide problems and subtle dynamic scoping issues, a merely
|
||||
local() variable isn't good enough. See L<perlfunc/my> and
|
||||
L<perlfunc/local>.
|
||||
|
||||
use strict 'vars';
|
||||
$X::foo = 1; # ok, fully qualified
|
||||
my $foo = 10; # ok, my() var
|
||||
local $foo = 9; # blows up
|
||||
|
||||
package Cinna;
|
||||
our $bar; # Declares $bar in current package
|
||||
$bar = 'HgS'; # ok, global declared via pragma
|
||||
|
||||
The local() generated a compile-time error because you just touched a global
|
||||
name without fully qualifying it.
|
||||
|
||||
Because of their special use by sort(), the variables $a and $b are
|
||||
exempted from this check.
|
||||
|
||||
=item C<strict subs>
|
||||
|
||||
This disables the poetry optimization, generating a compile-time error if
|
||||
you try to use a bareword identifier that's not a subroutine, unless it
|
||||
is a simple identifier (no colons) and that it appears in curly braces or
|
||||
on the left hand side of the C<< => >> symbol.
|
||||
|
||||
use strict 'subs';
|
||||
$SIG{PIPE} = Plumber; # blows up
|
||||
$SIG{PIPE} = "Plumber"; # just fine: quoted string is always ok
|
||||
$SIG{PIPE} = \&Plumber; # preferred form
|
||||
|
||||
=back
|
||||
|
||||
See L<perlmodlib/Pragmatic Modules>.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
C<strict 'subs'>, with Perl 5.6.1, erroneously permitted to use an unquoted
|
||||
compound identifier (e.g. C<Foo::Bar>) as a hash key (before C<< => >> or
|
||||
inside curlies), but without forcing it always to a literal string.
|
||||
|
||||
Starting with Perl 5.8.1 strict is strict about its restrictions:
|
||||
if unknown restrictions are used, the strict pragma will abort with
|
||||
|
||||
Unknown 'strict' tag(s) '...'
|
||||
|
||||
=cut
|
497
devtools/srcsrv/perl/lib/warnings.pm
Normal file
497
devtools/srcsrv/perl/lib/warnings.pm
Normal file
@ -0,0 +1,497 @@
|
||||
# -*- buffer-read-only: t -*-
|
||||
# !!!!!!! DO NOT EDIT THIS FILE !!!!!!!
|
||||
# This file was created by warnings.pl
|
||||
# Any changes made here will be lost.
|
||||
#
|
||||
|
||||
package warnings;
|
||||
|
||||
our $VERSION = '1.05';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
warnings - Perl pragma to control optional warnings
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use warnings;
|
||||
no warnings;
|
||||
|
||||
use warnings "all";
|
||||
no warnings "all";
|
||||
|
||||
use warnings::register;
|
||||
if (warnings::enabled()) {
|
||||
warnings::warn("some warning");
|
||||
}
|
||||
|
||||
if (warnings::enabled("void")) {
|
||||
warnings::warn("void", "some warning");
|
||||
}
|
||||
|
||||
if (warnings::enabled($object)) {
|
||||
warnings::warn($object, "some warning");
|
||||
}
|
||||
|
||||
warnings::warnif("some warning");
|
||||
warnings::warnif("void", "some warning");
|
||||
warnings::warnif($object, "some warning");
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The C<warnings> pragma is a replacement for the command line flag C<-w>,
|
||||
but the pragma is limited to the enclosing block, while the flag is global.
|
||||
See L<perllexwarn> for more information.
|
||||
|
||||
If no import list is supplied, all possible warnings are either enabled
|
||||
or disabled.
|
||||
|
||||
A number of functions are provided to assist module authors.
|
||||
|
||||
=over 4
|
||||
|
||||
=item use warnings::register
|
||||
|
||||
Creates a new warnings category with the same name as the package where
|
||||
the call to the pragma is used.
|
||||
|
||||
=item warnings::enabled()
|
||||
|
||||
Use the warnings category with the same name as the current package.
|
||||
|
||||
Return TRUE if that warnings category is enabled in the calling module.
|
||||
Otherwise returns FALSE.
|
||||
|
||||
=item warnings::enabled($category)
|
||||
|
||||
Return TRUE if the warnings category, C<$category>, is enabled in the
|
||||
calling module.
|
||||
Otherwise returns FALSE.
|
||||
|
||||
=item warnings::enabled($object)
|
||||
|
||||
Use the name of the class for the object reference, C<$object>, as the
|
||||
warnings category.
|
||||
|
||||
Return TRUE if that warnings category is enabled in the first scope
|
||||
where the object is used.
|
||||
Otherwise returns FALSE.
|
||||
|
||||
=item warnings::warn($message)
|
||||
|
||||
Print C<$message> to STDERR.
|
||||
|
||||
Use the warnings category with the same name as the current package.
|
||||
|
||||
If that warnings category has been set to "FATAL" in the calling module
|
||||
then die. Otherwise return.
|
||||
|
||||
=item warnings::warn($category, $message)
|
||||
|
||||
Print C<$message> to STDERR.
|
||||
|
||||
If the warnings category, C<$category>, has been set to "FATAL" in the
|
||||
calling module then die. Otherwise return.
|
||||
|
||||
=item warnings::warn($object, $message)
|
||||
|
||||
Print C<$message> to STDERR.
|
||||
|
||||
Use the name of the class for the object reference, C<$object>, as the
|
||||
warnings category.
|
||||
|
||||
If that warnings category has been set to "FATAL" in the scope where C<$object>
|
||||
is first used then die. Otherwise return.
|
||||
|
||||
|
||||
=item warnings::warnif($message)
|
||||
|
||||
Equivalent to:
|
||||
|
||||
if (warnings::enabled())
|
||||
{ warnings::warn($message) }
|
||||
|
||||
=item warnings::warnif($category, $message)
|
||||
|
||||
Equivalent to:
|
||||
|
||||
if (warnings::enabled($category))
|
||||
{ warnings::warn($category, $message) }
|
||||
|
||||
=item warnings::warnif($object, $message)
|
||||
|
||||
Equivalent to:
|
||||
|
||||
if (warnings::enabled($object))
|
||||
{ warnings::warn($object, $message) }
|
||||
|
||||
=back
|
||||
|
||||
See L<perlmodlib/Pragmatic Modules> and L<perllexwarn>.
|
||||
|
||||
=cut
|
||||
|
||||
use Carp ();
|
||||
|
||||
our %Offsets = (
|
||||
|
||||
# Warnings Categories added in Perl 5.008
|
||||
|
||||
'all' => 0,
|
||||
'closure' => 2,
|
||||
'deprecated' => 4,
|
||||
'exiting' => 6,
|
||||
'glob' => 8,
|
||||
'io' => 10,
|
||||
'closed' => 12,
|
||||
'exec' => 14,
|
||||
'layer' => 16,
|
||||
'newline' => 18,
|
||||
'pipe' => 20,
|
||||
'unopened' => 22,
|
||||
'misc' => 24,
|
||||
'numeric' => 26,
|
||||
'once' => 28,
|
||||
'overflow' => 30,
|
||||
'pack' => 32,
|
||||
'portable' => 34,
|
||||
'recursion' => 36,
|
||||
'redefine' => 38,
|
||||
'regexp' => 40,
|
||||
'severe' => 42,
|
||||
'debugging' => 44,
|
||||
'inplace' => 46,
|
||||
'internal' => 48,
|
||||
'malloc' => 50,
|
||||
'signal' => 52,
|
||||
'substr' => 54,
|
||||
'syntax' => 56,
|
||||
'ambiguous' => 58,
|
||||
'bareword' => 60,
|
||||
'digit' => 62,
|
||||
'parenthesis' => 64,
|
||||
'precedence' => 66,
|
||||
'printf' => 68,
|
||||
'prototype' => 70,
|
||||
'qw' => 72,
|
||||
'reserved' => 74,
|
||||
'semicolon' => 76,
|
||||
'taint' => 78,
|
||||
'threads' => 80,
|
||||
'uninitialized' => 82,
|
||||
'unpack' => 84,
|
||||
'untie' => 86,
|
||||
'utf8' => 88,
|
||||
'void' => 90,
|
||||
'y2k' => 92,
|
||||
);
|
||||
|
||||
our %Bits = (
|
||||
'all' => "\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x15", # [0..46]
|
||||
'ambiguous' => "\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00", # [29]
|
||||
'bareword' => "\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00", # [30]
|
||||
'closed' => "\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6]
|
||||
'closure' => "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1]
|
||||
'debugging' => "\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00", # [22]
|
||||
'deprecated' => "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2]
|
||||
'digit' => "\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00", # [31]
|
||||
'exec' => "\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7]
|
||||
'exiting' => "\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
|
||||
'glob' => "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4]
|
||||
'inplace' => "\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00", # [23]
|
||||
'internal' => "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00", # [24]
|
||||
'io' => "\x00\x54\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5..11]
|
||||
'layer' => "\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8]
|
||||
'malloc' => "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00", # [25]
|
||||
'misc' => "\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", # [12]
|
||||
'newline' => "\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9]
|
||||
'numeric' => "\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00", # [13]
|
||||
'once' => "\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00", # [14]
|
||||
'overflow' => "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", # [15]
|
||||
'pack' => "\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00", # [16]
|
||||
'parenthesis' => "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00", # [32]
|
||||
'pipe' => "\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10]
|
||||
'portable' => "\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00", # [17]
|
||||
'precedence' => "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00", # [33]
|
||||
'printf' => "\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00", # [34]
|
||||
'prototype' => "\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00", # [35]
|
||||
'qw' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00", # [36]
|
||||
'recursion' => "\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00", # [18]
|
||||
'redefine' => "\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00", # [19]
|
||||
'regexp' => "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00", # [20]
|
||||
'reserved' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00", # [37]
|
||||
'semicolon' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00", # [38]
|
||||
'severe' => "\x00\x00\x00\x00\x00\x54\x05\x00\x00\x00\x00\x00", # [21..25]
|
||||
'signal' => "\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00", # [26]
|
||||
'substr' => "\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x00", # [27]
|
||||
'syntax' => "\x00\x00\x00\x00\x00\x00\x00\x55\x55\x15\x00\x00", # [28..38]
|
||||
'taint' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00", # [39]
|
||||
'threads' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00", # [40]
|
||||
'uninitialized' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00", # [41]
|
||||
'unopened' => "\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11]
|
||||
'unpack' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00", # [42]
|
||||
'untie' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00", # [43]
|
||||
'utf8' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", # [44]
|
||||
'void' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04", # [45]
|
||||
'y2k' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10", # [46]
|
||||
);
|
||||
|
||||
our %DeadBits = (
|
||||
'all' => "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x2a", # [0..46]
|
||||
'ambiguous' => "\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00", # [29]
|
||||
'bareword' => "\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00", # [30]
|
||||
'closed' => "\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [6]
|
||||
'closure' => "\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [1]
|
||||
'debugging' => "\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00", # [22]
|
||||
'deprecated' => "\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [2]
|
||||
'digit' => "\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00", # [31]
|
||||
'exec' => "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [7]
|
||||
'exiting' => "\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [3]
|
||||
'glob' => "\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [4]
|
||||
'inplace' => "\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00", # [23]
|
||||
'internal' => "\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00", # [24]
|
||||
'io' => "\x00\xa8\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [5..11]
|
||||
'layer' => "\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [8]
|
||||
'malloc' => "\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00", # [25]
|
||||
'misc' => "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00", # [12]
|
||||
'newline' => "\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [9]
|
||||
'numeric' => "\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00", # [13]
|
||||
'once' => "\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00", # [14]
|
||||
'overflow' => "\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00", # [15]
|
||||
'pack' => "\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", # [16]
|
||||
'parenthesis' => "\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00", # [32]
|
||||
'pipe' => "\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [10]
|
||||
'portable' => "\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00", # [17]
|
||||
'precedence' => "\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00", # [33]
|
||||
'printf' => "\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00", # [34]
|
||||
'prototype' => "\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00", # [35]
|
||||
'qw' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00", # [36]
|
||||
'recursion' => "\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00", # [18]
|
||||
'redefine' => "\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00", # [19]
|
||||
'regexp' => "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00", # [20]
|
||||
'reserved' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00", # [37]
|
||||
'semicolon' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00", # [38]
|
||||
'severe' => "\x00\x00\x00\x00\x00\xa8\x0a\x00\x00\x00\x00\x00", # [21..25]
|
||||
'signal' => "\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00", # [26]
|
||||
'substr' => "\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x00\x00", # [27]
|
||||
'syntax' => "\x00\x00\x00\x00\x00\x00\x00\xaa\xaa\x2a\x00\x00", # [28..38]
|
||||
'taint' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00", # [39]
|
||||
'threads' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00", # [40]
|
||||
'uninitialized' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00", # [41]
|
||||
'unopened' => "\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00", # [11]
|
||||
'unpack' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00", # [42]
|
||||
'untie' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00", # [43]
|
||||
'utf8' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02", # [44]
|
||||
'void' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08", # [45]
|
||||
'y2k' => "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20", # [46]
|
||||
);
|
||||
|
||||
$NONE = "\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||
$LAST_BIT = 94 ;
|
||||
$BYTES = 12 ;
|
||||
|
||||
$All = "" ; vec($All, $Offsets{'all'}, 2) = 3 ;
|
||||
|
||||
sub Croaker
|
||||
{
|
||||
require Carp::Heavy; # this initializes %CarpInternal
|
||||
delete $Carp::CarpInternal{'warnings'};
|
||||
Carp::croak(@_);
|
||||
}
|
||||
|
||||
sub bits
|
||||
{
|
||||
# called from B::Deparse.pm
|
||||
|
||||
push @_, 'all' unless @_;
|
||||
|
||||
my $mask;
|
||||
my $catmask ;
|
||||
my $fatal = 0 ;
|
||||
my $no_fatal = 0 ;
|
||||
|
||||
foreach my $word ( @_ ) {
|
||||
if ($word eq 'FATAL') {
|
||||
$fatal = 1;
|
||||
$no_fatal = 0;
|
||||
}
|
||||
elsif ($word eq 'NONFATAL') {
|
||||
$fatal = 0;
|
||||
$no_fatal = 1;
|
||||
}
|
||||
elsif ($catmask = $Bits{$word}) {
|
||||
$mask |= $catmask ;
|
||||
$mask |= $DeadBits{$word} if $fatal ;
|
||||
$mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
|
||||
}
|
||||
else
|
||||
{ Croaker("Unknown warnings category '$word'")}
|
||||
}
|
||||
|
||||
return $mask ;
|
||||
}
|
||||
|
||||
sub import
|
||||
{
|
||||
shift;
|
||||
|
||||
my $catmask ;
|
||||
my $fatal = 0 ;
|
||||
my $no_fatal = 0 ;
|
||||
|
||||
my $mask = ${^WARNING_BITS} ;
|
||||
|
||||
if (vec($mask, $Offsets{'all'}, 1)) {
|
||||
$mask |= $Bits{'all'} ;
|
||||
$mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
|
||||
}
|
||||
|
||||
push @_, 'all' unless @_;
|
||||
|
||||
foreach my $word ( @_ ) {
|
||||
if ($word eq 'FATAL') {
|
||||
$fatal = 1;
|
||||
$no_fatal = 0;
|
||||
}
|
||||
elsif ($word eq 'NONFATAL') {
|
||||
$fatal = 0;
|
||||
$no_fatal = 1;
|
||||
}
|
||||
elsif ($catmask = $Bits{$word}) {
|
||||
$mask |= $catmask ;
|
||||
$mask |= $DeadBits{$word} if $fatal ;
|
||||
$mask &= ~($DeadBits{$word}|$All) if $no_fatal ;
|
||||
}
|
||||
else
|
||||
{ Croaker("Unknown warnings category '$word'")}
|
||||
}
|
||||
|
||||
${^WARNING_BITS} = $mask ;
|
||||
}
|
||||
|
||||
sub unimport
|
||||
{
|
||||
shift;
|
||||
|
||||
my $catmask ;
|
||||
my $mask = ${^WARNING_BITS} ;
|
||||
|
||||
if (vec($mask, $Offsets{'all'}, 1)) {
|
||||
$mask |= $Bits{'all'} ;
|
||||
$mask |= $DeadBits{'all'} if vec($mask, $Offsets{'all'}+1, 1);
|
||||
}
|
||||
|
||||
push @_, 'all' unless @_;
|
||||
|
||||
foreach my $word ( @_ ) {
|
||||
if ($word eq 'FATAL') {
|
||||
next;
|
||||
}
|
||||
elsif ($catmask = $Bits{$word}) {
|
||||
$mask &= ~($catmask | $DeadBits{$word} | $All);
|
||||
}
|
||||
else
|
||||
{ Croaker("Unknown warnings category '$word'")}
|
||||
}
|
||||
|
||||
${^WARNING_BITS} = $mask ;
|
||||
}
|
||||
|
||||
my %builtin_type; @builtin_type{qw(SCALAR ARRAY HASH CODE REF GLOB LVALUE Regexp)} = ();
|
||||
|
||||
sub __chk
|
||||
{
|
||||
my $category ;
|
||||
my $offset ;
|
||||
my $isobj = 0 ;
|
||||
|
||||
if (@_) {
|
||||
# check the category supplied.
|
||||
$category = shift ;
|
||||
if (my $type = ref $category) {
|
||||
Croaker("not an object")
|
||||
if exists $builtin_type{$type};
|
||||
$category = $type;
|
||||
$isobj = 1 ;
|
||||
}
|
||||
$offset = $Offsets{$category};
|
||||
Croaker("Unknown warnings category '$category'")
|
||||
unless defined $offset;
|
||||
}
|
||||
else {
|
||||
$category = (caller(1))[0] ;
|
||||
$offset = $Offsets{$category};
|
||||
Croaker("package '$category' not registered for warnings")
|
||||
unless defined $offset ;
|
||||
}
|
||||
|
||||
my $this_pkg = (caller(1))[0] ;
|
||||
my $i = 2 ;
|
||||
my $pkg ;
|
||||
|
||||
if ($isobj) {
|
||||
while (do { { package DB; $pkg = (caller($i++))[0] } } ) {
|
||||
last unless @DB::args && $DB::args[0] =~ /^$category=/ ;
|
||||
}
|
||||
$i -= 2 ;
|
||||
}
|
||||
else {
|
||||
for ($i = 2 ; $pkg = (caller($i))[0] ; ++ $i) {
|
||||
last if $pkg ne $this_pkg ;
|
||||
}
|
||||
$i = 2
|
||||
if !$pkg || $pkg eq $this_pkg ;
|
||||
}
|
||||
|
||||
my $callers_bitmask = (caller($i))[9] ;
|
||||
return ($callers_bitmask, $offset, $i) ;
|
||||
}
|
||||
|
||||
sub enabled
|
||||
{
|
||||
Croaker("Usage: warnings::enabled([category])")
|
||||
unless @_ == 1 || @_ == 0 ;
|
||||
|
||||
my ($callers_bitmask, $offset, $i) = __chk(@_) ;
|
||||
|
||||
return 0 unless defined $callers_bitmask ;
|
||||
return vec($callers_bitmask, $offset, 1) ||
|
||||
vec($callers_bitmask, $Offsets{'all'}, 1) ;
|
||||
}
|
||||
|
||||
|
||||
sub warn
|
||||
{
|
||||
Croaker("Usage: warnings::warn([category,] 'message')")
|
||||
unless @_ == 2 || @_ == 1 ;
|
||||
|
||||
my $message = pop ;
|
||||
my ($callers_bitmask, $offset, $i) = __chk(@_) ;
|
||||
Carp::croak($message)
|
||||
if vec($callers_bitmask, $offset+1, 1) ||
|
||||
vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
|
||||
Carp::carp($message) ;
|
||||
}
|
||||
|
||||
sub warnif
|
||||
{
|
||||
Croaker("Usage: warnings::warnif([category,] 'message')")
|
||||
unless @_ == 2 || @_ == 1 ;
|
||||
|
||||
my $message = pop ;
|
||||
my ($callers_bitmask, $offset, $i) = __chk(@_) ;
|
||||
|
||||
return
|
||||
unless defined $callers_bitmask &&
|
||||
(vec($callers_bitmask, $offset, 1) ||
|
||||
vec($callers_bitmask, $Offsets{'all'}, 1)) ;
|
||||
|
||||
Carp::croak($message)
|
||||
if vec($callers_bitmask, $offset+1, 1) ||
|
||||
vec($callers_bitmask, $Offsets{'all'}+1, 1) ;
|
||||
|
||||
Carp::carp($message) ;
|
||||
}
|
||||
|
||||
1;
|
||||
# ex: set ro:
|
51
devtools/srcsrv/perl/lib/warnings/register.pm
Normal file
51
devtools/srcsrv/perl/lib/warnings/register.pm
Normal file
@ -0,0 +1,51 @@
|
||||
package warnings::register;
|
||||
|
||||
our $VERSION = '1.01';
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
warnings::register - warnings import function
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use warnings::register;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Creates a warnings category with the same name as the current package.
|
||||
|
||||
See L<warnings> and L<perllexwarn> for more information on this module's
|
||||
usage.
|
||||
|
||||
=cut
|
||||
|
||||
require warnings;
|
||||
|
||||
sub mkMask
|
||||
{
|
||||
my ($bit) = @_;
|
||||
my $mask = "";
|
||||
|
||||
vec($mask, $bit, 1) = 1;
|
||||
return $mask;
|
||||
}
|
||||
|
||||
sub import
|
||||
{
|
||||
shift;
|
||||
my $package = (caller(0))[0];
|
||||
if (! defined $warnings::Bits{$package}) {
|
||||
$warnings::Bits{$package} = mkMask($warnings::LAST_BIT);
|
||||
vec($warnings::Bits{'all'}, $warnings::LAST_BIT, 1) = 1;
|
||||
$warnings::Offsets{$package} = $warnings::LAST_BIT ++;
|
||||
foreach my $k (keys %warnings::Bits) {
|
||||
vec($warnings::Bits{$k}, $warnings::LAST_BIT, 1) = 0;
|
||||
}
|
||||
$warnings::DeadBits{$package} = mkMask($warnings::LAST_BIT);
|
||||
vec($warnings::DeadBits{'all'}, $warnings::LAST_BIT++, 1) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
1
devtools/srcsrv/perl/site/lib/sitecustomize.pl
Normal file
1
devtools/srcsrv/perl/site/lib/sitecustomize.pl
Normal file
@ -0,0 +1 @@
|
||||
# empty sitecustomize.pl file
|
14
devtools/version_script.linux.txt
Normal file
14
devtools/version_script.linux.txt
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
global: *;
|
||||
local:
|
||||
extern "C++" {
|
||||
*std::*;
|
||||
__cxxabi*;
|
||||
__gcc*;
|
||||
__gxx*;
|
||||
__gnu_cxx*;
|
||||
__cxa*;
|
||||
operator*;
|
||||
__dynamic_cast
|
||||
};
|
||||
};
|
Reference in New Issue
Block a user