File Coverage

Makefile.PL
Criterion Covered Total %
statement n/a
branch n/a
condition n/a
subroutine n/a
pod n/a
total n/a


line stmt bran cond sub pod time code
1             use strict;
2             use warnings;
3             use lib qw(lib);
4             use PDL::Core::Dev;
5              
6             eval { require Devel::CheckLib; Devel::CheckLib->import; };
7             use ExtUtils::MakeMaker;
8             use ExtUtils::MakeMaker::Config;
9             use File::Spec::Functions qw(catdir catfile);
10              
11             my @cpan_deps = my @prereq = (
12             'Data::Dumper' => 2.121, # for PDL::IO::Dumper
13             'File::Map' => 0.57, # test new mmap implementation
14             'File::Which' => 0,
15             'Filter::Util::Call' => 0, # for PDL::NiceSlice
16             'Filter::Simple' => 0.88, # for new PDL::NiceSlice
17             'List::Util' => '1.33',
18             'Pod::Simple' => '3.40', # for PDL::Doc
19             'Scalar::Util' => 0,
20             'Storable' => 1.03, # for PDL::IO::Storable
21             'Text::Balanced' => '2.05', # for PDL::NiceSlice
22             'Math::Complex' => 0,
23             );
24             my %min_version = (
25             'Inline' => '0.83', # fixed ILSM-finding
26             'Inline::C' => '0.62',
27             'Term::ReadKey' => '2.34', #for perldl shell
28             'Astro::FITS::Header' => '2.1', # apparently before that, IO::FITS no work
29             );
30             for my $opt_dep (sort keys %min_version) {
31             (my $file = $opt_dep) =~ s#::#/#g;
32             next if !eval { require "$file.pm"; 1 }; # not installed, fine
33             next if eval { $opt_dep->VERSION($min_version{$opt_dep}); 1 };
34             push @prereq, $opt_dep => $min_version{$opt_dep};
35             }
36              
37             my $pdlroot = catfile qw(script pdl);
38             my @exe_files = map catfile('script', $_), qw(perldl pdldoc pptemplate);
39             push @exe_files, "$pdlroot$Config{exe_ext}" if $^O !~ /MSWin/;
40             my @cleanup = ("$pdlroot$Config{exe_ext}");
41              
42             ##############################
43             # Hack to include fPIC on x86_64 systems -
44             # use similar mods to affect CCFLAGS on other systems as needed...
45              
46             my $ccflags = $Config{ccflags};
47             if($Config{archname}=~m/amd64|i686|x86_64/) {
48             $ccflags .= " -fPIC";
49             }
50              
51             my $pthread_include = $ENV{POSIX_THREADS_INC} // '';
52             my $pthread_library = $ENV{POSIX_THREADS_LIBS} // '-lpthread';
53             if ($pthread_library) {
54             (my $libname = $pthread_library) =~ s/^-l//;
55             if (!eval { check_lib(lib=>$libname,header=>'pthread.h',incpath=>$pthread_include) }) {
56             print "\tDevel::CheckLib with '$libname' failed\n";
57             $pthread_library = '';
58             }
59             }
60             if (!$pthread_library) {
61             print "PDL will be built without POSIX thread support.\n";
62             print "\t==> *NOTE*: PDL threads are unrelated to perl threads (usethreads=y)!\n";
63             print "\t==> Enabling perl threads will not help!\n";
64             }
65             my $pthread_define = $pthread_library ? ' -DPDL_PTHREAD ' : '';
66             my $libs_string = "$pthread_library ".get_maths_libs();
67              
68             my $hdeps = join ' ', map catfile(qw(lib PDL Core), $_), qw(pdl.h pdlperl.h pdlcore.h pdlbroadcast.h pdlmagic.h);
69             my @cfiles = qw(pdlcore pdlapi pdlbroadcast pdlconv pdlmagic pdlaffine pdlutil);
70             my $cobj = join ' ', map catfile(qw(lib PDL Core), qq{$_\$(OBJ_EXT)}), @cfiles;
71             push @cleanup, $cobj;
72             my $core_obj = join('/', qw(lib PDL), 'Core$(OBJ_EXT)'); # EUMM XSMULTI targets are / not catfile
73              
74             # the modules in PDL::LiteF, used in t/core.t
75             my @BUILD_CORE = qw(Bad Core Math MatrixOps Ops Primitive Slices Ufunc);
76             # the modules needed in "use PDL"
77             my @BUILD_BASIC = qw(Compression FFT IO/Misc IO/Pnm ImageND ImageRGB);
78              
79             # create GENERATED subdir with *.pm files during 'make dist' (to make metacpan.org happy)
80             my $preop = '$(PERLRUNINST) -MPDL::Core::Dev -e pdlpp_mkgen $(DISTVNAME)';
81              
82             my %makefile_hash = (
83             PREREQ_PM => { @prereq },
84             LICENSE => 'perl',
85             CONFIGURE_REQUIRES => {
86             'Devel::CheckLib' => '1.01',
87             'File::Which' => 0,
88             'ExtUtils::MakeMaker' => '7.12', # working .g.c
89             'File::Path' => 0,
90             },
91             TEST_REQUIRES => {
92             'CPAN::Meta' => '2.120900',
93             'Test::Exception' => 0,
94             'Test::Warn' => 0, # for t/pptest.t
95             "Test::Deep" => 0, # for Test::Deep::PDL tests
96             },
97             BUILD_REQUIRES => {
98             'ExtUtils::MakeMaker' => 0,
99             'File::Path' => 0,
100             'Pod::Simple' => '3.40',
101             'ExtUtils::ParseXS' => '3.21', # ExtUtils::Typemaps::tidy_type
102             },
103             MIN_PERL_VERSION => '5.016',
104             NAME => 'PDL',
105             VERSION_FROM => 'lib/PDL.pm',
106             EXE_FILES => \@exe_files,
107             META_MERGE => {
108             "meta-spec" => { version => 2 },
109             resources => {
110             homepage => 'http://pdl.perl.org/',
111             bugtracker => {web=>'https://github.com/PDLPorters/pdl/issues'},
112             repository => {
113             url => 'git://github.com/PDLPorters/pdl.git',
114             type => 'git',
115             web => 'https://github.com/PDLPorters/pdl',
116             },
117             x_IRC => 'irc://irc.perl.org/#pdl',
118             },
119             prereqs => {
120             runtime => {
121             suggests => {
122             'Sys::SigAction' => 0, # Ctrl-C handling in shells
123             },
124             recommends => \%min_version,
125             requires => { @cpan_deps },
126             },
127             },
128             },
129             CCFLAGS => $ccflags,
130             XSMULTI => 1,
131             XSBUILD => {
132             xs => {
133             'lib/PDL/Core' => {
134             INC => join(' ',
135             PDL::Core::Dev::PDL_INCLUDE(),
136             map {length($_) ? qq{"$_"} : ()} $pthread_include
137             ),
138             OBJECT => "$core_obj $cobj",
139             },
140             },
141             },
142             DEFINE => $pthread_define,
143             LIBS => [$libs_string],
144             depend => {
145             $core_obj => $hdeps,
146             $cobj => $hdeps,
147             (map +(
148             "build_dynamic_PDL_".(s#/#_#gr) => catfile(qw($(INST_ARCHLIB) auto PDL), $_, (s#.*/##gr).".\$(DLEXT)"),
149             "build_static_PDL_".(s#/#_#gr) => catfile(qw($(INST_ARCHLIB) auto PDL), $_, (s#.*/##gr)."\$(LIB_EXT)"),
150             ), @BUILD_CORE, @BUILD_BASIC),
151             },
152             dist => { COMPRESS => 'gzip', SUFFIX => 'gz', PREOP => $preop },
153             clean => { FILES => join ' ',
154             qw(MANIFEST.bak _Inline/ .inlinepdlpp/ .inlinewith/ .pptest/), @cleanup,
155             catfile(qw(lib PDL Core pdl.h)),
156             },
157             AUTHOR => 'PerlDL Developers ',
158             ABSTRACT => 'Perl Data Language',
159             BINARY_LOCATION => 'PDL.tar.gz',
160             );
161              
162             WriteMakefile(%makefile_hash);
163              
164             {
165             package MY; # so that "SUPER" works right
166             my @pd_srcs;
167             sub postamble {
168             my ($self) = @_;
169             my $text = '';
170             $text .= <<'EOF';
171             doctest :: pm_to_blib
172             $(NOECHO) $(ECHO) "doctest: Building PDL documentation database in blib ..."
173             $(NOECHO) $(PERLRUNINST) utils$(DFSEP)scantree.pl
174              
175             doc_site_install :: doc_pdldoc_install
176              
177             doc_pdldoc_install :: pure_install # needs installed .../PDL dir to exist
178             $(NOECHO) $(ECHO) "doc_site_install: Building PDL documentation database ..."
179             $(NOECHO) $(PERLRUNINST) utils$(DFSEP)scantree.pl "$(DESTDIR)$(INSTALLSITEARCH)"
180              
181             doc_vendor_install ::
182             $(NOECHO) $(ECHO) "doc_vendor_install: Building PDL documentation database ..."
183             $(NOECHO) $(PERLRUNINST) utils$(DFSEP)scantree.pl "$(DESTDIR)$(INSTALLVENDORARCH)"
184              
185             doc_perl_install ::
186             $(NOECHO) $(ECHO) "doc_perl_install: Building PDL documentation database ..."
187             $(NOECHO) $(PERLRUNINST) utils$(DFSEP)scantree.pl "$(DESTDIR)$(INSTALLARCHLIB)"
188             EOF
189             $text .= <
190             $pdlroot$::Config{exe_ext} : $pdlroot.c
191             \t\$(CC) \$(CCFLAGS) \$(CPPFLAGS) \$(OPTIMIZE) \$(LDFLAGS) \$(CCCDLFLAGS) $pdlroot.c -o \$\@
192             EOT
193             my $typespm = ::catfile(qw(lib PDL Types.pm));
194             for (qw(pdl.h)) {
195             my $base = ::catfile(qw(lib PDL Core), $_);
196             $text .= "$base :: $base.PL $typespm\n\t\$(PERLRUN) $base.PL $base\n";
197             }
198             $text .= "\n" . ::coretarget($self);
199             my $coretest = join ' ', map ::catfile('t', $_.'.t'), qw(
200             01-pptest autoload bad basic bool clump constructor core croak lvalue
201             math matrix matrixops nat_complex ops-bitwise ops pdl_from_string
202             pdlchar pp_croaking pp_line_numbers pp_pod primitive-* ppt-* pthread reduce
203             slice subclass thread thread_def ufunc
204             );
205             my $basictest = join ' ', map ::catfile('t', $_.'.t'), qw(
206             compression fft imagergb picnorgb picrgb pic_16bit io-pnm pic-rim
207             io-misc
208             );
209             $text .= <
210             basictest : basic
211             \$(FULLPERLRUN) "$::Config{bin}/prove" -b $basictest
212             coretest : core
213             \$(FULLPERLRUN) "$::Config{bin}/prove" -b $coretest
214             update-ppport:
215             \$(PERLRUN) -MDevel::PPPort -e'Devel::PPPort::WriteFile' && \$(PERLRUN) lib/PDL/Core/ppport.h --strip
216             EOF
217             $text .= ::pdlpp_postamble_int(@pd_srcs);
218             $text;
219             }
220             sub _nopl { $_[0] =~ s/[.]PL$//r }
221             sub init_PM {
222             my ($self) = @_;
223             $self->SUPER::init_PM;
224             my ($pm, $plf) = @$self{qw(PM PL_FILES)};
225             for my $f (grep /pdl\.h\.PL$/, keys %$pm) {
226             $pm->{ ::catfile(split '/', _nopl($f)) } = _nopl(delete $pm->{$f}); # dealing in postamble but still install
227             }
228             for my $f (grep /\.PL$/, keys %$pm) {
229             $pm->{ $plf->{$f} = _nopl($f) } = _nopl(delete $pm->{$f});
230             }
231             @pd_srcs = ::pdlpp_eumm_update_deep($self);
232             }
233             }
234              
235             sub coretarget {
236             my ($self) = @_;
237             # remember the fundamental ones end up far to right as much deps on them
238             # a "right" is either scalar (named target) or tuple of
239             # [ \@dir, \@targets, \@prereqs ]
240             # @dir is dir parts for use by File::Spec
241             # @targets is make targets within that dir
242             # @prereqs are named targets - undef=[]
243             # all a left's rights are made concurrently, no sequence - list ALL prereqs
244             my @left2rights = (
245             [core => [ 'pm_to_blib', map qq{build_\$(LINKTYPE)_PDL_}.(s#/#_#gr), @BUILD_CORE ]],
246             [basic => ['core', (map qq{build_\$(LINKTYPE)_PDL_}.(s#/#_#gr), @BUILD_BASIC)]],
247             );
248             join "\n", map flatten_parallel_target($self, $_), @left2rights;
249             }
250              
251             sub format_chunk {
252             my ($self, $left, $deps, $dir, $targets) = @_;
253             my @m = join ' ', $left, ':', @{$deps||[]};
254             push @m, "\t" . $self->oneliner(
255             (@$dir ? "die \$! unless chdir q(".catdir(@$dir)."); " : '').
256             "exec q(\$(MAKE) @$targets)"
257             );
258             join '', map "$_\n", @m;
259             }
260              
261             # output: list of make chunks with target, deps, recipes
262             sub flatten_parallel_target {
263             my ($self, $left2rights) = @_;
264             my ($left, $rights) = @$left2rights;
265             my (@deps, @recipes, @otherchunks);
266             for my $right (@$rights) {
267             if (ref $right) {
268             # [ \@dir, \@targets, \@prereqs ]
269             # @dir is dir parts for use by File::Spec
270             # @targets is make targets within that dir
271             # @prereqs are named targets - undef=[]
272             my ($dir, $targets, $prereqs) = @$right;
273             my $target_name = parallel_target_mangle($self, $dir, $targets);
274             push @deps, $target_name;
275             push @otherchunks, format_chunk(
276             $self, $target_name, $prereqs, $dir, $targets
277             );
278             } else {
279             push @deps, $right;
280             }
281             }
282             (
283             join(' : ', $left, join ' ', @deps) . "\n",
284             @otherchunks,
285             );
286             }
287              
288             sub parallel_target_mangle {
289             my ($self, $dir, $targets) = @_;
290             my $target = join '_', @$dir, @$targets;
291             $target =~ s#[\$\(\)/\\_\.]+#_#g; # avoid ambiguity with filenames
292             $target;
293             }