Mailing List Archive

r3761 - trunk/perl/buildlib/Lucy
Author: creamyg
Date: 2008-08-25 09:16:33 -0700 (Mon, 25 Aug 2008)
New Revision: 3761

Modified:
trunk/perl/buildlib/Lucy/Build.pm
Log:
Manually compile C and XS files rather than rely on Module::Build. Eliminate
the silly consolidation of C files into one directory because M::B couldn't
handle multiple directories.


Modified: trunk/perl/buildlib/Lucy/Build.pm
===================================================================
--- trunk/perl/buildlib/Lucy/Build.pm 2008-08-25 13:17:49 UTC (rev 3760)
+++ trunk/perl/buildlib/Lucy/Build.pm 2008-08-25 16:16:33 UTC (rev 3761)
@@ -28,6 +28,7 @@
# Don't crash Build.PL if dependencies aren't installed yet
BEGIN {
eval q|use ExtUtils::CBuilder;
+ use ExtUtils::ParseXS;
use Parse::RecDescent;|;
my $bad_dep = $@;
eval q|
@@ -67,7 +68,6 @@
my $CHARMONIZER_SOURCE_DIR = 'charmonizer';
my $C_SOURCE_DIR = catdir( $base_dir, 'c_src' );
my $H_SOURCE_DIR = catdir( $C_SOURCE_DIR, 'h' );
-my $XS_TARG_DIR = catdir( $C_SOURCE_DIR, "xs" );
my $XS_SOURCE_DIR = 'xs';
my $AUTOBIND_PM_PATH = catfile(qw( lib KinoSearch Autobinding.pm ));
my $AUTOBIND_XS_PATH = catfile(qw( lib KinoSearch Autobinding.xs ));
@@ -102,12 +102,12 @@
=end comment
=cut

-my $XS_FILEPATH = catfile( 'lib', 'Lucy.xs' );
+my $XS_FILEPATH = 'Lucy.xs';
my ( $PREFIX, $Prefix, $prefix ) = qw( LUCY_ Lucy_ lucy_ );
my $kino_or_lucy = 'lucy';

sub use_kinosearch_mode {
- $XS_FILEPATH = catfile( 'lib', 'KinoSearch.xs' );
+ $XS_FILEPATH = 'KinoSearch.xs';
( $PREFIX, $Prefix, $prefix ) = qw( KINO_ Kino_ kino_ );
$kino_or_lucy = 'kino';
}
@@ -261,36 +261,6 @@
$self->add_to_cleanup( @o_files, $exe_path );
}

-sub _copy_xs_helper_files {
- my $self = shift;
-
- # Create target directory within dir spec'd as c_source to M::B.
- if ( !-d $XS_TARG_DIR ) {
- mkdir $XS_TARG_DIR or die "Can't mkdir '$XS_TARG_DIR': $!";
- }
- $self->add_to_cleanup($XS_TARG_DIR);
-
- # Copy everything into a single c_source dir. This is cheesy, but M::B
- # can't handle multiple c_source dirs.
- my $binding_files = $self->rscan_dir( $XS_SOURCE_DIR, qr/\.[hc]$/ );
- for my $source (@$binding_files) {
- my $target = catfile( $C_SOURCE_DIR, $source );
- my ( undef, $dir_to_make, undef ) = splitpath($target);
- if ( !-d $dir_to_make ) {
- mkpath($dir_to_make);
- if ( !-d $dir_to_make ) {
- confess("Can't mkpath '$dir_to_make': $!");
- }
- }
- if ( !$self->up_to_date( $source, $target ) ) {
- open( my $fh, '<', $source )
- or confess("Can't open '$source': $!");
- my $content = do { local $/; <$fh> };
- $self->_write_autogenerated_file( $target, $source, $content );
- }
- }
-}
-
sub ACTION_boilerplater {
my $self = shift;
my $xs_code = "";
@@ -301,7 +271,6 @@
mkdir $H_SOURCE_DIR or die "Can't mkdir '$H_SOURCE_DIR': $!";
}
$self->add_to_cleanup($H_SOURCE_DIR);
- $self->_copy_xs_helper_files;

# Concatenate all XS frags, process all AUTO_XS blocks.
my $pm_filepaths = $self->rscan_dir( 'lib', qr/\.pm$/ );
@@ -337,7 +306,7 @@
return
if $self->up_to_date(
[ @$bp_filepaths, @$pm_filepaths ],
- [ $XS_FILEPATH, $H_SOURCE_DIR ]
+ [ $XS_FILEPATH, $H_SOURCE_DIR, ]
);

my $session = Boilerplater::Session->new(
@@ -437,15 +406,98 @@
}
}

+sub ACTION_compile_custom_xs {
+ my $self = shift;
+ my $cbuilder = Lucy::Build::CBuilder->new;
+ my $archdir = catdir( $self->blib, 'arch', 'auto', 'KinoSearch' );
+ mkpath( $archdir, 0, 0777 ) unless -d $archdir;
+ my @include_dirs
+ = ( curdir(), $C_SOURCE_DIR, $H_SOURCE_DIR, $XS_SOURCE_DIR );
+ my @objects;
+
+ # Compile C source files.
+ my $c_files = $self->rscan_dir( $C_SOURCE_DIR, qr/\.c$/ );
+ push @$c_files, @{ $self->rscan_dir( $XS_SOURCE_DIR, qr/\.c$/ ) };
+ for my $c_file (@$c_files) {
+ my $o_file = $c_file;
+ $o_file =~ s/\.c/$Config{_o}/;
+ push @objects, $o_file;
+ next if $self->up_to_date( $c_file, $o_file );
+ $self->add_to_cleanup($o_file);
+ $cbuilder->compile(
+ source => $c_file,
+ extra_compiler_flags => $EXTRA_CCFLAGS,
+ include_dirs => \@include_dirs,
+ object_file => $o_file,
+ );
+ }
+
+ # .xs => .c
+ my $ks_c_file = 'KinoSearch.c';
+ $self->add_to_cleanup($ks_c_file);
+ if ( !$self->up_to_date( $XS_FILEPATH, $ks_c_file ) ) {
+ ExtUtils::ParseXS::process_file(
+ filename => $XS_FILEPATH,
+ prototypes => 0,
+ output => $ks_c_file,
+ );
+ }
+
+ # .c => .o
+ my $version = $self->dist_version;
+ my $ks_o_file = "KinoSearch$Config{_o}";
+ unshift @objects, $ks_o_file;
+ $self->add_to_cleanup($ks_o_file);
+ if ( !$self->up_to_date( $ks_c_file, $ks_o_file ) ) {
+ $cbuilder->compile(
+ source => $ks_c_file,
+ extra_compiler_flags => $EXTRA_CCFLAGS,
+ include_dirs => \@include_dirs,
+ object_file => $ks_o_file,
+ # 'defines' is an undocumented parameter to compile(), so we
+ # should officially roll our own variant and generate compiler
+ # flags. However, that involves writing a bunch of
+ # platform-dependent code, so we'll just take the chance that this
+ # will break.
+ defines => {
+ VERSION => qq|"$version"|,
+ XS_VERSION => qq|"$version"|,
+ },
+ );
+ }
+
+ # Create .bs bootstrap file, needed by Dynaloader.
+ my $ks_bs_file = catfile( $archdir, 'KinoSearch.bs' );
+ $self->add_to_cleanup($ks_bs_file);
+ if ( !$self->up_to_date( $ks_o_file, $ks_bs_file ) ) {
+ require ExtUtils::Mkbootstrap;
+ ExtUtils::Mkbootstrap::Mkbootstrap($ks_bs_file);
+ if ( !-f $ks_bs_file ) {
+ # Create file in case Mkbootstrap didn't do anything.
+ open( my $fh, '>', $ks_bs_file )
+ or confess "Can't open $ks_bs_file: $!";
+ }
+ utime( (time) x 2, $ks_bs_file ); # touch
+ }
+
+ # .o => .(a|bundle)
+ my $ks_lib_file = catfile( $archdir, "KinoSearch.$Config{dlext}" );
+ if ( !$self->up_to_date( \@objects, $ks_lib_file ) ) {
+ $cbuilder->link(
+ module_name => 'KinoSearch',
+ objects => \@objects,
+ lib_file => $ks_lib_file,
+ );
+ }
+}
+
sub ACTION_code {
my $self = shift;

- $self->include_dirs( [ curdir(), $H_SOURCE_DIR, $XS_TARG_DIR ] );
- $self->extra_compiler_flags( split / /, $EXTRA_CCFLAGS );
- $self->c_source($C_SOURCE_DIR);
$self->dispatch('build_charm_test');
$self->dispatch('boilerplater');
$self->dispatch('write_typemap');
+ $self->dispatch('compile_custom_xs');

$self->SUPER::ACTION_code;
}


_______________________________________________
kinosearch-commits mailing list
kinosearch-commits@rectangular.com
http://www.rectangular.com/mailman/listinfo/kinosearch-commits