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
90 if (exists $ENV{IM_ENABLE}) {
91 my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
92 for my $key (keys %formats) {
93 delete $formats{$key} unless $en{$key};
97 my %en = map { $_ => 1 } map { split /,/ } @enable;
98 for my $key (keys %formats) {
99 delete $formats{$key} unless $en{$key};
103 delete @formats{map { split /,/ } @disable};
106 # Pick what libraries are used
113 # Make sure there isn't a clash between the gif libraries.
120 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
121 my $frm = $formats{$frmkey};
122 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
123 $F_OBJECT .= ' ' .$frm->{objfiles};
124 if ($frm->{cflags}) {
125 $lib_cflags .= ' ' .$frm->{cflags};
126 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
127 grep /^-I./, split ' ', $frm->{cflags};
129 if ($frm->{lflags}) {
130 $lib_lflags .= ' ' . $frm->{lflags};
133 $F_LIBS .= ' ' .$frm->{libfiles};
139 print "EXIF support enabled\n";
140 push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
141 $F_OBJECT .= ' imexif.o';
144 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
145 grep !$definc{$_}, @incs;
146 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
147 grep !$deflib{$_}++, @libs) . $F_LIBS;
150 my $OSDEF = "-DOS_$^O";
152 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
153 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
155 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
156 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
157 filters.o dynaload.o stackmach.o datatypes.o
158 regmach.o trans2.o quant.o error.o convert.o
159 map.o tags.o palimg.o maskimg.o img16.o rotate.o
160 bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
161 imext.o scale.o rubthru.o render.o);
163 $Recommends{Imager} =
164 { 'Parse::RecDescent' => 0 };
168 'VERSION_FROM' => 'Imager.pm',
169 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
170 'DEFINE' => "$OSDEF $CFLAGS",
171 'INC' => "$lib_cflags $DFLAGS $F_INC",
172 'OBJECT' => join(' ', @objs, $F_OBJECT),
173 clean => { FILES=>'testout meta.tmp rubthru.c scale.c' },
175 PREREQ_PM => { 'Test::More' => 0.47 },
179 if ($Config{gccversion}) {
180 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs';
181 #$opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
184 die "Don't know the coverage C flags for your compiler\n";
188 # eval to prevent warnings about versions with _ in them
189 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
190 if ($MM_ver > 6.06) {
191 $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
192 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
194 if ($MM_ver > 6.10) {
198 make_imconfig(\@defines);
200 if ($VERBOSE) { print Dumper(\%opts); }
201 mkdir('testout',0777); # since we cannot include it in the archive.
203 make_metafile(\%opts);
205 WriteMakefile(%opts);
212 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
215 my @ims = grep /\.im$/, keys %$mani;
217 dyntest.$(MYEXTLIB) : dynfilt/Makefile
218 cd dynfilt && $(MAKE) $(PASTHRU)
220 lib/Imager/Regops.pm : regmach.h regops.perl
221 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
223 imconfig.h : Makefile.PL
224 $(ECHO) "imconfig.h out-of-date with respect to $?"
225 $(PERLRUN) Makefile.PL
226 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
228 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
229 $perl apidocs.perl lib/Imager/APIRef.pod
231 !.join('', map _im_rule($perl, $_), @ims)
236 my ($perl, $im) = @_;
238 (my $c = $im) =~ s/\.im$/.c/;
242 $perl imtoc.perl $im $c
248 # manual configuration of helper libraries
253 Please answer the following questions about
254 which formats are avaliable on your computer
256 press <return> to continue
259 <STDIN>; # eat one return
261 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
263 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
264 print "Enable $frm support: ";
267 if ($gz =~ m/^(y|yes|n|no)/i) {
268 $gz=substr(lc($gz),0,1);
270 delete $formats{$frm};
277 # automatic configuration of helper libraries
280 print "Automatic probing:\n" if $VERBOSE;
281 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
282 delete $formats{$frm} if !checkformat($frm);
288 if ($formats{'gif'} and $formats{'ungif'}) {
289 print "ungif and gif can not coexist - removing ungif support\n";
290 delete $formats{'ungif'};
293 for my $frm (qw(gif ungif)) {
294 checkformat($frm) if ($MANUAL and $formats{$frm});
298 for my $frm (grep $formats{$_}, qw(gif ungif)) {
299 push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
303 FILES: for my $dir (@dirs) {
304 my $h = "$dir/gif_lib.h";
305 open H, "< $h" or next;
307 if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
317 # we need the version in a #ifdefable form
319 push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
320 push @defines, [ IM_GIFMINOR => $minor ];
321 push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
322 if $no_gif_set_version;
329 # print "checking path $path\n";
330 if ( !opendir(DH,$path) ) {
331 warn "Cannot open dir $path: $!\n";
334 my @l=grep { $chk->($_) } readdir(DH);
337 return map $path, @l;
344 print " checkformat($frm)\n" if $VERBOSE;
346 my $code = $formats{$frm}{'code'};
347 if ($code && !$noprobe) {
348 print " Calling probe function\n" if $VERBOSE;
349 return 1 if $code->($formats{$frm}, $frm);
352 my $libchk=$formats{$frm}{'libcheck'};
353 my $incchk=$formats{$frm}{'inccheck'};
357 push(@l, gd($lp,$libchk));
362 push(@i, $ip) if $incchk->($ip,$frm);
365 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
366 $formats{$frm}{incdir} = \@i;
367 $formats{$frm}{libdir} = \@l;
368 return scalar(@i && @l);
375 print " Include paths:\n";
376 for (@incs) { print $_,"\n"; }
378 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
381 print "\nLibrary paths:\n";
382 for (@libs) { print $_,"\n"; }
384 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
389 # Format data initialization
391 # format definition is:
393 # default include path
394 # files needed for include (boolean perl code)
397 # files needed for link (boolean perl code)
398 # object files needed for the format
403 my @definc = qw(/usr/include);
404 @definc{@definc}=(1) x @definc;
405 @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
406 map { split /\Q$Config{path_sep}/} @incpaths );
407 if ($Config{locincpth}) {
408 push @incs, grep -d, split ' ', $Config{locincpth};
410 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
411 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
413 if ($Config{incpath}) {
414 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
418 /usr/include/freetype2
419 /usr/local/include/freetype2
420 /usr/local/include/freetype1/freetype
421 /usr/include /usr/local/include /usr/include/freetype
422 /usr/local/include/freetype);
423 if ($Config{ccflags}) {
424 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
426 @definc{@hidden} = (1) x @hidden;
429 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
430 map { split /\Q$Config{path_sep}/} @libpaths );
431 if ($Config{loclibpth}) {
432 push @libs, grep -d, split ' ', $Config{loclibpth};
435 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
436 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
437 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
438 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
440 if ($^O eq 'cygwin') {
441 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
442 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
444 if ($Config{ldflags}) {
445 # some builds of perl put -Ldir into ldflags without putting it in
446 # loclibpth, let's extract them
447 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
448 split ' ', $Config{ldflags};
450 # don't mark them as seen - EU::MM will remove any libraries
451 # it can't find and it doesn't look for -L in ldflags
452 #@deflib{@hidden} = @hidden;
454 push @libs, grep -d, qw(/usr/local/lib);
459 inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
460 libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
464 In order to use jpeg with this module you need to have libjpeg
465 installed on your computer}
471 inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
472 libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
476 In order to use tiff with this module you need to have libtiff
477 installed on your computer}
483 inccheck=>sub { -e catfile($_[0], 'png.h') },
484 libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
485 libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
488 Png stands for Portable Network Graphics and is intended as
489 a replacement for gif on the web. It is patent free and
490 is recommended by the w3c, you need libpng to use these formats},
497 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
498 libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
502 gif is the de facto standard for webgraphics at the moment,
503 it does have some patent problems. If you have giflib and
504 are not in violation with the unisys patent you should use
505 this instead of the 'ungif' option. Note that they cannot
506 be in use at the same time}
512 inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
513 libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
517 gif is the de facto standard for webgraphics at the moment,
518 it does have some patent problems. If you have libungif and
519 want to create images free from LZW patented compression you
520 should use this option instead of the 'gif' option}
523 $formats{'T1-fonts'}={
526 inccheck=>sub { -e catfile($_[0], 't1lib.h') },
527 libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
531 postscript t1 fonts are scalable fonts. They can include
532 ligatures and kerning information and generally yield good
533 visual quality. We depend on libt1 to rasterize the fonts
537 $formats{'TT-fonts'}=
541 inccheck=>sub { -e catfile($_[0], 'freetype.h')
542 && !-e catfile($_[0], 'fterrors.h') },
543 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
546 code => \&freetype1_probe,
548 Truetype fonts are scalable fonts. They can include
549 kerning and hinting information and generally yield good
550 visual quality esp on low resultions. The freetype library is
551 used to rasterize for us. The only drawback is that there
552 are alot of badly designed fonts out there.}
557 inccheck=>sub { -e catfile($_[0], 'windows.h') },
558 libcheck=>sub { lc $_[0] eq 'gdi32.lib'
559 || lc $_[0] eq 'libgdi32.a' },
560 libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
563 Uses the Win32 GDI for rendering text.
565 This currently only works on under normal Win32 and cygwin.
568 $formats{'freetype2'} = {
571 inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
572 libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
573 libfiles=>'-lfreetype',
574 objfiles=>'freetyp2.o',
576 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
577 scalable. It also supports a variety of other fonts.
579 code => \&freetype2_probe,
583 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
590 defined($V) ? $V : "";
594 # Get information from environment variables
606 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
621 open CONFIG, "> imconfig.h"
622 or die "Cannot create imconfig.h: $!\n";
624 /* This file is automatically generated by Makefile.PL.
625 Don't edit this file, since any changes will be lost */
627 #ifndef IMAGER_IMCONFIG_H
628 #define IMAGER_IMCONFIG_H
630 for my $define (@$defines) {
632 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
634 print CONFIG "#define $define->[0] $define->[1]\n";
636 print CONFIG "\n#endif\n";
640 # use pkg-config to probe for libraries
641 # works around the junk that pkg-config dumps on FreeBSD
645 is_exe('pkg-config') or return;
647 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
649 !system("pkg-config $pkg --exists $redir");
652 # probes for freetype1 by scanning @incs for the includes and
653 # @libs for the libs. This is done separately because freetype's headers
654 # are stored in a freetype or freetype1 directory under PREFIX/include.
656 # we could find the files with the existing mechanism, but it won't set
657 # -I flags correctly.
659 # This could be extended to freetype2 too, but freetype-config catches
661 sub freetype1_probe {
662 my ($frm, $frmkey) = @_;
666 for my $inc (@incs) {
667 for my $subdir (qw/freetype freetype1/) {
668 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
670 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
673 $found_inc = File::Spec->catdir($inc, $subdir);
680 for my $lib (@libs) {
681 my $a_path = File::Spec->catfile($lib, "libttf$aext");
682 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
683 if (-e $a_path || -e $l_path) {
689 return unless $found_inc && $found_lib;
690 printf("%10s: includes %s - libraries %s\n", $frmkey,
691 ($found_inc ? 'found' : 'not found'),
692 ($found_lib ? 'found' : 'not found'));
694 $frm->{cflags} = "-I$found_inc";
695 $frm->{libfiles} = "-lttf";
700 # probes for freetype2 by trying to run freetype-config
701 sub freetype2_probe {
702 my ($frm, $frmkey) = @_;
704 is_exe('freetype-config') or return;
706 my $cflags = `freetype-config --cflags`
710 my $lflags = `freetype-config --libs`
714 # before 2.1.5 freetype-config --cflags could output
715 # the -I options in the wrong order, causing a conflict with
716 # freetype1.x installed with the same --prefix
719 # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
721 # - freetype 1.x headers are in prefix/include/freetype
722 my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
724 && $incdirs[1] eq "$incdirs[0]/freetype2"
725 && -e "$incdirs[0]/freetype/freetype.h"
726 && -e "$incdirs[0]/freetype/fterrid.h") {
727 print "** freetype-config provided -I options out of order, correcting\n"
729 $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
730 map "-I$_", reverse @incdirs);
732 $frm->{cflags} = $cflags;
733 $frm->{lflags} = $lflags;
735 printf "%10s: configured via freetype-config\n", $frmkey;
740 # probes for libpng via pkg-config
742 my ($frm, $frmkey) = @_;
744 is_exe('pkg-config') or return;
747 for my $check_conf (qw(libpng libpng12 libpng10)) {
748 if (_pkg_probe($check_conf)) {
749 $config = $check_conf;
755 my $cflags = `pkg-config $config --cflags`
758 my $lflags = `pkg-config $config --libs`
763 $frm->{cflags} = $cflags;
764 $frm->{lflags} = $lflags;
766 printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
772 return File::Spec->catfile(@_);
778 for my $dir (File::Spec->path) {
779 -x catfile($dir, "$name$Config{_exe}")
788 Usage: $0 [--enable feature1,feature2,...] [other options]
789 $0 [--disable feature1,feature2,...] [other options]
791 Possible feature names are:
792 png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
795 Verbose library probing (or set IM_VERBOSE in the environment)
797 Disable logging (or set IM_NOLOG in the environment)
799 Add to the include search path
801 Add to the library search path
803 Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
809 # generate the PM MM argument
810 # I'd prefer to modify the public version, but there doesn't seem to be
811 # a public API to do that
814 my $instbase = '$(INST_LIBDIR)';
816 # first the basics, .pm and .pod files
817 $pm{"Imager.pm"} = "$instbase/Imager.pm";
819 my $mani = maniread();
821 for my $filename (keys %$mani) {
822 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
823 (my $work = $filename) =~ s/^lib//;
824 $pm{$filename} = $instbase . $work;
829 $pm{typemap} = $instbase . '/Imager/typemap';
831 # and the core headers
832 for my $filename (keys %$mani) {
833 if ($filename =~ /^\w+\.h$/) {
834 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
838 # and the generated header
839 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
847 # extract the version
848 my $version = MM->parse_version($opts->{VERSION_FROM})
849 or die "Could not extract version number from $opts->{VERSION_FROM}\n";
851 # we don't set this on older EU::MM and it corrupts META.yml
852 # so don't generate it
853 return unless $opts->{AUTHOR};
859 version_from: $opts->{VERSION_FROM}
860 author: $opts->{AUTHOR}
861 abstract: $opts->{ABSTRACT}
864 if (keys %{$Recommends{$opts->{NAME}}}) {
865 $meta .= "recommends:\n";
866 while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
867 $meta .= " $module: $version\n";
870 if ($opts->{PREREQ_PM}) {
871 $meta .= "requires:\n";
872 while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) {
873 $meta .= " $module: $version\n";
879 distribution_type: module
882 url: http://module-build.sourceforge.net/META-spec-v1.3.html
883 generated_by: $opts->{NAME} version $version
886 if (open META, "< META.yml") {
887 my $old_meta = do { local $/; <META> };
890 $save_meta = $old_meta ne $meta;
896 print "Updating META.yml\n";
897 open META, "> META.yml" or die "Cannot create META.yml: $!";