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 # eval to prevent warnings about versions with _ in them
175 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
176 if ($MM_ver > 6.06) {
177 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
178 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
180 if ($MM_ver > 6.10) {
184 make_imconfig(\@defines);
186 if ($VERBOSE) { print Dumper(\%opts); }
187 mkdir('testout',0777); # since we cannot include it in the archive.
189 make_metafile(\%opts);
191 WriteMakefile(%opts);
198 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
201 my @ims = grep /\.im$/, keys %$mani;
203 dyntest.$(MYEXTLIB) : dynfilt/Makefile
204 cd dynfilt && $(MAKE) $(PASTHRU)
206 lib/Imager/Regops.pm : regmach.h regops.perl
207 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
209 imconfig.h : Makefile.PL
210 $(ECHO) "imconfig.h out-of-date with respect to $?"
211 $(PERLRUN) Makefile.PL
212 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
214 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
215 $perl apidocs.perl lib/Imager/APIRef.pod
217 !.join('', map _im_rule($perl, $_), @ims)
222 my ($perl, $im) = @_;
224 (my $c = $im) =~ s/\.im$/.c/;
228 $perl imtoc.perl $im $c
234 # manual configuration of helper libraries
239 Please answer the following questions about
240 which formats are avaliable on your computer
242 press <return> to continue
245 <STDIN>; # eat one return
247 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
249 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
250 print "Enable $frm support: ";
253 if ($gz =~ m/^(y|yes|n|no)/i) {
254 $gz=substr(lc($gz),0,1);
256 delete $formats{$frm};
263 # automatic configuration of helper libraries
266 print "Automatic probing:\n" if $VERBOSE;
267 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
268 delete $formats{$frm} if !checkformat($frm);
274 if ($formats{'gif'} and $formats{'ungif'}) {
275 print "ungif and gif can not coexist - removing ungif support\n";
276 delete $formats{'ungif'};
279 for my $frm (qw(gif ungif)) {
280 checkformat($frm) if ($MANUAL and $formats{$frm});
284 for my $frm (grep $formats{$_}, qw(gif ungif)) {
285 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
289 FILES: for my $dir (@dirs) {
290 my $h = "$dir/gif_lib.h";
291 open H, "< $h" or next;
293 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
303 # we need the version in a #ifdefable form
305 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
306 push @defines, [ IM_GIFMINOR => $minor ];
313 # print "checking path $path\n";
314 if ( !opendir(DH,$path) ) {
315 warn "Cannot open dir $path: $!\n";
318 my @l=grep { $chk->($_) } readdir(DH);
321 return map $path, @l;
328 print " checkformat($frm)\n" if $VERBOSE;
330 my $code = $formats{$frm}{'code'};
331 if ($code && !$noprobe) {
332 print " Calling probe function\n" if $VERBOSE;
333 return 1 if $code->($formats{$frm}, $frm);
336 my $libchk=$formats{$frm}{'libcheck'};
337 my $incchk=$formats{$frm}{'inccheck'};
341 push(@l, gd($lp,$libchk));
346 push(@i, $ip) if $incchk->($ip,$frm);
349 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
350 $formats{$frm}{incdir} = \@i;
351 $formats{$frm}{libdir} = \@l;
352 return scalar(@i && @l);
359 print " Include paths:\n";
360 for (@incs) { print $_,"\n"; }
362 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
365 print "\nLibrary paths:\n";
366 for (@libs) { print $_,"\n"; }
368 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
373 # Format data initialization
375 # format definition is:
377 # default include path
378 # files needed for include (boolean perl code)
381 # files needed for link (boolean perl code)
382 # object files needed for the format
387 my @definc = qw(/usr/include);
388 @definc{@definc}=(1) x @definc;
389 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
390 map { split /\Q$Config{path_sep}/} @incpaths );
391 if ($Config{locincpth}) {
392 push @incs, grep -d, split ' ', $Config{locincpth};
394 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
395 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
399 /usr/include/freetype2
400 /usr/local/include/freetype2
401 /usr/local/include/freetype1/freetype
402 /usr/include /usr/local/include /usr/include/freetype
403 /usr/local/include/freetype);
404 if ($Config{ccflags}) {
405 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
407 @definc{@hidden} = (1) x @hidden;
410 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
411 map { split /\Q$Config{path_sep}/} @libpaths );
412 if ($Config{loclibpth}) {
413 push @libs, grep -d, split ' ', $Config{loclibpth};
416 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
417 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
418 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
419 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
421 if ($^O eq 'cygwin') {
422 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
423 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
425 if ($Config{ldflags}) {
426 # some builds of perl put -Ldir into ldflags without putting it in
427 # loclibpth, let's extract them
428 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
429 split ' ', $Config{ldflags};
431 # don't mark them as seen - EU::MM will remove any libraries
432 # it can't find and it doesn't look for -L in ldflags
433 #@deflib{@hidden} = @hidden;
435 push @libs, grep -d, qw(/usr/local/lib);
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->{lflags} = $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->{lflags} = $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";
832 # we don't set this on older EU::MM and it corrupts META.yml
833 # so don't generate it
834 return unless $opts->{AUTHOR};
840 version_from: $opts->{VERSION_FROM}
841 author: $opts->{AUTHOR}
842 abstract: $opts->{ABSTRACT}
845 if (keys %{$Recommends{$opts->{NAME}}}) {
846 $meta .= "recommends:\n";
847 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
848 $meta .= " $module: $version\n";
854 distribution_type: module
855 generated_by: $opts->{NAME} version $version
858 if (open META, "< META.yml") {
859 my $old_meta = do { local $/; <META> };
862 $save_meta = $old_meta ne $meta;
868 print "Updating META.yml\n";
869 open META, "> META.yml" or die "Cannot create META.yml: $!";
875 # this is intended to only be running on the development
879 # update Changes if needed
881 # get the last revision from Changes
882 if (open CHANGES, "< Changes") {
884 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
887 my ($revision) = grep s/^Revision: //, `svn info`
888 or die "Could not get Revision from svn";
891 $write_changes ||= $changes_rev != $revision;
897 if ($write_changes) {
898 print "Updating Changes file\n";
899 system 'svn log -v -r HEAD:943 >Changes';