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
86 if (exists $ENV{IM_ENABLE}) {
87 my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
88 for my $key (keys %formats) {
89 delete $formats{$key} unless $en{$key};
93 my %en = map { $_ => 1 } map { split /,/ } @enable;
94 for my $key (keys %formats) {
95 delete $formats{$key} unless $en{$key};
99 delete @formats{map { split /,/ } @disable};
102 # Pick what libraries are used
109 # Make sure there isn't a clash between the gif libraries.
115 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
116 my $frm = $formats{$frmkey};
117 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
118 $F_LIBS .= ' ' .$frm->{libfiles};
119 $F_OBJECT .= ' ' .$frm->{objfiles};
120 if ($frm->{cflags}) {
121 $lib_cflags .= ' ' .$frm->{cflags};
122 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
123 grep /^-I./, split ' ', $frm->{cflags};
128 print "EXIF support enabled\n";
129 push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
130 $F_OBJECT .= ' imexif.o';
133 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
134 grep !$definc{$_}, @incs;
135 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
136 grep !$deflib{$_}++, @libs) . $F_LIBS;
139 my $OSDEF = "-DOS_$^O";
141 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
142 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
144 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
145 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
146 filters.o dynaload.o stackmach.o datatypes.o
147 regmach.o trans2.o quant.o error.o convert.o
148 map.o tags.o palimg.o maskimg.o img16.o rotate.o
149 bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
152 $Recommends{Imager} =
153 { 'Parse::RecDescent' => 0 };
157 'VERSION_FROM' => 'Imager.pm',
158 'LIBS' => "$LFLAGS -lm $OSLIBS $F_LIBS",
159 'DEFINE' => "$OSDEF $CFLAGS",
160 'INC' => "$lib_cflags $DFLAGS $F_INC",
161 'OBJECT' => join(' ', @objs, $F_OBJECT),
162 clean => { FILES=>'testout meta.tmp' },
166 if ($ExtUtils::MakeMaker::VERSION > 6.06) {
167 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
168 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
170 if ($ExtUtils::MakeMaker::VERSION > 6.10) {
174 make_imconfig(\@defines);
176 if ($VERBOSE) { print Dumper(\%opts); }
177 mkdir('testout',0777); # since we cannot include it in the archive.
179 make_metafile(\%opts);
181 WriteMakefile(%opts);
188 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
190 dyntest.$(MYEXTLIB) : dynfilt/Makefile
191 cd dynfilt && $(MAKE) $(PASTHRU)
193 lib/Imager/Regops.pm : regmach.h regops.perl
194 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
196 imconfig.h : Makefile.PL
197 $(ECHO) "imconfig.h out-of-date with respect to $?"
198 $(PERLRUN) Makefile.PL
199 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
201 lib/Imager/APIRef.pm : \$(C_FILES) apidocs.perl
202 $perl apidocs.perl lib/Imager/APIRef.pm
208 # manual configuration of helper libraries
213 Please answer the following questions about
214 which formats are avaliable on your computer
216 press <return> to continue
219 <STDIN>; # eat one return
221 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
223 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
224 print "Enable $frm support: ";
227 if ($gz =~ m/^(y|yes|n|no)/i) {
228 $gz=substr(lc($gz),0,1);
230 delete $formats{$frm};
237 # automatic configuration of helper libraries
240 print "Automatic probing:\n" if $VERBOSE;
241 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
242 delete $formats{$frm} if !checkformat($frm);
248 if ($formats{'gif'} and $formats{'ungif'}) {
249 print "ungif and gif can not coexist - removing ungif support\n";
250 delete $formats{'ungif'};
254 if (($formats{'gif'} or $formats{'ungif'}) && !$ENV{IM_SUPPRESS_PROMPT}) {
257 You have libgif or libungif installed. They are both known to have
258 bugs. Imager can crash or display other strange behaviour after
259 reading or writing gif images. Some of the gif tests can even fail
260 since they stress some parts of the buggy code.
262 libungif 4.1.2 and later is safe. giflib 4.1.3 needs at least one
263 patch to have all the bugs fixed, see README for details.
265 Of course it's possible your operating system distributor has patched
266 all of these problems and you have nothing to worry about.
268 Do you want to remove gif support? [Y/n]
273 delete $formats{'gif'};
274 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;
439 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
440 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
444 In order to use jpeg with this module you need to have libjpeg
445 installed on your computer}
451 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
452 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
456 In order to use tiff with this module you need to have libtiff
457 installed on your computer}
463 inccheck=>sub { -e catfile($_[0], 'png.h') },
464 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
465 libfiles=>'-lpng -lz',
468 Png stands for Portable Network Graphics and is intended as
469 a replacement for gif on the web. It is patent free and
470 is recommended by the w3c, you need libpng to use these formats},
477 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
478 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
482 gif is the de facto standard for webgraphics at the moment,
483 it does have some patent problems. If you have giflib and
484 are not in violation with the unisys patent you should use
485 this instead of the 'ungif' option. Note that they cannot
486 be in use at the same time}
492 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
493 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
497 gif is the de facto standard for webgraphics at the moment,
498 it does have some patent problems. If you have libungif and
499 want to create images free from LZW patented compression you
500 should use this option instead of the 'gif' option}
503 $formats{'T1-fonts'}={
506 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
507 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
511 postscript t1 fonts are scalable fonts. They can include
512 ligatures and kerning information and generally yield good
513 visual quality. We depend on libt1 to rasterize the fonts
517 $formats{'TT-fonts'}=
521 inccheck=>sub { -e catfile($_[0], 'freetype.h')
522 && !-e catfile($_[0], 'fterrors.h') },
523 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
526 code => \&freetype1_probe,
528 Truetype fonts are scalable fonts. They can include
529 kerning and hinting information and generally yield good
530 visual quality esp on low resultions. The freetype library is
531 used to rasterize for us. The only drawback is that there
532 are alot of badly designed fonts out there.}
537 inccheck=>sub { -e catfile($_[0], 'windows.h') },
538 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
539 || lc $_[0] eq 'libgdi32.a' },
540 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
543 Uses the Win32 GDI for rendering text.
545 This currently only works on under normal Win32 and cygwin.
548 $formats{'freetype2'} = {
551 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
552 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
553 libfiles=>'-lfreetype',
554 objfiles=>'freetyp2.o',
556 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
557 scalable. It also supports a variety of other fonts.
559 code => \&freetype2_probe,
563 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
570 defined($V) ? $V : "";
574 # Get information from environment variables
586 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
601 open CONFIG, "> imconfig.h"
602 or die "Cannot create imconfig.h: $!\n";
604 /* This file is automatically generated by Makefile.PL.
605 Don't edit this file, since any changes will be lost */
607 #ifndef IMAGER_IMCONFIG_H
608 #define IMAGER_IMCONFIG_H
610 for my $define (@$defines) {
612 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
614 print CONFIG "#define $define->[0] $define->[1]\n";
616 print CONFIG "\n#endif\n";
620 # use pkg-config to probe for libraries
621 # works around the junk that pkg-config dumps on FreeBSD
625 is_exe('pkg-config') or return;
627 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
629 !system("pkg-config $pkg --exists $redir");
632 # probes for freetype1 by scanning @incs for the includes and
633 # @libs for the libs. This is done separately because freetype's headers
634 # are stored in a freetype or freetype1 directory under PREFIX/include.
636 # we could find the files with the existing mechanism, but it won't set
637 # -I flags correctly.
639 # This could be extended to freetype2 too, but freetype-config catches
641 sub freetype1_probe {
642 my ($frm, $frmkey) = @_;
646 for my $inc (@incs) {
647 for my $subdir (qw/freetype freetype1/) {
648 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
650 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
653 $found_inc = File::Spec->catdir($inc, $subdir);
660 for my $lib (@libs) {
661 my $a_path = File::Spec->catfile($lib, "libttf$aext");
662 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
663 if (-e $a_path || -e $l_path) {
669 return unless $found_inc && $found_lib;
670 printf("%10s: includes %s - libraries %s\n", $frmkey,
671 ($found_inc ? 'found' : 'not found'),
672 ($found_lib ? 'found' : 'not found'));
674 $frm->{cflags} = "-I$found_inc";
675 $frm->{libfiles} = "-lttf";
680 # probes for freetype2 by trying to run freetype-config
681 sub freetype2_probe {
682 my ($frm, $frmkey) = @_;
684 is_exe('freetype-config') or return;
686 my $cflags = `freetype-config --cflags`
690 my $lflags = `freetype-config --libs`
694 # before 2.1.5 freetype-config --cflags could output
695 # the -I options in the wrong order, causing a conflict with
696 # freetype1.x installed with the same --prefix
699 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
701 # - freetype 1.x headers are in prefix/include/freetype
702 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
704 && $incdirs[1] eq "$incdirs[0]/freetype2"
705 && -e "$incdirs[0]/freetype/freetype.h"
706 && -e "$incdirs[0]/freetype/fterrid.h") {
707 print "** freetype-config provided -I options out of order, correcting\n"
709 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
710 map "-I$_", reverse @incdirs);
712 $frm->{cflags} = $cflags;
713 $frm->{libfiles} = $lflags;
715 printf "%10s: configured via freetype-config\n", $frmkey;
720 # probes for libpng via pkg-config
722 my ($frm, $frmkey) = @_;
724 is_exe('pkg-config') or return;
727 for my $check_conf (qw(libpng libpng12 libpng10)) {
728 if (_pkg_probe($check_conf)) {
729 $config = $check_conf;
735 my $cflags = `pkg-config $config --cflags`
738 my $lflags = `pkg-config $config --libs`
743 $frm->{cflags} = $cflags;
744 $frm->{libfiles} = $lflags;
746 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
752 return File::Spec->catfile(@_);
758 for my $dir (File::Spec->path) {
759 -x catfile($dir, "$name$Config{_exe}")
768 Usage: $0 [--enable feature1,feature2,...] [other options]
769 $0 [--disable feature1,feature2,...] [other options]
771 Possible feature names are:
772 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
775 Verbose library probing (or set IM_VERBOSE in the environment)
777 Disable logging (or set IM_NOLOG in the environment)
779 Add to the include search path
781 Add to the library search path
783 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
789 # generate the PM MM argument
790 # I'd prefer to modify the public version, but there doesn't seem to be
791 # a public API to do that
794 my $instbase = '$(INST_LIBDIR)';
796 # first the basics, .pm and .pod files
797 $pm{"Imager.pm"} = "$instbase/Imager.pm";
799 my $mani = maniread();
801 for my $filename (keys %$mani) {
802 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
803 (my $work = $filename) =~ s/^lib//;
804 $pm{$filename} = $instbase . $work;
809 $pm{typemap} = $instbase . '/Imager/typemap';
811 # and the core headers
812 for my $filename (keys %$mani) {
813 if ($filename =~ /^\w+\.h$/) {
814 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
818 # and the generated header
819 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
827 # extract the version
828 my $version = MM->parse_version($opts->{VERSION_FROM})
829 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
835 version_from: $opts->{VERSION_FROM}
836 author: $opts->{AUTHOR}
837 abstract: $opts->{ABSTRACT}
840 if (keys %{$Recommends{$opts->{NAME}}}) {
841 $meta .= "recommends:\n";
842 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
843 $meta .= " $module: $version\n";
849 distribution_type: module
850 generated_by: $opts->{NAME} version $version
853 if (open META, "< META.yml") {
854 my $old_meta = do { local $/; <META> };
857 $save_meta = $old_meta ne $meta;
863 print "Updating META.yml\n";
864 open META, "> META.yml" or die "Cannot create META.yml: $!";