3 use ExtUtils::MakeMaker;
8 use vars qw(%Recommends %BuildRequires);
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 };
164 $BuildRequires{Imager} =
165 { 'Test::More' => 0.47 };
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 => $BuildRequires{Imager},
179 # eval to prevent warnings about versions with _ in them
180 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
181 if ($MM_ver > 6.06) {
182 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
183 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
185 if ($MM_ver > 6.10) {
189 make_imconfig(\@defines);
191 if ($VERBOSE) { print Dumper(\%opts); }
192 mkdir('testout',0777); # since we cannot include it in the archive.
194 make_metafile(\%opts);
196 WriteMakefile(%opts);
203 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
206 my @ims = grep /\.im$/, keys %$mani;
208 dyntest.$(MYEXTLIB) : dynfilt/Makefile
209 cd dynfilt && $(MAKE) $(PASTHRU)
211 lib/Imager/Regops.pm : regmach.h regops.perl
212 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
214 imconfig.h : Makefile.PL
215 $(ECHO) "imconfig.h out-of-date with respect to $?"
216 $(PERLRUN) Makefile.PL
217 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
219 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
220 $perl apidocs.perl lib/Imager/APIRef.pod
222 !.join('', map _im_rule($perl, $_), @ims)
227 my ($perl, $im) = @_;
229 (my $c = $im) =~ s/\.im$/.c/;
233 $perl imtoc.perl $im $c
239 # manual configuration of helper libraries
244 Please answer the following questions about
245 which formats are avaliable on your computer
247 press <return> to continue
250 <STDIN>; # eat one return
252 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
254 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
255 print "Enable $frm support: ";
258 if ($gz =~ m/^(y|yes|n|no)/i) {
259 $gz=substr(lc($gz),0,1);
261 delete $formats{$frm};
268 # automatic configuration of helper libraries
271 print "Automatic probing:\n" if $VERBOSE;
272 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
273 delete $formats{$frm} if !checkformat($frm);
279 if ($formats{'gif'} and $formats{'ungif'}) {
280 print "ungif and gif can not coexist - removing ungif support\n";
281 delete $formats{'ungif'};
284 for my $frm (qw(gif ungif)) {
285 checkformat($frm) if ($MANUAL and $formats{$frm});
289 for my $frm (grep $formats{$_}, qw(gif ungif)) {
290 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
294 FILES: for my $dir (@dirs) {
295 my $h = "$dir/gif_lib.h";
296 open H, "< $h" or next;
298 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
308 # we need the version in a #ifdefable form
310 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
311 push @defines, [ IM_GIFMINOR => $minor ];
312 push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
313 if $no_gif_set_version;
320 # print "checking path $path\n";
321 if ( !opendir(DH,$path) ) {
322 warn "Cannot open dir $path: $!\n";
325 my @l=grep { $chk->($_) } readdir(DH);
328 return map $path, @l;
335 print " checkformat($frm)\n" if $VERBOSE;
337 my $code = $formats{$frm}{'code'};
338 if ($code && !$noprobe) {
339 print " Calling probe function\n" if $VERBOSE;
340 return 1 if $code->($formats{$frm}, $frm);
343 my $libchk=$formats{$frm}{'libcheck'};
344 my $incchk=$formats{$frm}{'inccheck'};
348 push(@l, gd($lp,$libchk));
353 push(@i, $ip) if $incchk->($ip,$frm);
356 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
357 $formats{$frm}{incdir} = \@i;
358 $formats{$frm}{libdir} = \@l;
359 return scalar(@i && @l);
366 print " Include paths:\n";
367 for (@incs) { print $_,"\n"; }
369 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
372 print "\nLibrary paths:\n";
373 for (@libs) { print $_,"\n"; }
375 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
380 # Format data initialization
382 # format definition is:
384 # default include path
385 # files needed for include (boolean perl code)
388 # files needed for link (boolean perl code)
389 # object files needed for the format
394 my @definc = qw(/usr/include);
395 @definc{@definc}=(1) x @definc;
396 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
397 map { split /\Q$Config{path_sep}/} @incpaths );
398 if ($Config{locincpth}) {
399 push @incs, grep -d, split ' ', $Config{locincpth};
401 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
402 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
406 /usr/include/freetype2
407 /usr/local/include/freetype2
408 /usr/local/include/freetype1/freetype
409 /usr/include /usr/local/include /usr/include/freetype
410 /usr/local/include/freetype);
411 if ($Config{ccflags}) {
412 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
414 @definc{@hidden} = (1) x @hidden;
417 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
418 map { split /\Q$Config{path_sep}/} @libpaths );
419 if ($Config{loclibpth}) {
420 push @libs, grep -d, split ' ', $Config{loclibpth};
423 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
424 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
425 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
426 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
428 if ($^O eq 'cygwin') {
429 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
430 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
432 if ($Config{ldflags}) {
433 # some builds of perl put -Ldir into ldflags without putting it in
434 # loclibpth, let's extract them
435 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
436 split ' ', $Config{ldflags};
438 # don't mark them as seen - EU::MM will remove any libraries
439 # it can't find and it doesn't look for -L in ldflags
440 #@deflib{@hidden} = @hidden;
442 push @libs, grep -d, qw(/usr/local/lib);
447 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
448 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
452 In order to use jpeg with this module you need to have libjpeg
453 installed on your computer}
459 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
460 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
464 In order to use tiff with this module you need to have libtiff
465 installed on your computer}
471 inccheck=>sub { -e catfile($_[0], 'png.h') },
472 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
473 libfiles=>'-lpng -lz',
476 Png stands for Portable Network Graphics and is intended as
477 a replacement for gif on the web. It is patent free and
478 is recommended by the w3c, you need libpng to use these formats},
485 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
486 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
490 gif is the de facto standard for webgraphics at the moment,
491 it does have some patent problems. If you have giflib and
492 are not in violation with the unisys patent you should use
493 this instead of the 'ungif' option. Note that they cannot
494 be in use at the same time}
500 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
501 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
505 gif is the de facto standard for webgraphics at the moment,
506 it does have some patent problems. If you have libungif and
507 want to create images free from LZW patented compression you
508 should use this option instead of the 'gif' option}
511 $formats{'T1-fonts'}={
514 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
515 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
519 postscript t1 fonts are scalable fonts. They can include
520 ligatures and kerning information and generally yield good
521 visual quality. We depend on libt1 to rasterize the fonts
525 $formats{'TT-fonts'}=
529 inccheck=>sub { -e catfile($_[0], 'freetype.h')
530 && !-e catfile($_[0], 'fterrors.h') },
531 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
534 code => \&freetype1_probe,
536 Truetype fonts are scalable fonts. They can include
537 kerning and hinting information and generally yield good
538 visual quality esp on low resultions. The freetype library is
539 used to rasterize for us. The only drawback is that there
540 are alot of badly designed fonts out there.}
545 inccheck=>sub { -e catfile($_[0], 'windows.h') },
546 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
547 || lc $_[0] eq 'libgdi32.a' },
548 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
551 Uses the Win32 GDI for rendering text.
553 This currently only works on under normal Win32 and cygwin.
556 $formats{'freetype2'} = {
559 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
560 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
561 libfiles=>'-lfreetype',
562 objfiles=>'freetyp2.o',
564 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
565 scalable. It also supports a variety of other fonts.
567 code => \&freetype2_probe,
571 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
578 defined($V) ? $V : "";
582 # Get information from environment variables
594 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
609 open CONFIG, "> imconfig.h"
610 or die "Cannot create imconfig.h: $!\n";
612 /* This file is automatically generated by Makefile.PL.
613 Don't edit this file, since any changes will be lost */
615 #ifndef IMAGER_IMCONFIG_H
616 #define IMAGER_IMCONFIG_H
618 for my $define (@$defines) {
620 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
622 print CONFIG "#define $define->[0] $define->[1]\n";
624 print CONFIG "\n#endif\n";
628 # use pkg-config to probe for libraries
629 # works around the junk that pkg-config dumps on FreeBSD
633 is_exe('pkg-config') or return;
635 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
637 !system("pkg-config $pkg --exists $redir");
640 # probes for freetype1 by scanning @incs for the includes and
641 # @libs for the libs. This is done separately because freetype's headers
642 # are stored in a freetype or freetype1 directory under PREFIX/include.
644 # we could find the files with the existing mechanism, but it won't set
645 # -I flags correctly.
647 # This could be extended to freetype2 too, but freetype-config catches
649 sub freetype1_probe {
650 my ($frm, $frmkey) = @_;
654 for my $inc (@incs) {
655 for my $subdir (qw/freetype freetype1/) {
656 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
658 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
661 $found_inc = File::Spec->catdir($inc, $subdir);
668 for my $lib (@libs) {
669 my $a_path = File::Spec->catfile($lib, "libttf$aext");
670 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
671 if (-e $a_path || -e $l_path) {
677 return unless $found_inc && $found_lib;
678 printf("%10s: includes %s - libraries %s\n", $frmkey,
679 ($found_inc ? 'found' : 'not found'),
680 ($found_lib ? 'found' : 'not found'));
682 $frm->{cflags} = "-I$found_inc";
683 $frm->{libfiles} = "-lttf";
688 # probes for freetype2 by trying to run freetype-config
689 sub freetype2_probe {
690 my ($frm, $frmkey) = @_;
692 is_exe('freetype-config') or return;
694 my $cflags = `freetype-config --cflags`
698 my $lflags = `freetype-config --libs`
702 # before 2.1.5 freetype-config --cflags could output
703 # the -I options in the wrong order, causing a conflict with
704 # freetype1.x installed with the same --prefix
707 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
709 # - freetype 1.x headers are in prefix/include/freetype
710 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
712 && $incdirs[1] eq "$incdirs[0]/freetype2"
713 && -e "$incdirs[0]/freetype/freetype.h"
714 && -e "$incdirs[0]/freetype/fterrid.h") {
715 print "** freetype-config provided -I options out of order, correcting\n"
717 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
718 map "-I$_", reverse @incdirs);
720 $frm->{cflags} = $cflags;
721 $frm->{lflags} = $lflags;
723 printf "%10s: configured via freetype-config\n", $frmkey;
728 # probes for libpng via pkg-config
730 my ($frm, $frmkey) = @_;
732 is_exe('pkg-config') or return;
735 for my $check_conf (qw(libpng libpng12 libpng10)) {
736 if (_pkg_probe($check_conf)) {
737 $config = $check_conf;
743 my $cflags = `pkg-config $config --cflags`
746 my $lflags = `pkg-config $config --libs`
751 $frm->{cflags} = $cflags;
752 $frm->{lflags} = $lflags;
754 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
760 return File::Spec->catfile(@_);
766 for my $dir (File::Spec->path) {
767 -x catfile($dir, "$name$Config{_exe}")
776 Usage: $0 [--enable feature1,feature2,...] [other options]
777 $0 [--disable feature1,feature2,...] [other options]
779 Possible feature names are:
780 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
783 Verbose library probing (or set IM_VERBOSE in the environment)
785 Disable logging (or set IM_NOLOG in the environment)
787 Add to the include search path
789 Add to the library search path
791 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
797 # generate the PM MM argument
798 # I'd prefer to modify the public version, but there doesn't seem to be
799 # a public API to do that
802 my $instbase = '$(INST_LIBDIR)';
804 # first the basics, .pm and .pod files
805 $pm{"Imager.pm"} = "$instbase/Imager.pm";
807 my $mani = maniread();
809 for my $filename (keys %$mani) {
810 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
811 (my $work = $filename) =~ s/^lib//;
812 $pm{$filename} = $instbase . $work;
817 $pm{typemap} = $instbase . '/Imager/typemap';
819 # and the core headers
820 for my $filename (keys %$mani) {
821 if ($filename =~ /^\w+\.h$/) {
822 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
826 # and the generated header
827 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
835 # extract the version
836 my $version = MM->parse_version($opts->{VERSION_FROM})
837 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
839 # we don't set this on older EU::MM and it corrupts META.yml
840 # so don't generate it
841 return unless $opts->{AUTHOR};
847 version_from: $opts->{VERSION_FROM}
848 author: $opts->{AUTHOR}
849 abstract: $opts->{ABSTRACT}
852 if (keys %{$Recommends{$opts->{NAME}}}) {
853 $meta .= "recommends:\n";
854 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
855 $meta .= " $module: $version\n";
858 if (keys %{$BuildRequires{$opts->{NAME}}}) {
859 $meta .= "build_requires:\n";
860 while (my ($module, $version) = each %{$BuildRequires{$opts->{NAME}}}) {
861 $meta .= " $module: $version\n";
867 distribution_type: module
868 generated_by: $opts->{NAME} version $version
871 if (open META, "< META.yml") {
872 my $old_meta = do { local $/; <META> };
875 $save_meta = $old_meta ne $meta;
881 print "Updating META.yml\n";
882 open META, "> META.yml" or die "Cannot create META.yml: $!";
888 # this is intended to only be running on the development
892 # update Changes if needed
894 # get the last revision from Changes
895 if (open CHANGES, "< Changes") {
897 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
900 my ($revision) = grep s/^Revision: //, `svn info`
901 or die "Could not get Revision from svn";
904 $write_changes ||= $changes_rev != $revision;
910 if ($write_changes) {
911 print "Updating Changes file\n";
912 system 'svn log -v -r HEAD:943 >Changes';