
marvin at rectangular
Aug 25, 2008, 9:16 AM
Post #1 of 1
(433 views)
Permalink
|
|
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 [at] rectangular http://www.rectangular.com/mailman/listinfo/kinosearch-commits
|