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'};
262 if (($formats{'gif'} or $formats{'ungif'}) && !$ENV{IM_SUPPRESS_PROMPT}) {
265 You have libgif or libungif installed. They are both known to have
266 bugs. Imager can crash or display other strange behaviour after
267 reading or writing gif images. Some of the gif tests can fail since
268 they stress some parts of the buggy code.
270 libungif or libgif 4.1.4 and later is safe.
272 Of course it's possible your operating system distributor has patched
273 all of these problems and you have nothing to worry about.
275 Do you want to remove gif support? [Y/n]
278 my $resp = prompt($msg);
281 delete $formats{'gif'};
282 delete $formats{'ungif'};
287 for my $frm (qw(gif ungif)) {
288 checkformat($frm) if ($MANUAL and $formats{$frm});
292 for my $frm (grep $formats{$_}, qw(gif ungif)) {
293 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
297 FILES: for my $dir (@dirs) {
298 my $h = "$dir/gif_lib.h";
299 open H, "< $h" or next;
301 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
311 # we need the version in a #ifdefable form
313 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
314 push @defines, [ IM_GIFMINOR => $minor ];
321 # print "checking path $path\n";
322 if ( !opendir(DH,$path) ) {
323 warn "Cannot open dir $path: $!\n";
326 my @l=grep { $chk->($_) } readdir(DH);
329 return map $path, @l;
336 print " checkformat($frm)\n" if $VERBOSE;
338 my $code = $formats{$frm}{'code'};
339 if ($code && !$noprobe) {
340 print " Calling probe function\n" if $VERBOSE;
341 return 1 if $code->($formats{$frm}, $frm);
344 my $libchk=$formats{$frm}{'libcheck'};
345 my $incchk=$formats{$frm}{'inccheck'};
349 push(@l, gd($lp,$libchk));
354 push(@i, $ip) if $incchk->($ip,$frm);
357 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
358 $formats{$frm}{incdir} = \@i;
359 $formats{$frm}{libdir} = \@l;
360 return scalar(@i && @l);
367 print " Include paths:\n";
368 for (@incs) { print $_,"\n"; }
370 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
373 print "\nLibrary paths:\n";
374 for (@libs) { print $_,"\n"; }
376 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
381 # Format data initialization
383 # format definition is:
385 # default include path
386 # files needed for include (boolean perl code)
389 # files needed for link (boolean perl code)
390 # object files needed for the format
395 my @definc = qw(/usr/include);
396 @definc{@definc}=(1) x @definc;
397 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
398 map { split /\Q$Config{path_sep}/} @incpaths );
399 if ($Config{locincpth}) {
400 push @incs, grep -d, split ' ', $Config{locincpth};
402 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
403 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
407 /usr/include/freetype2
408 /usr/local/include/freetype2
409 /usr/local/include/freetype1/freetype
410 /usr/include /usr/local/include /usr/include/freetype
411 /usr/local/include/freetype);
412 if ($Config{ccflags}) {
413 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
415 @definc{@hidden} = (1) x @hidden;
418 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
419 map { split /\Q$Config{path_sep}/} @libpaths );
420 if ($Config{loclibpth}) {
421 push @libs, grep -d, split ' ', $Config{loclibpth};
424 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
425 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
426 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
427 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
429 if ($^O eq 'cygwin') {
430 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
431 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
433 if ($Config{ldflags}) {
434 # some builds of perl put -Ldir into ldflags without putting it in
435 # loclibpth, let's extract them
436 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
437 split ' ', $Config{ldflags};
439 # don't mark them as seen - EU::MM will remove any libraries
440 # it can't find and it doesn't look for -L in ldflags
441 #@deflib{@hidden} = @hidden;
443 push @libs, grep -d, qw(/usr/local/lib);
448 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
449 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
453 In order to use jpeg with this module you need to have libjpeg
454 installed on your computer}
460 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
461 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
465 In order to use tiff with this module you need to have libtiff
466 installed on your computer}
472 inccheck=>sub { -e catfile($_[0], 'png.h') },
473 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
474 libfiles=>'-lpng -lz',
477 Png stands for Portable Network Graphics and is intended as
478 a replacement for gif on the web. It is patent free and
479 is recommended by the w3c, you need libpng to use these formats},
486 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
487 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
491 gif is the de facto standard for webgraphics at the moment,
492 it does have some patent problems. If you have giflib and
493 are not in violation with the unisys patent you should use
494 this instead of the 'ungif' option. Note that they cannot
495 be in use at the same time}
501 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
502 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
506 gif is the de facto standard for webgraphics at the moment,
507 it does have some patent problems. If you have libungif and
508 want to create images free from LZW patented compression you
509 should use this option instead of the 'gif' option}
512 $formats{'T1-fonts'}={
515 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
516 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
520 postscript t1 fonts are scalable fonts. They can include
521 ligatures and kerning information and generally yield good
522 visual quality. We depend on libt1 to rasterize the fonts
526 $formats{'TT-fonts'}=
530 inccheck=>sub { -e catfile($_[0], 'freetype.h')
531 && !-e catfile($_[0], 'fterrors.h') },
532 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
535 code => \&freetype1_probe,
537 Truetype fonts are scalable fonts. They can include
538 kerning and hinting information and generally yield good
539 visual quality esp on low resultions. The freetype library is
540 used to rasterize for us. The only drawback is that there
541 are alot of badly designed fonts out there.}
546 inccheck=>sub { -e catfile($_[0], 'windows.h') },
547 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
548 || lc $_[0] eq 'libgdi32.a' },
549 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
552 Uses the Win32 GDI for rendering text.
554 This currently only works on under normal Win32 and cygwin.
557 $formats{'freetype2'} = {
560 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
561 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
562 libfiles=>'-lfreetype',
563 objfiles=>'freetyp2.o',
565 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
566 scalable. It also supports a variety of other fonts.
568 code => \&freetype2_probe,
572 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
579 defined($V) ? $V : "";
583 # Get information from environment variables
595 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
610 open CONFIG, "> imconfig.h"
611 or die "Cannot create imconfig.h: $!\n";
613 /* This file is automatically generated by Makefile.PL.
614 Don't edit this file, since any changes will be lost */
616 #ifndef IMAGER_IMCONFIG_H
617 #define IMAGER_IMCONFIG_H
619 for my $define (@$defines) {
621 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
623 print CONFIG "#define $define->[0] $define->[1]\n";
625 print CONFIG "\n#endif\n";
629 # use pkg-config to probe for libraries
630 # works around the junk that pkg-config dumps on FreeBSD
634 is_exe('pkg-config') or return;
636 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
638 !system("pkg-config $pkg --exists $redir");
641 # probes for freetype1 by scanning @incs for the includes and
642 # @libs for the libs. This is done separately because freetype's headers
643 # are stored in a freetype or freetype1 directory under PREFIX/include.
645 # we could find the files with the existing mechanism, but it won't set
646 # -I flags correctly.
648 # This could be extended to freetype2 too, but freetype-config catches
650 sub freetype1_probe {
651 my ($frm, $frmkey) = @_;
655 for my $inc (@incs) {
656 for my $subdir (qw/freetype freetype1/) {
657 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
659 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
662 $found_inc = File::Spec->catdir($inc, $subdir);
669 for my $lib (@libs) {
670 my $a_path = File::Spec->catfile($lib, "libttf$aext");
671 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
672 if (-e $a_path || -e $l_path) {
678 return unless $found_inc && $found_lib;
679 printf("%10s: includes %s - libraries %s\n", $frmkey,
680 ($found_inc ? 'found' : 'not found'),
681 ($found_lib ? 'found' : 'not found'));
683 $frm->{cflags} = "-I$found_inc";
684 $frm->{libfiles} = "-lttf";
689 # probes for freetype2 by trying to run freetype-config
690 sub freetype2_probe {
691 my ($frm, $frmkey) = @_;
693 is_exe('freetype-config') or return;
695 my $cflags = `freetype-config --cflags`
699 my $lflags = `freetype-config --libs`
703 # before 2.1.5 freetype-config --cflags could output
704 # the -I options in the wrong order, causing a conflict with
705 # freetype1.x installed with the same --prefix
708 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
710 # - freetype 1.x headers are in prefix/include/freetype
711 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
713 && $incdirs[1] eq "$incdirs[0]/freetype2"
714 && -e "$incdirs[0]/freetype/freetype.h"
715 && -e "$incdirs[0]/freetype/fterrid.h") {
716 print "** freetype-config provided -I options out of order, correcting\n"
718 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
719 map "-I$_", reverse @incdirs);
721 $frm->{cflags} = $cflags;
722 $frm->{lflags} = $lflags;
724 printf "%10s: configured via freetype-config\n", $frmkey;
729 # probes for libpng via pkg-config
731 my ($frm, $frmkey) = @_;
733 is_exe('pkg-config') or return;
736 for my $check_conf (qw(libpng libpng12 libpng10)) {
737 if (_pkg_probe($check_conf)) {
738 $config = $check_conf;
744 my $cflags = `pkg-config $config --cflags`
747 my $lflags = `pkg-config $config --libs`
752 $frm->{cflags} = $cflags;
753 $frm->{lflags} = $lflags;
755 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
761 return File::Spec->catfile(@_);
767 for my $dir (File::Spec->path) {
768 -x catfile($dir, "$name$Config{_exe}")
777 Usage: $0 [--enable feature1,feature2,...] [other options]
778 $0 [--disable feature1,feature2,...] [other options]
780 Possible feature names are:
781 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
784 Verbose library probing (or set IM_VERBOSE in the environment)
786 Disable logging (or set IM_NOLOG in the environment)
788 Add to the include search path
790 Add to the library search path
792 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
798 # generate the PM MM argument
799 # I'd prefer to modify the public version, but there doesn't seem to be
800 # a public API to do that
803 my $instbase = '$(INST_LIBDIR)';
805 # first the basics, .pm and .pod files
806 $pm{"Imager.pm"} = "$instbase/Imager.pm";
808 my $mani = maniread();
810 for my $filename (keys %$mani) {
811 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
812 (my $work = $filename) =~ s/^lib//;
813 $pm{$filename} = $instbase . $work;
818 $pm{typemap} = $instbase . '/Imager/typemap';
820 # and the core headers
821 for my $filename (keys %$mani) {
822 if ($filename =~ /^\w+\.h$/) {
823 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
827 # and the generated header
828 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
836 # extract the version
837 my $version = MM->parse_version($opts->{VERSION_FROM})
838 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
840 # we don't set this on older EU::MM and it corrupts META.yml
841 # so don't generate it
842 return unless $opts->{AUTHOR};
848 version_from: $opts->{VERSION_FROM}
849 author: $opts->{AUTHOR}
850 abstract: $opts->{ABSTRACT}
853 if (keys %{$Recommends{$opts->{NAME}}}) {
854 $meta .= "recommends:\n";
855 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
856 $meta .= " $module: $version\n";
862 distribution_type: module
863 generated_by: $opts->{NAME} version $version
866 if (open META, "< META.yml") {
867 my $old_meta = do { local $/; <META> };
870 $save_meta = $old_meta ne $meta;
876 print "Updating META.yml\n";
877 open META, "> META.yml" or die "Cannot create META.yml: $!";
883 # this is intended to only be running on the development
887 # update Changes if needed
889 # get the last revision from Changes
890 if (open CHANGES, "< Changes") {
892 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
895 my ($revision) = grep s/^Revision: //, `svn info`
896 or die "Could not get Revision from svn";
899 $write_changes ||= $changes_rev != $revision;
905 if ($write_changes) {
906 print "Updating Changes file\n";
907 system 'svn log -v -r HEAD:943 >Changes';