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 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};
404 /usr/include/freetype2
405 /usr/local/include/freetype2
406 /usr/local/include/freetype1/freetype
407 /usr/include /usr/local/include /usr/include/freetype
408 /usr/local/include/freetype);
409 if ($Config{ccflags}) {
410 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
412 @definc{@hidden} = (1) x @hidden;
415 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
416 map { split /\Q$Config{path_sep}/} @libpaths );
417 if ($Config{loclibpth}) {
418 push @libs, grep -d, split ' ', $Config{loclibpth};
421 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
422 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
423 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
424 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
426 if ($^O eq 'cygwin') {
427 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
428 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
430 if ($Config{ldflags}) {
431 # some builds of perl put -Ldir into ldflags without putting it in
432 # loclibpth, let's extract them
433 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
434 split ' ', $Config{ldflags};
436 # don't mark them as seen - EU::MM will remove any libraries
437 # it can't find and it doesn't look for -L in ldflags
438 #@deflib{@hidden} = @hidden;
440 push @libs, grep -d, qw(/usr/local/lib);
445 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
446 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
450 In order to use jpeg with this module you need to have libjpeg
451 installed on your computer}
457 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
458 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
462 In order to use tiff with this module you need to have libtiff
463 installed on your computer}
469 inccheck=>sub { -e catfile($_[0], 'png.h') },
470 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
471 libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
474 Png stands for Portable Network Graphics and is intended as
475 a replacement for gif on the web. It is patent free and
476 is recommended by the w3c, you need libpng to use these formats},
483 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
484 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
488 gif is the de facto standard for webgraphics at the moment,
489 it does have some patent problems. If you have giflib and
490 are not in violation with the unisys patent you should use
491 this instead of the 'ungif' option. Note that they cannot
492 be in use at the same time}
498 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
499 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
503 gif is the de facto standard for webgraphics at the moment,
504 it does have some patent problems. If you have libungif and
505 want to create images free from LZW patented compression you
506 should use this option instead of the 'gif' option}
509 $formats{'T1-fonts'}={
512 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
513 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
517 postscript t1 fonts are scalable fonts. They can include
518 ligatures and kerning information and generally yield good
519 visual quality. We depend on libt1 to rasterize the fonts
523 $formats{'TT-fonts'}=
527 inccheck=>sub { -e catfile($_[0], 'freetype.h')
528 && !-e catfile($_[0], 'fterrors.h') },
529 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
532 code => \&freetype1_probe,
534 Truetype fonts are scalable fonts. They can include
535 kerning and hinting information and generally yield good
536 visual quality esp on low resultions. The freetype library is
537 used to rasterize for us. The only drawback is that there
538 are alot of badly designed fonts out there.}
543 inccheck=>sub { -e catfile($_[0], 'windows.h') },
544 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
545 || lc $_[0] eq 'libgdi32.a' },
546 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
549 Uses the Win32 GDI for rendering text.
551 This currently only works on under normal Win32 and cygwin.
554 $formats{'freetype2'} = {
557 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
558 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
559 libfiles=>'-lfreetype',
560 objfiles=>'freetyp2.o',
562 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
563 scalable. It also supports a variety of other fonts.
565 code => \&freetype2_probe,
569 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
576 defined($V) ? $V : "";
580 # Get information from environment variables
592 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
607 open CONFIG, "> imconfig.h"
608 or die "Cannot create imconfig.h: $!\n";
610 /* This file is automatically generated by Makefile.PL.
611 Don't edit this file, since any changes will be lost */
613 #ifndef IMAGER_IMCONFIG_H
614 #define IMAGER_IMCONFIG_H
616 for my $define (@$defines) {
618 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
620 print CONFIG "#define $define->[0] $define->[1]\n";
622 print CONFIG "\n#endif\n";
626 # use pkg-config to probe for libraries
627 # works around the junk that pkg-config dumps on FreeBSD
631 is_exe('pkg-config') or return;
633 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
635 !system("pkg-config $pkg --exists $redir");
638 # probes for freetype1 by scanning @incs for the includes and
639 # @libs for the libs. This is done separately because freetype's headers
640 # are stored in a freetype or freetype1 directory under PREFIX/include.
642 # we could find the files with the existing mechanism, but it won't set
643 # -I flags correctly.
645 # This could be extended to freetype2 too, but freetype-config catches
647 sub freetype1_probe {
648 my ($frm, $frmkey) = @_;
652 for my $inc (@incs) {
653 for my $subdir (qw/freetype freetype1/) {
654 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
656 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
659 $found_inc = File::Spec->catdir($inc, $subdir);
666 for my $lib (@libs) {
667 my $a_path = File::Spec->catfile($lib, "libttf$aext");
668 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
669 if (-e $a_path || -e $l_path) {
675 return unless $found_inc && $found_lib;
676 printf("%10s: includes %s - libraries %s\n", $frmkey,
677 ($found_inc ? 'found' : 'not found'),
678 ($found_lib ? 'found' : 'not found'));
680 $frm->{cflags} = "-I$found_inc";
681 $frm->{libfiles} = "-lttf";
686 # probes for freetype2 by trying to run freetype-config
687 sub freetype2_probe {
688 my ($frm, $frmkey) = @_;
690 is_exe('freetype-config') or return;
692 my $cflags = `freetype-config --cflags`
696 my $lflags = `freetype-config --libs`
700 # before 2.1.5 freetype-config --cflags could output
701 # the -I options in the wrong order, causing a conflict with
702 # freetype1.x installed with the same --prefix
705 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
707 # - freetype 1.x headers are in prefix/include/freetype
708 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
710 && $incdirs[1] eq "$incdirs[0]/freetype2"
711 && -e "$incdirs[0]/freetype/freetype.h"
712 && -e "$incdirs[0]/freetype/fterrid.h") {
713 print "** freetype-config provided -I options out of order, correcting\n"
715 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
716 map "-I$_", reverse @incdirs);
718 $frm->{cflags} = $cflags;
719 $frm->{lflags} = $lflags;
721 printf "%10s: configured via freetype-config\n", $frmkey;
726 # probes for libpng via pkg-config
728 my ($frm, $frmkey) = @_;
730 is_exe('pkg-config') or return;
733 for my $check_conf (qw(libpng libpng12 libpng10)) {
734 if (_pkg_probe($check_conf)) {
735 $config = $check_conf;
741 my $cflags = `pkg-config $config --cflags`
744 my $lflags = `pkg-config $config --libs`
749 $frm->{cflags} = $cflags;
750 $frm->{lflags} = $lflags;
752 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
758 return File::Spec->catfile(@_);
764 for my $dir (File::Spec->path) {
765 -x catfile($dir, "$name$Config{_exe}")
774 Usage: $0 [--enable feature1,feature2,...] [other options]
775 $0 [--disable feature1,feature2,...] [other options]
777 Possible feature names are:
778 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
781 Verbose library probing (or set IM_VERBOSE in the environment)
783 Disable logging (or set IM_NOLOG in the environment)
785 Add to the include search path
787 Add to the library search path
789 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
795 # generate the PM MM argument
796 # I'd prefer to modify the public version, but there doesn't seem to be
797 # a public API to do that
800 my $instbase = '$(INST_LIBDIR)';
802 # first the basics, .pm and .pod files
803 $pm{"Imager.pm"} = "$instbase/Imager.pm";
805 my $mani = maniread();
807 for my $filename (keys %$mani) {
808 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
809 (my $work = $filename) =~ s/^lib//;
810 $pm{$filename} = $instbase . $work;
815 $pm{typemap} = $instbase . '/Imager/typemap';
817 # and the core headers
818 for my $filename (keys %$mani) {
819 if ($filename =~ /^\w+\.h$/) {
820 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
824 # and the generated header
825 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
833 # extract the version
834 my $version = MM->parse_version($opts->{VERSION_FROM})
835 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
837 # we don't set this on older EU::MM and it corrupts META.yml
838 # so don't generate it
839 return unless $opts->{AUTHOR};
845 version_from: $opts->{VERSION_FROM}
846 author: $opts->{AUTHOR}
847 abstract: $opts->{ABSTRACT}
850 if (keys %{$Recommends{$opts->{NAME}}}) {
851 $meta .= "recommends:\n";
852 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
853 $meta .= " $module: $version\n";
856 if ($opts->{PREREQ_PM}) {
857 $meta .= "requires:\n";
858 while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) {
859 $meta .= " $module: $version\n";
865 distribution_type: module
866 generated_by: $opts->{NAME} version $version
869 if (open META, "< META.yml") {
870 my $old_meta = do { local $/; <META> };
873 $save_meta = $old_meta ne $meta;
879 print "Updating META.yml\n";
880 open META, "> META.yml" or die "Cannot create META.yml: $!";
886 # this is intended to only be running on the development
890 # update Changes if needed
892 # get the last revision from Changes
893 if (open CHANGES, "< Changes") {
895 my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
898 my ($revision) = grep s/^Revision: //, `svn info`
899 or die "Could not get Revision from svn";
902 $write_changes ||= $changes_rev != $revision;
908 if ($write_changes) {
909 print "Updating Changes file\n";
910 system 'svn log -v -r HEAD:943 >Changes';