3 use ExtUtils::MakeMaker;
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);
13 # IM_INCPATH colon seperated list of paths to extra include paths
14 # IM_LIBPATH colon seperated list of paths to extra library paths
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
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
29 getenv(); # get environment variables
31 my $lext=$Config{'so'}; # Get extensions of libraries
32 my $aext=$Config{'_a'};
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,
49 "noexif" => \$noexif);
52 print "Verbose mode\n";
54 import Data::Dumper qw(Dumper);
63 if ($NOLOG) { print "Logging not compiled into module\n"; }
65 push @defines, [ IMAGER_LOG => 1, "Logging system" ];
69 push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
70 print "Malloc debugging enabled\n";
73 if (@enable && @disable) {
74 print STDERR "Only --enable or --disable can be used, not both, try --help\n";
80 my @incs; # all the places to look for headers
81 my @libs; # all the places to look for libraries
83 init(); # initialize global data
84 pathcheck(); # Check if directories exist
85 distcheck(); # for building dists
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};
94 my %en = map { $_ => 1 } map { split /,/ } @enable;
95 for my $key (keys %formats) {
96 delete $formats{$key} unless $en{$key};
100 delete @formats{map { split /,/ } @disable};
103 # Pick what libraries are used
110 # Make sure there isn't a clash between the gif libraries.
116 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
117 my $frm = $formats{$frmkey};
118 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
119 $F_LIBS .= ' ' .$frm->{libfiles};
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};
129 print "EXIF support enabled\n";
130 push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
131 $F_OBJECT .= ' imexif.o';
134 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
135 grep !$definc{$_}, @incs;
136 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
137 grep !$deflib{$_}++, @libs) . $F_LIBS;
140 my $OSDEF = "-DOS_$^O";
142 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
143 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
145 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
146 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
147 filters.o dynaload.o stackmach.o datatypes.o
148 regmach.o trans2.o quant.o error.o convert.o
149 map.o tags.o palimg.o maskimg.o img16.o rotate.o
150 bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
153 $Recommends{Imager} =
154 { 'Parse::RecDescent' => 0 };
158 'VERSION_FROM' => 'Imager.pm',
159 'LIBS' => "$LFLAGS -lm $OSLIBS $F_LIBS",
160 'DEFINE' => "$OSDEF $CFLAGS",
161 'INC' => "$lib_cflags $DFLAGS $F_INC",
162 'OBJECT' => join(' ', @objs, $F_OBJECT),
163 clean => { FILES=>'testout meta.tmp' },
167 if ($ExtUtils::MakeMaker::VERSION > 6.06) {
168 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
169 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
171 if ($ExtUtils::MakeMaker::VERSION > 6.10) {
175 make_imconfig(\@defines);
177 if ($VERBOSE) { print Dumper(\%opts); }
178 mkdir('testout',0777); # since we cannot include it in the archive.
180 make_metafile(\%opts);
182 WriteMakefile(%opts);
189 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
191 dyntest.$(MYEXTLIB) : dynfilt/Makefile
192 cd dynfilt && $(MAKE) $(PASTHRU)
194 lib/Imager/Regops.pm : regmach.h regops.perl
195 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
197 imconfig.h : Makefile.PL
198 $(ECHO) "imconfig.h out-of-date with respect to $?"
199 $(PERLRUN) Makefile.PL
200 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
202 lib/Imager/APIRef.pm : \$(C_FILES) apidocs.perl
203 $perl apidocs.perl lib/Imager/APIRef.pm
209 # manual configuration of helper libraries
214 Please answer the following questions about
215 which formats are avaliable on your computer
217 press <return> to continue
220 <STDIN>; # eat one return
222 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
224 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
225 print "Enable $frm support: ";
228 if ($gz =~ m/^(y|yes|n|no)/i) {
229 $gz=substr(lc($gz),0,1);
231 delete $formats{$frm};
238 # automatic configuration of helper libraries
241 print "Automatic probing:\n" if $VERBOSE;
242 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
243 delete $formats{$frm} if !checkformat($frm);
249 if ($formats{'gif'} and $formats{'ungif'}) {
250 print "ungif and gif can not coexist - removing ungif support\n";
251 delete $formats{'ungif'};
255 if (($formats{'gif'} or $formats{'ungif'}) && !$ENV{IM_SUPPRESS_PROMPT}) {
258 You have libgif or libungif installed. They are both known to have
259 bugs. Imager can crash or display other strange behaviour after
260 reading or writing gif images. Some of the gif tests can even fail
261 since they stress some parts of the buggy code.
263 libungif 4.1.2 and later is safe. giflib 4.1.3 needs at least one
264 patch to have all the bugs fixed, see README for details.
266 Of course it's possible your operating system distributor has patched
267 all of these problems and you have nothing to worry about.
269 Do you want to remove gif support? [Y/n]
274 delete $formats{'gif'};
275 delete $formats{'ungif'};
280 for my $frm (qw(gif ungif)) {
281 checkformat($frm) if ($MANUAL and $formats{$frm});
285 for my $frm (grep $formats{$_}, qw(gif ungif)) {
286 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
290 FILES: for my $dir (@dirs) {
291 my $h = "$dir/gif_lib.h";
292 open H, "< $h" or next;
294 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
304 # we need the version in a #ifdefable form
306 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
307 push @defines, [ IM_GIFMINOR => $minor ];
314 # print "checking path $path\n";
315 if ( !opendir(DH,$path) ) {
316 warn "Cannot open dir $path: $!\n";
319 my @l=grep { $chk->($_) } readdir(DH);
322 return map $path, @l;
329 print " checkformat($frm)\n" if $VERBOSE;
331 my $code = $formats{$frm}{'code'};
332 if ($code && !$noprobe) {
333 print " Calling probe function\n" if $VERBOSE;
334 return 1 if $code->($formats{$frm}, $frm);
337 my $libchk=$formats{$frm}{'libcheck'};
338 my $incchk=$formats{$frm}{'inccheck'};
342 push(@l, gd($lp,$libchk));
347 push(@i, $ip) if $incchk->($ip,$frm);
350 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
351 $formats{$frm}{incdir} = \@i;
352 $formats{$frm}{libdir} = \@l;
353 return scalar(@i && @l);
360 print " Include paths:\n";
361 for (@incs) { print $_,"\n"; }
363 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
366 print "\nLibrary paths:\n";
367 for (@libs) { print $_,"\n"; }
369 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
374 # Format data initialization
376 # format definition is:
378 # default include path
379 # files needed for include (boolean perl code)
382 # files needed for link (boolean perl code)
383 # object files needed for the format
388 my @definc = qw(/usr/include);
389 @definc{@definc}=(1) x @definc;
390 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
391 map { split /\Q$Config{path_sep}/} @incpaths );
392 if ($Config{locincpth}) {
393 push @incs, grep -d, split ' ', $Config{locincpth};
395 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
396 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
400 /usr/include/freetype2
401 /usr/local/include/freetype2
402 /usr/local/include/freetype1/freetype
403 /usr/include /usr/local/include /usr/include/freetype
404 /usr/local/include/freetype);
405 if ($Config{ccflags}) {
406 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
408 @definc{@hidden} = (1) x @hidden;
411 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
412 map { split /\Q$Config{path_sep}/} @libpaths );
413 if ($Config{loclibpth}) {
414 push @libs, grep -d, split ' ', $Config{loclibpth};
417 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
418 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
419 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
420 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
422 if ($^O eq 'cygwin') {
423 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
424 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
426 if ($Config{ldflags}) {
427 # some builds of perl put -Ldir into ldflags without putting it in
428 # loclibpth, let's extract them
429 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
430 split ' ', $Config{ldflags};
432 # don't mark them as seen - EU::MM will remove any libraries
433 # it can't find and it doesn't look for -L in ldflags
434 #@deflib{@hidden} = @hidden;
440 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
441 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
445 In order to use jpeg with this module you need to have libjpeg
446 installed on your computer}
452 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
453 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
457 In order to use tiff with this module you need to have libtiff
458 installed on your computer}
464 inccheck=>sub { -e catfile($_[0], 'png.h') },
465 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
466 libfiles=>'-lpng -lz',
469 Png stands for Portable Network Graphics and is intended as
470 a replacement for gif on the web. It is patent free and
471 is recommended by the w3c, you need libpng to use these formats},
478 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
479 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
483 gif is the de facto standard for webgraphics at the moment,
484 it does have some patent problems. If you have giflib and
485 are not in violation with the unisys patent you should use
486 this instead of the 'ungif' option. Note that they cannot
487 be in use at the same time}
493 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
494 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
498 gif is the de facto standard for webgraphics at the moment,
499 it does have some patent problems. If you have libungif and
500 want to create images free from LZW patented compression you
501 should use this option instead of the 'gif' option}
504 $formats{'T1-fonts'}={
507 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
508 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
512 postscript t1 fonts are scalable fonts. They can include
513 ligatures and kerning information and generally yield good
514 visual quality. We depend on libt1 to rasterize the fonts
518 $formats{'TT-fonts'}=
522 inccheck=>sub { -e catfile($_[0], 'freetype.h')
523 && !-e catfile($_[0], 'fterrors.h') },
524 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
527 code => \&freetype1_probe,
529 Truetype fonts are scalable fonts. They can include
530 kerning and hinting information and generally yield good
531 visual quality esp on low resultions. The freetype library is
532 used to rasterize for us. The only drawback is that there
533 are alot of badly designed fonts out there.}
538 inccheck=>sub { -e catfile($_[0], 'windows.h') },
539 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
540 || lc $_[0] eq 'libgdi32.a' },
541 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
544 Uses the Win32 GDI for rendering text.
546 This currently only works on under normal Win32 and cygwin.
549 $formats{'freetype2'} = {
552 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
553 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
554 libfiles=>'-lfreetype',
555 objfiles=>'freetyp2.o',
557 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
558 scalable. It also supports a variety of other fonts.
560 code => \&freetype2_probe,
564 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
571 defined($V) ? $V : "";
575 # Get information from environment variables
587 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
602 open CONFIG, "> imconfig.h"
603 or die "Cannot create imconfig.h: $!\n";
605 /* This file is automatically generated by Makefile.PL.
606 Don't edit this file, since any changes will be lost */
608 #ifndef IMAGER_IMCONFIG_H
609 #define IMAGER_IMCONFIG_H
611 for my $define (@$defines) {
613 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
615 print CONFIG "#define $define->[0] $define->[1]\n";
617 print CONFIG "\n#endif\n";
621 # use pkg-config to probe for libraries
622 # works around the junk that pkg-config dumps on FreeBSD
626 is_exe('pkg-config') or return;
628 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
630 !system("pkg-config $pkg --exists $redir");
633 # probes for freetype1 by scanning @incs for the includes and
634 # @libs for the libs. This is done separately because freetype's headers
635 # are stored in a freetype or freetype1 directory under PREFIX/include.
637 # we could find the files with the existing mechanism, but it won't set
638 # -I flags correctly.
640 # This could be extended to freetype2 too, but freetype-config catches
642 sub freetype1_probe {
643 my ($frm, $frmkey) = @_;
647 for my $inc (@incs) {
648 for my $subdir (qw/freetype freetype1/) {
649 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
651 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
654 $found_inc = File::Spec->catdir($inc, $subdir);
661 for my $lib (@libs) {
662 my $a_path = File::Spec->catfile($lib, "libttf$aext");
663 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
664 if (-e $a_path || -e $l_path) {
670 return unless $found_inc && $found_lib;
671 printf("%10s: includes %s - libraries %s\n", $frmkey,
672 ($found_inc ? 'found' : 'not found'),
673 ($found_lib ? 'found' : 'not found'));
675 $frm->{cflags} = "-I$found_inc";
676 $frm->{libfiles} = "-lttf";
681 # probes for freetype2 by trying to run freetype-config
682 sub freetype2_probe {
683 my ($frm, $frmkey) = @_;
685 is_exe('freetype-config') or return;
687 my $cflags = `freetype-config --cflags`
691 my $lflags = `freetype-config --libs`
695 # before 2.1.5 freetype-config --cflags could output
696 # the -I options in the wrong order, causing a conflict with
697 # freetype1.x installed with the same --prefix
700 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
702 # - freetype 1.x headers are in prefix/include/freetype
703 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
705 && $incdirs[1] eq "$incdirs[0]/freetype2"
706 && -e "$incdirs[0]/freetype/freetype.h"
707 && -e "$incdirs[0]/freetype/fterrid.h") {
708 print "** freetype-config provided -I options out of order, correcting\n"
710 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
711 map "-I$_", reverse @incdirs);
713 $frm->{cflags} = $cflags;
714 $frm->{libfiles} = $lflags;
716 printf "%10s: configured via freetype-config\n", $frmkey;
721 # probes for libpng via pkg-config
723 my ($frm, $frmkey) = @_;
725 is_exe('pkg-config') or return;
728 for my $check_conf (qw(libpng libpng12 libpng10)) {
729 if (_pkg_probe($check_conf)) {
730 $config = $check_conf;
736 my $cflags = `pkg-config $config --cflags`
739 my $lflags = `pkg-config $config --libs`
744 $frm->{cflags} = $cflags;
745 $frm->{libfiles} = $lflags;
747 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
753 return File::Spec->catfile(@_);
759 for my $dir (File::Spec->path) {
760 -x catfile($dir, "$name$Config{_exe}")
769 Usage: $0 [--enable feature1,feature2,...] [other options]
770 $0 [--disable feature1,feature2,...] [other options]
772 Possible feature names are:
773 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
776 Verbose library probing (or set IM_VERBOSE in the environment)
778 Disable logging (or set IM_NOLOG in the environment)
780 Add to the include search path
782 Add to the library search path
784 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
790 # generate the PM MM argument
791 # I'd prefer to modify the public version, but there doesn't seem to be
792 # a public API to do that
795 my $instbase = '$(INST_LIBDIR)';
797 # first the basics, .pm and .pod files
798 $pm{"Imager.pm"} = "$instbase/Imager.pm";
800 my $mani = maniread();
802 for my $filename (keys %$mani) {
803 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
804 (my $work = $filename) =~ s/^lib//;
805 $pm{$filename} = $instbase . $work;
810 $pm{typemap} = $instbase . '/Imager/typemap';
812 # and the core headers
813 for my $filename (keys %$mani) {
814 if ($filename =~ /^\w+\.h$/) {
815 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
819 # and the generated header
820 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
828 # extract the version
829 my $version = MM->parse_version($opts->{VERSION_FROM})
830 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
836 version_from: $opts->{VERSION_FROM}
837 author: $opts->{AUTHOR}
838 abstract: $opts->{ABSTRACT}
841 if (keys %{$Recommends{$opts->{NAME}}}) {
842 $meta .= "recommends:\n";
843 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
844 $meta .= " $module: $version\n";
850 distribution_type: module
851 generated_by: $opts->{NAME} version $version
854 if (open META, "< META.yml") {
855 my $old_meta = do { local $/; <META> };
858 $save_meta = $old_meta ne $meta;
864 print "Updating META.yml\n";
865 open META, "> META.yml" or die "Cannot create META.yml: $!";
871 # this is intended to only be running on the development
875 # update Changes if needed
877 # get the last revision from Changes
878 if (open CHANGES, "< Changes") {
880 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
881 or die "Could not get revision from Changes";
883 my ($revision) = grep s/^Revision: //, `svn info`
884 or die "Could not get Revision line";
887 $write_changes = $changes_rev != $revision-1;
893 if ($write_changes) {
894 print "Updating Changes file\n";
895 system 'svn log -v -r HEAD:943 >Changes';