3 use ExtUtils::MakeMaker;
8 use ExtUtils::Manifest qw(maniread);
10 use vars qw(%formats $VERBOSE $INCPATH $LIBPATH $NOLOG $DEBUG_MALLOC $MANUAL $CFLAGS $LFLAGS $DFLAGS);
14 # EU::MM runs Makefile.PL all in the same process, so sub-modules will
16 our $BUILDING_IMAGER = 1;
18 # used to display a summary after we've probed the world
22 # IM_INCPATH colon seperated list of paths to extra include paths
23 # IM_LIBPATH colon seperated list of paths to extra library paths
25 # IM_VERBOSE turns on verbose mode for the library finding and such
26 # IM_MANUAL to manually select which libraries are used and which not
27 # IM_ENABLE to programmatically select which libraries are used
29 # IM_NOLOG if true logging will not be compiled into the module
30 # IM_DEBUG_MALLOC if true malloc debbuging will be compiled into the module
31 # do not use IM_DEBUG_MALLOC in production - this slows
32 # everything down by alot
33 # IM_CFLAGS Extra flags to pass to the compiler
34 # IM_LFLAGS Extra flags to pass to the linker
35 # IM_DFLAGS Extra flags to pass to the preprocessor
37 my $KEEP_FILES = $ENV{IMAGER_KEEP_FILES};
39 getenv(); # get environment variables
41 my $lext=$Config{'so'}; # Get extensions of libraries
42 my $aext=$Config{'_a'};
44 my $help; # display help if set
45 my @enable; # list of drivers to enable
46 my @disable; # or list of drivers to disable
47 my @incpaths; # places to look for headers
48 my @libpaths; # places to look for libraries
49 my $coverage; # build for coverage testing
50 my $assert; # build with assertions
51 GetOptions("help" => \$help,
52 "enable=s" => \@enable,
53 "disable=s" => \@disable,
54 "incpath=s", \@incpaths,
55 "libpath=s" => \@libpaths,
56 "verbose|v" => \$VERBOSE,
58 'coverage' => \$coverage,
59 "assert|a" => \$assert);
63 if ($ENV{AUTOMATED_TESTING}) {
68 print "Verbose mode\n";
70 import Data::Dumper qw(Dumper);
79 if ($NOLOG) { print "Logging not compiled into module\n"; }
81 push @defines, [ IMAGER_LOG => 1, "Logging system" ];
85 push @defines, [ IM_ASSERT => 1, "im_assert() are effective" ];
89 push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
90 print "Malloc debugging enabled\n";
93 if (@enable && @disable) {
94 print STDERR "Only --enable or --disable can be used, not both, try --help\n";
100 my @incs; # all the places to look for headers
101 my @libs; # all the places to look for libraries
103 init(); # initialize global data
104 pathcheck(); # Check if directories exist
106 if (exists $ENV{IM_ENABLE}) {
107 my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
108 for my $key (keys %formats) {
109 delete $formats{$key} unless $en{$key};
113 my %en = map { $_ => 1 } map { split /,/ } @enable;
114 for my $key (keys %formats) {
115 delete $formats{$key} unless $en{$key};
119 delete @formats{map { split /,/ } @disable};
122 # Pick what libraries are used
133 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
134 my $frm = $formats{$frmkey};
135 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
136 $F_OBJECT .= ' ' .$frm->{objfiles};
137 if ($frm->{cflags}) {
138 $lib_cflags .= ' ' .$frm->{cflags};
139 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
140 grep /^-I./, split ' ', $frm->{cflags};
142 if ($frm->{lflags}) {
143 $lib_lflags .= ' ' . $frm->{lflags};
146 $F_LIBS .= ' ' .$frm->{libfiles};
151 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
152 grep !$definc{$_}, @incs;
153 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
154 grep !$deflib{$_}++, @libs) . $F_LIBS;
157 my $OSDEF = "-DOS_$^O";
159 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
160 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
162 my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
163 log.o gaussian.o conv.o pnm.o raw.o feat.o font.o combine.o
164 filters.o dynaload.o stackmach.o datatypes.o
165 regmach.o trans2.o quant.o error.o convert.o
166 map.o tags.o palimg.o maskimg.o img8.o img16.o rotate.o
167 bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
168 imext.o scale.o rubthru.o render.o paste.o compose.o flip.o);
170 my @typemaps = qw(typemap.local typemap);
172 unshift @typemaps, "typemap.oldperl";
178 'VERSION_FROM' => 'Imager.pm',
179 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
180 'DEFINE' => "$OSDEF $CFLAGS",
181 'INC' => "$lib_cflags $DFLAGS $F_INC",
182 'OBJECT' => join(' ', @objs, $F_OBJECT),
183 clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
187 'Test::More' => 0.47,
188 'Scalar::Util' => 1.00,
191 TYPEMAPS => \@typemaps,
195 if ($Config{gccversion}) {
196 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
197 $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
200 die "Don't know the coverage C flags for your compiler\n";
204 # eval to prevent warnings about versions with _ in them
205 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
206 if ($MM_ver > 6.06) {
207 $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
208 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
211 if ($MM_ver >= 6.46) {
216 "Parse::RecDescent" => 0
235 homepage => "http://imager.perl.org/",
236 repository => "git://git.imager.perl.org/imager.git",
237 bugtracker => "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager",
242 make_imconfig(\@defines);
244 if ($VERBOSE) { print Dumper(\%opts); }
245 mkdir('testout',0777); # since we cannot include it in the archive.
247 -d "probe" and rmdir "probe";
249 WriteMakefile(%opts);
253 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
254 if ($IMAGER_LIBS{$name}) {
263 print "Libraries found:\n" if @good;
264 print " $_\n" for @good;
265 print "Libraries *not* found:\n" if @bad;
266 print " $_\n" for @bad;
273 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
276 my @ims = grep /\.im$/, keys %$mani;
278 dyntest.$(MYEXTLIB) : dynfilt/Makefile
279 cd dynfilt && $(MAKE) $(PASTHRU)
281 lib/Imager/Regops.pm : regmach.h regops.perl
282 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
284 imconfig.h : Makefile.PL
285 $(ECHO) "imconfig.h out-of-date with respect to $?"
286 $(PERLRUN) Makefile.PL
287 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
289 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
290 $perl apidocs.perl lib/Imager/APIRef.pod
292 !.join('', map _im_rule($perl, $_), @ims)
297 my ($perl, $im) = @_;
299 (my $c = $im) =~ s/\.im$/.c/;
302 $c: $im lib/Imager/Preprocess.pm
303 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
309 # manual configuration of helper libraries
314 Please answer the following questions about
315 which formats are avaliable on your computer
317 press <return> to continue
320 <STDIN>; # eat one return
322 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
324 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
325 print "Enable $frm support: ";
328 if ($gz =~ m/^(y|yes|n|no)/i) {
329 $gz=substr(lc($gz),0,1);
331 delete $formats{$frm};
338 # automatic configuration of helper libraries
341 print "Automatic probing:\n" if $VERBOSE;
342 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
343 delete $formats{$frm} if !checkformat($frm);
350 # print "checking path $path\n";
351 if ( !opendir(DH,$path) ) {
352 warn "Cannot open dir $path: $!\n";
355 my @l=grep { $chk->($_) } readdir(DH);
358 return map $path, @l;
362 my ($format, $frm) = @_;
364 my $lib_check=$formats{$frm}{'libcheck'};
365 my $inc_check=$formats{$frm}{'inccheck'};
370 push(@l, grep_directory($lp,$lib_check));
375 push(@i, $ip) if $inc_check->($ip,$frm);
378 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
379 $formats{$frm}{incdir} = \@i;
380 $formats{$frm}{libdir} = \@l;
381 return 1 if scalar(@i && @l);
384 printf("%10s: not available\n", $frm);
393 print " checkformat($frm)\n" if $VERBOSE;
395 my $format = $formats{$frm};
398 if (my $code = $format->{'code'}) {
399 if (ref $code eq 'ARRAY') {
400 push @probes, @$code;
406 push @probes, \&_probe_default;
408 print " Calling probe function\n" if $VERBOSE;
410 for my $func (@probes) {
411 if ($func->($format, $frm)) {
419 if ($format->{postcheck}) {
420 print " Calling postcheck function\n" if $VERBOSE;
421 $format->{postcheck}->($format, $frm)
432 print " Include paths:\n";
433 for (@incs) { print $_,"\n"; }
435 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
438 print "\nLibrary paths:\n";
439 for (@libs) { print $_,"\n"; }
441 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
446 # Format data initialization
448 # format definition is:
450 # default include path
451 # files needed for include (boolean perl code)
454 # files needed for link (boolean perl code)
455 # object files needed for the format
460 my @definc = qw(/usr/include);
461 @definc{@definc}=(1) x @definc;
464 split(/\Q$Config{path_sep}/, $INCPATH),
465 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
467 if ($Config{locincpth}) {
468 push @incs, grep -d, split ' ', $Config{locincpth};
470 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
471 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
473 if ($Config{incpath}) {
474 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
478 /usr/include/freetype2
479 /usr/local/include/freetype2
480 /usr/local/include/freetype1/freetype
481 /usr/include /usr/local/include /usr/include/freetype
482 /usr/local/include/freetype);
483 if ($Config{ccflags}) {
484 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
486 @definc{@hidden} = (1) x @hidden;
489 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
490 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
491 if ($Config{loclibpth}) {
492 push @libs, grep -d, split ' ', $Config{loclibpth};
495 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
496 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
497 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
498 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
500 if ($^O eq 'cygwin') {
501 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
502 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
504 if ($Config{ldflags}) {
505 # some builds of perl put -Ldir into ldflags without putting it in
506 # loclibpth, let's extract them
507 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
508 split ' ', $Config{ldflags};
510 # don't mark them as seen - EU::MM will remove any libraries
511 # it can't find and it doesn't look for -L in ldflags
512 #@deflib{@hidden} = @hidden;
514 push @libs, grep -d, qw(/usr/local/lib);
516 $formats{'TT-fonts'}=
520 inccheck=>sub { -e catfile($_[0], 'freetype.h')
521 && !-e catfile($_[0], 'fterrors.h') },
522 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
525 code => \&freetype1_probe,
527 Truetype fonts are scalable fonts. They can include
528 kerning and hinting information and generally yield good
529 visual quality esp on low resultions. The freetype library is
530 used to rasterize for us. The only drawback is that there
531 are alot of badly designed fonts out there.}
534 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
541 defined($V) ? $V : "";
545 # Get information from environment variables
557 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
569 # populate the environment so that sub-modules get the same info
571 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
572 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
573 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
579 open CONFIG, "> imconfig.h"
580 or die "Cannot create imconfig.h: $!\n";
582 /* This file is automatically generated by Makefile.PL.
583 Don't edit this file, since any changes will be lost */
585 #ifndef IMAGER_IMCONFIG_H
586 #define IMAGER_IMCONFIG_H
588 for my $define (@$defines) {
590 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
592 print CONFIG "#define $define->[0] $define->[1]\n";
594 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
598 Compiler supports the GCC __attribute__((format...)) syntax.
602 #define IMAGER_FORMAT_ATTR 1
607 if ($Config{d_snprintf}) {
609 /* We can use snprintf() */
610 #define IMAGER_SNPRINTF 1
615 if ($Config{d_vsnprintf}) {
617 /* We can use vsnprintf() */
618 #define IMAGER_VSNPRINTF 1
625 Type and format code for formatted output as with printf.
627 This is intended for formatting i_img_dim values.
629 typedef $Config{ivtype} i_dim_format_t;
630 #define i_DF $Config{ivdformat}
633 print CONFIG "\n#endif\n";
637 # probes for freetype1 by scanning @incs for the includes and
638 # @libs for the libs. This is done separately because freetype's headers
639 # are stored in a freetype or freetype1 directory under PREFIX/include.
641 # we could find the files with the existing mechanism, but it won't set
642 # -I flags correctly.
644 # This could be extended to freetype2 too, but freetype-config catches
646 sub freetype1_probe {
647 my ($frm, $frmkey) = @_;
651 for my $inc (@incs) {
652 for my $subdir (qw/freetype freetype1/) {
653 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
655 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
658 $found_inc = File::Spec->catdir($inc, $subdir);
665 for my $lib (@libs) {
666 my $a_path = File::Spec->catfile($lib, "libttf$aext");
667 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
668 if (-e $a_path || -e $l_path) {
674 return unless $found_inc && $found_lib;
675 printf("%10s: includes %s - libraries %s\n", $frmkey,
676 ($found_inc ? 'found' : 'not found'),
677 ($found_lib ? 'found' : 'not found'));
679 $frm->{cflags} = "-I$found_inc";
680 $frm->{libfiles} = "-lttf";
686 return File::Spec->catfile(@_);
691 Usage: $0 [--enable feature1,feature2,...] [other options]
692 $0 [--disable feature1,feature2,...] [other options]
694 Possible feature names are:
698 Verbose library probing (or set IM_VERBOSE in the environment)
700 Disable logging (or set IM_NOLOG in the environment)
702 Add to the include search path
704 Add to the library search path
706 Build for coverage testing.
708 Build with assertions active.
714 # generate the PM MM argument
715 # I'd prefer to modify the public version, but there doesn't seem to be
716 # a public API to do that
719 my $instbase = '$(INST_LIBDIR)';
721 # first the basics, .pm and .pod files
722 $pm{"Imager.pm"} = "$instbase/Imager.pm";
724 my $mani = maniread();
726 for my $filename (keys %$mani) {
727 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
728 (my $work = $filename) =~ s/^lib//;
729 $pm{$filename} = $instbase . $work;
734 $pm{typemap} = $instbase . '/Imager/typemap';
736 # and the core headers
737 for my $filename (keys %$mani) {
738 if ($filename =~ /^\w+\.h$/) {
739 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
743 # and the generated header
744 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
753 if ($path =~ m!^~[/\\]!) {
754 defined $home or $home = $ENV{HOME};
755 if (!defined $home && $^O eq 'MSWin32'
756 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
757 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
759 unless (defined $home) {
760 $home = eval { (getpwuid($<))[7] };
762 defined $home or die "You supplied $path, but I can't find your home directory\n";
764 $path = File::Spec->catdir($home, $path);