]> git.imager.perl.org - imager.git/blob - Makefile.PL
warning clean up - clean up unusued variables, fix some const
[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 $noexif; # non-zero to disable EXIF parsing of JPEGs
40 my $no_gif_set_version; # disable calling EGifSetGifVersion
41 my $coverage; # build for coverage testing
42 GetOptions("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
53 if ($VERBOSE) { 
54   print "Verbose mode\n"; 
55   require Data::Dumper; 
56   import Data::Dumper qw(Dumper);
57 }
58
59 if ($help) {
60   usage();
61 }
62
63 my @defines;
64
65 if ($NOLOG)   { print "Logging not compiled into module\n"; }
66 else { 
67   push @defines, [ IMAGER_LOG => 1, "Logging system" ];
68 }
69
70 if ($DEBUG_MALLOC) {
71   push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
72   print "Malloc debugging enabled\n";
73 }
74
75 if (@enable && @disable) {
76   print STDERR "Only --enable or --disable can be used, not both, try --help\n";
77   exit 1;
78 }
79
80 my %definc;
81 my %deflib;
82 my @incs; # all the places to look for headers
83 my @libs; # all the places to look for libraries
84
85 init();       # initialize global data
86 pathcheck();  # Check if directories exist
87
88 if (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 }
94 if (@enable) {
95   my %en = map { $_ => 1 } map { split /,/ } @enable;
96   for my $key (keys %formats) {
97     delete $formats{$key} unless $en{$key};
98   }
99 }
100 elsif (@disable) {
101   delete @formats{map { split /,/ } @disable};
102 }
103
104 # Pick what libraries are used
105 if ($MANUAL) {
106   manual();
107 } else {
108   automatic();
109 }
110
111 # Make sure there isn't a clash between the gif libraries.
112 gifcheck();
113
114 my $lib_cflags = '';
115 my $lib_lflags = '';
116 my $F_LIBS = '';
117 my $F_OBJECT = '';
118 for 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
136 unless ($noexif) {
137   print "EXIF support enabled\n";
138   push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
139   $F_OBJECT .= ' imexif.o';
140 }
141
142 my $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
147 my $OSLIBS = '';
148 my $OSDEF  = "-DOS_$^O";
149
150 if ($^O eq 'hpux')                { $OSLIBS .= ' -ldld'; }
151 if (defined $Config{'d_dlsymun'}) { $OSDEF  .= ' -DDLSYMUN'; }
152
153 my @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 paste.o compose.o);
160
161 $Recommends{Imager} =
162   { 'Parse::RecDescent' => 0 };
163
164 my %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 conv.c  filters.c gaussian.c render.c rubthru.c' },
172           PM             => gen_PM(),
173           PREREQ_PM      => { 'Test::More' => 0.47 },
174          );
175
176 if ($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
187 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
188 if ($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 }
192 if ($MM_ver > 6.10) {
193   $opts{NO_META} = 1;
194 }
195
196 make_imconfig(\@defines);
197
198 if ($VERBOSE) { print Dumper(\%opts); }
199 mkdir('testout',0777); # since we cannot include it in the archive.
200
201 make_metafile(\%opts);
202
203 WriteMakefile(%opts);
204
205 exit;
206
207
208 sub 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 '
215 dyntest.$(MYEXTLIB) : dynfilt/Makefile
216         cd dynfilt && $(MAKE) $(PASTHRU)
217
218 lib/Imager/Regops.pm : regmach.h regops.perl
219         $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
220
221 imconfig.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!
226 lib/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
233 sub _im_rule {
234   my ($perl, $im) = @_;
235
236   (my $c = $im) =~ s/\.im$/.c/;
237   return <<MAKE;
238
239 $c: $im lib/Imager/Preprocess.pm
240         $perl -Ilib -MImager::Preprocess -epreprocess $im $c
241
242 MAKE
243
244 }
245
246 # manual configuration of helper libraries
247
248 sub manual {
249   print <<EOF;
250
251       Please answer the following questions about
252       which formats are avaliable on your computer
253
254 press <return> to continue
255 EOF
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
277 sub 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
285 sub 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
324 sub 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
339 sub 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
382 sub 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
411 sub init {
412
413   my @definc = qw(/usr/include);
414   @definc{@definc}=(1) x @definc;
415   @incs=
416     (
417      split(/\Q$Config{path_sep}/, $INCPATH),
418      map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths 
419     );
420   if ($Config{locincpth}) {
421     push @incs, grep -d, split ' ', $Config{locincpth};
422   }
423   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
424     push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
425   }
426   if ($Config{incpath}) {
427     push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
428   }
429   push @incs, grep -d,
430       qw(/sw/include 
431          /usr/include/freetype2
432          /usr/local/include/freetype2
433          /usr/local/include/freetype1/freetype
434          /usr/include /usr/local/include /usr/include/freetype
435          /usr/local/include/freetype);
436   if ($Config{ccflags}) {
437     my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
438     push @incs, @hidden;
439     @definc{@hidden} = (1) x @hidden;
440   }
441
442   @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
443     map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
444   if ($Config{loclibpth}) {
445     push @libs, grep -d, split ' ', $Config{loclibpth};
446   }
447   
448   push @libs, grep -d, qw(/sw/lib),  split(/ /, $Config{'libpth'});
449   push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
450   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
451     push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
452   }
453   if ($^O eq 'cygwin') {
454     push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
455     push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
456   }
457   if ($Config{ldflags}) {
458     # some builds of perl put -Ldir into ldflags without putting it in
459     # loclibpth, let's extract them
460     my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
461       split ' ', $Config{ldflags};
462     push @libs, @hidden;
463     # don't mark them as seen - EU::MM will remove any libraries
464     # it can't find and it doesn't look for -L in ldflags
465     #@deflib{@hidden} = @hidden;
466   }
467   push @libs, grep -d, qw(/usr/local/lib);
468
469   $formats{'jpeg'}={
470                     order=>'21',
471                     def=>'HAVE_LIBJPEG',
472                     inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
473                     libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
474                     libfiles=>'-ljpeg',
475                     objfiles=>'jpeg.o',
476                     docs=>q{
477                             In order to use jpeg with this module you need to have libjpeg
478                             installed on your computer}
479                    };
480
481   $formats{'tiff'}={
482                     order=>'23',
483                     def=>'HAVE_LIBTIFF',
484                     inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
485                     libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
486                     libfiles=>'-ltiff',
487                     objfiles=>'tiff.o',
488                     docs=>q{
489                             In order to use tiff with this module you need to have libtiff
490                             installed on your computer}
491                    };
492
493   $formats{'png'}={
494                    order=>'22',
495                    def=>'HAVE_LIBPNG',
496                    inccheck=>sub { -e catfile($_[0], 'png.h') },
497                    libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
498                    libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
499                    objfiles=>'png.o',
500                    docs=>q{
501                            Png stands for Portable Network Graphics and is intended as
502                            a replacement for gif on the web. It is patent free and
503                            is recommended by the w3c, you need libpng to use these formats},
504                    code => \&png_probe,
505                   };
506
507   $formats{'gif'}={
508                    order=>'20',
509                    def=>'HAVE_LIBGIF',
510                    inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
511                    libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
512                    libfiles=>'-lgif',
513                    objfiles=>'gif.o',
514                    docs=>q{
515                            gif is the de facto standard for webgraphics at the moment,
516                            it does have some patent problems. If you have giflib and
517                            are not in violation with the unisys patent you should use
518                            this instead of the 'ungif' option.  Note that they cannot
519                            be in use at the same time}
520                   };
521
522   $formats{'ungif'}={
523                      order=>'21',
524                      def=>'HAVE_LIBGIF',
525                      inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
526                      libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
527                      libfiles=>'-lungif',
528                      objfiles=>'gif.o',
529                      docs=>q{
530                              gif is the de facto standard for webgraphics at the moment,
531                              it does have some patent problems. If you have libungif and
532                              want to create images free from LZW patented compression you
533                              should use this option instead of the 'gif' option}
534                     };
535
536   $formats{'T1-fonts'}={
537                         order=>'30',
538                         def=>'HAVE_LIBT1',
539                         inccheck=>sub { -e catfile($_[0], 't1lib.h') },
540                         libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
541                         libfiles=>'-lt1',
542                         objfiles=>'',
543                         docs=>q{
544                                 postscript t1 fonts are scalable fonts. They can include 
545                                 ligatures and kerning information and generally yield good
546                                 visual quality. We depend on libt1 to rasterize the fonts
547                                 for use in images.}
548                        };
549
550   $formats{'TT-fonts'}=
551     {
552      order=>'31',
553      def=>'HAVE_LIBTT',
554      inccheck=>sub { -e catfile($_[0], 'freetype.h')
555                        && !-e catfile($_[0], 'fterrors.h') },
556      libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
557      libfiles=>'-lttf',
558      objfiles=>'',
559      code => \&freetype1_probe,
560      docs=>q{
561 Truetype fonts are scalable fonts. They can include 
562 kerning and hinting information and generally yield good
563 visual quality esp on low resultions. The freetype library is
564 used to rasterize for us. The only drawback is that there
565 are alot of badly designed fonts out there.}
566                        };
567   $formats{'w32'} = {
568                      order=>40,
569                      def=>'HAVE_WIN32',
570                      inccheck=>sub { -e catfile($_[0], 'windows.h') },
571                      libcheck=>sub { lc $_[0] eq 'gdi32.lib' 
572                                        || lc $_[0] eq 'libgdi32.a' },
573                      libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
574                      objfiles=>'win32.o',
575                      docs => <<DOCS
576 Uses the Win32 GDI for rendering text.
577
578 This currently only works on under normal Win32 and cygwin.
579 DOCS
580                     };
581   $formats{'freetype2'} = 
582   {
583    order=>'29',
584    def=>'HAVE_FT2',
585    # we always use a probe function
586    #inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
587    #libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
588    libfiles=>'-lfreetype',
589    objfiles=>'freetyp2.o',
590    docs=><<DOCS,
591 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
592 scalable.  It also supports a variety of other fonts.
593 DOCS
594    code =>
595    [ 
596     \&freetype2_probe_ftconfig,
597     \&freetype2_probe_scan
598    ],
599   };
600
601   # Make fix indent
602   for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/  /mg; }
603 }
604
605
606
607 sub gen {
608   my $V = $ENV{$_[0]};
609   defined($V) ? $V : "";
610 }
611
612
613 # Get information from environment variables
614
615 sub getenv {
616
617   ($VERBOSE,
618    $INCPATH,
619    $LIBPATH,
620    $NOLOG,
621    $DEBUG_MALLOC,
622    $MANUAL,
623    $CFLAGS,
624    $LFLAGS,
625    $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
626                                 IM_INCPATH
627                                 IM_LIBPATH
628                                 IM_NOLOG
629                                 IM_DEBUG_MALLOC
630                                 IM_MANUAL
631                                 IM_CFLAGS
632                                 IM_LFLAGS
633                                 IM_DFLAGS);
634
635 }
636
637 sub make_imconfig {
638   my ($defines) = @_;
639
640   open CONFIG, "> imconfig.h"
641     or die "Cannot create imconfig.h: $!\n";
642   print CONFIG <<EOS;
643 /* This file is automatically generated by Makefile.PL.
644    Don't edit this file, since any changes will be lost */
645
646 #ifndef IMAGER_IMCONFIG_H
647 #define IMAGER_IMCONFIG_H
648 EOS
649   for my $define (@$defines) {
650     if ($define->[2]) {
651       print CONFIG "\n/*\n  $define->[2]\n*/\n\n";
652     }
653     print CONFIG "#define $define->[0] $define->[1]\n";
654   }
655   print CONFIG "\n#endif\n";
656   close CONFIG;
657 }
658
659 # use pkg-config to probe for libraries
660 # works around the junk that pkg-config dumps on FreeBSD
661 sub _pkg_probe {
662   my ($pkg) = @_;
663
664   is_exe('pkg-config') or return;
665
666   my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
667
668   !system("pkg-config $pkg --exists $redir");
669 }
670
671 # probes for freetype1 by scanning @incs for the includes and 
672 # @libs for the libs.  This is done separately because freetype's headers
673 # are stored in a freetype or freetype1 directory under PREFIX/include.
674 #
675 # we could find the files with the existing mechanism, but it won't set
676 # -I flags correctly.
677 #
678 # This could be extended to freetype2 too, but freetype-config catches
679 # that
680 sub freetype1_probe {
681   my ($frm, $frmkey) = @_;
682
683   my $found_inc;
684  INCS:
685   for my $inc (@incs) {
686     for my $subdir (qw/freetype freetype1/) {
687       my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
688       -e $path or next;
689       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
690       -e $path and next;
691
692       $found_inc = File::Spec->catdir($inc, $subdir);
693       last INCS;
694     }
695   }
696
697   my $found_lib;
698  LIBS:
699   for my $lib (@libs) {
700     my $a_path = File::Spec->catfile($lib, "libttf$aext");
701     my $l_path = File::Spec->catfile($lib, "libttf.$lext");
702     if (-e $a_path || -e $l_path) {
703       $found_lib = $lib;
704       last LIBS;
705     }
706   }
707
708   return unless $found_inc && $found_lib;
709   printf("%10s: includes %s - libraries %s\n", $frmkey,
710          ($found_inc ? 'found' : 'not found'), 
711          ($found_lib ? 'found' : 'not found'));
712
713   $frm->{cflags} = "-I$found_inc";
714   $frm->{libfiles} = "-lttf";
715
716   return 1;
717 }
718
719 # probes for freetype2 by trying to run freetype-config
720 sub freetype2_probe_ftconfig {
721   my ($frm, $frmkey) = @_;
722
723   is_exe('freetype-config') or return;
724
725   my $cflags = `freetype-config --cflags`
726     and !$? or return;
727   chomp $cflags;
728
729   my $lflags = `freetype-config --libs`
730     and !$? or return;
731   chomp $lflags;
732
733   # before 2.1.5 freetype-config --cflags could output
734   # the -I options in the wrong order, causing a conflict with
735   # freetype1.x installed with the same --prefix
736   #
737   # can happen iff:
738   #  - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
739   #    in that order
740   #  - freetype 1.x headers are in prefix/include/freetype
741   my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
742   if (@incdirs == 2 
743       && $incdirs[1] eq "$incdirs[0]/freetype2"
744       && -e "$incdirs[0]/freetype/freetype.h"
745       && -e "$incdirs[0]/freetype/fterrid.h") {
746     print "** freetype-config provided -I options out of order, correcting\n"
747       if $VERBOSE;
748     $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
749                    map "-I$_", reverse @incdirs);
750   }
751   $frm->{cflags} = $cflags;
752   $frm->{lflags} = $lflags;
753
754   printf "%10s: configured via freetype-config\n", $frmkey;
755
756   return 1;
757 }
758
759 # attempt to probe for freetype2 by scanning directories
760 # we can't use the normal scan since we need to find the directory
761 # containing most of the includes
762 sub freetype2_probe_scan {
763   my ($frm, $frmkey) = @_;
764
765   my $found_inc;
766   my $found_inc2;
767  INCS:
768   for my $inc (@incs) {
769     my $path = File::Spec->catfile($inc, 'ft2build.h');
770     -e $path or next;
771
772     # try to find what it's including
773     my $ftheader;
774     open FT2BUILD, "< $path"
775       or next;
776     while (<FT2BUILD>) {
777       if (m!^\s*\#\s*include\s+<([\w/.]+)>!
778           || m!^\s*\#\s*include\s+"([\w/.]+)"!) {
779         $ftheader = $1;
780         last;
781       }
782     }
783     close FT2BUILD;
784     $ftheader
785       or next;
786     # non-Unix installs put this directly under the same directory in
787     # theory
788     if (-e File::Spec->catfile($inc, $ftheader)) {
789       $found_inc = $inc;
790       last INCS;
791     }
792     for my $subdir (qw/freetype2 freetype/) {
793       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
794       -e $path and next;
795
796       $found_inc = $inc;
797       $found_inc2 = File::Spec->catdir($inc, $subdir);
798       last INCS;
799     }
800   }
801
802   my $found_lib;
803  LIBS:
804   for my $lib (@libs) {
805     my $a_path = File::Spec->catfile($lib, "libfreetype$aext");
806     my $l_path = File::Spec->catfile($lib, "libfreetype.$lext");
807     if (-e $a_path || -e $l_path) {
808       $found_lib = $lib;
809       last LIBS;
810     }
811   }
812
813   printf("%10s: includes %s - libraries %s\n", $frmkey,
814          ($found_inc ? 'found' : 'not found'), 
815          ($found_lib ? 'found' : 'not found'));
816
817   return unless $found_inc && $found_lib;
818
819   $frm->{cflags} = _make_I($found_inc);
820   $frm->{cflags} .= " " . _make_I($found_inc2) if $found_inc2;
821   $frm->{libfiles} = "-lfreetype";
822
823   return 1;
824 }
825
826 sub _make_I {
827   my ($inc_dir) = @_;
828
829   $definc{$inc_dir}
830     and return '';
831
832   $inc_dir =~ / / ? qq!-I"$inc_dir"! : "-I$inc_dir";
833 }
834
835 # probes for libpng via pkg-config
836 sub png_probe {
837   my ($frm, $frmkey) = @_;
838
839   is_exe('pkg-config') or return;
840
841   my $config;
842   for my $check_conf (qw(libpng libpng12 libpng10)) {
843     if (_pkg_probe($check_conf)) {
844       $config = $check_conf;
845       last;
846     }
847   }
848   $config or return;
849
850   my $cflags = `pkg-config $config --cflags`
851     and !$? or return;
852
853   my $lflags = `pkg-config $config --libs`
854     and !$? or return;
855
856   chomp $cflags;
857   chomp $lflags;
858   $frm->{cflags} = $cflags;
859   $frm->{lflags} = $lflags;
860
861   printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
862
863   return 1;
864 }
865
866 sub catfile {
867   return File::Spec->catfile(@_);
868 }
869
870 sub is_exe {
871   my ($name) = @_;
872
873   for my $dir (File::Spec->path) {
874     -x catfile($dir, "$name$Config{_exe}")
875       and return 1;
876   }
877
878   return;
879 }
880
881 sub usage {
882   print STDERR <<EOS;
883 Usage: $0 [--enable feature1,feature2,...] [other options]
884        $0 [--disable feature1,feature2,...]  [other options]
885        $0 --help
886 Possible feature names are:
887   png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
888 Other options:
889   --verbose | -v
890     Verbose library probing (or set IM_VERBOSE in the environment)
891   --nolog
892     Disable logging (or set IM_NOLOG in the environment)
893   --incpath dir
894     Add to the include search path
895   --libpath dir
896     Add to the library search path
897 EOS
898   exit 1;
899
900 }
901
902 # generate the PM MM argument
903 # I'd prefer to modify the public version, but there doesn't seem to be 
904 # a public API to do that
905 sub gen_PM {
906   my %pm;
907   my $instbase = '$(INST_LIBDIR)';
908
909   # first the basics, .pm and .pod files
910   $pm{"Imager.pm"} = "$instbase/Imager.pm";
911
912   my $mani = maniread();
913
914   for my $filename (keys %$mani) {
915     if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
916       (my $work = $filename) =~ s/^lib//;
917       $pm{$filename} = $instbase . $work;
918     }
919   }
920
921   # need the typemap
922   $pm{typemap} = $instbase . '/Imager/typemap';
923
924   # and the core headers
925   for my $filename (keys %$mani) {
926     if ($filename =~ /^\w+\.h$/) {
927       $pm{$filename} = $instbase . '/Imager/include/' . $filename;
928     }
929   }
930
931   # and the generated header
932   $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
933
934   \%pm;
935 }
936
937 sub make_metafile {
938   my ($opts) = @_;
939
940   # extract the version
941   my $version = MM->parse_version($opts->{VERSION_FROM})
942     or die "Could not extract version number from $opts->{VERSION_FROM}\n";
943
944   # we don't set this on older EU::MM and it corrupts META.yml
945   # so don't generate it
946   return unless $opts->{AUTHOR};
947
948   my $meta = <<YAML;
949 --- #YAML:1.0
950 name: $opts->{NAME}
951 version: $version
952 version_from: $opts->{VERSION_FROM}
953 author:
954 YAML
955   for my $author (split /,\s*/, $opts->{AUTHOR}) {
956     $meta .= " - $author\n";
957   }
958   $meta .= <<YAML;
959 abstract: $opts->{ABSTRACT}
960 installdirs: site
961 YAML
962   if (keys %{$Recommends{$opts->{NAME}}}) {
963     $meta .= "recommends:\n";
964     while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
965       $meta .= "  $module: $version\n";
966     }
967   }
968   if ($opts->{PREREQ_PM}) {
969     $meta .= "requires:\n";
970     while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) {
971       $meta .= "  $module: $version\n";
972     }
973   }
974   $meta .= <<YAML;
975 license: perl
976 dynamic_config: 1
977 distribution_type: module
978 meta-spec:
979   version: 1.3
980   url: http://module-build.sourceforge.net/META-spec-v1.3.html
981 generated_by: $opts->{NAME} version $version
982 YAML
983   my $save_meta;
984   if (open META, "< META.yml") {
985     my $old_meta = do { local $/; <META> };
986     close META;
987
988     $save_meta = $old_meta ne $meta;
989   }
990   else {
991     ++$save_meta;
992   }
993   if ($save_meta) {
994     print "Updating META.yml\n";
995     open META, "> META.yml" or die "Cannot create META.yml: $!";
996     print META $meta;
997     close META;
998   }
999 }
1000
1001 my $home;
1002 sub _tilde_expand {
1003   my ($path) = @_;
1004
1005   if ($path =~ m!^~[/\\]!) {
1006     defined $home or $home = $ENV{HOME};
1007     if (!defined $home && $^O eq 'MSWin32'
1008        && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
1009       $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
1010     }
1011     unless (defined $home) {
1012       $home = eval { (getpwuid($<))[7] };
1013     }
1014     defined $home or die "You supplied $path, but I can't find your home directory\n";
1015     $path =~ s/^~//;
1016     $path = File::Spec->catdir($home, $path);
1017   }
1018
1019   $path;
1020 }
1021
1022 # This isn't a module, but some broken tools, like
1023 # Module::Depends::Instrusive insist on treating it like one.
1024 #
1025 # http://rt.cpan.org/Public/Bug/Display.html?id=21229
1026
1027 1;