On Thu, Oct 15, 2009 at 02:28:07PM +0200, Manuel Prinz wrote: > > However, this means the Inline'd code would need to be moved to a separate > > module ("used only for modules"). That seems easy to do though. > > This seems to be the proper solution and easy to do. Is there a special > naming convention and location for modules that are private to apps?
I think the existing /usr/share/findimagedupes/lib would be fine. As for the naming convention, maybe the App:: namespace on CPAN would do? OTOH as long as they're private nobody should care. > > FWIW, the few other packages depending on libinline-perl don't seem > > to be broken. I looked at libogg-vorbis-header-perl (which uses the > > VERSION parameter) and it's loading the C extension fine. > > Right. But also none of them seems to include the .inl file. Could the > libinline maintainers please comment on whether this file (and others > generated by libinline) is/are needed? The perldoc does not really > clarify it from a distribution point of view for me. libogg-v-h-p seems > to work well without them. It seems the standard way to go is with Inline::MakeMaker. Here's a lightly tested patch that seems to work for me, hope you find it useful. I tried to be non-intrusive, but I couldn't resist reworking the sed parts of debian/rules a bit. YMMV there of course :) -- Niko Tyni nt...@debian.org
>From 6f4165577573245722c86b03fea0695afd2d4c3a Mon Sep 17 00:00:00 2001 From: Niko Tyni <nt...@debian.org> Date: Sun, 18 Oct 2009 20:53:19 +0300 Subject: [PATCH] Keep the C parts working across binary compatible Perl upgrades * Use Inline::MakeMaker to keep the C parts working across binary compatible Perl upgrades. (Closes: #549447) * Build-Depend on cdbs (>= 0.4.57) to make sure 'make install' uses DESTDIR and not PREFIX (which doesn't work with the way we set the private library installation path through LIB). * Rework the installation instructions removal a bit so that 'debian/rules clean' undoes the effects. --- C.pm | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile.PL | 6 +++ debian/changelog | 13 ++++++ debian/control | 2 +- debian/install | 3 - debian/manpages | 1 - debian/rules | 21 ++++------ findimagedupes | 109 +------------------------------------------------- 8 files changed, 146 insertions(+), 125 deletions(-) create mode 100644 C.pm create mode 100644 Makefile.PL delete mode 100644 debian/install delete mode 100644 debian/manpages diff --git a/C.pm b/C.pm new file mode 100644 index 0000000..1dbffad --- /dev/null +++ b/C.pm @@ -0,0 +1,116 @@ +package findimagedupes::C; + +use Inline + C => 'DATA', + NAME => 'findimagedupes::C', + VERSION => '0.01', +; + +our $VERSION = '0.01'; +1; + +__DATA__ + +__C__ + +/* efficient bit-comparison */ + +#include <stdint.h> +#include <string.h> + +#define LOOKUP_SIZE 65536 +#define FP_CHUNKS 16 + +typedef uint16_t FP[FP_CHUNKS]; + +unsigned int simplecountbits (unsigned int i) { + unsigned int val = i, res = 0; + + while (val) { + res += (val&1); + val >>= 1; + } + return(res); +} + +void diffbits (SV* oldfiles, SV* newfiles, unsigned int threshold, unsigned limit) { + FP *the_data, *a, *b; + unsigned int lookup[LOOKUP_SIZE]; + unsigned int i, j, k, m, bits, old, new; + HV *oldhash; + HE *oldhash_entry; + HV *newhash; + HE *newhash_entry; + unsigned int numkeys = 0; + SV *sv_val; + Inline_Stack_Vars; + + if ((threshold<0) || (threshold>256)) { + croak("ridiculous threshold specified"); + } + + /* pack fingerprints into C array */ + /* partly lifted from Inline::C-Cookbook */ + + if (! SvROK(newfiles)) { + croak("newfiles is not a reference"); + } + newhash = (HV *)SvRV(newfiles); + new = hv_iterinit(newhash); + + if (! SvROK(oldfiles)) { + croak("oldfiles is not a reference"); + } + oldhash = (HV *)SvRV(oldfiles); + old = hv_iterinit(oldhash); + + numkeys = new+old; + if (numkeys<2) { + /* minor optimization: return without doing anything */ + /* malloc(0) could be bad... */ + Inline_Stack_Void; + } + the_data = (FP *)malloc(numkeys*sizeof(FP)); + if (!the_data) { + croak("malloc failed"); + } + + for (i = 0; i<new; i++) { + newhash_entry = hv_iternext(newhash); + sv_val = hv_iterval(newhash, newhash_entry); + memcpy(the_data+i, SvPV(sv_val, PL_na), sizeof(FP)); + } + for (i = new; i<numkeys; i++) { + oldhash_entry = hv_iternext(oldhash); + sv_val = hv_iterval(oldhash, oldhash_entry); + memcpy(the_data+i, SvPV(sv_val, PL_na), sizeof(FP)); + } + + /* initialise lookup table */ + /* XXX: fast enough? could optimise more or compile-in a static table */ + for (i=0; i<LOOKUP_SIZE; i++) { + lookup[i] = simplecountbits(i); + } + + /* look for matches */ + Inline_Stack_Reset; + for (a=the_data, i=0, m=(limit>0 ? new : numkeys-1); i<m; a++, i++) { + for (b=a+1, j=i+1; j<numkeys; b++, j++) { + for (bits=0, k=0; k<FP_CHUNKS; k++) { + bits += lookup[(*a)[k]^(*b)[k]]; + if (bits > threshold) goto abortmatch; + } + /* if (bits <= threshold) */ { + Inline_Stack_Push(sv_2mortal(newSViv(i))); + Inline_Stack_Push(sv_2mortal(newSViv(j))); + Inline_Stack_Push(sv_2mortal(newSViv(bits))); + } +abortmatch:; + } + } + Inline_Stack_Done; + + /* clean up */ + free(the_data); +} + diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..83df31d --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,6 @@ +use Inline::MakeMaker; +WriteInlineMakefile( + 'NAME' => 'findimagedupes::C', + 'VERSION_FROM' => 'C.pm', + 'EXE_FILES' => [ 'findimagedupes' ], +); diff --git a/debian/changelog b/debian/changelog index 17b51b6..560afe7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +findimagedupes (2.18-3.1) UNRELEASED; urgency=low + + * Non-maintainer upload. + * Use Inline::MakeMaker to keep the C parts working across + binary compatible Perl upgrades. (Closes: #549447) + * Build-Depend on cdbs (>= 0.4.57) to make sure 'make install' + uses DESTDIR and not PREFIX (which doesn't work with the way + we set the private library installation path through LIB). + * Rework the installation instructions removal a bit so that + 'debian/rules clean' undoes the effects. + + -- Niko Tyni <nt...@debian.org> Fri, 16 Oct 2009 09:44:30 +0300 + findimagedupes (2.18-3) unstable; urgency=low * Corrected path in DIRECTORY config option. Closes: #532318. diff --git a/debian/control b/debian/control index 1e79a10..4a64166 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Priority: optional Maintainer: Debian Science Maintainers <debian-science-maintain...@lists.alioth.debian.org> DM-Upload-Allowed: yes Uploaders: Andreas Tille <ti...@debian.org>, Manuel Prinz <man...@debian.org> -Build-Depends: cdbs, debhelper, libfile-mimeinfo-perl, libgraphics-magick-perl, +Build-Depends: cdbs (>= 0.4.57), debhelper, libfile-mimeinfo-perl, libgraphics-magick-perl, libinline-perl Standards-Version: 3.8.1 Vcs-Browser: http://git.debian.org/?p=debian-science/packages/findimagedupes.git diff --git a/debian/install b/debian/install deleted file mode 100644 index 1b2e103..0000000 --- a/debian/install +++ /dev/null @@ -1,3 +0,0 @@ -findimagedupes usr/bin -tmp/lib usr/lib/findimagedupes -tmp/config usr/lib/findimagedupes diff --git a/debian/manpages b/debian/manpages deleted file mode 100644 index d01e926..0000000 --- a/debian/manpages +++ /dev/null @@ -1 +0,0 @@ -findimagedupes.1 diff --git a/debian/rules b/debian/rules index 8e0b48c..aa239de 100755 --- a/debian/rules +++ b/debian/rules @@ -5,27 +5,22 @@ pkg:=findimagedupes include /usr/share/cdbs/1/rules/debhelper.mk -# include /usr/share/cdbs/1/class/perlmodule.mk +include /usr/share/cdbs/1/class/perlmodule.mk -DEB_DH_PERL_ARGS := usr/lib/findimagedupes/lib/auto/findimagedupes - -clean:: - rm -fr ./$(pkg)_tmp ./tmp findimagedupes.1 +DEB_DH_PERL_ARGS := usr/lib/findimagedupes/lib +DEB_MAKEMAKER_USER_FLAGS := LIB=/usr/lib/findimagedupes/lib build/findimagedupes:: - sed -i "s?/usr/local/lib/$(pkg)?/usr/lib/$(pkg)?g" $(pkg) - sed "s?/usr/lib/$(pkg)?./tmp?g" $(pkg) > $(pkg)_tmp - mkdir -p ./tmp - chmod 755 $(pkg)_tmp - ./$(pkg)_tmp # Bug #531145: Removing installation instructions from the manpage, as # they are useless if the package is installed. Upstream has no other # documentation, so this section will stay in upstream's version. - sed -i '/^=head1 INSTALLATION/,/^=head1 /{/^=head1 OPTIONS/p;d;}' \ - $(pkg) - pod2man $(pkg) > findimagedupes.1 + if grep -q '^=head1 INSTALLATION' $(pkg); then \ + sed -i.pristine '/^=head1 INSTALLATION/,/^=head1 /{/^=head1 OPTIONS/p;d;}' \ + $(pkg); fi # Upstream has now updated README himself in version 2.18 # It might be reasonable to create the README this way anyway # pod2text findimagedupes > ./tmp/README +clean:: + [ ! -f findimagedupes.pristine ] || mv findimagedupes.pristine findimagedupes diff --git a/findimagedupes b/findimagedupes index 489a7a0..3eb12d3 100755 --- a/findimagedupes +++ b/findimagedupes @@ -34,10 +34,8 @@ use Graphics::Magick; use MIME::Base64; use Pod::Usage; -use Inline - C => 'DATA', - NAME => 'findimagedupes', - DIRECTORY => '/usr/local/lib/findimagedupes'; +use lib "/usr/lib/findimagedupes/lib"; +use findimagedupes::C; # ---------------------------------------------------------------------- # @@ -990,106 +988,3 @@ algorithm. =cut -__C__ - -/* efficient bit-comparison */ - -#include <stdint.h> -#include <string.h> - -#define LOOKUP_SIZE 65536 -#define FP_CHUNKS 16 - -typedef uint16_t FP[FP_CHUNKS]; - -unsigned int simplecountbits (unsigned int i) { - unsigned int val = i, res = 0; - - while (val) { - res += (val&1); - val >>= 1; - } - return(res); -} - -void diffbits (SV* oldfiles, SV* newfiles, unsigned int threshold, unsigned limit) { - FP *the_data, *a, *b; - unsigned int lookup[LOOKUP_SIZE]; - unsigned int i, j, k, m, bits, old, new; - HV *oldhash; - HE *oldhash_entry; - HV *newhash; - HE *newhash_entry; - unsigned int numkeys = 0; - SV *sv_val; - Inline_Stack_Vars; - - if ((threshold<0) || (threshold>256)) { - croak("ridiculous threshold specified"); - } - - /* pack fingerprints into C array */ - /* partly lifted from Inline::C-Cookbook */ - - if (! SvROK(newfiles)) { - croak("newfiles is not a reference"); - } - newhash = (HV *)SvRV(newfiles); - new = hv_iterinit(newhash); - - if (! SvROK(oldfiles)) { - croak("oldfiles is not a reference"); - } - oldhash = (HV *)SvRV(oldfiles); - old = hv_iterinit(oldhash); - - numkeys = new+old; - if (numkeys<2) { - /* minor optimization: return without doing anything */ - /* malloc(0) could be bad... */ - Inline_Stack_Void; - } - the_data = (FP *)malloc(numkeys*sizeof(FP)); - if (!the_data) { - croak("malloc failed"); - } - - for (i = 0; i<new; i++) { - newhash_entry = hv_iternext(newhash); - sv_val = hv_iterval(newhash, newhash_entry); - memcpy(the_data+i, SvPV(sv_val, PL_na), sizeof(FP)); - } - for (i = new; i<numkeys; i++) { - oldhash_entry = hv_iternext(oldhash); - sv_val = hv_iterval(oldhash, oldhash_entry); - memcpy(the_data+i, SvPV(sv_val, PL_na), sizeof(FP)); - } - - /* initialise lookup table */ - /* XXX: fast enough? could optimise more or compile-in a static table */ - for (i=0; i<LOOKUP_SIZE; i++) { - lookup[i] = simplecountbits(i); - } - - /* look for matches */ - Inline_Stack_Reset; - for (a=the_data, i=0, m=(limit>0 ? new : numkeys-1); i<m; a++, i++) { - for (b=a+1, j=i+1; j<numkeys; b++, j++) { - for (bits=0, k=0; k<FP_CHUNKS; k++) { - bits += lookup[(*a)[k]^(*b)[k]]; - if (bits > threshold) goto abortmatch; - } - /* if (bits <= threshold) */ { - Inline_Stack_Push(sv_2mortal(newSViv(i))); - Inline_Stack_Push(sv_2mortal(newSViv(j))); - Inline_Stack_Push(sv_2mortal(newSViv(bits))); - } -abortmatch:; - } - } - Inline_Stack_Done; - - /* clean up */ - free(the_data); -} - -- 1.6.4.3