Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed build scripts, changed absolute to relative time offsets

Builds should now work on most other systems which were failing before
  • Loading branch information...
commit 9c6277d601479fd1f33c987f353cedd4f7423c1b 1 parent 22fe27c
@mnunberg mnunberg authored
View
11 MANIFEST
@@ -8,6 +8,8 @@ PLCB_ConfUtil.pm
PLCB_Config.pm
build_libraries.pl
+inc/Devel/CheckLib.pm
+
lib/Couchbase/Client.pm
lib/Couchbase/Client/Return.pm
lib/Couchbase/Client/Errors.pm
@@ -55,6 +57,11 @@ t/00-load.t
t/01-main.t
t/tmp/CouchbaseMock.jar
+src/Makefile.PL
+src/libcouchbase.pm
+
src/memcached-headers.tar.gz
-src/libcouchbase-1.0.0_50_g1a42d9e.tar.gz
-src/libvbucket-1.8.0.1_5_ga4397f3.tar.gz
+src/libcouchbase-1.0.1.tar.gz
+src/libvbucket-1.8.0.2.tar.gz
+src/libevent-2.0.17-stable.tar.gz
+src/libisasl-1.0.0_2_gc3f3496.tar.gz
View
1  MANIFEST.SKIP
@@ -5,3 +5,4 @@
^inst_dir/
.+_const\.pm
^author_utils
+^INSTALL_DIR
View
7 MANIFEST.in
@@ -8,6 +8,8 @@ PLCB_ConfUtil.pm
PLCB_Config.pm
build_libraries.pl
+inc/Devel/CheckLib.pm
+
lib/Couchbase/Client.pm
lib/Couchbase/Client/Return.pm
lib/Couchbase/Client/Errors.pm
@@ -55,6 +57,11 @@ t/00-load.t
t/01-main.t
t/tmp/CouchbaseMock.jar
+src/Makefile.PL
+src/libcouchbase.pm
+
src/memcached-headers.tar.gz
src/libcouchbase-__LIBCOUCHBASE_RELEASE__.tar.gz
src/libvbucket-__LIBVBUCKET_RELEASE__.tar.gz
+src/libevent-__LIBEVENT_RELEASE__.tar.gz
+src/libisasl-__LIBISASL_RELEASE__.tar.gz
View
130 Makefile.PL
@@ -1,7 +1,7 @@
#!/usr/bin/perl
+package PLCBTopLevel;
use strict;
use warnings;
-
use ExtUtils::MakeMaker;
use Dir::Self;
use Getopt::Long;
@@ -10,14 +10,50 @@ use File::Spec;
use Config;
use lib __DIR__;
use PLCB_ConfUtil;
+use lib 'inc';
+use Devel::CheckLib;
+use Data::Dumper;
+
+log_err(__DIR__ . "/Makefile.PL");
+$ENV{LD_RUN_PATH} ||= "";
+
+#$Verbose = 99;
GetOptions(
'dynamic' => \my $UseDynamic,
- 'include=s' => \my $ExtraInclude,
- 'ldpath=s' => \my $ExtraLDPath,
+ 'bundled' => \my $UseBundled,
+ 'incpath=s' => \our $U_IncPath,
+ 'libpath=s' => \our $U_LibPath
+) or die <<EOD;
+OPTIONS:
+--incpath=CPPFLAGS
+--libpath=LDFLAGS
+EOD
+
+#my $mm = ExtUtils::MakeMaker->new();
+
+our (@LIBS,$INC);
+our $MM_TopLevel;
+our $Constants_INC;
+
+push @LIBS, $U_LibPath if $U_LibPath;
+$INC = $U_IncPath || "";
+$Constants_INC = $INC;
+
+
+push @LIBS, '-lcouchbase';
+
+my %MM_Options = (
+ INC => $INC,
+ LIBS => [ join(' ', @LIBS) || '' ],
);
-my %MM_Options;
+$MM_Options{CONFIGURE} = sub {
+ my ($cls,$h) = @_;
+ $MM_TopLevel = $h;
+ return $h;
+};
+
################################################################################
### Our C Source Files ###
################################################################################
@@ -52,71 +88,16 @@ foreach ([qw(error Errors)], [qw(idx IDXConst)]) {
}
################################################################################
-### Check dependencies ###
-################################################################################
-my $inc;
-my $libs;
-
-################################################################################
### Check build type and options ###
################################################################################
-my $myextlib;
-
-my $inst_dir = PLCB_ConfUtil::get_inst_dir();
-my $inst_lib_dir = File::Spec->catfile($inst_dir, 'lib');
-my $inst_inc_dir = File::Spec->catfile($inst_dir, 'include');
-
-my $buildscript_options = "";
-
-#my @extra_deps;
-#foreach my $dep (['sasl2', 'sasl'], ['event', 'event']) {
-# my ($installed,$new) = @$dep;
-# print STDERR "Checking if $installed is present...";
-# if(check_lib(lib => $installed,
-# LIBS => $ExtraLDPath, INC => $ExtraInclude)) {
-# print STDERR "OK\n";
-# push @extra_deps, "-l$installed";
-# } else {
-# print STDERR "NOT FOUND (will build embedded)\n";
-# push @extra_deps, File::Spec->catfile($inst_lib_dir,
-# "lib".$new.$Config{lib_ext});
-# $buildscript_options .= ' --build-'.$new;
-# }
-#}
-
-if(!$UseDynamic) {
- $inc = '-I' . $inst_inc_dir;
- $libs = "-L$inst_lib_dir -lsasl2 -levent -ldl -lresolv";
-
- #Set path for linker and friends
- $myextlib = join(' ',
- map(File::Spec->catfile($inst_lib_dir, $_.'$(LIB_EXT)'),
- qw(libcouchbase libvbucket)));
-} else {
- $myextlib = "";
- $libs = " -lcouchbase -lvbucket -lcouchbase_libevent";
-}
-{
- $inc .= " " . join(" ", map("-I$_", split(/\s+/, $Config{locincpth})));
- $libs .= " " . join(" ", map("-L$_", split(/\s+/, $Config{libpth})));
+if($ENV{PLCB_BUILD_AUTHOR}) {
+ $MM_Options{OPTIMIZE} = '-Wdeclaration-after-statement -Werror -std=gnu89';
}
-foreach ([\$inc, \$ExtraInclude], [\$libs, \$ExtraLDPath]) {
- my ($defl,$extra) = @$_;
- if($$extra) {
- $$defl ||= "";
- $$defl = "$$extra $$defl";
- }
-}
-
-$MM_Options{INC} = $inc;
-$MM_Options{LIBS} = $libs;
-$MM_Options{MYEXTLIB} = $myextlib;
-
-#Write our temporary parameters
-PLCB_ConfUtil::write_tmpflags($inc, $libs);
+use Log::Fu;
+$MM_Options{NEEDS_LINKING} = 1;
WriteMakefile(
@@ -152,21 +133,21 @@ WriteMakefile(
'POE::Sugar::Attributes' => 0.02,
'POE' => 1.312,
},
-
- NEEDS_LINKING => 1,
- OPTIMIZE =>
- ' -Wdeclaration-after-statement -Werror -std=gnu89',
-
+
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Couchbase-Client-* COMPILER_FLAGS' },
%MM_Options,
);
+#Write a list of compiler flags for our constants scripts.
+PLCB_ConfUtil::write_tmpflags($Constants_INC);
+
package MY;
use Config;
use strict;
use warnings;
+use Data::Dumper;
#thanks rafl!
sub const_cccmd {
@@ -188,17 +169,4 @@ sub libscan {
} else {
return $path;
}
-}
-
-sub postamble {
- return unless $myextlib;
-
- my $make_text = <<'EOM';
-$(MYEXTLIB):
- $(PERLRUN) build_libraries.pl __BUILD_LIBRARIES_OPTIONS__
-EOM
-
- $make_text =~ s/__BUILD_LIBRARIES_OPTIONS__/$buildscript_options/g;
- $make_text =~ s/^\s+/\t/msg;
- $make_text;
}
View
10 PLCB_ConfUtil.pm
@@ -41,10 +41,12 @@ sub get_include_dir {
sub clean_cbc_sources {
my $dir_base = $config->{SRC_DIR};
-
- foreach my $lib (qw(couchbase vbucket)) {
- my $dir = sprintf("lib%s-%s", $lib,
- $config->{ "LIB" . uc($lib) . "_RELEASE" });
+ while (my ($kname,$release) = each %$config) {
+ next unless $kname =~ /RELEASE/;
+ my ($libname,$version) = ($kname =~ /(LIB[^_]+)(.+)/);
+ $libname = lc($libname);
+ my $dir = "$libname-$release";
+ warn $dir;
$dir = File::Spec->catfile($dir_base, $dir);
rmtree($dir);
}
View
7 PLCB_Config.pm
@@ -15,8 +15,11 @@ my $params = {
'perl-Couchbase-Client/CouchbaseMock-0.5-SNAPSHOT.jar',
#version numbers for libcouchbase and libvbucket
- LIBVBUCKET_RELEASE => '1.8.0.1_5_ga4397f3',
- LIBCOUCHBASE_RELEASE => '1.0.0_50_g1a42d9e'
+ LIBVBUCKET_RELEASE => '1.8.0.2',
+ LIBCOUCHBASE_RELEASE => '1.0.1',
+
+ LIBISASL_RELEASE => '1.0.0_2_gc3f3496',
+ LIBEVENT_RELEASE => '2.0.17-stable',
};
View
166 README.pod
@@ -50,143 +50,96 @@ Just a little utility module. May be useful for testing.
=head1 Installing
-I will be focusing on installing and configuring C<libcouchbase> itself, the C
-client library. It is assumed you have a functional installation of the couchbase
-server somewhere. If not, go to http://www.couchbase.org
+The following components are required for a proper C<Couchbase::Client>
-To use this module, you should have installed C<libvbucket> (see the links on
-the side here http://www.couchbase.com/develop/c/current).
+=over
-As of 01/28/2011, you will need to download C<libcouchbase> itself from
-github (the current release versions contain bugs which may break this module).
+=item libcouchbase >= 1.0.1 (L<release|http://www.couchbase.com/develop/c/current>)
-=head2 Building C<libcouchbase>
+=item libvbucket >= 1.8.0.2 (L<release|http://www.couchbase.com/develop/c/current>)
+=item libevent >= 1.4
-C<libcouchbase> itself depends on C<libvbucket>, so make sure to install that
-(and its development libraries) first.
+=item libsasl/libsasl2 (any version).
-Currently, I know of these dependencies:
+=item Java (for the tests).
-=over
+=back
-=item libevent >= 1.4
+All of the above components (except Java) are bundled in source form with the
+tarball distribution (see further).
-For embedded default event loop functionality
+=head2 Building Couchbase::Client
-=item java
+Couchbase::Client is bundled (in its tarball distribution) with source distributions
+of libevent, libisasl, libvbucket, and libcouchbase. These are not present on
+the git version because it is assumed that the user may want to provide copies
+of their own.
-For the Perl and C tests
+The bundled configuration will only substitute I<missing> dependencies from
+the bundle; thus, if you have C<libsasl> but are missing a proper version of
+C<libevent>, then only the bundled libevent (but not libsasl) will be used.
-=item libsasl2
+C<Couchbase::Client> can be configured to either link against the bundled
+libraries, or to link against a custom or system directory.
-=back
+=head3 Using Embedded Libraries:
-Additionally, C<libcouchbase> depends on header files available from the
-C<engine-pu> branch of the C<memcached> project. Note that actually building
-memcached itself is not required.
+In order to use embedded libraries, you should ensure that you have a proper
+distribution for each needed and unfound library.
-Your best bet would be to do
-something like this:
-
- ~$ mkdir couch
- ~$ git clone https://github.com/memcached/memcached.git -b engine-pu couch/memcached
- ~$ git clone https://github.com/couchbase/libcouchbase.git couch/libcouchbase
-
- #Get vbucket stuff:
-
- # I pick RPM, since that's what my target production platform is:
-
- ~$ wget http://packages.couchbase.com/clients/c/libvbucket1-1.8.0.1-1.x86_64.rpm
- ~$ rpm -ivh libvbucket1-1.8.0.1-1.x86_64.rpm
- ~$ wget http://packages.couchbase.com/clients/c/libvbucket-1.8.0.1.tar.gz
- ~$ cd couch; tar xf ../libvbucket-1.8.0.1.tar.gz
- ~$ ln -s libvbucket-1.8.0.1 libvbucket
-
-
- # Note for CentOS/RHEL 5 users, you will need to perform the autorun
- # to generate the 'configure' script on a newer platform, then copy it over
- # to your target platform
-
-
- ~$ cd couch/libcouchbase
- ~$ ./config/autorun.sh
-
- #make sure we know about the new memcached (and vbucket) headers:
-
- ~$ CPPFLAGS='-I../memcached/include -I../libvbucket/include' ./configure
-
- # (EL5: If configure complains about not finding libvbucket, try:)
- ~$ ln -s /usr/lib64/libvbucket.so.1 /usr/lib64/libvbucket.so
-
-
- ~$ make
-
- #optional, run some tests:
- ~$ make check
+The file C<PLCB_Config.pm> should contain a bunch of hash entries in the format
+of
+
+ LIBFOO_RELEASE => 1.2.3-sdff
+where C<LIBFOO> is the uper-case name of the library, and the value is the
+version of the library.
-=head2 Building Couchbase::Client
+The tarball B<must> be named C<libfoo-1.2.3-sdff.tar.gz>, and its top-level
+directory must be C<libfoo-1.2.3/>
-There are two ways to build Couchbase::Client and associated modules.
+You will find that the config file has sane defaults, and that the main task
+is downloading them.
-=over
+The tarballs should then be relocated to the C<src/> directory.
-=item Static libcouchbase and libvbucket
+Once all is ready, you can invoke the C<Makefile.PL> script, optionally
+passing some arguments.
-This is the mode of distribution and is the default option.
+=head4 Makefile.PL arguments
-You should edit the C<LIBVBUCKET_TARRBALL> and C<LIBCOUCHBASE_TARBALL>
-keys in C<PLCB_Config.pm> to correspond to the basename (the release string,
-without the .tar.gz suffix), thus:
+=over
- == PLCB_Config.pm ==
- my $params = {
-
- #...
-
- LIBVBUCKET_RELEASE => '1.8.0.1_4_g677e403',
- LIBCOUCHBASE_RELEASE => '1.0.0_45_g58818c5'
-
- };
+=item --libpath
-
- $ mkdir src
- cp libvbucket-1.8.0.1_4_g677e403.tar.gz src/
- cp libcouchbase-1.0.0_45_g58818c5.tar.gz src/
-
- cp -a memcached/include src
-
-Note that the tarball MUST have as its top-level directory the name of the
-tarball itself, without the .tar.gz suffix.
+A string for passing to the linker which should contain something like
+C<-L/foo -L/bar> etc.
-If you are not using a 'release-style' tarball but rather checking out from git,
-then you will likely need to run ./configure and then C<make dist>, which should
-give you a tarball.
+This is only necessary if your standard dependencies are found outside the linker's
+default search path (e.g. macports)
-run
+=item --incpath
- $ perl Makefile.PL
- $ make test install #and whatever other targets you want
-
-=item Dynamic Linking
+This is the same as C<--libpath>, but are passed to the preprocessor and would
+look like C<-I/usr/foo/include> etc.
-This is the non-default option, and should be used if you want to use your system's
-libcouchbase, which may or may not break the perl client.
+=back
-Granted libcouchbase is rather new, so most systems will not have available
-packaging for libcouchbase or its tributaries.
+Thus you can invoke somehting like:
-Know where your include and linker paths are, and do the following:
+ $ perl Makefile.PL --incpath=-I/opt/local/include --libpath=-L/opt/local/lib
+ $ make
+ $ make test # but see the testing section, later
+ $ make install
+
+=head3 Providing your own libraries.
- perl Makefile.PL --dynamic \
- --include=-I/sources/libcouchbase/include \
- --ldpath=-L/sources/libcouchbase/.libs
+This is a relatively straight-forward option, and is what I use for development.
- make
-
-
-=back
+Simply make use of the aforementioned C<--libpath> and C<--incpath> arguments to
+point to the directory which contains the necessary dependencies, and follow
+the relevant parts from the above section.
There are some top-level scripts. Some have meaning to only the author, some might
@@ -202,6 +155,9 @@ Also, check out the runnable modules in the C<t/> directory
The tests in this module require java to run. Some tests furthermore will only
work on a real cluster, due to some of the limitations in the Java client.
+A C<CouchbaseMock.jar> should be located within the C<t/tmp> directory. You can
+obtain one from L<here|http://files.couchbase.com/maven2/org/couchbase/mock/CouchbaseMock/0.5-SNAPSHOT/CouchbaseMock-0.5-20120202.071818-12.jar>
+
To run the tests on a real cluster, you can make use of the
C<PLCB_TEST_REAL_SERVER> environment variable.
View
3  author_utils/gen_manifest.pl
@@ -8,6 +8,7 @@
my $vbucket_release = $config->{LIBVBUCKET_RELEASE};
my $couchbase_release = $config->{LIBCOUCHBASE_RELEASE};
+my $libevent_release = $config->{LIBEVENT_RELEASE};
open my $infh, "<", "MANIFEST.in";
open my $outfh, ">", "MANIFEST";
@@ -16,6 +17,8 @@
next unless $line;
$line =~ s/__LIBCOUCHBASE_RELEASE__/$couchbase_release/g;
$line =~ s/__LIBVBUCKET_RELEASE__/$vbucket_release/g;
+ $line =~ s/__LIBEVENT_RELEASE__/$libevent_release/g;
+ $line =~ s/__LIBISASL_RELEASE__/$config->{LIBISASL_RELEASE}/g;
print $outfh $line;
}
View
210 build_libraries.pl
@@ -5,9 +5,19 @@
use File::Basename qw(fileparse);
use Log::Fu;
use File::Spec;
-use Dir::Self;
+use Dir::Self qw(:static);
use Config;
-use File::Path qw(mkpath);
+use File::Path qw(mkpath rmtree);
+use Getopt::Long;
+
+GetOptions(
+ "build-prefix=s" => \my $BuildPrefix,
+ "install-prefix=s" => \my $InstallPrefix,
+ 'env-cppflags=s' => \my $ENV_CPPFLAGS,
+ 'env-ldflags=s' => \my $ENV_LDFLAGS,
+ 'env-libs=s' => \my $ENV_LIBS,
+ 'rpath=s' => \my $RPATH,
+);
use lib __DIR__;
use PLCB_ConfUtil;
@@ -16,26 +26,38 @@
my $plcb_conf = do 'PLCB_Config.pm' or die "Cannot find configuration";
-sub runcmd {
- my $cmd = join(" ", @_);
- system($cmd . " > /dev/null") == 0 or die "$cmd failed";
+my $BUILD_SILENT = "> /dev/null";
+if($ENV{PLCB_BUILD_NOISY}) {
+ $BUILD_SILENT = "";
}
-#Figure out various ways to get a tarball
-
-
+my $RUN_TESTS = 1;
+if(exists $ENV{PLCB_RUN_TESTS}) {
+ $RUN_TESTS = $ENV{PLCB_RUN_TESTS};
+}
+if($^O =~ /solaris/) {
+ print STDERR "Tests disabled on solaris\n";
+ $RUN_TESTS = 0;
+}
-my $LIBVBUCKET_TARBALL = $plcb_conf->{LIBVBUCKET_RELEASE};
-my $LIBCOUCHBASE_TARBALL = $plcb_conf->{LIBCOUCHBASE_RELEASE};
+my %DEPS = map { ( $_, $_ ) } @ARGV;
-unless ($LIBCOUCHBASE_TARBALL && $LIBVBUCKET_TARBALL) {
- die("Cannot find appropriate tarball names. Please edit PLCB_Config.pm");
+sub runcmd {
+ my $cmd = join(" ", @_);
+ print STDERR "Running $cmd\n";
+ unless(system($cmd . " $BUILD_SILENT") == 0) {
+ print STDERR "Command $cmd failed\n";
+ printf STDERR ("CPPFLAGS=%s\nLDFLAGS=%s\n", $ENV{CPPFLAGS}, $ENV{LDFLAGS});
+ printf STDERR ("LD_RUN_PATH=%s\n", $ENV{LD_RUN_PATH});
+ die "";
+ }
}
-$LIBVBUCKET_TARBALL = "libvbucket-$LIBVBUCKET_TARBALL.tar.gz";
-$LIBCOUCHBASE_TARBALL = "libcouchbase-$LIBCOUCHBASE_TARBALL.tar.gz";
-
-my $MEMCACHED_H_TARBALL = "memcached-headers.tar.gz";
+sub lib_2_tarball {
+ my $lib = shift;
+ my $release = $plcb_conf->{uc($lib) . "_RELEASE"};
+ my $name = "$lib-$release.tar.gz";
+}
sub tarball_2_dir {
my $tarball = shift;
@@ -44,50 +66,140 @@ sub tarball_2_dir {
return $filename;
}
+################################################################################
+################################################################################
+### Tarball Names ###
+################################################################################
+################################################################################
+my $LIBVBUCKET_TARBALL = lib_2_tarball('libvbucket');
+my $LIBCOUCHBASE_TARBALL = lib_2_tarball('libcouchbase');
+my $LIBISASL_TARBALL = lib_2_tarball('libisasl');
+my $LIBEVENT_TARBALL = lib_2_tarball('libevent');
+my $MEMCACHED_H_TARBALL = "memcached-headers.tar.gz";
+
+################################################################################
+################################################################################
+### Target Directory Structure ###
+################################################################################
+################################################################################
my $TOPLEVEL = PLCB_ConfUtil::get_toplevel_dir();
-my $INST_DIR = PLCB_ConfUtil::get_inst_dir();
+my $INST_DIR = $BuildPrefix;
+my $INCLUDE_PATH = File::Spec->catfile($INST_DIR, 'include');
+my $LIB_PATH = File::Spec->catfile($INST_DIR, 'lib');
chdir $TOPLEVEL;
+
mkpath($INST_DIR);
+mkpath($INCLUDE_PATH);
+mkpath($LIB_PATH);
+
+runcmd("tar xf $MEMCACHED_H_TARBALL");
+rmtree(File::Spec->catfile($INCLUDE_PATH, 'memcached'));
+runcmd("mv include/memcached $INCLUDE_PATH && rm -rf include/memcached");
+unless(-e File::Spec->catfile($INCLUDE_PATH, 'memcached', 'protocol_binary.h')) {
+ die("Can't extract memcached headers");
+}
+
+$ENV{PKG_CONFIG_PATH} .= ":"
+. File::Spec->catfile($INST_DIR, 'lib', 'pkgconfig');
+#$ENV{CC} = $Config{cc};
+$ENV{LD_RUN_PATH} .= ":$RPATH";
+$ENV{LD_LIBRARY_PATH} .= ":" . $ENV{LD_RUN_PATH};
+
+$ENV{CPPFLAGS} .= $ENV_CPPFLAGS;
+$ENV{LIBS} .= $ENV_LIBS;
+
+my $MAKEPROG = $ENV{MAKE};
+if(!$MAKEPROG) {
+ if(system("gmake --version") == 0) {
+ $MAKEPROG = "gmake";
+ } else {
+ $MAKEPROG = "make";
+ }
+}
+
+
+my $MAKE_CONCURRENT = $ENV{PLCB_MAKE_CONCURRENT};
+$MAKEPROG = "$MAKEPROG $MAKE_CONCURRENT";
log_info("We're in $TOPLEVEL now");
my @COMMON_OPTIONS = (
-"--prefix=$INST_DIR",
+"--prefix=$BuildPrefix",
qw(
--silent
---disable-shared
---enable-static
--without-docs)
);
-runcmd("tar xf $MEMCACHED_H_TARBALL -C $INST_DIR");
+sub should_build {
+ my $name = shift;
+ $name = uc($name);
+ exists $DEPS{$name};
+}
-$ENV{CPPFLAGS} .= ' -fPIC ';
-$ENV{CPPFLAGS} .= " -I".File::Spec->catfile($INST_DIR, "include");
-$ENV{LDFLAGS} .= " -lm -L".File::Spec->catfile($INST_DIR, "lib");
+sub lib_is_built {
+ my $libname = shift;
+ if(-e File::Spec->catfile($LIB_PATH, $libname . "." . $Config{so})) {
+ return 1;
+ }
+ return 0;
+}
-$ENV{CPPFLAGS} .= " " . join(" ", map("-I$_", split(/\s+/, $Config{locincpth})));
-$ENV{LDFLAGS} .= " " . join(" ", map("-L$_", split(/\s+/, $Config{libpth})));
+################################################################################
+### ISASL ###
+################################################################################
+if(should_build('ISASL')) {
+ chdir $TOPLEVEL;
+ chdir tarball_2_dir($LIBISASL_TARBALL);
+ runcmd("./configure", @COMMON_OPTIONS) unless -e 'Makefile';
+ log_info("Configuring libisasl");
+ runcmd("$MAKEPROG install");
+ log_info("Installed libisasl");
+}
+
+################################################################################
+### libevent ###
+################################################################################
+if(should_build('EVENT')) {
+ chdir $TOPLEVEL;
+ my @libevent_options = (qw(
+ --disable-openssl
+ --disable-debug-mode
+ ), @COMMON_OPTIONS
+ );
+
+ chdir tarball_2_dir($LIBEVENT_TARBALL);
+ runcmd("./configure", @libevent_options) unless -e 'Makefile';
+ log_info("Configured libevent");
+ runcmd("$MAKEPROG install");
+}
-log_info("CPPFLAGS:", $ENV{CPPFLAGS});
-log_info("LDFLAS:", $ENV{LDFLAGS});
-#build libvbucket first:
+################################################################################
+### libvbucket ###
+################################################################################
+# if(should_build('VBUCKET'))
{
+ chdir $TOPLEVEL;
chdir tarball_2_dir($LIBVBUCKET_TARBALL);
if(!-e 'Makefile') {
runcmd("./configure", @COMMON_OPTIONS);
log_info("Configured libvbucket");
}
- runcmd("make");
+ runcmd("$MAKEPROG");
log_info("build libvbucket");
- runcmd("make install");
+ runcmd("$MAKEPROG install");
log_info("installed libvbucket");
- runcmd("make check");
+ runcmd("$MAKEPROG check") if $RUN_TESTS;
log_info("tested libvbucket");
}
+
+
+################################################################################
+### libcouchbase ###
+################################################################################
+#if (should_build('COUCHBASE')) {
{
chdir $TOPLEVEL;
chdir tarball_2_dir($LIBCOUCHBASE_TARBALL);
@@ -98,20 +210,44 @@ sub tarball_2_dir {
"--enable-embed-libevent-plugin",
);
+ if($^O =~ /solaris/) {
+ print STDERR "Disabling tools (won't compile on solaris)\n";
+ push @libcouchbase_options, '--disable-tools';
+ }
+
my $have_java = eval { runcmd("java", "-version"); 1; };
my $mockpath = File::Spec->catfile(
__DIR__, 't', 'tmp', 'CouchbaseMock.jar');
+ if(!-e $mockpath) {
+ die("Can't find mock in $mockpath");
+ }
if($have_java && -e $mockpath) {
- push @libcouchbase_options, '--with-couchbase-mock='.$mockpath;
+ push @libcouchbase_options, '--with-couchbasemock='.$mockpath;
} else {
push @libcouchbase_options, '--disable-couchbasemock';
}
- if(!-e 'Makefile') {
- runcmd("./configure", @libcouchbase_options);
+ #First, we need to mangle the 'configure' script:
+ {
+ my @conflines;
+ open my $confh, "+<", "configure" or die "opening configure: $!";
+ @conflines = <$confh>;
+ foreach my $line (@conflines) {
+ if($line =~ s/LIBS=(-l\S+)/LIBS="\$LIBS $1"/msg) {
+ print STDERR ">> REPLACING: $line";
+ }
+ }
+ seek($confh, 0, 0);
+ print $confh @conflines;
+ truncate($confh, tell($confh));
+
+ close($confh);
}
- runcmd("make install check -s");
+
+ runcmd("./configure", @libcouchbase_options) unless -e 'Makefile';
+ runcmd("$MAKEPROG install");
+ runcmd("$MAKEPROG check -s") if $RUN_TESTS;
}
-#Write a little file about where our stuff is located:
+exit(0);
View
483 inc/Devel/CheckLib.pm
@@ -0,0 +1,483 @@
+# $Id: CheckLib.pm,v 1.25 2008/10/27 12:16:23 drhyde Exp $
+
+package #
+Devel::CheckLib;
+
+use 5.00405; #postfix foreach
+use strict;
+use vars qw($VERSION @ISA @EXPORT);
+$VERSION = '0.96';
+use Config qw(%Config);
+use Text::ParseWords 'quotewords';
+
+use File::Spec;
+use File::Temp;
+
+require Exporter;
+@ISA = qw(Exporter);
+@EXPORT = qw(assert_lib check_lib_or_exit check_lib);
+
+# localising prevents the warningness leaking out of this module
+local $^W = 1; # use warnings is a 5.6-ism
+
+_findcc(); # bomb out early if there's no compiler
+
+=head1 NAME
+
+Devel::CheckLib - check that a library is available
+
+=head1 DESCRIPTION
+
+Devel::CheckLib is a perl module that checks whether a particular C
+library and its headers are available.
+
+=head1 SYNOPSIS
+
+ use Devel::CheckLib;
+
+ check_lib_or_exit( lib => 'jpeg', header => 'jpeglib.h' );
+ check_lib_or_exit( lib => [ 'iconv', 'jpeg' ] );
+
+ # or prompt for path to library and then do this:
+ check_lib_or_exit( lib => 'jpeg', libpath => $additional_path );
+
+=head1 USING IT IN Makefile.PL or Build.PL
+
+If you want to use this from Makefile.PL or Build.PL, do
+not simply copy the module into your distribution as this may cause
+problems when PAUSE and search.cpan.org index the distro. Instead, use
+the use-devel-checklib script.
+
+=head1 HOW IT WORKS
+
+You pass named parameters to a function, describing to it how to build
+and link to the libraries.
+
+It works by trying to compile some code - which defaults to this:
+
+ int main(void) { return 0; }
+
+and linking it to the specified libraries. If something pops out the end
+which looks executable, it gets executed, and if main() returns 0 we know
+that it worked. That tiny program is
+built once for each library that you specify, and (without linking) once
+for each header file.
+
+If you want to check for the presence of particular functions in a
+library, or even that those functions return particular results, then
+you can pass your own function body for main() thus:
+
+ check_lib_or_exit(
+ function => 'foo();if(libversion() > 5) return 0; else return 1;'
+ incpath => ...
+ libpath => ...
+ lib => ...
+ header => ...
+ );
+
+In that case, it will fail to build if either foo() or libversion() don't
+exist, and main() will return the wrong value if libversion()'s return
+value isn't what you want.
+
+=head1 FUNCTIONS
+
+All of these take the same named parameters and are exported by default.
+To avoid exporting them, C<use Devel::CheckLib ()>.
+
+=head2 assert_lib
+
+This takes several named parameters, all of which are optional, and dies
+with an error message if any of the libraries listed can
+not be found. B<Note>: dying in a Makefile.PL or Build.PL may provoke
+a 'FAIL' report from CPAN Testers' automated smoke testers. Use
+C<check_lib_or_exit> instead.
+
+The named parameters are:
+
+=over
+
+=item lib
+
+Must be either a string with the name of a single
+library or a reference to an array of strings of library names. Depending
+on the compiler found, library names will be fed to the compiler either as
+C<-l> arguments or as C<.lib> file names. (E.g. C<-ljpeg> or C<jpeg.lib>)
+
+=item libpath
+
+a string or an array of strings
+representing additional paths to search for libraries.
+
+=item LIBS
+
+a C<ExtUtils::MakeMaker>-style space-seperated list of
+libraries (each preceded by '-l') and directories (preceded by '-L').
+
+This can also be supplied on the command-line.
+
+=back
+
+And libraries are no use without header files, so ...
+
+=over
+
+=item header
+
+Must be either a string with the name of a single
+header file or a reference to an array of strings of header file names.
+
+=item incpath
+
+a string or an array of strings
+representing additional paths to search for headers.
+
+=item INC
+
+a C<ExtUtils::MakeMaker>-style space-seperated list of
+incpaths, each preceded by '-I'.
+
+This can also be supplied on the command-line.
+
+=back
+
+=head2 check_lib_or_exit
+
+This behaves exactly the same as C<assert_lib()> except that instead of
+dieing, it warns (with exactly the same error message) and exits.
+This is intended for use in Makefile.PL / Build.PL
+when you might want to prompt the user for various paths and
+things before checking that what they've told you is sane.
+
+If any library or header is missing, it exits with an exit value of 0 to avoid
+causing a CPAN Testers 'FAIL' report. CPAN Testers should ignore this
+result -- which is what you want if an external library dependency is not
+available.
+
+=head2 check_lib
+
+This behaves exactly the same as C<assert_lib()> except that it is silent,
+returning false instead of dieing, or true otherwise.
+
+=cut
+
+sub check_lib_or_exit {
+ eval 'assert_lib(@_)';
+ if($@) {
+ warn $@;
+ exit;
+ }
+}
+
+sub check_lib {
+ eval 'assert_lib(@_)';
+ return $@ ? 0 : 1;
+}
+
+sub assert_lib {
+ my %args = @_;
+ my (@libs, @libpaths, @headers, @incpaths);
+
+ # FIXME: these four just SCREAM "refactor" at me
+ @libs = (ref($args{lib}) ? @{$args{lib}} : $args{lib})
+ if $args{lib};
+ @libpaths = (ref($args{libpath}) ? @{$args{libpath}} : $args{libpath})
+ if $args{libpath};
+ @headers = (ref($args{header}) ? @{$args{header}} : $args{header})
+ if $args{header};
+ @incpaths = (ref($args{incpath}) ? @{$args{incpath}} : $args{incpath})
+ if $args{incpath};
+
+ # work-a-like for Makefile.PL's LIBS and INC arguments
+ # if given as command-line argument, append to %args
+ for my $arg (@ARGV) {
+ for my $mm_attr_key (qw(LIBS INC)) {
+ if (my ($mm_attr_value) = $arg =~ /\A $mm_attr_key = (.*)/x) {
+ # it is tempting to put some \s* into the expression, but the
+ # MM command-line parser only accepts LIBS etc. followed by =,
+ # so we should not be any more lenient with whitespace than that
+ $args{$mm_attr_key} .= " $mm_attr_value";
+ }
+ }
+ }
+
+ # using special form of split to trim whitespace
+ if(defined($args{LIBS})) {
+ foreach my $arg (split(' ', $args{LIBS})) {
+ die("LIBS argument badly-formed: $arg\n") unless($arg =~ /^-l/i);
+ push @{$arg =~ /^-l/ ? \@libs : \@libpaths}, substr($arg, 2);
+ }
+ }
+ if(defined($args{INC})) {
+ foreach my $arg (split(' ', $args{INC})) {
+ die("INC argument badly-formed: $arg\n") unless($arg =~ /^-I/);
+ push @incpaths, substr($arg, 2);
+ }
+ }
+
+ my ($cc, $ld) = _findcc();
+ my @missing;
+ my @wrongresult;
+ my @use_headers;
+
+ # first figure out which headers we can't find ...
+ for my $header (@headers) {
+ push @use_headers, $header;
+ my($ch, $cfile) = File::Temp::tempfile(
+ 'assertlibXXXXXXXX', SUFFIX => '.c'
+ );
+ my $ofile = $cfile;
+ $ofile =~ s/\.c$/$Config{_o}/;
+ print $ch qq{#include <$_>\n} for @use_headers;
+ print $ch qq{int main(void) { return 0; }\n};
+ close($ch);
+ my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
+ my @sys_cmd;
+ # FIXME: re-factor - almost identical code later when linking
+ if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
+ require Win32;
+ @sys_cmd = (
+ @$cc,
+ $cfile,
+ "/Fe$exefile",
+ (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
+ "/link",
+ @$ld
+ );
+ } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
+ @sys_cmd = (
+ @$cc,
+ @$ld,
+ (map { "-I$_" } @incpaths),
+ "-o$exefile",
+ $cfile
+ );
+ } else { # Unix-ish: gcc, Sun, AIX (gcc, cc), ...
+ @sys_cmd = (
+ @$cc,
+ @$ld,
+ $cfile,
+ (map { "-I$_" } @incpaths),
+ "-o", "$exefile"
+ );
+ }
+ warn "# @sys_cmd\n" if $args{debug};
+ my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
+ push @missing, $header if $rv != 0 || ! -x $exefile;
+ _cleanup_exe($exefile);
+ unlink $ofile if -e $ofile;
+ unlink $cfile;
+ }
+
+ # now do each library in turn with headers
+ my($ch, $cfile) = File::Temp::tempfile(
+ 'assertlibXXXXXXXX', SUFFIX => '.c'
+ );
+ my $ofile = $cfile;
+ $ofile =~ s/\.c$/$Config{_o}/;
+ print $ch qq{#include <$_>\n} foreach (@headers);
+ print $ch "int main(void) { ".($args{function} || 'return 0;')." }\n";
+ close($ch);
+ for my $lib ( @libs ) {
+ my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
+ my @sys_cmd;
+ if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
+ require Win32;
+ my @libpath = map {
+ q{/libpath:} . Win32::GetShortPathName($_)
+ } @libpaths;
+ # this is horribly sensitive to the order of arguments
+ @sys_cmd = (
+ @$cc,
+ $cfile,
+ "${lib}.lib",
+ "/Fe$exefile",
+ (map { '/I'.Win32::GetShortPathName($_) } @incpaths),
+ "/link",
+ @$ld,
+ (map {'/libpath:'.Win32::GetShortPathName($_)} @libpaths),
+ );
+ } elsif($Config{cc} eq 'CC/DECC') { # VMS
+ } elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
+ @sys_cmd = (
+ @$cc,
+ @$ld,
+ "-o$exefile",
+ "-l$lib",
+ (map { "-I$_" } @incpaths),
+ (map { "-L$_" } @libpaths),
+ $cfile);
+ } else { # Unix-ish
+ # gcc, Sun, AIX (gcc, cc)
+ @sys_cmd = (
+ @$cc,
+ @$ld,
+ $cfile,
+ "-o", "$exefile",
+ "-l$lib",
+ (map { "-I$_" } @incpaths),
+ (map { "-L$_" } @libpaths)
+ );
+ }
+ warn "# @sys_cmd\n" if $args{debug};
+ my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
+ push @missing, $lib if $rv != 0 || ! -x $exefile;
+ my $absexefile = File::Spec->rel2abs($exefile);
+ $absexefile = '"'.$absexefile.'"' if $absexefile =~ m/\s/;
+ push @wrongresult, $lib if $rv == 0 && -x $exefile && system($absexefile) != 0;
+ unlink $ofile if -e $ofile;
+ _cleanup_exe($exefile);
+ }
+ unlink $cfile;
+
+ my $miss_string = join( q{, }, map { qq{'$_'} } @missing );
+ die("Can't link/include C library $miss_string, aborting.\n") if @missing;
+ my $wrong_string = join( q{, }, map { qq{'$_'} } @wrongresult);
+ die("wrong result: $wrong_string\n") if @wrongresult;
+}
+
+sub _cleanup_exe {
+ my ($exefile) = @_;
+ my $ofile = $exefile;
+ $ofile =~ s/$Config{_exe}$/$Config{_o}/;
+ unlink $exefile if -f $exefile;
+ unlink $ofile if -f $ofile;
+ unlink "$exefile\.manifest" if -f "$exefile\.manifest";
+ if ( $Config{cc} eq 'cl' ) {
+ # MSVC also creates foo.ilk and foo.pdb
+ my $ilkfile = $exefile;
+ $ilkfile =~ s/$Config{_exe}$/.ilk/;
+ my $pdbfile = $exefile;
+ $pdbfile =~ s/$Config{_exe}$/.pdb/;
+ unlink $ilkfile if -f $ilkfile;
+ unlink $pdbfile if -f $pdbfile;
+ }
+ return
+}
+
+# return ($cc, $ld)
+# where $cc is an array ref of compiler name, compiler flags
+# where $ld is an array ref of linker flags
+sub _findcc {
+ # Need to use $keep=1 to work with MSWin32 backslashes and quotes
+ my $Config_ccflags = $Config{ccflags}; # use copy so ASPerl will compile
+ my @Config_ldflags = @Config{qw(ldflags perllibs)};
+ my @ccflags = grep { length } quotewords('\s+', 1, $Config_ccflags);
+ my @ldflags = grep { length } quotewords('\s+', 1, @Config_ldflags);
+ my @paths = split(/$Config{path_sep}/, $ENV{PATH});
+ my @cc = split(/\s+/, $Config{cc});
+ return ( [ @cc, @ccflags ], \@ldflags ) if -x $cc[0];
+ foreach my $path (@paths) {
+ my $compiler = File::Spec->catfile($path, $cc[0]) . $Config{_exe};
+ return ([ $compiler, @cc[1 .. $#cc], @ccflags ], \@ldflags)
+ if -x $compiler;
+ }
+ die("Couldn't find your C compiler\n");
+}
+
+# code substantially borrowed from IPC::Run3
+sub _quiet_system {
+ my (@cmd) = @_;
+
+ # save handles
+ local *STDOUT_SAVE;
+ local *STDERR_SAVE;
+ open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT";
+ open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR";
+
+ # redirect to nowhere
+ local *DEV_NULL;
+ open DEV_NULL, ">" . File::Spec->devnull
+ or die "CheckLib: $! opening handle to null device";
+ open STDOUT, ">&" . fileno DEV_NULL
+ or die "CheckLib: $! redirecting STDOUT to null handle";
+ open STDERR, ">&" . fileno DEV_NULL
+ or die "CheckLib: $! redirecting STDERR to null handle";
+
+ # run system command
+ my $rv = system(@cmd);
+
+ # restore handles
+ open STDOUT, ">&" . fileno STDOUT_SAVE
+ or die "CheckLib: $! restoring STDOUT handle";
+ open STDERR, ">&" . fileno STDERR_SAVE
+ or die "CheckLib: $! restoring STDERR handle";
+
+ return $rv;
+}
+
+=head1 PLATFORMS SUPPORTED
+
+You must have a C compiler installed. We check for C<$Config{cc}>,
+both literally as it is in Config.pm and also in the $PATH.
+
+It has been tested with varying degrees on rigourousness on:
+
+=over
+
+=item gcc (on Linux, *BSD, Mac OS X, Solaris, Cygwin)
+
+=item Sun's compiler tools on Solaris
+
+=item IBM's tools on AIX
+
+=item SGI's tools on Irix 6.5
+
+=item Microsoft's tools on Windows
+
+=item MinGW on Windows (with Strawberry Perl)
+
+=item Borland's tools on Windows
+
+=item QNX
+
+=back
+
+=head1 WARNINGS, BUGS and FEEDBACK
+
+This is a very early release intended primarily for feedback from
+people who have discussed it. The interface may change and it has
+not been adequately tested.
+
+Feedback is most welcome, including constructive criticism.
+Bug reports should be made using L<http://rt.cpan.org/> or by email.
+
+When submitting a bug report, please include the output from running:
+
+ perl -V
+ perl -MDevel::CheckLib -e0
+
+=head1 SEE ALSO
+
+L<Devel::CheckOS>
+
+L<Probe::Perl>
+
+=head1 AUTHORS
+
+David Cantrell E<lt>david@cantrell.org.ukE<gt>
+
+David Golden E<lt>dagolden@cpan.orgE<gt>
+
+Yasuhiro Matsumoto E<lt>mattn@cpan.orgE<gt>
+
+Thanks to the cpan-testers-discuss mailing list for prompting us to write it
+in the first place;
+
+to Chris Williams for help with Borland support;
+
+to Tony Cook for help with Microsoft compiler command-line options
+
+=head1 COPYRIGHT and LICENCE
+
+Copyright 2007 David Cantrell. Portions copyright 2007 David Golden.
+
+This module is free-as-in-speech software, and may be used, distributed,
+and modified under the same conditions as perl itself.
+
+=head1 CONSPIRACY
+
+This module is also free-as-in-mason software.
+
+=cut
+
+1;
View
4 lib/Couchbase/Client.pm
@@ -2,7 +2,7 @@ package Couchbase::Client;
BEGIN {
require XSLoader;
- our $VERSION = '0.12_0';
+ our $VERSION = '0.13_0';
XSLoader::load(__PACKAGE__, $VERSION);
}
@@ -195,8 +195,6 @@ Couchbase::Client - Perl Couchbase Client
This page documents the API of C<Couchbase::Client>. To install this module,
see L<Couchbase::Client::README> for a broader overview.
-Just downloading and doing the traditional dance via CPAN I<might> work.
-
=head1 WARNING
The bundled C<libcouchbase> is not an official release version, and might break.
View
2  lib/Couchbase/Client/Async.pm
@@ -1,7 +1,7 @@
package Couchbase::Client::Async;
use strict;
use warnings;
-our $VERSION = '0.12_0';
+our $VERSION = '0.13_0';
require XSLoader;
XSLoader::load('Couchbase::Client', $VERSION);
use Couchbase::Client;
View
293 src/Makefile.PL
@@ -0,0 +1,293 @@
+#!/usr/bin/perl
+package PLCBCDeps;
+
+use strict;
+use warnings;
+use ExtUtils::MakeMaker;
+use Dir::Self;
+use Devel::CheckLib;
+use Log::Fu { level => 'debug' };
+use Dir::Self;
+use Data::Dumper;
+use File::Spec;
+use Dir::Self;
+
+use Cwd qw(abs_path);
+
+use lib (__DIR__ . '/..');
+
+my $Sharepath = File::Spec->catfile(
+ 'auto', 'share', 'dist', 'Couchbase-Client','Libary');
+
+require ExtUtils::Liblist;
+
+my $PARENT_MM;
+
+my $SEARCHPATH_S;
+{
+ my @checklib_libs = grep $_ && $_ ne '-lcouchbase', @PLCBTopLevel::LIBS;
+ $SEARCHPATH_S = join(' ', @checklib_libs) || '';
+}
+
+my %CHECKLIB_OPTIONS = (
+ LIBS => $SEARCHPATH_S,
+ INC => $PLCBTopLevel::INC
+);
+
+my %MM_Options = (
+ NAME => 'Couchbase::libcouchbase',
+ AUTHOR => q{M. Nunberg <mnunberg@haskalah.org},
+ VERSION_FROM => 'libcouchbase.pm',
+ ABSTRACT_FROM => 'libcouchbase.pm'
+);
+
+my $LIBCOUCHBASE_CFUNC = <<'EOC';
+unsigned int version = 0;
+(void)libcouchbase_get_version(&version);
+if(version >= 0x010001) {
+ return 0;
+}
+return 1;
+EOC
+
+my $LIBEVENT_CFUNC = <<EOC;
+int version_major = 0, version_minor = 0;
+const char *version_string = event_get_version();
+if(!version_string) {
+ return 1;
+}
+sscanf(version_string, "%d.%d", &version_major, &version_minor);
+if(version_major >= 2) {
+ return 0;
+} else if(version_major == 1 && version_minor >= 4) {
+ return 0;
+}
+return 1;
+
+EOC
+
+#sub have_
+
+
+sub check_dependency {
+ my ($names,$fn,%extra) = @_;
+ $names = ref $names ? $names : [ $names ];
+ log_info("Checking for", @$names);
+ local $ENV;
+
+ foreach my $libname (@$names) {
+ my (undef,undef,$ldargs,$runpath,$sofile) =
+ ExtUtils::Liblist->ext("$SEARCHPATH_S -l$libname", 0, 1);
+
+ next unless ($sofile && ($sofile = $sofile->[0]) );
+
+ log_info("Have:", $sofile);
+ my %cl_opts = (
+ %CHECKLIB_OPTIONS,
+ lib => $libname,
+ #libpath => "-Wl,$ldargs,$sofile",
+ );
+
+ if($runpath) {
+ $ENV{LD_RUN_PATH} .= $runpath;
+ }
+
+ if($fn) {
+ $cl_opts{function} = $fn;
+ }
+ if(check_lib(%cl_opts, %extra)) {
+ log_info("have $libname");
+ return 1;
+ }
+ }
+ log_warn("Couldn't find anything for", @$names);
+}
+
+
+sub insert_announcement {
+ my $msg = shift;
+ my @lines;
+ my $line = "\t\$(NOECHO)\$(ECHO) ";
+ push(@lines, $line . "~" x 60) for (0..2);
+ push @lines, $line . $msg;
+ push(@lines, $line . "~" x 60) for (0..2);
+ if(wantarray) {
+ return @lines;
+ } else {
+ return join("\n", @lines);
+ }
+}
+
+sub create_buildscript_invocation {
+ my ($mm,$build,$install,$deps) = @_;
+
+ #mm is the parent Makefile, here
+
+ my @lines = (
+
+ #begin long commandline invocation:
+
+ "\t".
+ #'$(NOECHO) $(ECHO) '.
+ '$(PERLRUN) ' .
+ File::Spec->catfile('..', 'build_libraries.pl') . "\\",
+ "\t\t".sprintf(" --build-prefix=%s \\\n\t\t--install-prefix=%s",
+ $mm->quote_literal($build),
+ $mm->quote_literal($install)) . "\\",
+
+ "\t\t".sprintf(" --env-cppflags=%s",
+ $mm->quote_literal($mm->{INC})) . "\\",
+
+
+ "\t\t".sprintf(" --env-libs=%s",
+ $mm->quote_literal($mm->{LDLOADLIBS}. ' ' .
+ $PLCBTopLevel::U_LibPath)) . "\\",
+
+
+ "\t\t".sprintf(" --rpath=%s",
+ $mm->quote_literal($mm->{LD_RUN_PATH})) . "\\",
+ "\t\t".join(" ", @$deps)
+
+
+
+ #end long commandline invocation
+ #"\t".'$(MKPATH) ' . $build,
+ #"\t".'$(TOUCH) $@',
+ );
+
+ return @lines;
+
+}
+
+
+
+sub mangle_parent_makefile {
+ my ($parent,$deps) = @_;
+ no strict 'refs';
+
+ log_warn("Mangling parent MM methods for extra dependencies");
+
+ my $libpath = File::Spec->catfile($Sharepath, 'lib');
+
+ my $methname = ref($parent).'::dynamic_lib';
+ my $old_meth = $parent->can('dynamic_lib');
+
+ my $blib_dep_path = "\$(INST_LIB)\$(DFSEP)$Sharepath";
+ my $dest_dep_path = "\$(DESTINSTALLSITELIB)\$(DFSEP)$Sharepath";
+
+ my $dep = "$blib_dep_path\$(DFSEP)lib\$(DFSEP)libcouchbase.\$(SO)";
+
+ $parent->{MYEXTLIB} = $dep;
+
+ *{ref($parent) . "::dynamic_lib"} = sub {
+ my ($mm,@args) = @_;
+ my $ret = $old_meth->($mm,@args, INST_DYNAMIC_DEP => $dep);
+ $ret = join("\n",
+ "\$(MYEXTLIB) ::",
+ "\t\$(NOOP)",
+ ) . $ret;
+
+ return $ret;
+ };
+
+ my $ldload = $parent->{LDLOADLIBS} || "";
+ my $runpath = $parent->{LD_RUN_PATH} || "";
+
+
+ $runpath = "$blib_dep_path\$(DFSEP)lib:" .
+ "$dest_dep_path\$(DFSEP)lib".
+ ":$runpath";
+ $ldload = "-L$blib_dep_path\$(DFSEP)lib";
+
+ {
+ my $parent_dir = abs_path("..");
+ $parent->{INST_LIB} = File::Spec->catfile($parent_dir,
+ $parent->{INST_LIB});
+ }
+
+ $parent->{LDLOADLIBS} = $ldload;
+ $parent->{LD_RUN_PATH} = $runpath;
+
+ $parent->{INC} .= " -I$blib_dep_path\$(DFSEP)include";
+
+
+ my $parent_inc = $parent->{INC};
+
+ my $inc_oneliner = sprintf("PLCB_ConfUtil::write_tmpflags(qq{%s})",
+ $parent_inc);
+
+ no warnings qw(redefine once);
+ *MY::postamble = sub {
+ my @lines = (
+ #get an absolute reference to $(INST_LIB)
+
+ #"INST_LIB := ".
+ #'$(shell '.
+ # $parent->oneliner('print abs_path("$(INST_LIB)")',
+ # [ '-MCwd=abs_path' ])
+ #.' )',
+
+ "$dep:",
+ (insert_announcement("will build for ultimate target $dep")),
+ (create_buildscript_invocation($parent,
+ $blib_dep_path, $dest_dep_path, $deps)),
+ (insert_announcement("dependencies done")),
+
+ #now try to insert some constants.
+ "\t".$parent->oneliner($inc_oneliner, ['-I../', '-MPLCB_ConfUtil']),
+ "",
+ "",
+
+
+ "all :: $dep",
+ );
+
+ return join("\n", @lines);
+ };
+}
+
+sub MM_Configure {
+ my ($self,$h) = @_;
+ my $parent = $ExtUtils::MakeMaker::Parent[0];
+ $PLCBTopLevel::MM_TopLevel = $parent;
+
+ $PARENT_MM = $parent;
+ die("Must be run from within top-level Makefile.PL") unless $parent;
+ my @to_build;
+
+ if($ENV{PLCB_BUILD_ALL}) {
+ log_err('build_all reuqested');
+ @to_build = qw(VBUCKET COUCHBASE EVENT ISASL);
+ goto GT_MANGLE;
+ }
+
+ my $have_libcouchbase =
+ check_dependency('couchbase',$LIBCOUCHBASE_CFUNC);
+
+ if($have_libcouchbase) {
+
+ return $h; #nothing to do here.
+ } else {
+ push @to_build, qw(COUCHBASE VBUCKET);
+ }
+
+ if(!check_dependency(
+ 'event', $LIBEVENT_CFUNC, header => 'event.h')) {
+ push @to_build, 'EVENT';
+ }
+ if(!check_dependency(['sasl2', 'sasl', 'isasl'])) {
+ push @to_build, 'ISASL';
+ }
+
+ GT_MANGLE:
+ log_err("We need to build the following dependencies:", @to_build);
+ mangle_parent_makefile($parent, \@to_build);
+
+
+ return $h;
+
+}
+
+$MM_Options{CONFIGURE} = \&MM_Configure;
+
+WriteMakefile(%MM_Options);
View
9 xs/Client.xs
@@ -170,8 +170,8 @@ static SV *PLCB_set_common(SV *self,
av_clear(object->errors);
_sync_initialize_single(object, syncp);
-
- exp = exp_offset ? time(NULL) + exp_offset : 0;
+
+ PLCB_UEXP2EXP(exp, exp_offset, 0);
plcb_convert_storage(object, &value, &vlen, &store_flags);
err = libcouchbase_store(instance, syncp, storop,
@@ -197,7 +197,7 @@ static SV *PLCB_arithmetic_common(SV *self,
libcouchbase_error_t err;
mk_instance_vars(self, instance, object);
- exp = exp_offset ? time(NULL) + exp_offset : 0;
+ PLCB_UEXP2EXP(exp, exp_offset, 0);
plcb_get_str_or_die(key, skey, nkey, "Key");
@@ -228,7 +228,8 @@ static SV *PLCB_get_common(SV *self, SV *key, int exp_offset)
_sync_initialize_single(object, syncp);
av_clear(object->errors);
- exp_arg = (exp_offset && (exp = time(NULL) + exp_offset)) ? &exp : NULL;
+ PLCB_UEXP2EXP(exp, exp_offset, 0);
+ exp_arg = (exp) ? &exp : NULL;
err = libcouchbase_mget(instance, syncp, 1,
(const void * const*)&skey, &klen,
View
4 xs/Client_multi.xs
@@ -38,7 +38,7 @@
#define _exp_from_av(av, idx, nowvar, expvar, tmpsv) \
if( (tmpsv = av_fetch(av, idx, 0)) && (expvar = SvUV(*tmpsv))) { \
- expvar += nowvar; \
+ PLCB_UEXP2EXP(expvar, expvar, nowvar); \
}
#define _cas_from_av(av, idx, casvar, tmpsv) \
@@ -346,7 +346,7 @@ PLCB_multi_arithmetic_common(SV *self, AV *args, int cmd)
}
if ( (tmpsv = av_fetch(argav, 3, 0)) && (exp = SvUV(*tmpsv)) ) {
- exp += now;
+ PLCB_UEXP2EXP(exp, exp, now);
}
GT_CBC_CMD:
View
5 xs/async_base.c
@@ -21,7 +21,10 @@ static inline void av2request(
request->exp = 0; \
if((_fetch_nonull(PLCBA_REQIDX_EXP)) && SvIOK(*tmpsv) \
&& SvUV(*tmpsv) > 0) \
- { request->exp = time(NULL) + SvUV(*tmpsv); }
+ { \
+ UV utmp = SvUV(*tmpsv); \
+ PLCB_UEXP2EXP((request->exp), utmp, 0); \
+ }
SV **tmpsv;
STRLEN dummy;
View
2  xs/perl-couchbase.h
@@ -23,8 +23,6 @@
#include "plcb-util.h"
-
-
typedef struct PLCB_st PLCB_t;
typedef struct {
View
28 xs/plcb-util.h
@@ -1,6 +1,8 @@
#ifndef PLCB_UTIL_H_
#define PLCB_UTIL_H_
+/* This file contains various conversion functions and macros */
+
/*this stuff converts from SVs to int64_t (signed and unsigned) depending
on the perl*/
@@ -67,5 +69,31 @@ static inline uint64_t plcb_sv_to_u64(SV *in)
: (void*)die("Got NULL %s", diespec)
+#define PLCB_TIME_ABS_OFFSET
+
+#ifdef PLCB_TIME_ABS_OFFSET
+#define PLCB_UEXP2EXP(cbexp, uexp, now) \
+ cbexp = ((uexp) \
+ ? ((now) \
+ ? (now + uexp) \
+ : (time(NULL)) + uexp) \
+ : 0)
+
+#else
+
+/*Memcached protocol states that a time offset greater than 30 days is taken
+ to be an epoch time. We hide this from perl by simply generating our own
+ epoch time based on the user's time*/
+
+#define PLCB_UEXP2EXP(cbexp, uexp, now) \
+ cbexp = ((uexp) \
+ ? ((uexp > (30*24*60*60)) \
+ ? ((now) \
+ ? (now + uexp) \
+ : (time(NULL) + uexp)) \
+ : uexp) \
+ : 0)
+#endif
+
#endif /* PLCB_UTIL_H_ */
Please sign in to comment.
Something went wrong with that request. Please try again.