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 my $coverage; # build for coverage testing
43 GetOptions("help" => \$help,
44 "enable=s" => \@enable,
45 "disable=s" => \@disable,
46 "incpath=s", \@incpaths,
47 "libpath=s" => \@libpaths,
48 "noprobe" => \$noprobe,
49 "verbose|v" => \$VERBOSE,
52 "nogifsetversion" => \$no_gif_set_version,
53 'coverage' => \$coverage);
56 print "Verbose mode\n";
58 import Data::Dumper qw(Dumper);
67 if ($NOLOG) { print "Logging not compiled into module\n"; }
69 push @defines, [ IMAGER_LOG => 1, "Logging system" ];
73 push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
74 print "Malloc debugging enabled\n";
77 if (@enable && @disable) {
78 print STDERR "Only --enable or --disable can be used, not both, try --help\n";
84 my @incs; # all the places to look for headers
85 my @libs; # all the places to look for libraries
87 init(); # initialize global data
88 pathcheck(); # Check if directories exist
89 distcheck(); # for building dists
91 if (exists $ENV{IM_ENABLE}) {
92 my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
93 for my $key (keys %formats) {
94 delete $formats{$key} unless $en{$key};
98 my %en = map { $_ => 1 } map { split /,/ } @enable;
99 for my $key (keys %formats) {
100 delete $formats{$key} unless $en{$key};
104 delete @formats{map { split /,/ } @disable};
107 # Pick what libraries are used
114 # Make sure there isn't a clash between the gif libraries.
121 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
122 my $frm = $formats{$frmkey};
123 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
124 $F_OBJECT .= ' ' .$frm->{objfiles};
125 if ($frm->{cflags}) {
126 $lib_cflags .= ' ' .$frm->{cflags};
127 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
128 grep /^-I./, split ' ', $frm->{cflags};
130 if ($frm->{lflags}) {
131 $lib_lflags .= ' ' . $frm->{lflags};
134 $F_LIBS .= ' ' .$frm->{libfiles};
140 print "EXIF support enabled\n";
141 push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
142 $F_OBJECT .= ' imexif.o';
145 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
146 grep !$definc{$_}, @incs;
147 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
148 grep !$deflib{$_}++, @libs) . $F_LIBS;
151 my $OSDEF = "-DOS_$^O";
153 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
154 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
156 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
157 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
158 filters.o dynaload.o stackmach.o datatypes.o
159 regmach.o trans2.o quant.o error.o convert.o
160 map.o tags.o palimg.o maskimg.o img16.o rotate.o
161 bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
162 imext.o scale.o rubthru.o render.o);
164 $Recommends{Imager} =
165 { 'Parse::RecDescent' => 0 };
169 'VERSION_FROM' => 'Imager.pm',
170 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
171 'DEFINE' => "$OSDEF $CFLAGS",
172 'INC' => "$lib_cflags $DFLAGS $F_INC",
173 'OBJECT' => join(' ', @objs, $F_OBJECT),
174 clean => { FILES=>'testout meta.tmp rubthru.c scale.c' },
176 PREREQ_PM => { 'Test::More' => 0.47 },
180 if ($Config{gccversion}) {
181 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs';
182 #$opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
185 die "Don't know the coverage C flags for your compiler\n";
189 # eval to prevent warnings about versions with _ in them
190 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
191 if ($MM_ver > 6.06) {
192 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
193 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
195 if ($MM_ver > 6.10) {
199 make_imconfig(\@defines);
201 if ($VERBOSE) { print Dumper(\%opts); }
202 mkdir('testout',0777); # since we cannot include it in the archive.
204 make_metafile(\%opts);
206 WriteMakefile(%opts);
213 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
216 my @ims = grep /\.im$/, keys %$mani;
218 dyntest.$(MYEXTLIB) : dynfilt/Makefile
219 cd dynfilt && $(MAKE) $(PASTHRU)
221 lib/Imager/Regops.pm : regmach.h regops.perl
222 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
224 imconfig.h : Makefile.PL
225 $(ECHO) "imconfig.h out-of-date with respect to $?"
226 $(PERLRUN) Makefile.PL
227 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
229 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
230 $perl apidocs.perl lib/Imager/APIRef.pod
232 !.join('', map _im_rule($perl, $_), @ims)
237 my ($perl, $im) = @_;
239 (my $c = $im) =~ s/\.im$/.c/;
243 $perl imtoc.perl $im $c
249 # manual configuration of helper libraries
254 Please answer the following questions about
255 which formats are avaliable on your computer
257 press <return> to continue
260 <STDIN>; # eat one return
262 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
264 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
265 print "Enable $frm support: ";
268 if ($gz =~ m/^(y|yes|n|no)/i) {
269 $gz=substr(lc($gz),0,1);
271 delete $formats{$frm};
278 # automatic configuration of helper libraries
281 print "Automatic probing:\n" if $VERBOSE;
282 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
283 delete $formats{$frm} if !checkformat($frm);
289 if ($formats{'gif'} and $formats{'ungif'}) {
290 print "ungif and gif can not coexist - removing ungif support\n";
291 delete $formats{'ungif'};
294 for my $frm (qw(gif ungif)) {
295 checkformat($frm) if ($MANUAL and $formats{$frm});
299 for my $frm (grep $formats{$_}, qw(gif ungif)) {
300 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
304 FILES: for my $dir (@dirs) {
305 my $h = "$dir/gif_lib.h";
306 open H, "< $h" or next;
308 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
318 # we need the version in a #ifdefable form
320 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
321 push @defines, [ IM_GIFMINOR => $minor ];
322 push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
323 if $no_gif_set_version;
330 # print "checking path $path\n";
331 if ( !opendir(DH,$path) ) {
332 warn "Cannot open dir $path: $!\n";
335 my @l=grep { $chk->($_) } readdir(DH);
338 return map $path, @l;
345 print " checkformat($frm)\n" if $VERBOSE;
347 my $code = $formats{$frm}{'code'};
348 if ($code && !$noprobe) {
349 print " Calling probe function\n" if $VERBOSE;
350 return 1 if $code->($formats{$frm}, $frm);
353 my $libchk=$formats{$frm}{'libcheck'};
354 my $incchk=$formats{$frm}{'inccheck'};
358 push(@l, gd($lp,$libchk));
363 push(@i, $ip) if $incchk->($ip,$frm);
366 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
367 $formats{$frm}{incdir} = \@i;
368 $formats{$frm}{libdir} = \@l;
369 return scalar(@i && @l);
376 print " Include paths:\n";
377 for (@incs) { print $_,"\n"; }
379 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
382 print "\nLibrary paths:\n";
383 for (@libs) { print $_,"\n"; }
385 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
390 # Format data initialization
392 # format definition is:
394 # default include path
395 # files needed for include (boolean perl code)
398 # files needed for link (boolean perl code)
399 # object files needed for the format
404 my @definc = qw(/usr/include);
405 @definc{@definc}=(1) x @definc;
406 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
407 map { split /\Q$Config{path_sep}/} @incpaths );
408 if ($Config{locincpth}) {
409 push @incs, grep -d, split ' ', $Config{locincpth};
411 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
412 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
414 if ($Config{incpath}) {
415 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
419 /usr/include/freetype2
420 /usr/local/include/freetype2
421 /usr/local/include/freetype1/freetype
422 /usr/include /usr/local/include /usr/include/freetype
423 /usr/local/include/freetype);
424 if ($Config{ccflags}) {
425 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
427 @definc{@hidden} = (1) x @hidden;
430 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
431 map { split /\Q$Config{path_sep}/} @libpaths );
432 if ($Config{loclibpth}) {
433 push @libs, grep -d, split ' ', $Config{loclibpth};
436 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
437 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
438 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
439 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
441 if ($^O eq 'cygwin') {
442 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
443 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
445 if ($Config{ldflags}) {
446 # some builds of perl put -Ldir into ldflags without putting it in
447 # loclibpth, let's extract them
448 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
449 split ' ', $Config{ldflags};
451 # don't mark them as seen - EU::MM will remove any libraries
452 # it can't find and it doesn't look for -L in ldflags
453 #@deflib{@hidden} = @hidden;
455 push @libs, grep -d, qw(/usr/local/lib);
460 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
461 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
465 In order to use jpeg with this module you need to have libjpeg
466 installed on your computer}
472 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
473 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
477 In order to use tiff with this module you need to have libtiff
478 installed on your computer}
484 inccheck=>sub { -e catfile($_[0], 'png.h') },
485 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
486 libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
489 Png stands for Portable Network Graphics and is intended as
490 a replacement for gif on the web. It is patent free and
491 is recommended by the w3c, you need libpng to use these formats},
498 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
499 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
503 gif is the de facto standard for webgraphics at the moment,
504 it does have some patent problems. If you have giflib and
505 are not in violation with the unisys patent you should use
506 this instead of the 'ungif' option. Note that they cannot
507 be in use at the same time}
513 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
514 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
518 gif is the de facto standard for webgraphics at the moment,
519 it does have some patent problems. If you have libungif and
520 want to create images free from LZW patented compression you
521 should use this option instead of the 'gif' option}
524 $formats{'T1-fonts'}={
527 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
528 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
532 postscript t1 fonts are scalable fonts. They can include
533 ligatures and kerning information and generally yield good
534 visual quality. We depend on libt1 to rasterize the fonts
538 $formats{'TT-fonts'}=
542 inccheck=>sub { -e catfile($_[0], 'freetype.h')
543 && !-e catfile($_[0], 'fterrors.h') },
544 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
547 code => \&freetype1_probe,
549 Truetype fonts are scalable fonts. They can include
550 kerning and hinting information and generally yield good
551 visual quality esp on low resultions. The freetype library is
552 used to rasterize for us. The only drawback is that there
553 are alot of badly designed fonts out there.}
558 inccheck=>sub { -e catfile($_[0], 'windows.h') },
559 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
560 || lc $_[0] eq 'libgdi32.a' },
561 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
564 Uses the Win32 GDI for rendering text.
566 This currently only works on under normal Win32 and cygwin.
569 $formats{'freetype2'} = {
572 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
573 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
574 libfiles=>'-lfreetype',
575 objfiles=>'freetyp2.o',
577 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
578 scalable. It also supports a variety of other fonts.
580 code => \&freetype2_probe,
584 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
591 defined($V) ? $V : "";
595 # Get information from environment variables
607 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
622 open CONFIG, "> imconfig.h"
623 or die "Cannot create imconfig.h: $!\n";
625 /* This file is automatically generated by Makefile.PL.
626 Don't edit this file, since any changes will be lost */
628 #ifndef IMAGER_IMCONFIG_H
629 #define IMAGER_IMCONFIG_H
631 for my $define (@$defines) {
633 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
635 print CONFIG "#define $define->[0] $define->[1]\n";
637 print CONFIG "\n#endif\n";
641 # use pkg-config to probe for libraries
642 # works around the junk that pkg-config dumps on FreeBSD
646 is_exe('pkg-config') or return;
648 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
650 !system("pkg-config $pkg --exists $redir");
653 # probes for freetype1 by scanning @incs for the includes and
654 # @libs for the libs. This is done separately because freetype's headers
655 # are stored in a freetype or freetype1 directory under PREFIX/include.
657 # we could find the files with the existing mechanism, but it won't set
658 # -I flags correctly.
660 # This could be extended to freetype2 too, but freetype-config catches
662 sub freetype1_probe {
663 my ($frm, $frmkey) = @_;
667 for my $inc (@incs) {
668 for my $subdir (qw/freetype freetype1/) {
669 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
671 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
674 $found_inc = File::Spec->catdir($inc, $subdir);
681 for my $lib (@libs) {
682 my $a_path = File::Spec->catfile($lib, "libttf$aext");
683 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
684 if (-e $a_path || -e $l_path) {
690 return unless $found_inc && $found_lib;
691 printf("%10s: includes %s - libraries %s\n", $frmkey,
692 ($found_inc ? 'found' : 'not found'),
693 ($found_lib ? 'found' : 'not found'));
695 $frm->{cflags} = "-I$found_inc";
696 $frm->{libfiles} = "-lttf";
701 # probes for freetype2 by trying to run freetype-config
702 sub freetype2_probe {
703 my ($frm, $frmkey) = @_;
705 is_exe('freetype-config') or return;
707 my $cflags = `freetype-config --cflags`
711 my $lflags = `freetype-config --libs`
715 # before 2.1.5 freetype-config --cflags could output
716 # the -I options in the wrong order, causing a conflict with
717 # freetype1.x installed with the same --prefix
720 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
722 # - freetype 1.x headers are in prefix/include/freetype
723 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
725 && $incdirs[1] eq "$incdirs[0]/freetype2"
726 && -e "$incdirs[0]/freetype/freetype.h"
727 && -e "$incdirs[0]/freetype/fterrid.h") {
728 print "** freetype-config provided -I options out of order, correcting\n"
730 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
731 map "-I$_", reverse @incdirs);
733 $frm->{cflags} = $cflags;
734 $frm->{lflags} = $lflags;
736 printf "%10s: configured via freetype-config\n", $frmkey;
741 # probes for libpng via pkg-config
743 my ($frm, $frmkey) = @_;
745 is_exe('pkg-config') or return;
748 for my $check_conf (qw(libpng libpng12 libpng10)) {
749 if (_pkg_probe($check_conf)) {
750 $config = $check_conf;
756 my $cflags = `pkg-config $config --cflags`
759 my $lflags = `pkg-config $config --libs`
764 $frm->{cflags} = $cflags;
765 $frm->{lflags} = $lflags;
767 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
773 return File::Spec->catfile(@_);
779 for my $dir (File::Spec->path) {
780 -x catfile($dir, "$name$Config{_exe}")
789 Usage: $0 [--enable feature1,feature2,...] [other options]
790 $0 [--disable feature1,feature2,...] [other options]
792 Possible feature names are:
793 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
796 Verbose library probing (or set IM_VERBOSE in the environment)
798 Disable logging (or set IM_NOLOG in the environment)
800 Add to the include search path
802 Add to the library search path
804 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
810 # generate the PM MM argument
811 # I'd prefer to modify the public version, but there doesn't seem to be
812 # a public API to do that
815 my $instbase = '$(INST_LIBDIR)';
817 # first the basics, .pm and .pod files
818 $pm{"Imager.pm"} = "$instbase/Imager.pm";
820 my $mani = maniread();
822 for my $filename (keys %$mani) {
823 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
824 (my $work = $filename) =~ s/^lib//;
825 $pm{$filename} = $instbase . $work;
830 $pm{typemap} = $instbase . '/Imager/typemap';
832 # and the core headers
833 for my $filename (keys %$mani) {
834 if ($filename =~ /^\w+\.h$/) {
835 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
839 # and the generated header
840 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
848 # extract the version
849 my $version = MM->parse_version($opts->{VERSION_FROM})
850 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
852 # we don't set this on older EU::MM and it corrupts META.yml
853 # so don't generate it
854 return unless $opts->{AUTHOR};
860 version_from: $opts->{VERSION_FROM}
861 author: $opts->{AUTHOR}
862 abstract: $opts->{ABSTRACT}
865 if (keys %{$Recommends{$opts->{NAME}}}) {
866 $meta .= "recommends:\n";
867 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
868 $meta .= " $module: $version\n";
871 if ($opts->{PREREQ_PM}) {
872 $meta .= "requires:\n";
873 while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) {
874 $meta .= " $module: $version\n";
880 distribution_type: module
883 url: http://module-build.sourceforge.net/META-spec-v1.3.html
884 generated_by: $opts->{NAME} version $version
887 if (open META, "< META.yml") {
888 my $old_meta = do { local $/; <META> };
891 $save_meta = $old_meta ne $meta;
897 print "Updating META.yml\n";
898 open META, "> META.yml" or die "Cannot create META.yml: $!";
904 # this is intended to only be running on the development
908 # update Changes if needed
910 # get the last revision from Changes
911 if (open CHANGES, "< Changes") {
913 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
916 my ($revision) = grep s/^Revision: //, `svn info`
917 or die "Could not get Revision from svn";
920 $write_changes ||= $changes_rev != $revision;
926 if ($write_changes) {
927 print "Updating Changes file\n";
928 system 'svn log -v -r HEAD:943 >Changes';