Skip to content

Commit

Permalink
* Include the Nix Perl bindings in Nix itself. This will allow the
Browse files Browse the repository at this point in the history
  bindings to be used in Nix's own Perl scripts.

  The only downside is that Perl XS and Automake/libtool don't really
  like each other, so building is a bit tricky.
  • Loading branch information
edolstra committed Oct 10, 2011
1 parent 55481c4 commit 73fe687
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS = externals src scripts corepkgs doc misc tests
SUBDIRS = externals src perl scripts corepkgs doc misc tests
EXTRA_DIST = substitute.mk nix.spec nix.spec.in bootstrap.sh \
nix.conf.example NEWS version

Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ AC_CONFIG_FILES([Makefile
src/nix-setuid-helper/Makefile
src/nix-log2xml/Makefile
src/bsdiff-4.3/Makefile
perl/Makefile
scripts/Makefile
corepkgs/Makefile
corepkgs/nar/Makefile
Expand Down
7 changes: 7 additions & 0 deletions perl/MANIFEST
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Changes
Makefile.PL
MANIFEST
Nix.xs
README
t/Nix.t
lib/Nix.pm
25 changes: 25 additions & 0 deletions perl/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
perlversion := $(shell perl -e 'use Config; print $$Config{version};')
perlarchname := $(shell perl -e 'use Config; print $$Config{archname};')
perllibdir = $(libdir)/perl5/site_perl/$(perlversion)/$(perlarchname)

install-exec-local: lib/Nix/*.pm
$(INSTALL) -d $(DESTDIR)$(perllibdir)/Nix
$(INSTALL_DATA) lib/Nix/*.pm $(DESTDIR)$(perllibdir)/Nix
$(INSTALL) -d $(DESTDIR)$(perllibdir)/auto/Nix/Store
ln -sfn $(pkglibdir)/libNixStore.so $(DESTDIR)$(perllibdir)/auto/Nix/Store/Store.so

# Awful hackery to get libtool to build Perl XS bindings.
pkglib_LTLIBRARIES = libNixStore.la

libNixStore_la_SOURCES = lib/Nix/Store.cc

libNixStore_la_LIBADD = $(top_srcdir)/src/libstore/libstore.la

AM_CXXFLAGS = \
-I$(top_srcdir)/src -I$(top_srcdir)/src/libutil -I$(top_srcdir)/src/libstore \
-I$(shell perl -e 'use Config; print $$Config{archlibexp};')/CORE

lib/Nix/Store.cc: lib/Nix/Store.xs
xsubpp $^ -output $@

EXTRA_DIST = lib/Nix/*.pm lib/Nix/Store.xs
23 changes: 23 additions & 0 deletions perl/lib/Nix/Store.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package Nix::Store;

use 5.010001;
use strict;
use warnings;

require Exporter;

our @ISA = qw(Exporter);

our %EXPORT_TAGS = ( 'all' => [ qw( ) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw( );

our $VERSION = '0.15';

require XSLoader;
XSLoader::load('Nix::Store', $VERSION);

1;
__END__
129 changes: 129 additions & 0 deletions perl/lib/Nix/Store.xs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

/* Prevent a clash between some Perl and libstdc++ macros. */
#undef do_open
#undef do_close

#include <store-api.hh>
#include <globals.hh>
#include <misc.hh>
#include <util.hh>


using namespace nix;


void doInit()
{
if (!store) {
nixStore = canonPath(getEnv("NIX_STORE_DIR", getEnv("NIX_STORE", "/nix/store")));
nixStateDir = canonPath(getEnv("NIX_STATE_DIR", "/nix/var/nix"));
nixDBPath = getEnv("NIX_DB_DIR", nixStateDir + "/db");
try {
store = openStore();
} catch (Error & e) {
croak(e.what());
}
}
}


MODULE = Nix::Store PACKAGE = Nix::Store
PROTOTYPES: ENABLE


void init()
CODE:
doInit();


int isValidPath(path)
char * path
CODE:
try {
doInit();
RETVAL = store->isValidPath(path);
} catch (Error & e) {
croak(e.what());
}
OUTPUT:
RETVAL


SV * queryReferences(path)
char * path
PPCODE:
try {
doInit();
PathSet paths;
store->queryReferences(path, paths);
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}


SV * queryPathHash(path)
char * path
PPCODE:
try {
doInit();
Hash hash = store->queryPathHash(path);
string s = "sha256:" + printHash(hash);
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}


SV * queryDeriver(path)
char * path
PPCODE:
try {
doInit();
Path deriver = store->queryDeriver(path);
if (deriver == "") XSRETURN_UNDEF;
XPUSHs(sv_2mortal(newSVpv(deriver.c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}


SV * queryPathInfo(path)
char * path
PPCODE:
try {
doInit();
ValidPathInfo info = store->queryPathInfo(path);
if (info.deriver == "")
XPUSHs(&PL_sv_undef);
else
XPUSHs(sv_2mortal(newSVpv(info.deriver.c_str(), 0)));
string s = "sha256:" + printHash(info.hash);
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
mXPUSHi(info.registrationTime);
mXPUSHi(info.narSize);
AV * arr = newAV();
for (PathSet::iterator i = info.references.begin(); i != info.references.end(); ++i)
av_push(arr, newSVpv(i->c_str(), 0));
XPUSHs(sv_2mortal(newRV((SV *) arr)));
} catch (Error & e) {
croak(e.what());
}


SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
PPCODE:
try {
doInit();
PathSet paths;
for (int n = 2; n < items; ++n)
computeFSClosure(*store, SvPV_nolen(ST(n)), paths, flipDirection, includeOutputs);
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
} catch (Error & e) {
croak(e.what());
}

0 comments on commit 73fe687

Please sign in to comment.