Tom -

There are ways to do this in which each subdirectory gets its own
Makefile.PL. Although it might be something worth figuring out, I just
use Module::Build instead. Module::Build examines all the
subdirectories of lib/ (in your distribution's source directory) and
(1) runs all *.pm.PL files, (2) transforms all .xs files, and (3)
compiles all .c files. It's the part about looking at all the files in
your lib/ directory that really sold me on it.

In order to get this to work, I needed to un-engineer some of the
PDL-specific incantations that get recommended (but not explained) for
use with ExtUtils::MakeMaker. First, this involves extracting the
compile/link arguments from PDL's configuration, as demonstrated on
lines 11, 12, 32, and 33 in this Build.PL:
https://github.com/run4flat/PDL-Parallel-threads/blob/master/Build.PL

Second, you must depend on ExtUtils::ParseXS v 3.0 or higher, as older
versions don't handle BOOT sections in multiple XS files in a single
distribution: 
https://github.com/run4flat/PDL-Parallel-threads/blob/master/Build.PL#L25

Third, you need to write your .pd files in terms of .pm.PL files. You
do this by renaming the files, placing them in the lib/PDL/whatever
directory where you want them to end up, and adding the appropriate
material from the top 25 lines from this file:
https://github.com/run4flat/PDL-Drawing-Prima/blob/master/lib/PDL/Drawing/Prima.pm.PL.
Notice that the vast majority of these 25 lines could be extracted
into a module, like PDL::PP::Module::Build or something, I just
haven't gotten around to it.

I've been meaning to write all of this up for some time, and I'll be
happy to expand on what I just wrote if anything is not clear.

There is on caveat to using Module::Build at the moment: all of your
source code must use the same set of C compile and link flags. This is
not the case for PDL itself but is often the case for CPAN modules. A
part of me has thought about taking this up with the Module::Build
folks, and I'd likely have the individual .pm.PL files (converted from
.pd, of course) tweak their own compiler/linker settings. But my round
tuits are not numerous to get it done at the moment. Bigger fish to
fry, it seems.

Let me know if that works, doesn't work, or seems confusing.

David

P.S. If you need a typemap, see
https://github.com/run4flat/PDL-Drawing-Prima/blob/master/typemap

On Thu, Aug 23, 2012 at 7:27 PM, Tom Nishimura <[email protected]> wrote:
> Hello,
> Is it possible/recommendable to have more than one pdlpp file per
> module?  I noticed that the PDL itself never does this (it puts each
> *.pd in its own directory and with its own Makefile.PL, referenced by
> parent Makefile.PL's).
>
> I tried to see if I could accomplish this... below are four files
> (Makefile.PL, Sample1.pd, Sample2.pd, and t/test.t).  Sample1.pd (to be
> Foo::Sample1) and Sample2.pd (to be Foo::Sample2) have dummy pp_def's.
> In Makefile.PL, I tried to generalize the example in PDL::PP... I added
> entries for PM, OBJECT, MAN3PODS, and clean, and concatenated the
> pdlpp_postamble calls in MY::postamble(). NAME was set to Foo.
>
> After make-ing, I run 'prove -vlbc t/test.t', and get:
>
>  t/test.t .. Can't locate loadable object for module Foo::Sample1 in
>  @INC (@INC contains: [... snip ...]) at t/test.t line 6.
>
> because apparently Foo::Sample1 tries to load
> auto/Foo/Sample1/Sample1.so, but PDL builds auto/Foo/Foo.so instead
> instead, based on the EUMM's NAME argument.
>
> Is there an easy, recommended way around this?
>
>  ### Sample1.pd
>  pp_def(
>      'mysumover1',
>      Pars => 'a(n); [o]b();',
>      Code => q{ $GENERIC() tmp=0; loop(n) %{ tmp += $a(); %} $b() = tmp;
>      },
>  );
>  pp_done();
>
>  ### Sample2.pd
>  pp_def(
>      'mysumover2',
>      Pars => 'a(n); [o]b();',
>      Code => q{ $GENERIC() tmp=0; loop(n) %{ tmp += $a(); %} $b() = tmp;
>      },
>  );
>  pp_done();
>
>  ### Makefile.PL
>
>  use PDL::Core::Dev;            # Pick up development utilities
>  use ExtUtils::MakeMaker;
>
>  my $package1 = ["Sample1.pd","Sample1","Foo::Sample1"];
>  my $package2 = ["Sample2.pd","Sample2","Foo::Sample2"];
>
>  my %hash = (
>      'MAN3PODS' => {
>          'Sample1.pm' => '$(INST_MAN3DIR)/Foo::Sample1.$(MAN3EXT)',
>          'Sample2.pm' => '$(INST_MAN3DIR)/Foo::Sample2.$(MAN3EXT)',
>      },
>      'TYPEMAPS' => [
>      '/opt/perl/lib/site_perl/5.16.0/x86_64-linux/PDL/Core/typemap.pdl'
>      ],
>      'NAME' => 'Foo',
>      'LIBS' => [],
>      'INC' => '-I/opt/perl/lib/site_perl/5.16.0/x86_64-linux/PDL/Core ',
>      'OBJECT' => 'Sample1$(OBJ_EXT) Sample2$(OBJ_EXT)',
>      'clean' => {
>          'FILES' => 'Sample1.xs Sample1.pm Sample1$(OBJ_EXT) Sample1.c
>          Sample2.xs Sample2.pm Sample2$(OBJ_EXT) Sample2.c',
>      },
>      'PM' => {
>          'Sample1.pm' => '$(INST_LIBDIR)/Foo/Sample1.pm',
>          'Sample2.pm' => '$(INST_LIBDIR)/Foo/Sample2.pm',
>      }
>  );
>
>  $hash{'VERSION'} = '0.0.1';
>  WriteMakefile(%hash);
>
>  sub MY::postamble {
>      join "\n", pdlpp_postamble($package1), pdlpp_postamble($package2);
>  }
>
>  ### t/test.t
>
>  use strict;
>  use warnings;
>  use Test::More qw(no_plan);
>  use PDL;
>  use Foo::Sample1;
>  use Foo::Sample2;
>  use List::Util qw//;
>
>  my %v = (
>      first  => long (1 .. 10),
>      second => long (-5 .. 19),
>      third  => long (72 .. 100),
>  );
>
>  while (my ($name,$pdl) = each %v) {
>      is($pdl->mysumover1(), List::Util::sum(list($pdl)), $name);
>      is($pdl->mysumover2(), List::Util::sum(list($pdl)), $name);
>  }
>
>
> thanks,
> Tom
>
> _______________________________________________
> Perldl mailing list
> [email protected]
> http://mailman.jach.hawaii.edu/mailman/listinfo/perldl



-- 
 "Debugging is twice as hard as writing the code in the first place.
  Therefore, if you write the code as cleverly as possible, you are,
  by definition, not smart enough to debug it." -- Brian Kernighan

_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl

Reply via email to