#!/usr/local/bin/perl -w
=head1 NAME
build_vcp_executable.pl
=head1 SYNOPSIS
cd VCP
bin\build_vcp_executable.pl ## build ./vcp-bin or ./vcp.exe
bin\build_vcp_executable.pl --build-vcp-pl ## build ./vcp.pl
=head1 DESCRIPTION
Builds vcp binaries using PAR's pp command. Make sure you have all the
VCP prereqs installed because pp silently won't include any not found.
=cut
###############################################################################
sub scan_pm_files_in {
my ( $prefix ) = @_ ;
my $dirname = $prefix . '::' ;
$dirname =~ s{(::)+}{/}g ;
my %seen ;
require File::Spec;
for ( @INC ) {
my $dir = File::Spec->catdir( $_, $dirname ) ;
opendir( D, $dir ) or next ;
my @files = grep $_ !~ /^\.\.?$/ && s/\.pm$//i, readdir D ;
closedir D ;
$seen{$_} = 1 for @files ;
}
return map "${prefix}::$_", keys %seen;
}
sub scan_pod_files_in {
my ( $prefix ) = @_ ;
my $dirname = $prefix . '::' ;
$dirname =~ s{(::)+}{/}g ;
my %seen ;
require File::Spec;
for ( @INC ) {
my $dir = File::Spec->catdir( $_, $dirname ) ;
opendir( D, $dir ) or next ;
my @files = grep $_ !~ /^\.\.?$/ && s/\.pod$//i, readdir D ;
closedir D ;
$seen{$_} = 1 for @files ;
}
return map "${prefix}::$_", keys %seen;
}
###############################################################################
use strict;
use lib "lib";
use constant is_win32 => $^O =~ /Win32/i;
use Getopt::Long;
use VCP::TestUtils qw( run );
GetOptions( "build-vcp-pl" => \my $build_vcp_pl ) or die $!;
warn "ignoring command line parameter(s): ", join ", ", map "\"$_\"", @ARGV
if @ARGV;
## VCP uses lazy loading extensively...
my %skip_modules = (
"VCP::TestUtils" => 1,
"VCP::PodDESCRIPTIONParser" => 1,
"VCP::PodOPTIONSParser" => 1,
);
my @modules =
grep !$skip_modules{$_},
sort( (
scan_pm_files_in( "RevML" ),
scan_pm_files_in( "RevML::Doctype" ),
scan_pm_files_in( "VCP" ),
scan_pm_files_in( "VCP::Source" ),
scan_pm_files_in( "VCP::Filter" ),
scan_pm_files_in( "VCP::Dest" ),
scan_pm_files_in( "VCP::Utils" ),
scan_pm_files_in( "VCP::UI" ),
) );
#my @pod_files = map { s{::}{/}g; "$_.pod" } sort( (
# scan_pod_files_in( "VCP" ),
# scan_pod_files_in( "VCP::Source" ),
# scan_pod_files_in( "VCP::Filter" ),
# scan_pod_files_in( "VCP::Dest" ),
# scan_pod_files_in( "VCP::Utils" ),
# scan_pod_files_in( "VCP::UI" ),
#) );
## PAR <= v0.79 doesn't let vcp scan @INC, so we hardcode in a list of
## modules.
mkdir "tmp" unless -e "tmp";
{
my @files = sort
# @pod_files,
map {
local $_ = $_;
s{::}{/}g;
"$_.pm";
} @modules;
open VCP, "<bin/vcp" or die "$!: bin/vcp\n";
open VCP_OUT, ">tmp/vcp_par" or die "$!: tmp/vcp_par\n";
while (<VCP>) {
if ( s{^(\s*)#.*INSERT.*BUNDLE.*HERE.*\r?\n}{} ) {
my $indent = $1;
print VCP_OUT map "$indent'$_',\n", @files;
}
print VCP_OUT $_ or die "$!: bin/vcp_par\n";
}
close VCP;
close VCP_OUT;
}
my $exe_name = $build_vcp_pl ? "vcp.pl" : is_win32 ? "vcp.exe" : "vcp-bin";
if ( 1 ) {
if ( -e $exe_name ) {
unlink $exe_name or die $!;
}
my @cmd = (
"pp",
$build_vcp_pl
? ( "-P", "-o", "vcp.pl" )
: ( "-o", $exe_name ),
"-lib=lib",
sort(
map "--add=$_", @modules#, map "lib/$_", @pod_files
),
"tmp/vcp_par"
);
warn join( " ", @cmd ), "\n";
system @cmd and die $!;
}
warn "Testing generated executable\n";
delete $ENV{$_} for grep /p4|perl/i, keys %ENV;
my $ok = 1;
{
my $zip_list = "<NO WZUNZIP.EXE OUTPUT>\n";
eval {
run [ is_win32 ? ( "wzunzip", "-v" ) : ( "unzip", "-l" ), $exe_name ],
\undef, \$zip_list;
warn "DB_File.pm not in $exe_name, patch the pp perl script\n"
unless $zip_list =~ /DB_File\.pm/;
1;
} or do {
$ok = 0;
warn $@, $zip_list;
}
}
unless ( -e "tmp" ) {
mkdir "tmp" or die "$!: tmp/";
}
use File::Spec;
my $abs_exe_name = File::Spec->rel2abs( $exe_name );
chdir "tmp" or die "$!: tmp/";
{
my $vcp_output = "<NO VCP.EXE OUTPUT>\n";
eval {
run [ $abs_exe_name, "help" ], \undef, \$vcp_output;
1;
} or do {
$ok = 0;
warn $@, $vcp_output;
}
}
die "$exe_name fails test(s).\n" unless $ok;
print "$exe_name seems ok, please test in a real application.\n";
syntax highlighted by Code2HTML, v. 0.9.1