]> git.imager.perl.org - imager.git/blame_incremental - Makefile.PL
work around the 5.005_0[45] B bug
[imager.git] / Makefile.PL
... / ...
CommitLineData
1#!perl -w
2use strict;
3use ExtUtils::MakeMaker;
4use Cwd;
5use Config;
6use File::Spec;
7use Getopt::Long;
8use vars qw(%Recommends);
9use ExtUtils::Manifest qw(maniread);
10use vars qw(%formats $VERBOSE $INCPATH $LIBPATH $NOLOG $DEBUG_MALLOC $MANUAL $CFLAGS $LFLAGS $DFLAGS);
11
12#
13# IM_INCPATH colon seperated list of paths to extra include paths
14# IM_LIBPATH colon seperated list of paths to extra library paths
15#
16# IM_VERBOSE turns on verbose mode for the library finding and such
17# IM_MANUAL to manually select which libraries are used and which not
18# IM_ENABLE to programmatically select which libraries are used
19# and which are not
20# IM_NOLOG if true logging will not be compiled into the module
21# IM_DEBUG_MALLOC if true malloc debbuging will be compiled into the module
22# do not use IM_DEBUG_MALLOC in production - this slows
23# everything down by alot
24# IM_CFLAGS Extra flags to pass to the compiler
25# IM_LFLAGS Extra flags to pass to the linker
26# IM_DFLAGS Extra flags to pass to the preprocessor
27# IM_SUPPRESS_PROMPT Suppress the prompt asking about gif support
28
29getenv(); # get environment variables
30
31my $lext=$Config{'so'}; # Get extensions of libraries
32my $aext=$Config{'_a'};
33
34my $help; # display help if set
35my @enable; # list of drivers to enable
36my @disable; # or list of drivers to disable
37my @incpaths; # places to look for headers
38my @libpaths; # places to look for libraries
39my $noexif; # non-zero to disable EXIF parsing of JPEGs
40my $no_gif_set_version; # disable calling EGifSetGifVersion
41my $coverage; # build for coverage testing
42GetOptions("help" => \$help,
43 "enable=s" => \@enable,
44 "disable=s" => \@disable,
45 "incpath=s", \@incpaths,
46 "libpath=s" => \@libpaths,
47 "verbose|v" => \$VERBOSE,
48 "nolog" => \$NOLOG,
49 "noexif" => \$noexif,
50 "nogifsetversion" => \$no_gif_set_version,
51 'coverage' => \$coverage);
52
53if ($VERBOSE) {
54 print "Verbose mode\n";
55 require Data::Dumper;
56 import Data::Dumper qw(Dumper);
57}
58
59if ($help) {
60 usage();
61}
62
63my @defines;
64
65if ($NOLOG) { print "Logging not compiled into module\n"; }
66else {
67 push @defines, [ IMAGER_LOG => 1, "Logging system" ];
68}
69
70if ($DEBUG_MALLOC) {
71 push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
72 print "Malloc debugging enabled\n";
73}
74
75if (@enable && @disable) {
76 print STDERR "Only --enable or --disable can be used, not both, try --help\n";
77 exit 1;
78}
79
80my %definc;
81my %deflib;
82my @incs; # all the places to look for headers
83my @libs; # all the places to look for libraries
84
85init(); # initialize global data
86pathcheck(); # Check if directories exist
87
88if (exists $ENV{IM_ENABLE}) {
89 my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
90 for my $key (keys %formats) {
91 delete $formats{$key} unless $en{$key};
92 }
93}
94if (@enable) {
95 my %en = map { $_ => 1 } map { split /,/ } @enable;
96 for my $key (keys %formats) {
97 delete $formats{$key} unless $en{$key};
98 }
99}
100elsif (@disable) {
101 delete @formats{map { split /,/ } @disable};
102}
103
104# Pick what libraries are used
105if ($MANUAL) {
106 manual();
107} else {
108 automatic();
109}
110
111# Make sure there isn't a clash between the gif libraries.
112gifcheck();
113
114my $lib_cflags = '';
115my $lib_lflags = '';
116my $F_LIBS = '';
117my $F_OBJECT = '';
118for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
119 my $frm = $formats{$frmkey};
120 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
121 $F_OBJECT .= ' ' .$frm->{objfiles};
122 if ($frm->{cflags}) {
123 $lib_cflags .= ' ' .$frm->{cflags};
124 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
125 grep /^-I./, split ' ', $frm->{cflags};
126 }
127 if ($frm->{lflags}) {
128 $lib_lflags .= ' ' . $frm->{lflags};
129 }
130 else {
131 $F_LIBS .= ' ' .$frm->{libfiles};
132 }
133
134}
135
136unless ($noexif) {
137 print "EXIF support enabled\n";
138 push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
139 $F_OBJECT .= ' imexif.o';
140}
141
142my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
143 grep !$definc{$_}, @incs;
144$F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
145 grep !$deflib{$_}++, @libs) . $F_LIBS;
146
147my $OSLIBS = '';
148my $OSDEF = "-DOS_$^O";
149
150if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
151if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
152
153my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
154 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
155 filters.o dynaload.o stackmach.o datatypes.o
156 regmach.o trans2.o quant.o error.o convert.o
157 map.o tags.o palimg.o maskimg.o img16.o rotate.o
158 bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
159 imext.o scale.o rubthru.o render.o);
160
161$Recommends{Imager} =
162 { 'Parse::RecDescent' => 0 };
163
164my %opts=(
165 'NAME' => 'Imager',
166 'VERSION_FROM' => 'Imager.pm',
167 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
168 'DEFINE' => "$OSDEF $CFLAGS",
169 'INC' => "$lib_cflags $DFLAGS $F_INC",
170 'OBJECT' => join(' ', @objs, $F_OBJECT),
171 clean => { FILES=>'testout meta.tmp rubthru.c scale.c' },
172 PM => gen_PM(),
173 PREREQ_PM => { 'Test::More' => 0.47 },
174 );
175
176if ($coverage) {
177 if ($Config{gccversion}) {
178 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs';
179 #$opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
180 }
181 else {
182 die "Don't know the coverage C flags for your compiler\n";
183 }
184}
185
186# eval to prevent warnings about versions with _ in them
187my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
188if ($MM_ver > 6.06) {
189 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
190 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
191}
192if ($MM_ver > 6.10) {
193 $opts{NO_META} = 1;
194}
195
196make_imconfig(\@defines);
197
198if ($VERBOSE) { print Dumper(\%opts); }
199mkdir('testout',0777); # since we cannot include it in the archive.
200
201make_metafile(\%opts);
202
203WriteMakefile(%opts);
204
205exit;
206
207
208sub MY::postamble {
209 my $self = shift;
210 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
211 my $mani = maniread;
212
213 my @ims = grep /\.im$/, keys %$mani;
214'
215dyntest.$(MYEXTLIB) : dynfilt/Makefile
216 cd dynfilt && $(MAKE) $(PASTHRU)
217
218lib/Imager/Regops.pm : regmach.h regops.perl
219 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
220
221imconfig.h : Makefile.PL
222 $(ECHO) "imconfig.h out-of-date with respect to $?"
223 $(PERLRUN) Makefile.PL
224 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
225'.qq!
226lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
227 $perl apidocs.perl lib/Imager/APIRef.pod
228
229!.join('', map _im_rule($perl, $_), @ims)
230
231}
232
233sub _im_rule {
234 my ($perl, $im) = @_;
235
236 (my $c = $im) =~ s/\.im$/.c/;
237 return <<MAKE;
238
239$c: $im imtoc.perl
240 $perl imtoc.perl $im $c
241
242MAKE
243
244}
245
246# manual configuration of helper libraries
247
248sub manual {
249 print <<EOF;
250
251 Please answer the following questions about
252 which formats are avaliable on your computer
253
254press <return> to continue
255EOF
256
257 <STDIN>; # eat one return
258
259 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
260 SWX:
261 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
262 print "Enable $frm support: ";
263 my $gz = <STDIN>;
264 chomp($gz);
265 if ($gz =~ m/^(y|yes|n|no)/i) {
266 $gz=substr(lc($gz),0,1);
267 if ($gz eq 'n') {
268 delete $formats{$frm};
269 }
270 } else { goto SWX; }
271 }
272}
273
274
275# automatic configuration of helper libraries
276
277sub automatic {
278 print "Automatic probing:\n" if $VERBOSE;
279 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
280 delete $formats{$frm} if !checkformat($frm);
281 }
282}
283
284
285sub gifcheck {
286 if ($formats{'gif'} and $formats{'ungif'}) {
287 print "ungif and gif can not coexist - removing ungif support\n";
288 delete $formats{'ungif'};
289 }
290
291 for my $frm (qw(gif ungif)) {
292 checkformat($frm) if ($MANUAL and $formats{$frm});
293 }
294
295 my @dirs;
296 for my $frm (grep $formats{$_}, qw(gif ungif)) {
297 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
298 }
299 my $minor = 0;
300 my $major = 0;
301 FILES: for my $dir (@dirs) {
302 my $h = "$dir/gif_lib.h";
303 open H, "< $h" or next;
304 while (<H>) {
305 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
306 $major = $1;
307 $minor = $2;
308 close H;
309 last FILES;
310 }
311 }
312 close H;
313 }
314
315 # we need the version in a #ifdefable form
316
317 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
318 push @defines, [ IM_GIFMINOR => $minor ];
319 push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
320 if $no_gif_set_version;
321}
322
323
324sub grep_directory {
325 my($path, $chk)=@_;
326
327# print "checking path $path\n";
328 if ( !opendir(DH,$path) ) {
329 warn "Cannot open dir $path: $!\n";
330 return;
331 }
332 my @l=grep { $chk->($_) } readdir(DH);
333 # print @l;
334 close(DH);
335 return map $path, @l;
336}
337
338
339sub checkformat {
340 my $frm=shift;
341
342 print " checkformat($frm)\n" if $VERBOSE;
343
344 my $probe_array = $formats{$frm}{'code'};
345 if ($probe_array) {
346 print " Calling probe function\n" if $VERBOSE;
347 if (ref $probe_array ne 'ARRAY') {
348 $probe_array = [ $probe_array ];
349 }
350 for my $func (@$probe_array) {
351 return 1 if $func->($formats{$frm}, $frm);
352 }
353 }
354
355 my $lib_check=$formats{$frm}{'libcheck'};
356 my $inc_check=$formats{$frm}{'inccheck'};
357
358 if ($lib_check) {
359 my @l;
360 for my $lp (@libs) {
361 push(@l, grep_directory($lp,$lib_check));
362 }
363
364 my @i;
365 for my $ip (@incs) {
366 push(@i, $ip) if $inc_check->($ip,$frm);
367 }
368
369 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
370 $formats{$frm}{incdir} = \@i;
371 $formats{$frm}{libdir} = \@l;
372 return 1 if scalar(@i && @l);
373 }
374 else {
375 printf("%10s: not available\n", $frm);
376 }
377
378 return 0;
379}
380
381
382sub pathcheck {
383 if ($VERBOSE) {
384 print "pathcheck\n";
385 print " Include paths:\n";
386 for (@incs) { print $_,"\n"; }
387 }
388 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
389
390 if ($VERBOSE) {
391 print "\nLibrary paths:\n";
392 for (@libs) { print $_,"\n"; }
393 }
394 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
395 print "\ndone.\n";
396}
397
398
399# Format data initialization
400
401# format definition is:
402# defines needed
403# default include path
404# files needed for include (boolean perl code)
405# default lib path
406# libs needed
407# files needed for link (boolean perl code)
408# object files needed for the format
409
410
411sub init {
412
413 my @definc = qw(/usr/include);
414 @definc{@definc}=(1) x @definc;
415 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
416 map { split /\Q$Config{path_sep}/} @incpaths );
417 if ($Config{locincpth}) {
418 push @incs, grep -d, split ' ', $Config{locincpth};
419 }
420 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
421 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
422 }
423 if ($Config{incpath}) {
424 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
425 }
426 push @incs, grep -d,
427 qw(/sw/include
428 /usr/include/freetype2
429 /usr/local/include/freetype2
430 /usr/local/include/freetype1/freetype
431 /usr/include /usr/local/include /usr/include/freetype
432 /usr/local/include/freetype);
433 if ($Config{ccflags}) {
434 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
435 push @incs, @hidden;
436 @definc{@hidden} = (1) x @hidden;
437 }
438
439 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
440 map { split /\Q$Config{path_sep}/} @libpaths );
441 if ($Config{loclibpth}) {
442 push @libs, grep -d, split ' ', $Config{loclibpth};
443 }
444
445 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
446 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
447 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
448 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
449 }
450 if ($^O eq 'cygwin') {
451 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
452 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
453 }
454 if ($Config{ldflags}) {
455 # some builds of perl put -Ldir into ldflags without putting it in
456 # loclibpth, let's extract them
457 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
458 split ' ', $Config{ldflags};
459 push @libs, @hidden;
460 # don't mark them as seen - EU::MM will remove any libraries
461 # it can't find and it doesn't look for -L in ldflags
462 #@deflib{@hidden} = @hidden;
463 }
464 push @libs, grep -d, qw(/usr/local/lib);
465
466 $formats{'jpeg'}={
467 order=>'21',
468 def=>'HAVE_LIBJPEG',
469 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
470 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
471 libfiles=>'-ljpeg',
472 objfiles=>'jpeg.o',
473 docs=>q{
474 In order to use jpeg with this module you need to have libjpeg
475 installed on your computer}
476 };
477
478 $formats{'tiff'}={
479 order=>'23',
480 def=>'HAVE_LIBTIFF',
481 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
482 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
483 libfiles=>'-ltiff',
484 objfiles=>'tiff.o',
485 docs=>q{
486 In order to use tiff with this module you need to have libtiff
487 installed on your computer}
488 };
489
490 $formats{'png'}={
491 order=>'22',
492 def=>'HAVE_LIBPNG',
493 inccheck=>sub { -e catfile($_[0], 'png.h') },
494 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
495 libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
496 objfiles=>'png.o',
497 docs=>q{
498 Png stands for Portable Network Graphics and is intended as
499 a replacement for gif on the web. It is patent free and
500 is recommended by the w3c, you need libpng to use these formats},
501 code => \&png_probe,
502 };
503
504 $formats{'gif'}={
505 order=>'20',
506 def=>'HAVE_LIBGIF',
507 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
508 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
509 libfiles=>'-lgif',
510 objfiles=>'gif.o',
511 docs=>q{
512 gif is the de facto standard for webgraphics at the moment,
513 it does have some patent problems. If you have giflib and
514 are not in violation with the unisys patent you should use
515 this instead of the 'ungif' option. Note that they cannot
516 be in use at the same time}
517 };
518
519 $formats{'ungif'}={
520 order=>'21',
521 def=>'HAVE_LIBGIF',
522 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
523 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
524 libfiles=>'-lungif',
525 objfiles=>'gif.o',
526 docs=>q{
527 gif is the de facto standard for webgraphics at the moment,
528 it does have some patent problems. If you have libungif and
529 want to create images free from LZW patented compression you
530 should use this option instead of the 'gif' option}
531 };
532
533 $formats{'T1-fonts'}={
534 order=>'30',
535 def=>'HAVE_LIBT1',
536 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
537 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
538 libfiles=>'-lt1',
539 objfiles=>'',
540 docs=>q{
541 postscript t1 fonts are scalable fonts. They can include
542 ligatures and kerning information and generally yield good
543 visual quality. We depend on libt1 to rasterize the fonts
544 for use in images.}
545 };
546
547 $formats{'TT-fonts'}=
548 {
549 order=>'31',
550 def=>'HAVE_LIBTT',
551 inccheck=>sub { -e catfile($_[0], 'freetype.h')
552 && !-e catfile($_[0], 'fterrors.h') },
553 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
554 libfiles=>'-lttf',
555 objfiles=>'',
556 code => \&freetype1_probe,
557 docs=>q{
558Truetype fonts are scalable fonts. They can include
559kerning and hinting information and generally yield good
560visual quality esp on low resultions. The freetype library is
561used to rasterize for us. The only drawback is that there
562are alot of badly designed fonts out there.}
563 };
564 $formats{'w32'} = {
565 order=>40,
566 def=>'HAVE_WIN32',
567 inccheck=>sub { -e catfile($_[0], 'windows.h') },
568 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
569 || lc $_[0] eq 'libgdi32.a' },
570 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
571 objfiles=>'win32.o',
572 docs => <<DOCS
573Uses the Win32 GDI for rendering text.
574
575This currently only works on under normal Win32 and cygwin.
576DOCS
577 };
578 $formats{'freetype2'} =
579 {
580 order=>'29',
581 def=>'HAVE_FT2',
582 # we always use a probe function
583 #inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
584 #libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
585 libfiles=>'-lfreetype',
586 objfiles=>'freetyp2.o',
587 docs=><<DOCS,
588Freetype 2 supports both Truetype and Type 1 fonts, both of which are
589scalable. It also supports a variety of other fonts.
590DOCS
591 code =>
592 [
593 \&freetype2_probe_ftconfig,
594 \&freetype2_probe_scan
595 ],
596 };
597
598 # Make fix indent
599 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
600}
601
602
603
604sub gen {
605 my $V = $ENV{$_[0]};
606 defined($V) ? $V : "";
607}
608
609
610# Get information from environment variables
611
612sub getenv {
613
614 ($VERBOSE,
615 $INCPATH,
616 $LIBPATH,
617 $NOLOG,
618 $DEBUG_MALLOC,
619 $MANUAL,
620 $CFLAGS,
621 $LFLAGS,
622 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
623 IM_INCPATH
624 IM_LIBPATH
625 IM_NOLOG
626 IM_DEBUG_MALLOC
627 IM_MANUAL
628 IM_CFLAGS
629 IM_LFLAGS
630 IM_DFLAGS);
631
632}
633
634sub make_imconfig {
635 my ($defines) = @_;
636
637 open CONFIG, "> imconfig.h"
638 or die "Cannot create imconfig.h: $!\n";
639 print CONFIG <<EOS;
640/* This file is automatically generated by Makefile.PL.
641 Don't edit this file, since any changes will be lost */
642
643#ifndef IMAGER_IMCONFIG_H
644#define IMAGER_IMCONFIG_H
645EOS
646 for my $define (@$defines) {
647 if ($define->[2]) {
648 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
649 }
650 print CONFIG "#define $define->[0] $define->[1]\n";
651 }
652 print CONFIG "\n#endif\n";
653 close CONFIG;
654}
655
656# use pkg-config to probe for libraries
657# works around the junk that pkg-config dumps on FreeBSD
658sub _pkg_probe {
659 my ($pkg) = @_;
660
661 is_exe('pkg-config') or return;
662
663 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
664
665 !system("pkg-config $pkg --exists $redir");
666}
667
668# probes for freetype1 by scanning @incs for the includes and
669# @libs for the libs. This is done separately because freetype's headers
670# are stored in a freetype or freetype1 directory under PREFIX/include.
671#
672# we could find the files with the existing mechanism, but it won't set
673# -I flags correctly.
674#
675# This could be extended to freetype2 too, but freetype-config catches
676# that
677sub freetype1_probe {
678 my ($frm, $frmkey) = @_;
679
680 my $found_inc;
681 INCS:
682 for my $inc (@incs) {
683 for my $subdir (qw/freetype freetype1/) {
684 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
685 -e $path or next;
686 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
687 -e $path and next;
688
689 $found_inc = File::Spec->catdir($inc, $subdir);
690 last INCS;
691 }
692 }
693
694 my $found_lib;
695 LIBS:
696 for my $lib (@libs) {
697 my $a_path = File::Spec->catfile($lib, "libttf$aext");
698 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
699 if (-e $a_path || -e $l_path) {
700 $found_lib = $lib;
701 last LIBS;
702 }
703 }
704
705 return unless $found_inc && $found_lib;
706 printf("%10s: includes %s - libraries %s\n", $frmkey,
707 ($found_inc ? 'found' : 'not found'),
708 ($found_lib ? 'found' : 'not found'));
709
710 $frm->{cflags} = "-I$found_inc";
711 $frm->{libfiles} = "-lttf";
712
713 return 1;
714}
715
716# probes for freetype2 by trying to run freetype-config
717sub freetype2_probe_ftconfig {
718 my ($frm, $frmkey) = @_;
719
720 is_exe('freetype-config') or return;
721
722 my $cflags = `freetype-config --cflags`
723 and !$? or return;
724 chomp $cflags;
725
726 my $lflags = `freetype-config --libs`
727 and !$? or return;
728 chomp $lflags;
729
730 # before 2.1.5 freetype-config --cflags could output
731 # the -I options in the wrong order, causing a conflict with
732 # freetype1.x installed with the same --prefix
733 #
734 # can happen iff:
735 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
736 # in that order
737 # - freetype 1.x headers are in prefix/include/freetype
738 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
739 if (@incdirs == 2
740 && $incdirs[1] eq "$incdirs[0]/freetype2"
741 && -e "$incdirs[0]/freetype/freetype.h"
742 && -e "$incdirs[0]/freetype/fterrid.h") {
743 print "** freetype-config provided -I options out of order, correcting\n"
744 if $VERBOSE;
745 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
746 map "-I$_", reverse @incdirs);
747 }
748 $frm->{cflags} = $cflags;
749 $frm->{lflags} = $lflags;
750
751 printf "%10s: configured via freetype-config\n", $frmkey;
752
753 return 1;
754}
755
756# attempt to probe for freetype2 by scanning directories
757# we can't use the normal scan since we need to find the directory
758# containing most of the includes
759sub freetype2_probe_scan {
760 my ($frm, $frmkey) = @_;
761
762 my $found_inc;
763 my $found_inc2;
764 INCS:
765 for my $inc (@incs) {
766 my $path = File::Spec->catfile($inc, 'ft2build.h');
767 -e $path or next;
768
769 # try to find what it's including
770 my $ftheader;
771 open FT2BUILD, "< $path"
772 or next;
773 while (<FT2BUILD>) {
774 if (m!^\s*\#\s*include\s+<([\w/.]+)>!
775 || m!^\s*\#\s*include\s+"([\w/.]+)"!) {
776 $ftheader = $1;
777 last;
778 }
779 }
780 close FT2BUILD;
781 $ftheader
782 or next;
783 # non-Unix installs put this directly under the same directory in
784 # theory
785 if (-e File::Spec->catfile($inc, $ftheader)) {
786 $found_inc = $inc;
787 last INCS;
788 }
789 for my $subdir (qw/freetype2 freetype/) {
790 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
791 -e $path and next;
792
793 $found_inc = $inc;
794 $found_inc2 = File::Spec->catdir($inc, $subdir);
795 last INCS;
796 }
797 }
798
799 my $found_lib;
800 LIBS:
801 for my $lib (@libs) {
802 my $a_path = File::Spec->catfile($lib, "libfreetype$aext");
803 my $l_path = File::Spec->catfile($lib, "libfreetype.$lext");
804 if (-e $a_path || -e $l_path) {
805 $found_lib = $lib;
806 last LIBS;
807 }
808 }
809
810 printf("%10s: includes %s - libraries %s\n", $frmkey,
811 ($found_inc ? 'found' : 'not found'),
812 ($found_lib ? 'found' : 'not found'));
813
814 return unless $found_inc && $found_lib;
815
816 $frm->{cflags} = _make_I($found_inc);
817 $frm->{cflags} .= " " . _make_I($found_inc2) if $found_inc2;
818 $frm->{libfiles} = "-lfreetype";
819
820 return 1;
821}
822
823sub _make_I {
824 my ($inc_dir) = @_;
825
826 $definc{$inc_dir}
827 and return '';
828
829 $inc_dir =~ / / ? qq!-I"$inc_dir"! : "-I$inc_dir";
830}
831
832# probes for libpng via pkg-config
833sub png_probe {
834 my ($frm, $frmkey) = @_;
835
836 is_exe('pkg-config') or return;
837
838 my $config;
839 for my $check_conf (qw(libpng libpng12 libpng10)) {
840 if (_pkg_probe($check_conf)) {
841 $config = $check_conf;
842 last;
843 }
844 }
845 $config or return;
846
847 my $cflags = `pkg-config $config --cflags`
848 and !$? or return;
849
850 my $lflags = `pkg-config $config --libs`
851 and !$? or return;
852
853 chomp $cflags;
854 chomp $lflags;
855 $frm->{cflags} = $cflags;
856 $frm->{lflags} = $lflags;
857
858 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
859
860 return 1;
861}
862
863sub catfile {
864 return File::Spec->catfile(@_);
865}
866
867sub is_exe {
868 my ($name) = @_;
869
870 for my $dir (File::Spec->path) {
871 -x catfile($dir, "$name$Config{_exe}")
872 and return 1;
873 }
874
875 return;
876}
877
878sub usage {
879 print STDERR <<EOS;
880Usage: $0 [--enable feature1,feature2,...] [other options]
881 $0 [--disable feature1,feature2,...] [other options]
882 $0 --help
883Possible feature names are:
884 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
885Other options:
886 --verbose | -v
887 Verbose library probing (or set IM_VERBOSE in the environment)
888 --nolog
889 Disable logging (or set IM_NOLOG in the environment)
890 --incpath dir
891 Add to the include search path
892 --libpath dir
893 Add to the library search path
894EOS
895 exit 1;
896
897}
898
899# generate the PM MM argument
900# I'd prefer to modify the public version, but there doesn't seem to be
901# a public API to do that
902sub gen_PM {
903 my %pm;
904 my $instbase = '$(INST_LIBDIR)';
905
906 # first the basics, .pm and .pod files
907 $pm{"Imager.pm"} = "$instbase/Imager.pm";
908
909 my $mani = maniread();
910
911 for my $filename (keys %$mani) {
912 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
913 (my $work = $filename) =~ s/^lib//;
914 $pm{$filename} = $instbase . $work;
915 }
916 }
917
918 # need the typemap
919 $pm{typemap} = $instbase . '/Imager/typemap';
920
921 # and the core headers
922 for my $filename (keys %$mani) {
923 if ($filename =~ /^\w+\.h$/) {
924 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
925 }
926 }
927
928 # and the generated header
929 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
930
931 \%pm;
932}
933
934sub make_metafile {
935 my ($opts) = @_;
936
937 # extract the version
938 my $version = MM->parse_version($opts->{VERSION_FROM})
939 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
940
941 # we don't set this on older EU::MM and it corrupts META.yml
942 # so don't generate it
943 return unless $opts->{AUTHOR};
944
945 my $meta = <<YAML;
946--- #YAML:1.0
947name: $opts->{NAME}
948version: $version
949version_from: $opts->{VERSION_FROM}
950author:
951YAML
952 for my $author (split /,\s*/, $opts->{AUTHOR}) {
953 $meta .= " - $author\n";
954 }
955 $meta .= <<YAML;
956abstract: $opts->{ABSTRACT}
957installdirs: site
958YAML
959 if (keys %{$Recommends{$opts->{NAME}}}) {
960 $meta .= "recommends:\n";
961 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
962 $meta .= " $module: $version\n";
963 }
964 }
965 if ($opts->{PREREQ_PM}) {
966 $meta .= "requires:\n";
967 while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) {
968 $meta .= " $module: $version\n";
969 }
970 }
971 $meta .= <<YAML;
972license: perl
973dynamic_config: 1
974distribution_type: module
975meta-spec:
976 version: 1.3
977 url: http://module-build.sourceforge.net/META-spec-v1.3.html
978generated_by: $opts->{NAME} version $version
979YAML
980 my $save_meta;
981 if (open META, "< META.yml") {
982 my $old_meta = do { local $/; <META> };
983 close META;
984
985 $save_meta = $old_meta ne $meta;
986 }
987 else {
988 ++$save_meta;
989 }
990 if ($save_meta) {
991 print "Updating META.yml\n";
992 open META, "> META.yml" or die "Cannot create META.yml: $!";
993 print META $meta;
994 close META;
995 }
996}
997