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.
117 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
118 my $frm = $formats{$frmkey};
119 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
120 $F_OBJECT .= ' ' .$frm->{objfiles};
121 if ($frm->{cflags}) {
122 $lib_cflags .= ' ' .$frm->{cflags};
123 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
124 grep /^-I./, split ' ', $frm->{cflags};
126 if ($frm->{lflags}) {
127 $lib_lflags .= ' ' . $frm->{lflags};
130 $F_LIBS .= ' ' .$frm->{libfiles};
136 print "EXIF support enabled\n";
137 push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
138 $F_OBJECT .= ' imexif.o';
141 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
142 grep !$definc{$_}, @incs;
143 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
144 grep !$deflib{$_}++, @libs) . $F_LIBS;
147 my $OSDEF = "-DOS_$^O";
149 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
150 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
152 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
153 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
154 filters.o dynaload.o stackmach.o datatypes.o
155 regmach.o trans2.o quant.o error.o convert.o
156 map.o tags.o palimg.o maskimg.o img16.o rotate.o
157 bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
160 $Recommends{Imager} =
161 { 'Parse::RecDescent' => 0 };
165 'VERSION_FROM' => 'Imager.pm',
166 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
167 'DEFINE' => "$OSDEF $CFLAGS",
168 'INC' => "$lib_cflags $DFLAGS $F_INC",
169 'OBJECT' => join(' ', @objs, $F_OBJECT),
170 clean => { FILES=>'testout meta.tmp' },
174 if ($ExtUtils::MakeMaker::VERSION > 6.06) {
175 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
176 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
178 if ($ExtUtils::MakeMaker::VERSION > 6.10) {
182 make_imconfig(\@defines);
184 if ($VERBOSE) { print Dumper(\%opts); }
185 mkdir('testout',0777); # since we cannot include it in the archive.
187 make_metafile(\%opts);
189 WriteMakefile(%opts);
196 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
198 dyntest.$(MYEXTLIB) : dynfilt/Makefile
199 cd dynfilt && $(MAKE) $(PASTHRU)
201 lib/Imager/Regops.pm : regmach.h regops.perl
202 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
204 imconfig.h : Makefile.PL
205 $(ECHO) "imconfig.h out-of-date with respect to $?"
206 $(PERLRUN) Makefile.PL
207 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
209 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
210 $perl apidocs.perl lib/Imager/APIRef.pod
216 # manual configuration of helper libraries
221 Please answer the following questions about
222 which formats are avaliable on your computer
224 press <return> to continue
227 <STDIN>; # eat one return
229 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
231 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
232 print "Enable $frm support: ";
235 if ($gz =~ m/^(y|yes|n|no)/i) {
236 $gz=substr(lc($gz),0,1);
238 delete $formats{$frm};
245 # automatic configuration of helper libraries
248 print "Automatic probing:\n" if $VERBOSE;
249 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
250 delete $formats{$frm} if !checkformat($frm);
256 if ($formats{'gif'} and $formats{'ungif'}) {
257 print "ungif and gif can not coexist - removing ungif support\n";
258 delete $formats{'ungif'};
261 for my $frm (qw(gif ungif)) {
262 checkformat($frm) if ($MANUAL and $formats{$frm});
266 for my $frm (grep $formats{$_}, qw(gif ungif)) {
267 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
271 FILES: for my $dir (@dirs) {
272 my $h = "$dir/gif_lib.h";
273 open H, "< $h" or next;
275 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
285 # we need the version in a #ifdefable form
287 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
288 push @defines, [ IM_GIFMINOR => $minor ];
295 # print "checking path $path\n";
296 if ( !opendir(DH,$path) ) {
297 warn "Cannot open dir $path: $!\n";
300 my @l=grep { $chk->($_) } readdir(DH);
303 return map $path, @l;
310 print " checkformat($frm)\n" if $VERBOSE;
312 my $code = $formats{$frm}{'code'};
313 if ($code && !$noprobe) {
314 print " Calling probe function\n" if $VERBOSE;
315 return 1 if $code->($formats{$frm}, $frm);
318 my $libchk=$formats{$frm}{'libcheck'};
319 my $incchk=$formats{$frm}{'inccheck'};
323 push(@l, gd($lp,$libchk));
328 push(@i, $ip) if $incchk->($ip,$frm);
331 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
332 $formats{$frm}{incdir} = \@i;
333 $formats{$frm}{libdir} = \@l;
334 return scalar(@i && @l);
341 print " Include paths:\n";
342 for (@incs) { print $_,"\n"; }
344 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
347 print "\nLibrary paths:\n";
348 for (@libs) { print $_,"\n"; }
350 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
355 # Format data initialization
357 # format definition is:
359 # default include path
360 # files needed for include (boolean perl code)
363 # files needed for link (boolean perl code)
364 # object files needed for the format
369 my @definc = qw(/usr/include);
370 @definc{@definc}=(1) x @definc;
371 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
372 map { split /\Q$Config{path_sep}/} @incpaths );
373 if ($Config{locincpth}) {
374 push @incs, grep -d, split ' ', $Config{locincpth};
376 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
377 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
381 /usr/include/freetype2
382 /usr/local/include/freetype2
383 /usr/local/include/freetype1/freetype
384 /usr/include /usr/local/include /usr/include/freetype
385 /usr/local/include/freetype);
386 if ($Config{ccflags}) {
387 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
389 @definc{@hidden} = (1) x @hidden;
392 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
393 map { split /\Q$Config{path_sep}/} @libpaths );
394 if ($Config{loclibpth}) {
395 push @libs, grep -d, split ' ', $Config{loclibpth};
398 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
399 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
400 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
401 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
403 if ($^O eq 'cygwin') {
404 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
405 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
407 if ($Config{ldflags}) {
408 # some builds of perl put -Ldir into ldflags without putting it in
409 # loclibpth, let's extract them
410 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
411 split ' ', $Config{ldflags};
413 # don't mark them as seen - EU::MM will remove any libraries
414 # it can't find and it doesn't look for -L in ldflags
415 #@deflib{@hidden} = @hidden;
417 push @libs, grep -d, qw(/usr/local/lib);
422 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
423 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
427 In order to use jpeg with this module you need to have libjpeg
428 installed on your computer}
434 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
435 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
439 In order to use tiff with this module you need to have libtiff
440 installed on your computer}
446 inccheck=>sub { -e catfile($_[0], 'png.h') },
447 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
448 libfiles=>'-lpng -lz',
451 Png stands for Portable Network Graphics and is intended as
452 a replacement for gif on the web. It is patent free and
453 is recommended by the w3c, you need libpng to use these formats},
460 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
461 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
465 gif is the de facto standard for webgraphics at the moment,
466 it does have some patent problems. If you have giflib and
467 are not in violation with the unisys patent you should use
468 this instead of the 'ungif' option. Note that they cannot
469 be in use at the same time}
475 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
476 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
480 gif is the de facto standard for webgraphics at the moment,
481 it does have some patent problems. If you have libungif and
482 want to create images free from LZW patented compression you
483 should use this option instead of the 'gif' option}
486 $formats{'T1-fonts'}={
489 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
490 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
494 postscript t1 fonts are scalable fonts. They can include
495 ligatures and kerning information and generally yield good
496 visual quality. We depend on libt1 to rasterize the fonts
500 $formats{'TT-fonts'}=
504 inccheck=>sub { -e catfile($_[0], 'freetype.h')
505 && !-e catfile($_[0], 'fterrors.h') },
506 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
509 code => \&freetype1_probe,
511 Truetype fonts are scalable fonts. They can include
512 kerning and hinting information and generally yield good
513 visual quality esp on low resultions. The freetype library is
514 used to rasterize for us. The only drawback is that there
515 are alot of badly designed fonts out there.}
520 inccheck=>sub { -e catfile($_[0], 'windows.h') },
521 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
522 || lc $_[0] eq 'libgdi32.a' },
523 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
526 Uses the Win32 GDI for rendering text.
528 This currently only works on under normal Win32 and cygwin.
531 $formats{'freetype2'} = {
534 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
535 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
536 libfiles=>'-lfreetype',
537 objfiles=>'freetyp2.o',
539 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
540 scalable. It also supports a variety of other fonts.
542 code => \&freetype2_probe,
546 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
553 defined($V) ? $V : "";
557 # Get information from environment variables
569 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
584 open CONFIG, "> imconfig.h"
585 or die "Cannot create imconfig.h: $!\n";
587 /* This file is automatically generated by Makefile.PL.
588 Don't edit this file, since any changes will be lost */
590 #ifndef IMAGER_IMCONFIG_H
591 #define IMAGER_IMCONFIG_H
593 for my $define (@$defines) {
595 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
597 print CONFIG "#define $define->[0] $define->[1]\n";
599 print CONFIG "\n#endif\n";
603 # use pkg-config to probe for libraries
604 # works around the junk that pkg-config dumps on FreeBSD
608 is_exe('pkg-config') or return;
610 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
612 !system("pkg-config $pkg --exists $redir");
615 # probes for freetype1 by scanning @incs for the includes and
616 # @libs for the libs. This is done separately because freetype's headers
617 # are stored in a freetype or freetype1 directory under PREFIX/include.
619 # we could find the files with the existing mechanism, but it won't set
620 # -I flags correctly.
622 # This could be extended to freetype2 too, but freetype-config catches
624 sub freetype1_probe {
625 my ($frm, $frmkey) = @_;
629 for my $inc (@incs) {
630 for my $subdir (qw/freetype freetype1/) {
631 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
633 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
636 $found_inc = File::Spec->catdir($inc, $subdir);
643 for my $lib (@libs) {
644 my $a_path = File::Spec->catfile($lib, "libttf$aext");
645 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
646 if (-e $a_path || -e $l_path) {
652 return unless $found_inc && $found_lib;
653 printf("%10s: includes %s - libraries %s\n", $frmkey,
654 ($found_inc ? 'found' : 'not found'),
655 ($found_lib ? 'found' : 'not found'));
657 $frm->{cflags} = "-I$found_inc";
658 $frm->{libfiles} = "-lttf";
663 # probes for freetype2 by trying to run freetype-config
664 sub freetype2_probe {
665 my ($frm, $frmkey) = @_;
667 is_exe('freetype-config') or return;
669 my $cflags = `freetype-config --cflags`
673 my $lflags = `freetype-config --libs`
677 # before 2.1.5 freetype-config --cflags could output
678 # the -I options in the wrong order, causing a conflict with
679 # freetype1.x installed with the same --prefix
682 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
684 # - freetype 1.x headers are in prefix/include/freetype
685 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
687 && $incdirs[1] eq "$incdirs[0]/freetype2"
688 && -e "$incdirs[0]/freetype/freetype.h"
689 && -e "$incdirs[0]/freetype/fterrid.h") {
690 print "** freetype-config provided -I options out of order, correcting\n"
692 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
693 map "-I$_", reverse @incdirs);
695 $frm->{cflags} = $cflags;
696 $frm->{lflags} = $lflags;
698 printf "%10s: configured via freetype-config\n", $frmkey;
703 # probes for libpng via pkg-config
705 my ($frm, $frmkey) = @_;
707 is_exe('pkg-config') or return;
710 for my $check_conf (qw(libpng libpng12 libpng10)) {
711 if (_pkg_probe($check_conf)) {
712 $config = $check_conf;
718 my $cflags = `pkg-config $config --cflags`
721 my $lflags = `pkg-config $config --libs`
726 $frm->{cflags} = $cflags;
727 $frm->{lflags} = $lflags;
729 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
735 return File::Spec->catfile(@_);
741 for my $dir (File::Spec->path) {
742 -x catfile($dir, "$name$Config{_exe}")
751 Usage: $0 [--enable feature1,feature2,...] [other options]
752 $0 [--disable feature1,feature2,...] [other options]
754 Possible feature names are:
755 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
758 Verbose library probing (or set IM_VERBOSE in the environment)
760 Disable logging (or set IM_NOLOG in the environment)
762 Add to the include search path
764 Add to the library search path
766 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
772 # generate the PM MM argument
773 # I'd prefer to modify the public version, but there doesn't seem to be
774 # a public API to do that
777 my $instbase = '$(INST_LIBDIR)';
779 # first the basics, .pm and .pod files
780 $pm{"Imager.pm"} = "$instbase/Imager.pm";
782 my $mani = maniread();
784 for my $filename (keys %$mani) {
785 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
786 (my $work = $filename) =~ s/^lib//;
787 $pm{$filename} = $instbase . $work;
792 $pm{typemap} = $instbase . '/Imager/typemap';
794 # and the core headers
795 for my $filename (keys %$mani) {
796 if ($filename =~ /^\w+\.h$/) {
797 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
801 # and the generated header
802 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
810 # extract the version
811 my $version = MM->parse_version($opts->{VERSION_FROM})
812 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
814 # we don't set this on older EU::MM and it corrupts META.yml
815 # so don't generate it
816 return unless $opts->{AUTHOR};
822 version_from: $opts->{VERSION_FROM}
823 author: $opts->{AUTHOR}
824 abstract: $opts->{ABSTRACT}
827 if (keys %{$Recommends{$opts->{NAME}}}) {
828 $meta .= "recommends:\n";
829 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
830 $meta .= " $module: $version\n";
836 distribution_type: module
837 generated_by: $opts->{NAME} version $version
840 if (open META, "< META.yml") {
841 my $old_meta = do { local $/; <META> };
844 $save_meta = $old_meta ne $meta;
850 print "Updating META.yml\n";
851 open META, "> META.yml" or die "Cannot create META.yml: $!";
857 # this is intended to only be running on the development
861 # update Changes if needed
863 # get the last revision from Changes
864 if (open CHANGES, "< Changes") {
866 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
869 my ($revision) = grep s/^Revision: //, `svn info`
870 or die "Could not get Revision from svn";
873 $write_changes ||= $changes_rev != $revision;
879 if ($write_changes) {
880 print "Updating Changes file\n";
881 system 'svn log -v -r HEAD:943 >Changes';