#******************************************************************************* # Copyright (c) 1997-2004, Perforce Software, Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #******************************************************************************* use ExtUtils::MakeMaker; use Getopt::Long; use English; use Cwd; use Cwd 'abs_path'; use Config; use strict; #$ExtUtils::MakeMaker::Verbose = 1; our $APIDIR = undef; our $MAX_API_VERSION = undef; # # Check the Perforce API version from the Version file # sub extract_api_version { my $path = shift; my $cwd = getcwd(); my $apiver = undef; foreach my $vfile ( "$path/Version", "$path/sample/Version" ) { next unless ( -e $vfile ); open( VF, $vfile ) or die( "Can't open $vfile" ); while( <VF> ) { if( /^RELEASE = (.*) ;/ ) { $apiver = encode_api_version( $1 ); last; } } close( FH ); } my $tries = 3; while( !defined( $apiver ) && --$tries ) { print( "Unable to determine API version string\n" ); print( "Enter API version: " ); $apiver = <STDIN>; $apiver = encode_api_version( $apiver ); } die( "Aborting: API version not provided" ) unless $apiver; printf( "Found %d.%d Perforce API in %s\n", api_major( $apiver ), api_minor( $apiver ), $path ); return $apiver; } # # Encode an API version string into an integer # sub encode_api_version( $ ) { my $vs = shift; if( defined $vs && $vs =~ /(\d+)(\.|\s)(\d+)/ ) { return (($1 << 8 ) | $3 ); } return undef; } sub api_major( $ ) { my $v = shift; return $v >> 8; } sub api_minor( $ ) { my $v = shift; return $v & 0xff; } sub is_api_dir( $ ) { my $dir = shift; return 0 unless ( -d $dir ); return 1 if( -e "$dir/Version" ); return 1 if( -e "$dir/sample/Version" ); return 0; } # # Check that they're using an API version we can digest. # sub check_api_version( $ ) { my $api_ver = shift; my $max_ver_name = sprintf( "%d.%d", api_major( $MAX_API_VERSION ), api_minor( $MAX_API_VERSION ) ); return 1 if( $api_ver <= $MAX_API_VERSION ); print <<EOF; This version of P4Perl was designed for use with the $max_ver_name Perforce C++ API. Using it with later releases may not work. EOF print( "Do you wish to continue? (y/n): " ); my $answer = <STDIN>; chomp( $answer ); return 0 unless $answer eq "y"; return 1; } sub get_api_dir() { if( defined( $APIDIR ) && is_api_dir( $APIDIR ) ) { return $APIDIR; } # Get the path to the Perforce API my $apipath = undef; my $tries = 3; $apipath = $APIDIR if( defined( $APIDIR ) ); while( !defined( $apipath ) && --$tries ) { print <<EOF; This extension requires the Perforce API in order to be built. If you do not yet have the API files, then download them from ftp://ftp.perforce.com before continuing. EOF print( "Where is the Perforce API to be found: " ); $apipath = <STDIN>; $apipath =~ s/\n//; # Filthy support for ~/ type paths ( NOT ~user/ though! ) $apipath =~ s#\~/#$ENV{HOME}/#; $apipath = abs_path( $apipath ); $apipath = undef unless( is_api_dir( $apipath ) ); } die ( "Aborting - no API directory provided" ) unless $apipath; return $apipath; } # # Add the Perforce libraries to the linker configuration # sub add_p4_libs( $$$ ) { my $cfg = shift; # Perl's pre-set config my $flags = shift; # Flags we want to add my $apidir = shift; # Our API directory my $libdir = $apidir; $libdir = "$libdir/lib" if( -d "$libdir/lib" ); $flags->{'LIBS'} = []; if( defined( $cfg->{LIBS} ) ) { my $libs = $cfg->{LIBS}; foreach my $libset (@$libs ) { push( @{$flags->{LIBS}}, "-L$libdir -lclient -lrpc -lsupp $libset" ); } } else { push( @{$flags->{LIBS}}, "-L$libdir -lclient -lrpc -lsupp" ); } } # # Add the Perforce headers to the includes # sub add_p4_hdrs( $$ ) { my $flags = shift; my $apipath = shift; $apipath = "$apipath/include/p4" if( -d "$apipath/include/p4" ); $flags->{ 'INC' } = "-I$apipath -Ilib"; } # # This sub adds the Perforce API path to the header includes and libs # used by the compiler. It's called by WriteMakefile. # sub config_sub { my $class = shift; my $href = shift; # First warn them about potential build problems print <<EOF; Warning: This extension uses C++ and requires that you use the C++ compiler to compile the XSUB file ( normally just a C compiler is required ). If your build fails with a plethora of errors, then check the following first: 1. That the correct compilers are being used. 2. That you're using the correct build of the Perforce API. 3. That you have defined the correct OS_xxxxx macro for your platform ( see the Perforce API documentation for more info ) See hints/linux.pl to see how it should be done. EOF # Now find that API! my $flags = {}; # Get the path to the Perforce API my $apiver = undef; my $apipath = get_api_dir(); # dies if API not found $apiver = extract_api_version( $apipath ); # # Abort if the user's decided not to press ahead with a newer # version of the API than this version was written for # exit( 1 ) unless ( check_api_version( $apiver ) ); $href->{ 'DEFINE' } .= " -DP4API_VERSION=$apiver"; # # Set the build date # my $now = time(); $href->{ 'DEFINE' } .= " -DBUILD_DATE=$now"; # # Decide how const_char should be handled. If the API is 2006.1 or # later, then const_char should always be 'const char'. If it's # earlier, then go with the hint (if any) or default to 'char' # my $sixone = encode_api_version( "2006.1" ); if( $apiver ge $sixone ) { $href->{ 'DEFINE' } .= qq( -Dconst_char="const char"); } elsif( defined $href->{CONST_CHAR_HINT} ) { $href->{ 'DEFINE' } .= qq( -Dconst_char="$href->{CONST_CHAR_HINT}"); } else { $href->{ 'DEFINE' } .= qq( -Dconst_char="char"); } delete $href->{CONST_CHAR_HINT} if( defined($href->{CONST_CHAR_HINT}) ); add_p4_libs( $href, $flags, $apipath ); add_p4_hdrs( $flags, $apipath ); # # Make sure we're not linking with -debug on Windows - because the # linker chokes. # if( $^O eq "MSWin32" ) { $flags->{ 'LDDLFLAGS' } = $Config{ 'lddlflags' }; $flags->{ 'LDDLFLAGS' } =~ s/ -debug//g; } # # # Last thing to do is to get the address of their perforce # server for the tests print <<EOF; The test suite needs to know where your Perforce server is. The tests are non-invasive and no new data will be added to your depot during the tests EOF print( "Enter the address of your Perforce server: [perforce:1666]: "); my $p4port = <STDIN>; $p4port =~ s/\n//; $p4port = "perforce:1666" if ( $p4port =~ /^$/ ); open( IN, "test.pl.skel" ) or die( "Can't open test.pl.skel! "); open( OUT, ">test.pl" ) or die( "Can't create test.pl" ); my $line; while ( $line = <IN> ) { $line =~ s/__P4PORT__/$p4port/g; print( OUT $line ); } close( IN ); close( OUT ); return $flags; } # Ensure that the clientuserperl interface gets built. sub MY::postamble { ' $(MYEXTLIB): lib/Makefile cd lib && $(MAKE) $(PASSTHRU) '; } #******************************************************************************* #* START OF MAIN SCRIPT #******************************************************************************* # # This is the version of the API that was current when this build of # P4Perl was produced. It may build with later releases, but it may # not. # $MAX_API_VERSION = encode_api_version( "2007.2" ); my %flags = ( 'NAME' => 'P4', 'VERSION_FROM' => 'P4.pm', # finds $VERSION 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 'MYEXTLIB' => 'lib/libp4$(LIB_EXT)', 'XSOPT' => '-C++ -prototypes', 'CONFIGURE' => \&config_sub, 'clean' => { FILES => 'test.pl' }, ); our $APIDIR = undef; my $result = GetOptions ( "apidir=s" => \$APIDIR ); WriteMakefile( %flags );
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#10 | 5943 | Tony Smith |
Update P4Perl to build against 2007.2 API. The 2007.2 API has a more traditional directory structure and P4Perl needs to take that into account. This change also makes Makefile.PL check that the version of the API being used is less than or equal to the highest API version known when this version was written. Hopefully this will prevent people from struggling to build older (stable) versions of P4Perl against recent APIs only supported by the development builds. |
||
#9 | 5708 | Tony Smith |
Add static P4::Identify() method to report the version of P4Perl, and the API used to build it. |
||
#8 | 5704 | Tony Smith |
Fix bug introduced in change 5677: the quoting of the const_char definition wasn't good on Windows as it doesn't really understand single quotes. Switched to using double-quotes. |
||
#7 | 5677 | Tony Smith |
Rework P4Perl build script to support 2006.1 API. There were some sweeping changes in the 2006.1 API which did away with the old const_char definition. Unfortunately, since P4Perl has to build with older APIs, I can't quite do the same. This change tweaks the way that Makefile.PL determines the definition for const_char so that (a) it's always 'const char' when a 2006.1 or later API is used, (b) it uses the platform specific hint for older APIs (c) it falls back on 'char' in the absence of a hint. In an ideal world, we'd be able to compute the options based on (a) OS, (b) compiler version (c) Perl version and (d) API version, but that's tough to get right. No functional change. |
||
#6 | 5073 | Tony Smith |
Yet another P4::SetProg fix. Turns out the last change fixed everything except the build script and it all worked... unless you used the 2005.1 API which has a different format for the Version file. P4::SetProg is a no-op when P4Perl is built with an older API so not identifying the API build properly breaks it thoroughly. This change adapts P4Perl's setup script to support both pre-2005.1 and 2005.1 formats, and gives the user the chance to enter the API version manually if it can't be automatically determined. Installers also included in this change |
||
#5 | 4864 | Tony Smith |
Bug fix: Introduce workaround for obscure 2000.1/2000.2 protocol bug that I really thought we'd seen the last of. Along the way, a total revamp of the debugging output - required to diagnose the problem. |
||
#4 | 4585 | Tony Smith |
Make the new P4Perl work with older versions of the Perforce API (i.e those without ClientApi::SetProg() defined ). This also introduces automatic determination of the API version being used so we can selectively exclude functionality that isn't available. No functional change. |
||
#3 | 4579 | Tony Smith |
Rewrite P4Perl to be more like P4Ruby. This change does away with the old P4/P4::Client split and pulls all the functionality of P4::Client into P4. Hence P4::Client is now deprecated. There are a few gotcha's - see the Changes file, and documentation for the details, but in general it's backwards compatible. As part of this change, I'm also releasing the previous current versions of P4 and P4::Client as released versions - for posterity. P4 now gets a v3.x version number so the old versions will stand out clearly. Hopefully it's all working - works fine for me - but people should consider this a beta build, for now at least. |
||
#2 | 2003 | Tony Smith |
MakeMaker tweaks to cheer up the CPAN folks. Just guessing with the PPD file, but it's better than nothing (I'm told). |
||
#1 | 1011 | Tony Smith |
Moved Perl API stuff one level down to make way for upcoming Ruby interface. |
||
//guest/tony_smith/perforce/API/P4/Makefile.PL | |||||
#1 | 922 | Tony Smith |
First crack at a much simpler perl interface. Just wraps up the P4::Client and P4::UI classes in an easier to use interface returning the output to the caller in Array or Scalar context as they request it. |