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
158 imext.o scale.o rubthru.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)';
199 my @ims = grep /\.im$/, keys %$mani;
201 dyntest.$(MYEXTLIB) : dynfilt/Makefile
202 cd dynfilt && $(MAKE) $(PASTHRU)
204 lib/Imager/Regops.pm : regmach.h regops.perl
205 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
207 imconfig.h : Makefile.PL
208 $(ECHO) "imconfig.h out-of-date with respect to $?"
209 $(PERLRUN) Makefile.PL
210 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
212 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
213 $perl apidocs.perl lib/Imager/APIRef.pod
215 !.join('', map _im_rule($perl, $_), @ims)
220 my ($perl, $im) = @_;
222 (my $c = $im) =~ s/\.im$/.c/;
226 $perl imtoc.perl $im $c
232 # manual configuration of helper libraries
237 Please answer the following questions about
238 which formats are avaliable on your computer
240 press <return> to continue
243 <STDIN>; # eat one return
245 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
247 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
248 print "Enable $frm support: ";
251 if ($gz =~ m/^(y|yes|n|no)/i) {
252 $gz=substr(lc($gz),0,1);
254 delete $formats{$frm};
261 # automatic configuration of helper libraries
264 print "Automatic probing:\n" if $VERBOSE;
265 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
266 delete $formats{$frm} if !checkformat($frm);
272 if ($formats{'gif'} and $formats{'ungif'}) {
273 print "ungif and gif can not coexist - removing ungif support\n";
274 delete $formats{'ungif'};
277 for my $frm (qw(gif ungif)) {
278 checkformat($frm) if ($MANUAL and $formats{$frm});
282 for my $frm (grep $formats{$_}, qw(gif ungif)) {
283 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
287 FILES: for my $dir (@dirs) {
288 my $h = "$dir/gif_lib.h";
289 open H, "< $h" or next;
291 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
301 # we need the version in a #ifdefable form
303 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
304 push @defines, [ IM_GIFMINOR => $minor ];
311 # print "checking path $path\n";
312 if ( !opendir(DH,$path) ) {
313 warn "Cannot open dir $path: $!\n";
316 my @l=grep { $chk->($_) } readdir(DH);
319 return map $path, @l;
326 print " checkformat($frm)\n" if $VERBOSE;
328 my $code = $formats{$frm}{'code'};
329 if ($code && !$noprobe) {
330 print " Calling probe function\n" if $VERBOSE;
331 return 1 if $code->($formats{$frm}, $frm);
334 my $libchk=$formats{$frm}{'libcheck'};
335 my $incchk=$formats{$frm}{'inccheck'};
339 push(@l, gd($lp,$libchk));
344 push(@i, $ip) if $incchk->($ip,$frm);
347 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
348 $formats{$frm}{incdir} = \@i;
349 $formats{$frm}{libdir} = \@l;
350 return scalar(@i && @l);
357 print " Include paths:\n";
358 for (@incs) { print $_,"\n"; }
360 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
363 print "\nLibrary paths:\n";
364 for (@libs) { print $_,"\n"; }
366 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
371 # Format data initialization
373 # format definition is:
375 # default include path
376 # files needed for include (boolean perl code)
379 # files needed for link (boolean perl code)
380 # object files needed for the format
385 my @definc = qw(/usr/include);
386 @definc{@definc}=(1) x @definc;
387 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
388 map { split /\Q$Config{path_sep}/} @incpaths );
389 if ($Config{locincpth}) {
390 push @incs, grep -d, split ' ', $Config{locincpth};
392 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
393 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
397 /usr/include/freetype2
398 /usr/local/include/freetype2
399 /usr/local/include/freetype1/freetype
400 /usr/include /usr/local/include /usr/include/freetype
401 /usr/local/include/freetype);
402 if ($Config{ccflags}) {
403 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
405 @definc{@hidden} = (1) x @hidden;
408 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
409 map { split /\Q$Config{path_sep}/} @libpaths );
410 if ($Config{loclibpth}) {
411 push @libs, grep -d, split ' ', $Config{loclibpth};
414 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
415 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
416 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
417 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
419 if ($^O eq 'cygwin') {
420 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
421 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
423 if ($Config{ldflags}) {
424 # some builds of perl put -Ldir into ldflags without putting it in
425 # loclibpth, let's extract them
426 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
427 split ' ', $Config{ldflags};
429 # don't mark them as seen - EU::MM will remove any libraries
430 # it can't find and it doesn't look for -L in ldflags
431 #@deflib{@hidden} = @hidden;
433 push @libs, grep -d, qw(/usr/local/lib);
438 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
439 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
443 In order to use jpeg with this module you need to have libjpeg
444 installed on your computer}
450 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
451 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
455 In order to use tiff with this module you need to have libtiff
456 installed on your computer}
462 inccheck=>sub { -e catfile($_[0], 'png.h') },
463 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
464 libfiles=>'-lpng -lz',
467 Png stands for Portable Network Graphics and is intended as
468 a replacement for gif on the web. It is patent free and
469 is recommended by the w3c, you need libpng to use these formats},
476 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
477 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
481 gif is the de facto standard for webgraphics at the moment,
482 it does have some patent problems. If you have giflib and
483 are not in violation with the unisys patent you should use
484 this instead of the 'ungif' option. Note that they cannot
485 be in use at the same time}
491 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
492 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
496 gif is the de facto standard for webgraphics at the moment,
497 it does have some patent problems. If you have libungif and
498 want to create images free from LZW patented compression you
499 should use this option instead of the 'gif' option}
502 $formats{'T1-fonts'}={
505 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
506 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
510 postscript t1 fonts are scalable fonts. They can include
511 ligatures and kerning information and generally yield good
512 visual quality. We depend on libt1 to rasterize the fonts
516 $formats{'TT-fonts'}=
520 inccheck=>sub { -e catfile($_[0], 'freetype.h')
521 && !-e catfile($_[0], 'fterrors.h') },
522 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
525 code => \&freetype1_probe,
527 Truetype fonts are scalable fonts. They can include
528 kerning and hinting information and generally yield good
529 visual quality esp on low resultions. The freetype library is
530 used to rasterize for us. The only drawback is that there
531 are alot of badly designed fonts out there.}
536 inccheck=>sub { -e catfile($_[0], 'windows.h') },
537 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
538 || lc $_[0] eq 'libgdi32.a' },
539 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
542 Uses the Win32 GDI for rendering text.
544 This currently only works on under normal Win32 and cygwin.
547 $formats{'freetype2'} = {
550 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
551 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
552 libfiles=>'-lfreetype',
553 objfiles=>'freetyp2.o',
555 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
556 scalable. It also supports a variety of other fonts.
558 code => \&freetype2_probe,
562 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
569 defined($V) ? $V : "";
573 # Get information from environment variables
585 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
600 open CONFIG, "> imconfig.h"
601 or die "Cannot create imconfig.h: $!\n";
603 /* This file is automatically generated by Makefile.PL.
604 Don't edit this file, since any changes will be lost */
606 #ifndef IMAGER_IMCONFIG_H
607 #define IMAGER_IMCONFIG_H
609 for my $define (@$defines) {
611 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
613 print CONFIG "#define $define->[0] $define->[1]\n";
615 print CONFIG "\n#endif\n";
619 # use pkg-config to probe for libraries
620 # works around the junk that pkg-config dumps on FreeBSD
624 is_exe('pkg-config') or return;
626 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
628 !system("pkg-config $pkg --exists $redir");
631 # probes for freetype1 by scanning @incs for the includes and
632 # @libs for the libs. This is done separately because freetype's headers
633 # are stored in a freetype or freetype1 directory under PREFIX/include.
635 # we could find the files with the existing mechanism, but it won't set
636 # -I flags correctly.
638 # This could be extended to freetype2 too, but freetype-config catches
640 sub freetype1_probe {
641 my ($frm, $frmkey) = @_;
645 for my $inc (@incs) {
646 for my $subdir (qw/freetype freetype1/) {
647 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
649 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
652 $found_inc = File::Spec->catdir($inc, $subdir);
659 for my $lib (@libs) {
660 my $a_path = File::Spec->catfile($lib, "libttf$aext");
661 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
662 if (-e $a_path || -e $l_path) {
668 return unless $found_inc && $found_lib;
669 printf("%10s: includes %s - libraries %s\n", $frmkey,
670 ($found_inc ? 'found' : 'not found'),
671 ($found_lib ? 'found' : 'not found'));
673 $frm->{cflags} = "-I$found_inc";
674 $frm->{libfiles} = "-lttf";
679 # probes for freetype2 by trying to run freetype-config
680 sub freetype2_probe {
681 my ($frm, $frmkey) = @_;
683 is_exe('freetype-config') or return;
685 my $cflags = `freetype-config --cflags`
689 my $lflags = `freetype-config --libs`
693 # before 2.1.5 freetype-config --cflags could output
694 # the -I options in the wrong order, causing a conflict with
695 # freetype1.x installed with the same --prefix
698 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
700 # - freetype 1.x headers are in prefix/include/freetype
701 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
703 && $incdirs[1] eq "$incdirs[0]/freetype2"
704 && -e "$incdirs[0]/freetype/freetype.h"
705 && -e "$incdirs[0]/freetype/fterrid.h") {
706 print "** freetype-config provided -I options out of order, correcting\n"
708 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
709 map "-I$_", reverse @incdirs);
711 $frm->{cflags} = $cflags;
712 $frm->{lflags} = $lflags;
714 printf "%10s: configured via freetype-config\n", $frmkey;
719 # probes for libpng via pkg-config
721 my ($frm, $frmkey) = @_;
723 is_exe('pkg-config') or return;
726 for my $check_conf (qw(libpng libpng12 libpng10)) {
727 if (_pkg_probe($check_conf)) {
728 $config = $check_conf;
734 my $cflags = `pkg-config $config --cflags`
737 my $lflags = `pkg-config $config --libs`
742 $frm->{cflags} = $cflags;
743 $frm->{lflags} = $lflags;
745 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
751 return File::Spec->catfile(@_);
757 for my $dir (File::Spec->path) {
758 -x catfile($dir, "$name$Config{_exe}")
767 Usage: $0 [--enable feature1,feature2,...] [other options]
768 $0 [--disable feature1,feature2,...] [other options]
770 Possible feature names are:
771 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
774 Verbose library probing (or set IM_VERBOSE in the environment)
776 Disable logging (or set IM_NOLOG in the environment)
778 Add to the include search path
780 Add to the library search path
782 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
788 # generate the PM MM argument
789 # I'd prefer to modify the public version, but there doesn't seem to be
790 # a public API to do that
793 my $instbase = '$(INST_LIBDIR)';
795 # first the basics, .pm and .pod files
796 $pm{"Imager.pm"} = "$instbase/Imager.pm";
798 my $mani = maniread();
800 for my $filename (keys %$mani) {
801 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
802 (my $work = $filename) =~ s/^lib//;
803 $pm{$filename} = $instbase . $work;
808 $pm{typemap} = $instbase . '/Imager/typemap';
810 # and the core headers
811 for my $filename (keys %$mani) {
812 if ($filename =~ /^\w+\.h$/) {
813 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
817 # and the generated header
818 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
826 # extract the version
827 my $version = MM->parse_version($opts->{VERSION_FROM})
828 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
830 # we don't set this on older EU::MM and it corrupts META.yml
831 # so don't generate it
832 return unless $opts->{AUTHOR};
838 version_from: $opts->{VERSION_FROM}
839 author: $opts->{AUTHOR}
840 abstract: $opts->{ABSTRACT}
843 if (keys %{$Recommends{$opts->{NAME}}}) {
844 $meta .= "recommends:\n";
845 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
846 $meta .= " $module: $version\n";
852 distribution_type: module
853 generated_by: $opts->{NAME} version $version
856 if (open META, "< META.yml") {
857 my $old_meta = do { local $/; <META> };
860 $save_meta = $old_meta ne $meta;
866 print "Updating META.yml\n";
867 open META, "> META.yml" or die "Cannot create META.yml: $!";
873 # this is intended to only be running on the development
877 # update Changes if needed
879 # get the last revision from Changes
880 if (open CHANGES, "< Changes") {
882 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
885 my ($revision) = grep s/^Revision: //, `svn info`
886 or die "Could not get Revision from svn";
889 $write_changes ||= $changes_rev != $revision;
895 if ($write_changes) {
896 print "Updating Changes file\n";
897 system 'svn log -v -r HEAD:943 >Changes';