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