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 my $no_gif_set_version; # disable calling EGifSetGifVersion
42 GetOptions("help" => \$help,
43 "enable=s" => \@enable,
44 "disable=s" => \@disable,
45 "incpath=s", \@incpaths,
46 "libpath=s" => \@libpaths,
47 "noprobe" => \$noprobe,
48 "verbose|v" => \$VERBOSE,
51 "nogifsetversion" => \$no_gif_set_version);
54 print "Verbose mode\n";
56 import Data::Dumper qw(Dumper);
65 if ($NOLOG) { print "Logging not compiled into module\n"; }
67 push @defines, [ IMAGER_LOG => 1, "Logging system" ];
71 push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
72 print "Malloc debugging enabled\n";
75 if (@enable && @disable) {
76 print STDERR "Only --enable or --disable can be used, not both, try --help\n";
82 my @incs; # all the places to look for headers
83 my @libs; # all the places to look for libraries
85 init(); # initialize global data
86 pathcheck(); # Check if directories exist
87 distcheck(); # for building dists
89 if (exists $ENV{IM_ENABLE}) {
90 my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
91 for my $key (keys %formats) {
92 delete $formats{$key} unless $en{$key};
96 my %en = map { $_ => 1 } map { split /,/ } @enable;
97 for my $key (keys %formats) {
98 delete $formats{$key} unless $en{$key};
102 delete @formats{map { split /,/ } @disable};
105 # Pick what libraries are used
112 # Make sure there isn't a clash between the gif libraries.
119 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
120 my $frm = $formats{$frmkey};
121 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
122 $F_OBJECT .= ' ' .$frm->{objfiles};
123 if ($frm->{cflags}) {
124 $lib_cflags .= ' ' .$frm->{cflags};
125 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
126 grep /^-I./, split ' ', $frm->{cflags};
128 if ($frm->{lflags}) {
129 $lib_lflags .= ' ' . $frm->{lflags};
132 $F_LIBS .= ' ' .$frm->{libfiles};
138 print "EXIF support enabled\n";
139 push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
140 $F_OBJECT .= ' imexif.o';
143 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
144 grep !$definc{$_}, @incs;
145 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
146 grep !$deflib{$_}++, @libs) . $F_LIBS;
149 my $OSDEF = "-DOS_$^O";
151 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
152 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
154 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
155 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
156 filters.o dynaload.o stackmach.o datatypes.o
157 regmach.o trans2.o quant.o error.o convert.o
158 map.o tags.o palimg.o maskimg.o img16.o rotate.o
159 bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
160 imext.o scale.o rubthru.o);
162 $Recommends{Imager} =
163 { 'Parse::RecDescent' => 0 };
167 'VERSION_FROM' => 'Imager.pm',
168 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
169 'DEFINE' => "$OSDEF $CFLAGS",
170 'INC' => "$lib_cflags $DFLAGS $F_INC",
171 'OBJECT' => join(' ', @objs, $F_OBJECT),
172 clean => { FILES=>'testout meta.tmp' },
176 # eval to prevent warnings about versions with _ in them
177 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
178 if ($MM_ver > 6.06) {
179 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
180 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
182 if ($MM_ver > 6.10) {
186 make_imconfig(\@defines);
188 if ($VERBOSE) { print Dumper(\%opts); }
189 mkdir('testout',0777); # since we cannot include it in the archive.
191 make_metafile(\%opts);
193 WriteMakefile(%opts);
200 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
203 my @ims = grep /\.im$/, keys %$mani;
205 dyntest.$(MYEXTLIB) : dynfilt/Makefile
206 cd dynfilt && $(MAKE) $(PASTHRU)
208 lib/Imager/Regops.pm : regmach.h regops.perl
209 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
211 imconfig.h : Makefile.PL
212 $(ECHO) "imconfig.h out-of-date with respect to $?"
213 $(PERLRUN) Makefile.PL
214 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
216 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
217 $perl apidocs.perl lib/Imager/APIRef.pod
219 !.join('', map _im_rule($perl, $_), @ims)
224 my ($perl, $im) = @_;
226 (my $c = $im) =~ s/\.im$/.c/;
230 $perl imtoc.perl $im $c
236 # manual configuration of helper libraries
241 Please answer the following questions about
242 which formats are avaliable on your computer
244 press <return> to continue
247 <STDIN>; # eat one return
249 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
251 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
252 print "Enable $frm support: ";
255 if ($gz =~ m/^(y|yes|n|no)/i) {
256 $gz=substr(lc($gz),0,1);
258 delete $formats{$frm};
265 # automatic configuration of helper libraries
268 print "Automatic probing:\n" if $VERBOSE;
269 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
270 delete $formats{$frm} if !checkformat($frm);
276 if ($formats{'gif'} and $formats{'ungif'}) {
277 print "ungif and gif can not coexist - removing ungif support\n";
278 delete $formats{'ungif'};
281 for my $frm (qw(gif ungif)) {
282 checkformat($frm) if ($MANUAL and $formats{$frm});
286 for my $frm (grep $formats{$_}, qw(gif ungif)) {
287 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
291 FILES: for my $dir (@dirs) {
292 my $h = "$dir/gif_lib.h";
293 open H, "< $h" or next;
295 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
305 # we need the version in a #ifdefable form
307 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
308 push @defines, [ IM_GIFMINOR => $minor ];
309 push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
310 if $no_gif_set_version;
317 # print "checking path $path\n";
318 if ( !opendir(DH,$path) ) {
319 warn "Cannot open dir $path: $!\n";
322 my @l=grep { $chk->($_) } readdir(DH);
325 return map $path, @l;
332 print " checkformat($frm)\n" if $VERBOSE;
334 my $code = $formats{$frm}{'code'};
335 if ($code && !$noprobe) {
336 print " Calling probe function\n" if $VERBOSE;
337 return 1 if $code->($formats{$frm}, $frm);
340 my $libchk=$formats{$frm}{'libcheck'};
341 my $incchk=$formats{$frm}{'inccheck'};
345 push(@l, gd($lp,$libchk));
350 push(@i, $ip) if $incchk->($ip,$frm);
353 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
354 $formats{$frm}{incdir} = \@i;
355 $formats{$frm}{libdir} = \@l;
356 return scalar(@i && @l);
363 print " Include paths:\n";
364 for (@incs) { print $_,"\n"; }
366 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
369 print "\nLibrary paths:\n";
370 for (@libs) { print $_,"\n"; }
372 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
377 # Format data initialization
379 # format definition is:
381 # default include path
382 # files needed for include (boolean perl code)
385 # files needed for link (boolean perl code)
386 # object files needed for the format
391 my @definc = qw(/usr/include);
392 @definc{@definc}=(1) x @definc;
393 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
394 map { split /\Q$Config{path_sep}/} @incpaths );
395 if ($Config{locincpth}) {
396 push @incs, grep -d, split ' ', $Config{locincpth};
398 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
399 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
403 /usr/include/freetype2
404 /usr/local/include/freetype2
405 /usr/local/include/freetype1/freetype
406 /usr/include /usr/local/include /usr/include/freetype
407 /usr/local/include/freetype);
408 if ($Config{ccflags}) {
409 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
411 @definc{@hidden} = (1) x @hidden;
414 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
415 map { split /\Q$Config{path_sep}/} @libpaths );
416 if ($Config{loclibpth}) {
417 push @libs, grep -d, split ' ', $Config{loclibpth};
420 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
421 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
422 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
423 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
425 if ($^O eq 'cygwin') {
426 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
427 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
429 if ($Config{ldflags}) {
430 # some builds of perl put -Ldir into ldflags without putting it in
431 # loclibpth, let's extract them
432 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
433 split ' ', $Config{ldflags};
435 # don't mark them as seen - EU::MM will remove any libraries
436 # it can't find and it doesn't look for -L in ldflags
437 #@deflib{@hidden} = @hidden;
439 push @libs, grep -d, qw(/usr/local/lib);
444 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
445 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
449 In order to use jpeg with this module you need to have libjpeg
450 installed on your computer}
456 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
457 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
461 In order to use tiff with this module you need to have libtiff
462 installed on your computer}
468 inccheck=>sub { -e catfile($_[0], 'png.h') },
469 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
470 libfiles=>'-lpng -lz',
473 Png stands for Portable Network Graphics and is intended as
474 a replacement for gif on the web. It is patent free and
475 is recommended by the w3c, you need libpng to use these formats},
482 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
483 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
487 gif is the de facto standard for webgraphics at the moment,
488 it does have some patent problems. If you have giflib and
489 are not in violation with the unisys patent you should use
490 this instead of the 'ungif' option. Note that they cannot
491 be in use at the same time}
497 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
498 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
502 gif is the de facto standard for webgraphics at the moment,
503 it does have some patent problems. If you have libungif and
504 want to create images free from LZW patented compression you
505 should use this option instead of the 'gif' option}
508 $formats{'T1-fonts'}={
511 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
512 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
516 postscript t1 fonts are scalable fonts. They can include
517 ligatures and kerning information and generally yield good
518 visual quality. We depend on libt1 to rasterize the fonts
522 $formats{'TT-fonts'}=
526 inccheck=>sub { -e catfile($_[0], 'freetype.h')
527 && !-e catfile($_[0], 'fterrors.h') },
528 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
531 code => \&freetype1_probe,
533 Truetype fonts are scalable fonts. They can include
534 kerning and hinting information and generally yield good
535 visual quality esp on low resultions. The freetype library is
536 used to rasterize for us. The only drawback is that there
537 are alot of badly designed fonts out there.}
542 inccheck=>sub { -e catfile($_[0], 'windows.h') },
543 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
544 || lc $_[0] eq 'libgdi32.a' },
545 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
548 Uses the Win32 GDI for rendering text.
550 This currently only works on under normal Win32 and cygwin.
553 $formats{'freetype2'} = {
556 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
557 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
558 libfiles=>'-lfreetype',
559 objfiles=>'freetyp2.o',
561 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
562 scalable. It also supports a variety of other fonts.
564 code => \&freetype2_probe,
568 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
575 defined($V) ? $V : "";
579 # Get information from environment variables
591 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
606 open CONFIG, "> imconfig.h"
607 or die "Cannot create imconfig.h: $!\n";
609 /* This file is automatically generated by Makefile.PL.
610 Don't edit this file, since any changes will be lost */
612 #ifndef IMAGER_IMCONFIG_H
613 #define IMAGER_IMCONFIG_H
615 for my $define (@$defines) {
617 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
619 print CONFIG "#define $define->[0] $define->[1]\n";
621 print CONFIG "\n#endif\n";
625 # use pkg-config to probe for libraries
626 # works around the junk that pkg-config dumps on FreeBSD
630 is_exe('pkg-config') or return;
632 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
634 !system("pkg-config $pkg --exists $redir");
637 # probes for freetype1 by scanning @incs for the includes and
638 # @libs for the libs. This is done separately because freetype's headers
639 # are stored in a freetype or freetype1 directory under PREFIX/include.
641 # we could find the files with the existing mechanism, but it won't set
642 # -I flags correctly.
644 # This could be extended to freetype2 too, but freetype-config catches
646 sub freetype1_probe {
647 my ($frm, $frmkey) = @_;
651 for my $inc (@incs) {
652 for my $subdir (qw/freetype freetype1/) {
653 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
655 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
658 $found_inc = File::Spec->catdir($inc, $subdir);
665 for my $lib (@libs) {
666 my $a_path = File::Spec->catfile($lib, "libttf$aext");
667 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
668 if (-e $a_path || -e $l_path) {
674 return unless $found_inc && $found_lib;
675 printf("%10s: includes %s - libraries %s\n", $frmkey,
676 ($found_inc ? 'found' : 'not found'),
677 ($found_lib ? 'found' : 'not found'));
679 $frm->{cflags} = "-I$found_inc";
680 $frm->{libfiles} = "-lttf";
685 # probes for freetype2 by trying to run freetype-config
686 sub freetype2_probe {
687 my ($frm, $frmkey) = @_;
689 is_exe('freetype-config') or return;
691 my $cflags = `freetype-config --cflags`
695 my $lflags = `freetype-config --libs`
699 # before 2.1.5 freetype-config --cflags could output
700 # the -I options in the wrong order, causing a conflict with
701 # freetype1.x installed with the same --prefix
704 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
706 # - freetype 1.x headers are in prefix/include/freetype
707 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
709 && $incdirs[1] eq "$incdirs[0]/freetype2"
710 && -e "$incdirs[0]/freetype/freetype.h"
711 && -e "$incdirs[0]/freetype/fterrid.h") {
712 print "** freetype-config provided -I options out of order, correcting\n"
714 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
715 map "-I$_", reverse @incdirs);
717 $frm->{cflags} = $cflags;
718 $frm->{lflags} = $lflags;
720 printf "%10s: configured via freetype-config\n", $frmkey;
725 # probes for libpng via pkg-config
727 my ($frm, $frmkey) = @_;
729 is_exe('pkg-config') or return;
732 for my $check_conf (qw(libpng libpng12 libpng10)) {
733 if (_pkg_probe($check_conf)) {
734 $config = $check_conf;
740 my $cflags = `pkg-config $config --cflags`
743 my $lflags = `pkg-config $config --libs`
748 $frm->{cflags} = $cflags;
749 $frm->{lflags} = $lflags;
751 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
757 return File::Spec->catfile(@_);
763 for my $dir (File::Spec->path) {
764 -x catfile($dir, "$name$Config{_exe}")
773 Usage: $0 [--enable feature1,feature2,...] [other options]
774 $0 [--disable feature1,feature2,...] [other options]
776 Possible feature names are:
777 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
780 Verbose library probing (or set IM_VERBOSE in the environment)
782 Disable logging (or set IM_NOLOG in the environment)
784 Add to the include search path
786 Add to the library search path
788 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
794 # generate the PM MM argument
795 # I'd prefer to modify the public version, but there doesn't seem to be
796 # a public API to do that
799 my $instbase = '$(INST_LIBDIR)';
801 # first the basics, .pm and .pod files
802 $pm{"Imager.pm"} = "$instbase/Imager.pm";
804 my $mani = maniread();
806 for my $filename (keys %$mani) {
807 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
808 (my $work = $filename) =~ s/^lib//;
809 $pm{$filename} = $instbase . $work;
814 $pm{typemap} = $instbase . '/Imager/typemap';
816 # and the core headers
817 for my $filename (keys %$mani) {
818 if ($filename =~ /^\w+\.h$/) {
819 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
823 # and the generated header
824 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
832 # extract the version
833 my $version = MM->parse_version($opts->{VERSION_FROM})
834 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
836 # we don't set this on older EU::MM and it corrupts META.yml
837 # so don't generate it
838 return unless $opts->{AUTHOR};
844 version_from: $opts->{VERSION_FROM}
845 author: $opts->{AUTHOR}
846 abstract: $opts->{ABSTRACT}
849 if (keys %{$Recommends{$opts->{NAME}}}) {
850 $meta .= "recommends:\n";
851 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
852 $meta .= " $module: $version\n";
858 distribution_type: module
859 generated_by: $opts->{NAME} version $version
862 if (open META, "< META.yml") {
863 my $old_meta = do { local $/; <META> };
866 $save_meta = $old_meta ne $meta;
872 print "Updating META.yml\n";
873 open META, "> META.yml" or die "Cannot create META.yml: $!";
879 # this is intended to only be running on the development
883 # update Changes if needed
885 # get the last revision from Changes
886 if (open CHANGES, "< Changes") {
888 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
891 my ($revision) = grep s/^Revision: //, `svn info`
892 or die "Could not get Revision from svn";
895 $write_changes ||= $changes_rev != $revision;
901 if ($write_changes) {
902 print "Updating Changes file\n";
903 system 'svn log -v -r HEAD:943 >Changes';