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