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 render.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 rubthru.c scale.c' },
174 PREREQ_PM => { 'Test::More' => 0.47 },
177 # eval to prevent warnings about versions with _ in them
178 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
179 if ($MM_ver > 6.06) {
180 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
181 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
183 if ($MM_ver > 6.10) {
187 make_imconfig(\@defines);
189 if ($VERBOSE) { print Dumper(\%opts); }
190 mkdir('testout',0777); # since we cannot include it in the archive.
192 make_metafile(\%opts);
194 WriteMakefile(%opts);
201 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
204 my @ims = grep /\.im$/, keys %$mani;
206 dyntest.$(MYEXTLIB) : dynfilt/Makefile
207 cd dynfilt && $(MAKE) $(PASTHRU)
209 lib/Imager/Regops.pm : regmach.h regops.perl
210 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
212 imconfig.h : Makefile.PL
213 $(ECHO) "imconfig.h out-of-date with respect to $?"
214 $(PERLRUN) Makefile.PL
215 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
217 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
218 $perl apidocs.perl lib/Imager/APIRef.pod
220 !.join('', map _im_rule($perl, $_), @ims)
225 my ($perl, $im) = @_;
227 (my $c = $im) =~ s/\.im$/.c/;
231 $perl imtoc.perl $im $c
237 # manual configuration of helper libraries
242 Please answer the following questions about
243 which formats are avaliable on your computer
245 press <return> to continue
248 <STDIN>; # eat one return
250 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
252 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
253 print "Enable $frm support: ";
256 if ($gz =~ m/^(y|yes|n|no)/i) {
257 $gz=substr(lc($gz),0,1);
259 delete $formats{$frm};
266 # automatic configuration of helper libraries
269 print "Automatic probing:\n" if $VERBOSE;
270 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
271 delete $formats{$frm} if !checkformat($frm);
277 if ($formats{'gif'} and $formats{'ungif'}) {
278 print "ungif and gif can not coexist - removing ungif support\n";
279 delete $formats{'ungif'};
282 for my $frm (qw(gif ungif)) {
283 checkformat($frm) if ($MANUAL and $formats{$frm});
287 for my $frm (grep $formats{$_}, qw(gif ungif)) {
288 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
292 FILES: for my $dir (@dirs) {
293 my $h = "$dir/gif_lib.h";
294 open H, "< $h" or next;
296 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
306 # we need the version in a #ifdefable form
308 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
309 push @defines, [ IM_GIFMINOR => $minor ];
310 push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
311 if $no_gif_set_version;
318 # print "checking path $path\n";
319 if ( !opendir(DH,$path) ) {
320 warn "Cannot open dir $path: $!\n";
323 my @l=grep { $chk->($_) } readdir(DH);
326 return map $path, @l;
333 print " checkformat($frm)\n" if $VERBOSE;
335 my $code = $formats{$frm}{'code'};
336 if ($code && !$noprobe) {
337 print " Calling probe function\n" if $VERBOSE;
338 return 1 if $code->($formats{$frm}, $frm);
341 my $libchk=$formats{$frm}{'libcheck'};
342 my $incchk=$formats{$frm}{'inccheck'};
346 push(@l, gd($lp,$libchk));
351 push(@i, $ip) if $incchk->($ip,$frm);
354 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
355 $formats{$frm}{incdir} = \@i;
356 $formats{$frm}{libdir} = \@l;
357 return scalar(@i && @l);
364 print " Include paths:\n";
365 for (@incs) { print $_,"\n"; }
367 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
370 print "\nLibrary paths:\n";
371 for (@libs) { print $_,"\n"; }
373 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
378 # Format data initialization
380 # format definition is:
382 # default include path
383 # files needed for include (boolean perl code)
386 # files needed for link (boolean perl code)
387 # object files needed for the format
392 my @definc = qw(/usr/include);
393 @definc{@definc}=(1) x @definc;
394 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
395 map { split /\Q$Config{path_sep}/} @incpaths );
396 if ($Config{locincpth}) {
397 push @incs, grep -d, split ' ', $Config{locincpth};
399 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
400 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
402 if ($Config{incpath}) {
403 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
407 /usr/include/freetype2
408 /usr/local/include/freetype2
409 /usr/local/include/freetype1/freetype
410 /usr/include /usr/local/include /usr/include/freetype
411 /usr/local/include/freetype);
412 if ($Config{ccflags}) {
413 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
415 @definc{@hidden} = (1) x @hidden;
418 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
419 map { split /\Q$Config{path_sep}/} @libpaths );
420 if ($Config{loclibpth}) {
421 push @libs, grep -d, split ' ', $Config{loclibpth};
424 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
425 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
426 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
427 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
429 if ($^O eq 'cygwin') {
430 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
431 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
433 if ($Config{ldflags}) {
434 # some builds of perl put -Ldir into ldflags without putting it in
435 # loclibpth, let's extract them
436 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
437 split ' ', $Config{ldflags};
439 # don't mark them as seen - EU::MM will remove any libraries
440 # it can't find and it doesn't look for -L in ldflags
441 #@deflib{@hidden} = @hidden;
443 push @libs, grep -d, qw(/usr/local/lib);
448 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
449 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
453 In order to use jpeg with this module you need to have libjpeg
454 installed on your computer}
460 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
461 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
465 In order to use tiff with this module you need to have libtiff
466 installed on your computer}
472 inccheck=>sub { -e catfile($_[0], 'png.h') },
473 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
474 libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
477 Png stands for Portable Network Graphics and is intended as
478 a replacement for gif on the web. It is patent free and
479 is recommended by the w3c, you need libpng to use these formats},
486 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
487 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
491 gif is the de facto standard for webgraphics at the moment,
492 it does have some patent problems. If you have giflib and
493 are not in violation with the unisys patent you should use
494 this instead of the 'ungif' option. Note that they cannot
495 be in use at the same time}
501 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
502 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
506 gif is the de facto standard for webgraphics at the moment,
507 it does have some patent problems. If you have libungif and
508 want to create images free from LZW patented compression you
509 should use this option instead of the 'gif' option}
512 $formats{'T1-fonts'}={
515 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
516 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
520 postscript t1 fonts are scalable fonts. They can include
521 ligatures and kerning information and generally yield good
522 visual quality. We depend on libt1 to rasterize the fonts
526 $formats{'TT-fonts'}=
530 inccheck=>sub { -e catfile($_[0], 'freetype.h')
531 && !-e catfile($_[0], 'fterrors.h') },
532 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
535 code => \&freetype1_probe,
537 Truetype fonts are scalable fonts. They can include
538 kerning and hinting information and generally yield good
539 visual quality esp on low resultions. The freetype library is
540 used to rasterize for us. The only drawback is that there
541 are alot of badly designed fonts out there.}
546 inccheck=>sub { -e catfile($_[0], 'windows.h') },
547 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
548 || lc $_[0] eq 'libgdi32.a' },
549 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
552 Uses the Win32 GDI for rendering text.
554 This currently only works on under normal Win32 and cygwin.
557 $formats{'freetype2'} = {
560 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
561 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
562 libfiles=>'-lfreetype',
563 objfiles=>'freetyp2.o',
565 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
566 scalable. It also supports a variety of other fonts.
568 code => \&freetype2_probe,
572 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
579 defined($V) ? $V : "";
583 # Get information from environment variables
595 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
610 open CONFIG, "> imconfig.h"
611 or die "Cannot create imconfig.h: $!\n";
613 /* This file is automatically generated by Makefile.PL.
614 Don't edit this file, since any changes will be lost */
616 #ifndef IMAGER_IMCONFIG_H
617 #define IMAGER_IMCONFIG_H
619 for my $define (@$defines) {
621 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
623 print CONFIG "#define $define->[0] $define->[1]\n";
625 print CONFIG "\n#endif\n";
629 # use pkg-config to probe for libraries
630 # works around the junk that pkg-config dumps on FreeBSD
634 is_exe('pkg-config') or return;
636 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
638 !system("pkg-config $pkg --exists $redir");
641 # probes for freetype1 by scanning @incs for the includes and
642 # @libs for the libs. This is done separately because freetype's headers
643 # are stored in a freetype or freetype1 directory under PREFIX/include.
645 # we could find the files with the existing mechanism, but it won't set
646 # -I flags correctly.
648 # This could be extended to freetype2 too, but freetype-config catches
650 sub freetype1_probe {
651 my ($frm, $frmkey) = @_;
655 for my $inc (@incs) {
656 for my $subdir (qw/freetype freetype1/) {
657 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
659 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
662 $found_inc = File::Spec->catdir($inc, $subdir);
669 for my $lib (@libs) {
670 my $a_path = File::Spec->catfile($lib, "libttf$aext");
671 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
672 if (-e $a_path || -e $l_path) {
678 return unless $found_inc && $found_lib;
679 printf("%10s: includes %s - libraries %s\n", $frmkey,
680 ($found_inc ? 'found' : 'not found'),
681 ($found_lib ? 'found' : 'not found'));
683 $frm->{cflags} = "-I$found_inc";
684 $frm->{libfiles} = "-lttf";
689 # probes for freetype2 by trying to run freetype-config
690 sub freetype2_probe {
691 my ($frm, $frmkey) = @_;
693 is_exe('freetype-config') or return;
695 my $cflags = `freetype-config --cflags`
699 my $lflags = `freetype-config --libs`
703 # before 2.1.5 freetype-config --cflags could output
704 # the -I options in the wrong order, causing a conflict with
705 # freetype1.x installed with the same --prefix
708 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
710 # - freetype 1.x headers are in prefix/include/freetype
711 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
713 && $incdirs[1] eq "$incdirs[0]/freetype2"
714 && -e "$incdirs[0]/freetype/freetype.h"
715 && -e "$incdirs[0]/freetype/fterrid.h") {
716 print "** freetype-config provided -I options out of order, correcting\n"
718 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
719 map "-I$_", reverse @incdirs);
721 $frm->{cflags} = $cflags;
722 $frm->{lflags} = $lflags;
724 printf "%10s: configured via freetype-config\n", $frmkey;
729 # probes for libpng via pkg-config
731 my ($frm, $frmkey) = @_;
733 is_exe('pkg-config') or return;
736 for my $check_conf (qw(libpng libpng12 libpng10)) {
737 if (_pkg_probe($check_conf)) {
738 $config = $check_conf;
744 my $cflags = `pkg-config $config --cflags`
747 my $lflags = `pkg-config $config --libs`
752 $frm->{cflags} = $cflags;
753 $frm->{lflags} = $lflags;
755 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
761 return File::Spec->catfile(@_);
767 for my $dir (File::Spec->path) {
768 -x catfile($dir, "$name$Config{_exe}")
777 Usage: $0 [--enable feature1,feature2,...] [other options]
778 $0 [--disable feature1,feature2,...] [other options]
780 Possible feature names are:
781 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
784 Verbose library probing (or set IM_VERBOSE in the environment)
786 Disable logging (or set IM_NOLOG in the environment)
788 Add to the include search path
790 Add to the library search path
792 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
798 # generate the PM MM argument
799 # I'd prefer to modify the public version, but there doesn't seem to be
800 # a public API to do that
803 my $instbase = '$(INST_LIBDIR)';
805 # first the basics, .pm and .pod files
806 $pm{"Imager.pm"} = "$instbase/Imager.pm";
808 my $mani = maniread();
810 for my $filename (keys %$mani) {
811 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
812 (my $work = $filename) =~ s/^lib//;
813 $pm{$filename} = $instbase . $work;
818 $pm{typemap} = $instbase . '/Imager/typemap';
820 # and the core headers
821 for my $filename (keys %$mani) {
822 if ($filename =~ /^\w+\.h$/) {
823 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
827 # and the generated header
828 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
836 # extract the version
837 my $version = MM->parse_version($opts->{VERSION_FROM})
838 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
840 # we don't set this on older EU::MM and it corrupts META.yml
841 # so don't generate it
842 return unless $opts->{AUTHOR};
848 version_from: $opts->{VERSION_FROM}
849 author: $opts->{AUTHOR}
850 abstract: $opts->{ABSTRACT}
853 if (keys %{$Recommends{$opts->{NAME}}}) {
854 $meta .= "recommends:\n";
855 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
856 $meta .= " $module: $version\n";
859 if ($opts->{PREREQ_PM}) {
860 $meta .= "requires:\n";
861 while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) {
862 $meta .= " $module: $version\n";
868 distribution_type: module
871 url: http://module-build.sourceforge.net/META-spec-v1.3.html
872 generated_by: $opts->{NAME} version $version
875 if (open META, "< META.yml") {
876 my $old_meta = do { local $/; <META> };
879 $save_meta = $old_meta ne $meta;
885 print "Updating META.yml\n";
886 open META, "> META.yml" or die "Cannot create META.yml: $!";
892 # this is intended to only be running on the development
896 # update Changes if needed
898 # get the last revision from Changes
899 if (open CHANGES, "< Changes") {
901 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
904 my ($revision) = grep s/^Revision: //, `svn info`
905 or die "Could not get Revision from svn";
908 $write_changes ||= $changes_rev != $revision;
914 if ($write_changes) {
915 print "Updating Changes file\n";
916 system 'svn log -v -r HEAD:943 >Changes';