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 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,
190 TYPEMAPS => \@typemaps,
194 if ($Config{gccversion}) {
195 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
196 $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
199 die "Don't know the coverage C flags for your compiler\n";
203 # eval to prevent warnings about versions with _ in them
204 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
205 if ($MM_ver > 6.06) {
206 $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
207 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
210 if ($MM_ver >= 6.46) {
215 "Parse::RecDescent" => 0
234 homepage => "http://imager.perl.org/",
235 repository => "git://git.imager.perl.org/imager.git",
236 bugtracker => "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager",
241 make_imconfig(\@defines);
243 if ($VERBOSE) { print Dumper(\%opts); }
244 mkdir('testout',0777); # since we cannot include it in the archive.
246 -d "probe" and rmdir "probe";
248 WriteMakefile(%opts);
252 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
253 if ($IMAGER_LIBS{$name}) {
262 print "Libraries found:\n" if @good;
263 print " $_\n" for @good;
264 print "Libraries *not* found:\n" if @bad;
265 print " $_\n" for @bad;
272 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
275 my @ims = grep /\.im$/, keys %$mani;
277 dyntest.$(MYEXTLIB) : dynfilt/Makefile
278 cd dynfilt && $(MAKE) $(PASTHRU)
280 lib/Imager/Regops.pm : regmach.h regops.perl
281 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
283 imconfig.h : Makefile.PL
284 $(ECHO) "imconfig.h out-of-date with respect to $?"
285 $(PERLRUN) Makefile.PL
286 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
288 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
289 $perl apidocs.perl lib/Imager/APIRef.pod
291 !.join('', map _im_rule($perl, $_), @ims)
296 my ($perl, $im) = @_;
298 (my $c = $im) =~ s/\.im$/.c/;
301 $c: $im lib/Imager/Preprocess.pm
302 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
308 # manual configuration of helper libraries
313 Please answer the following questions about
314 which formats are avaliable on your computer
316 press <return> to continue
319 <STDIN>; # eat one return
321 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
323 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
324 print "Enable $frm support: ";
327 if ($gz =~ m/^(y|yes|n|no)/i) {
328 $gz=substr(lc($gz),0,1);
330 delete $formats{$frm};
337 # automatic configuration of helper libraries
340 print "Automatic probing:\n" if $VERBOSE;
341 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
342 delete $formats{$frm} if !checkformat($frm);
349 # print "checking path $path\n";
350 if ( !opendir(DH,$path) ) {
351 warn "Cannot open dir $path: $!\n";
354 my @l=grep { $chk->($_) } readdir(DH);
357 return map $path, @l;
361 my ($format, $frm) = @_;
363 my $lib_check=$formats{$frm}{'libcheck'};
364 my $inc_check=$formats{$frm}{'inccheck'};
369 push(@l, grep_directory($lp,$lib_check));
374 push(@i, $ip) if $inc_check->($ip,$frm);
377 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
378 $formats{$frm}{incdir} = \@i;
379 $formats{$frm}{libdir} = \@l;
380 return 1 if scalar(@i && @l);
383 printf("%10s: not available\n", $frm);
392 print " checkformat($frm)\n" if $VERBOSE;
394 my $format = $formats{$frm};
397 if (my $code = $format->{'code'}) {
398 if (ref $code eq 'ARRAY') {
399 push @probes, @$code;
405 push @probes, \&_probe_default;
407 print " Calling probe function\n" if $VERBOSE;
409 for my $func (@probes) {
410 if ($func->($format, $frm)) {
418 if ($format->{postcheck}) {
419 print " Calling postcheck function\n" if $VERBOSE;
420 $format->{postcheck}->($format, $frm)
431 print " Include paths:\n";
432 for (@incs) { print $_,"\n"; }
434 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
437 print "\nLibrary paths:\n";
438 for (@libs) { print $_,"\n"; }
440 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
445 # Format data initialization
447 # format definition is:
449 # default include path
450 # files needed for include (boolean perl code)
453 # files needed for link (boolean perl code)
454 # object files needed for the format
459 my @definc = qw(/usr/include);
460 @definc{@definc}=(1) x @definc;
463 split(/\Q$Config{path_sep}/, $INCPATH),
464 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
466 if ($Config{locincpth}) {
467 push @incs, grep -d, split ' ', $Config{locincpth};
469 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
470 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
472 if ($Config{incpath}) {
473 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
477 /usr/include/freetype2
478 /usr/local/include/freetype2
479 /usr/local/include/freetype1/freetype
480 /usr/include /usr/local/include /usr/include/freetype
481 /usr/local/include/freetype);
482 if ($Config{ccflags}) {
483 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
485 @definc{@hidden} = (1) x @hidden;
488 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
489 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
490 if ($Config{loclibpth}) {
491 push @libs, grep -d, split ' ', $Config{loclibpth};
494 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
495 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
496 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
497 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
499 if ($^O eq 'cygwin') {
500 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
501 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
503 if ($Config{ldflags}) {
504 # some builds of perl put -Ldir into ldflags without putting it in
505 # loclibpth, let's extract them
506 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
507 split ' ', $Config{ldflags};
509 # don't mark them as seen - EU::MM will remove any libraries
510 # it can't find and it doesn't look for -L in ldflags
511 #@deflib{@hidden} = @hidden;
513 push @libs, grep -d, qw(/usr/local/lib);
515 $formats{'TT-fonts'}=
519 inccheck=>sub { -e catfile($_[0], 'freetype.h')
520 && !-e catfile($_[0], 'fterrors.h') },
521 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
524 code => \&freetype1_probe,
526 Truetype fonts are scalable fonts. They can include
527 kerning and hinting information and generally yield good
528 visual quality esp on low resultions. The freetype library is
529 used to rasterize for us. The only drawback is that there
530 are alot of badly designed fonts out there.}
533 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
540 defined($V) ? $V : "";
544 # Get information from environment variables
556 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
568 # populate the environment so that sub-modules get the same info
570 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
571 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
572 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
578 open CONFIG, "> imconfig.h"
579 or die "Cannot create imconfig.h: $!\n";
581 /* This file is automatically generated by Makefile.PL.
582 Don't edit this file, since any changes will be lost */
584 #ifndef IMAGER_IMCONFIG_H
585 #define IMAGER_IMCONFIG_H
587 for my $define (@$defines) {
589 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
591 print CONFIG "#define $define->[0] $define->[1]\n";
593 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
597 Compiler supports the GCC __attribute__((format...)) syntax.
601 #define IMAGER_FORMAT_ATTR 1
606 if ($Config{d_snprintf}) {
608 /* We can use snprintf() */
609 #define IMAGER_SNPRINTF 1
614 if ($Config{d_vsnprintf}) {
616 /* We can use vsnprintf() */
617 #define IMAGER_VSNPRINTF 1
624 Type and format code for formatted output as with printf.
626 This is intended for formatting i_img_dim values.
628 typedef $Config{ivtype} i_dim_format_t;
629 #define i_DF $Config{ivdformat}
632 print CONFIG "\n#endif\n";
636 # probes for freetype1 by scanning @incs for the includes and
637 # @libs for the libs. This is done separately because freetype's headers
638 # are stored in a freetype or freetype1 directory under PREFIX/include.
640 # we could find the files with the existing mechanism, but it won't set
641 # -I flags correctly.
643 # This could be extended to freetype2 too, but freetype-config catches
645 sub freetype1_probe {
646 my ($frm, $frmkey) = @_;
650 for my $inc (@incs) {
651 for my $subdir (qw/freetype freetype1/) {
652 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
654 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
657 $found_inc = File::Spec->catdir($inc, $subdir);
664 for my $lib (@libs) {
665 my $a_path = File::Spec->catfile($lib, "libttf$aext");
666 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
667 if (-e $a_path || -e $l_path) {
673 return unless $found_inc && $found_lib;
674 printf("%10s: includes %s - libraries %s\n", $frmkey,
675 ($found_inc ? 'found' : 'not found'),
676 ($found_lib ? 'found' : 'not found'));
678 $frm->{cflags} = "-I$found_inc";
679 $frm->{libfiles} = "-lttf";
685 return File::Spec->catfile(@_);
690 Usage: $0 [--enable feature1,feature2,...] [other options]
691 $0 [--disable feature1,feature2,...] [other options]
693 Possible feature names are:
697 Verbose library probing (or set IM_VERBOSE in the environment)
699 Disable logging (or set IM_NOLOG in the environment)
701 Add to the include search path
703 Add to the library search path
705 Build for coverage testing.
707 Build with assertions active.
713 # generate the PM MM argument
714 # I'd prefer to modify the public version, but there doesn't seem to be
715 # a public API to do that
718 my $instbase = '$(INST_LIBDIR)';
720 # first the basics, .pm and .pod files
721 $pm{"Imager.pm"} = "$instbase/Imager.pm";
723 my $mani = maniread();
725 for my $filename (keys %$mani) {
726 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
727 (my $work = $filename) =~ s/^lib//;
728 $pm{$filename} = $instbase . $work;
733 $pm{typemap} = $instbase . '/Imager/typemap';
735 # and the core headers
736 for my $filename (keys %$mani) {
737 if ($filename =~ /^\w+\.h$/) {
738 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
742 # and the generated header
743 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
752 if ($path =~ m!^~[/\\]!) {
753 defined $home or $home = $ENV{HOME};
754 if (!defined $home && $^O eq 'MSWin32'
755 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
756 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
758 unless (defined $home) {
759 $home = eval { (getpwuid($<))[7] };
761 defined $home or die "You supplied $path, but I can't find your home directory\n";
763 $path = File::Spec->catdir($home, $path);