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