- added experimental EXIF decoding when reading JPEG files.
[imager.git] / Makefile.PL
1 #!perl -w
2 use ExtUtils::MakeMaker;
3 use Cwd;
4 use Config;
5 use File::Spec;
6 use Getopt::Long;
7
8 #
9 # IM_INCPATH      colon seperated list of paths to extra include paths
10 # IM_LIBPATH      colon seperated list of paths to extra library paths
11 #
12 # IM_VERBOSE      turns on verbose mode for the library finding and such
13 # IM_MANUAL       to manually select which libraries are used and which not
14 # IM_ENABLE       to programmatically select which libraries are used
15 #                 and which are not
16 # IM_NOLOG        if true logging will not be compiled into the module
17 # IM_DEBUG_MALLOC if true malloc debbuging will be compiled into the module
18 #                 do not use IM_DEBUG_MALLOC in production - this slows
19 #                 everything down by alot
20 # IM_CFLAGS       Extra flags to pass to the compiler
21 # IM_LFLAGS       Extra flags to pass to the linker
22 # IM_DFLAGS       Extra flags to pass to the preprocessor
23 # IM_SUPPRESS_PROMPT  Suppress the prompt asking about gif support
24
25 getenv();     # get environment variables
26
27 my $help;
28 my @enable;
29 my @disable;
30 my @incpaths;
31 my @libpaths;
32 my $noprobe;
33 my $noexif;
34 GetOptions("help" => \$help,
35            "enable=s" => \@enable,
36            "disable=s" => \@disable,
37            "incpath=s", \@incpaths,
38            "libpath=s" => \@libpaths,
39            "noprobe" => \$noprobe,
40            "verbose|v" => \$VERBOSE,
41            "nolog" => \$NOLOG,
42            "noexif" => \$noexif);
43
44 if ($VERBOSE) { 
45   print "Verbose mode\n"; 
46   require Data::Dumper; 
47   import Data::Dumper qw(Dumper);
48 }
49
50 if ($help) {
51   usage();
52 }
53
54 my @defines;
55
56 if ($NOLOG)   { print "Logging not compiled into module\n"; }
57 else { 
58   push @defines, [ IMAGER_LOG => 1, "Logging system" ];
59 }
60
61 if ($DEBUG_MALLOC) {
62   push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
63   print "Malloc debugging enabled\n";
64 }
65
66 if (@enable && @disable) {
67   print STDERR "Only --enable or --disable can be used, not both, try --help\n";
68   exit 1;
69 }
70
71 init();       # initialize global data
72 pathcheck();  # Check if directories exist
73
74 if (exists $ENV{IM_ENABLE}) {
75   my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
76   for my $key (keys %formats) {
77     delete $formats{$key} unless $en{$key};
78   }
79 }
80 if (@enable) {
81   my %en = map { $_ => 1 } map { split /,/ } @enable;
82   for my $key (keys %formats) {
83     delete $formats{$key} unless $en{$key};
84   }
85 }
86 elsif (@disable) {
87   delete @formats{map { split /,/ } @disable};
88 }
89
90 # Pick what libraries are used
91 if ($MANUAL) {
92   manual();
93 } else {
94   automatic();
95 }
96
97 # Make sure there isn't a clash between the gif libraries.
98 gifcheck();
99
100 my $lib_cflags = '';
101 my $F_LIBS = '';
102 my $F_OBJECT = '';
103 for my $frmkey (keys %formats) {
104   my $frm = $formats{$frmkey};
105   push @defines, [ $frm->{def}, 1, "$frmkey available" ];
106   $F_LIBS   .= ' '  .$frm->{libfiles};
107   $F_OBJECT .= ' '  .$frm->{objfiles};
108   $lib_cflags   .= ' '  .$frm->{cflags} if $frm->{cflags};
109 }
110 unless ($noexif) {
111   print "EXIF support enabled\n";
112   push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
113   $F_OBJECT .= ' imexif.o';
114 }
115
116 $F_INC  = join ' ', map "-I$_", map / / ? qq{"$_"} : $_, 
117   grep !exists $definc{$_}, @incs;
118 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_, @libs) . $F_LIBS;
119
120 $OSLIBS = '';
121 $OSDEF  = "-DOS_$^O";
122
123 if ($^O eq 'hpux')                { $OSLIBS .= ' -ldld'; }
124 if (defined $Config{'d_dlsymun'}) { $OSDEF  .= ' -DDLSYMUN'; }
125
126 @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
127            log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
128            filters.o dynaload.o stackmach.o datatypes.o
129            regmach.o trans2.o quant.o error.o convert.o
130            map.o tags.o palimg.o maskimg.o img16.o rotate.o
131            bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o);
132
133 %opts=(
134        'NAME'         => 'Imager',
135        'VERSION_FROM' => 'Imager.pm',
136        'LIBS'         => "$LFLAGS -lm $OSLIBS $F_LIBS",
137        'DEFINE'       => "$OSDEF $CFLAGS",
138        'INC'          => "$lib_cflags $DFLAGS $F_INC",
139        'OBJECT'       => join(' ', @objs, $F_OBJECT),
140        clean          => { FILES=>'testout meta.tmp' },
141       );
142
143 if ($ExtUtils::MakeMaker::VERSION > 6.06) {
144   $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
145   $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
146 }
147
148 make_imconfig(\@defines);
149
150 if ($VERBOSE) { print Dumper(\%opts); }
151 mkdir('testout',0777); # since we cannot include it in the archive.
152 WriteMakefile(%opts);
153
154 exit;
155
156
157 sub MY::postamble {
158 '
159 dyntest.$(MYEXTLIB) : dynfilt/Makefile
160         cd dynfilt && $(MAKE) $(PASTHRU)
161
162 lib/Imager/Regops.pm : regmach.h regops.perl
163         $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
164
165 imconfig.h: Makefile.PL
166         $(ECHO) "imconfig.h out-of-date with respect to $?"
167         $(PERLRUN) Makefile.PL
168         $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
169 ';
170 }
171
172 sub MY::metafile {
173   my ($self) = @_;
174
175   my $meta = <<YAML;
176 --- #YAML:1.0
177 name: Imager
178 version: $self->{VERSION}
179 version_from: $self->{VERSION_FROM}
180 author: $self->{AUTHOR}
181 abstract: $self->{ABSTRACT}
182 installdirs: $self->{INSTALLDIRS}
183 recommends:
184   Parse::RecDescent: 0
185 license: perl
186 dynamic_config: 1
187 distribution_type: module
188 generated_by: Imager version $self->{VERSION}
189 YAML
190   open META, "> meta.tmp" or die "Cannot create meta.tmp: $!";
191   print META $meta;
192   close META;
193   
194   return sprintf "metafile :\n\t\$(CP) meta.tmp META.yml\n";
195 }
196
197 # manual configuration of helper libraries
198
199 sub manual {
200   print <<EOF;
201
202       Please answer the following questions about
203       which formats are avaliable on your computer
204
205 press <return> to continue
206 EOF
207
208   <STDIN>; # eat one return
209
210   for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
211   SWX:
212     if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
213     print "Enable $frm support: ";
214     $gz = <STDIN>;
215     chomp($gz);
216     if ($gz =~ m/^(y|yes|n|no)/i) {
217       $gz=substr(lc($gz),0,1);
218       if ($gz eq 'n') {
219         delete $formats{$frm};
220       }
221     } else { goto SWX; }
222   }
223 }
224
225
226 # automatic configuration of helper libraries
227
228 sub automatic {
229   for $frm(keys %formats) {
230     delete $formats{$frm} if !checkformat($frm);        
231   }
232 }
233
234
235 sub gifcheck {
236   if ($formats{'gif'} and $formats{'ungif'}) {
237     print "ungif and gif can not coexist - removing ungif support\n";
238     delete $formats{'ungif'};
239   }
240
241  RETR:
242   if (($formats{'gif'} or $formats{'ungif'}) && !$ENV{IM_SUPPRESS_PROMPT}) {
243     print <<EOFF;
244
245 You have libgif or libungif installed.  They are both known to have
246 bugs.  Imager can crash or display other strange behaviour after
247 reading or writing gif images.  Some of the gif tests can even fail
248 since they stress some parts of the buggy code.
249
250 libungif 4.1.2 and later is safe.  giflib 4.1.3 needs at least one
251 patch to have all the bugs fixed, see README for details.
252
253 Of course it's possible your operating system distributor has patched
254 all of these problems and you have nothing to worry about.
255
256 Do you want to remove gif support? [Y/n]
257 EOFF
258     my $resp = <STDIN>;
259     chomp($resp);
260     if ($resp ne "n") {
261       delete $formats{'gif'};
262       delete $formats{'ungif'};
263       return;
264     }
265   }
266
267   for my $frm (qw(gif ungif)) {
268     checkformat($frm) if ($MANUAL and $formats{$frm});
269   }
270
271   my @dirs;
272   for my $frm (grep $formats{$_}, qw(gif ungif)) {
273     push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
274   }
275   my $minor = 0;
276   my $major = 0;
277   FILES: for my $dir (@dirs) {
278     my $h = "$dir/gif_lib.h";
279     open H, "< $h" or next;
280     while (<H>) {
281       if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
282         $major = $1;
283         $minor = $2;
284         close H;
285         last FILES;
286       }
287     }
288     close H;
289   }
290
291   # we need the version in a #ifdefable form
292
293   push @defines, [ IM_GIFMAJOR, $major, "Parsed giflib version" ];
294   push @defines, [ IM_GIFMINOR, $minor ];
295 }
296
297
298 sub gd {
299   my($path,$chk)=@_;
300
301 #    print "checking path $path\n";
302   if ( !opendir(DH,$path) ) {
303     warn "Cannot open dir $path: $!\n";
304     return;
305   }
306   my @l=grep { $chk->($_) } readdir(DH);
307   #    print @l;
308   close(DH);
309   return map $path, @l;
310 }
311
312
313 sub checkformat {
314   my $frm=shift;
315   
316   my $code = $formats{$frm}{'code'};
317   if ($code && !$noprobe) {
318     return 1 if $code->($formats{$frm}, $frm);
319   }
320
321   my $libchk=$formats{$frm}{'libcheck'};
322   my $incchk=$formats{$frm}{'inccheck'};
323
324   my @l;
325   for my $lp (@libs) {
326     push(@l, gd($lp,$libchk));
327   }
328
329   my @i;
330   for my $ip (@incs) {
331     push(@i, $ip) if $incchk->($ip,$frm);
332   }
333
334   printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
335   $formats{$frm}{incdir} = \@i;
336   $formats{$frm}{libdir} = \@l;
337   return scalar(@i && @l);
338 }
339
340
341 sub pathcheck {
342   if ($VERBOSE) {
343     print "pathcheck\n";
344     print "  Include paths:\n";
345     for (@incs) { print $_,"\n"; }
346   }
347   @incs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
348
349   if ($VERBOSE) {
350     print "\nLibrary paths:\n";
351     for (@libs) { print $_,"\n"; }
352   }
353   @libs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
354   print "\ndone.\n";
355 }
356
357
358 # Format data initialization
359
360 # format definition is:
361 # defines needed
362 # default include path
363 # files needed for include (boolean perl code)
364 # default lib path
365 # libs needed
366 # files needed for link (boolean perl code)
367 # object files needed for the format
368
369
370 sub init {
371
372   @definc{'/usr/include'}=();
373   @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
374         map { split /\Q$Config{path_sep}/} @incpaths );
375   if ($Config{locincpth}) {
376     push @incs, grep -d, split ' ', $Config{locincpth};
377   }
378   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
379     push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
380   }
381   push @incs, grep -d,
382       qw(/sw/include 
383          /usr/include/freetype2
384          /usr/local/include/freetype2
385          /usr/local/include/freetype1/freetype
386          /usr/include /usr/local/include /usr/include/freetype
387          /usr/local/include/freetype);
388
389   @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
390     map { split /\Q$Config{path_sep}/} @libpaths );
391   if ($Config{loclibpth}) {
392     push @libs, grep -d, split ' ', $Config{loclibpth};
393   }
394   push @libs, grep -d, qw(/sw/lib),  split(/ /, $Config{'libpth'});
395   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
396     push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
397   }
398   if ($^O eq 'cygwin') {
399     push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
400     push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
401   }
402
403   my $lext=$Config{'so'};   # Get extensions of libraries
404   my $aext=$Config{'_a'};
405
406   $formats{'jpeg'}={
407                     order=>'21',
408                     def=>'HAVE_LIBJPEG',
409                     inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
410                     libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
411                     libfiles=>'-ljpeg',
412                     objfiles=>'jpeg.o',
413                     docs=>q{
414                             In order to use jpeg with this module you need to have libjpeg
415                             installed on your computer}
416                    };
417
418   $formats{'tiff'}={
419                     order=>'23',
420                     def=>'HAVE_LIBTIFF',
421                     inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
422                     libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
423                     libfiles=>'-ltiff',
424                     objfiles=>'tiff.o',
425                     docs=>q{
426                             In order to use tiff with this module you need to have libtiff
427                             installed on your computer}
428                    };
429
430   $formats{'png'}={
431                    order=>'22',
432                    def=>'HAVE_LIBPNG',
433                    inccheck=>sub { -e catfile($_[0], 'png.h') },
434                    libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
435                    libfiles=>'-lpng -lz',
436                    objfiles=>'png.o',
437                    docs=>q{
438                            Png stands for Portable Network Graphics and is intended as
439                            a replacement for gif on the web. It is patent free and
440                            is recommended by the w3c, you need libpng to use these formats},
441                    code => \&png_probe,
442                   };
443
444   $formats{'gif'}={
445                    order=>'20',
446                    def=>'HAVE_LIBGIF',
447                    inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
448                    libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
449                    libfiles=>'-lgif',
450                    objfiles=>'gif.o',
451                    docs=>q{
452                            gif is the de facto standard for webgraphics at the moment,
453                            it does have some patent problems. If you have giflib and
454                            are not in violation with the unisys patent you should use
455                            this instead of the 'ungif' option.  Note that they cannot
456                            be in use at the same time}
457                   };
458
459   $formats{'ungif'}={
460                      order=>'21',
461                      def=>'HAVE_LIBGIF',
462                      inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
463                      libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
464                      libfiles=>'-lungif',
465                      objfiles=>'gif.o',
466                      docs=>q{
467                              gif is the de facto standard for webgraphics at the moment,
468                              it does have some patent problems. If you have libungif and
469                              want to create images free from LZW patented compression you
470                              should use this option instead of the 'gif' option}
471                     };
472
473   $formats{'T1-fonts'}={
474                         order=>'30',
475                         def=>'HAVE_LIBT1',
476                         inccheck=>sub { -e catfile($_[0], 't1lib.h') },
477                         libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
478                         libfiles=>'-lt1',
479                         objfiles=>'',
480                         docs=>q{
481                                 postscript t1 fonts are scalable fonts. They can include 
482                                 ligatures and kerning information and generally yield good
483                                 visual quality. We depend on libt1 to rasterize the fonts
484                                 for use in images.}
485                        };
486
487   $formats{'TT-fonts'}=
488     {
489      order=>'31',
490      def=>'HAVE_LIBTT',
491      inccheck=>sub { -e catfile($_[0], 'freetype.h')
492                        && !-e catfile($_[0], 'fterrors.h') },
493      libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
494      libfiles=>'-lttf',
495      objfiles=>'',
496      docs=>q{
497 Truetype fonts are scalable fonts. They can include 
498 kerning and hinting information and generally yield good
499 visual quality esp on low resultions. The freetype library is
500 used to rasterize for us. The only drawback is that there
501 are alot of badly designed fonts out there.}
502                        };
503   $formats{'w32'} = {
504                      order=>40,
505                      def=>'HAVE_WIN32',
506                      inccheck=>sub { -e catfile($_[0], 'windows.h') },
507                      libcheck=>sub { lc $_[0] eq 'gdi32.lib' 
508                                        || lc $_[0] eq 'libgdi32.a' },
509                      libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
510                      objfiles=>'win32.o',
511                      docs => <<DOCS
512 Uses the Win32 GDI for rendering text.
513
514 This currently only works on under normal Win32 and cygwin.
515 DOCS
516                     };
517   $formats{'freetype2'} = {
518                            order=>'29',
519                            def=>'HAVE_FT2',
520                            inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
521                            libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
522                            libfiles=>'-lfreetype',
523                            objfiles=>'freetyp2.o',
524                            docs=><<DOCS,
525 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
526 scalable.  It also supports a variety of other fonts.
527 DOCS
528                            code => \&freetype2_probe,
529                           };
530
531   # Make fix indent
532   for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/  /mg; }
533 }
534
535
536
537 sub gen {
538   my $V = $ENV{$_[0]};
539   defined($V) ? $V : "";
540 }
541
542
543 # Get information from environment variables
544
545 sub getenv {
546
547   ($VERBOSE,
548    $INCPATH,
549    $LIBPATH,
550    $NOLOG,
551    $DEBUG_MALLOC,
552    $MANUAL,
553    $CFLAGS,
554    $LFLAGS,
555    $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
556                                 IM_INCPATH
557                                 IM_LIBPATH
558                                 IM_NOLOG
559                                 IM_DEBUG_MALLOC
560                                 IM_MANUAL
561                                 IM_CFLAGS
562                                 IM_LFLAGS
563                                 IM_DFLAGS);
564
565 }
566
567 sub make_imconfig {
568   my ($defines) = @_;
569
570   open CONFIG, "> imconfig.h"
571     or die "Cannot create imconfig.h: $!\n";
572   print CONFIG <<EOS;
573 /* This file is automatically generated by Makefile.PL.
574    Don't edit this file, since any changes will be lost */
575
576 #ifndef IMAGER_IMCONFIG_H
577 #define IMAGER_IMCONFIG_H
578 EOS
579   for my $define (@$defines) {
580     if ($define->[2]) {
581       print CONFIG "\n/*\n  $define->[2]\n*/\n\n";
582     }
583     print CONFIG "#define $define->[0] $define->[1]\n";
584   }
585   print CONFIG "\n#endif\n";
586   close CONFIG;
587 }
588
589 # use pkg-config to probe for libraries
590 # works around the junk that pkg-config dumps on FreeBSD
591 sub _pkg_probe {
592   my ($pkg) = @_;
593
594   is_exe('pkg-config') or return;
595
596   my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
597
598   !system("pkg-config $pkg --exists $redir");
599 }
600
601 # probes for freetype2 by trying to run freetype-config
602 sub freetype2_probe {
603   my ($frm, $frmkey) = @_;
604
605   is_exe('freetype-config') or return;
606
607   my $cflags = `freetype-config --cflags`
608     and !$? or return;
609   chomp $cflags;
610   
611   $frm->{cflags} = $cflags;
612   my $lflags = `freetype-config --libs`
613     and !$? or return;
614   chomp $lflags;
615   $frm->{libfiles} = $lflags;
616
617   printf "%10s: configured via freetype-config\n", $frmkey;
618
619   return 1;
620 }
621
622 # probes for libpng via pkg-config
623 sub png_probe {
624   my ($frm, $frmkey) = @_;
625
626   is_exe('pkg-config') or return;
627
628   my $config;
629   for my $check_conf (qw(libpng libpng12 libpng10)) {
630     if (_pkg_probe($check_conf)) {
631       $config = $check_conf;
632       last;
633     }
634   }
635   $config or return;
636
637   my $cflags = `pkg-config $config --cflags`
638     and !$? or return;
639
640   my $lflags = `pkg-config $config --libs`
641     and !$? or return;
642
643   chomp $cflags;
644   chomp $lflags;
645   $frm->{cflags} = $cflags;
646   $frm->{libfiles} = $lflags;
647
648   printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
649
650   return 1;
651 }
652
653 sub catfile {
654   return File::Spec->catfile(@_);
655 }
656
657 sub is_exe {
658   my ($name) = @_;
659
660   for my $dir (File::Spec->path) {
661     -x catfile($dir, "$name$Config{_exe}")
662       and return 1;
663   }
664
665   return;
666 }
667
668 sub usage {
669   print STDERR <<EOS;
670 Usage: $0 [--enable feature1,feature2,...] [other options]
671        $0 [--disable feature1,feature2,...]  [other options]
672        $0 --help
673 Possible feature names are:
674   png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
675 Other options:
676   --verbose | -v
677     Verbose library probing (or set IM_VERBOSE in the environment)
678   --nolog
679     Disable logging (or set IM_NOLOG in the environment)
680   --incpath dir
681     Add to the include search path
682   --libpath dir
683     Add to the library search path
684   --noprobe
685     Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
686 EOS
687   exit 1;
688
689 }