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);
172 'VERSION_FROM' => 'Imager.pm',
173 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
174 'DEFINE' => "$OSDEF $CFLAGS",
175 'INC' => "$lib_cflags $DFLAGS $F_INC",
176 'OBJECT' => join(' ', @objs, $F_OBJECT),
177 clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
179 PREREQ_PM => { 'Test::More' => 0.47 },
183 if ($Config{gccversion}) {
184 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs';
185 #$opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
188 die "Don't know the coverage C flags for your compiler\n";
192 # eval to prevent warnings about versions with _ in them
193 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
194 if ($MM_ver > 6.06) {
195 $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
196 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
199 if ($MM_ver >= 6.46) {
204 "Parse::RecDescent" => 0
223 homepage => "http://imager.perl.org/",
224 repository => "git://git.imager.perl.org/imager.git",
225 bugtracker => "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager",
230 make_imconfig(\@defines);
232 if ($VERBOSE) { print Dumper(\%opts); }
233 mkdir('testout',0777); # since we cannot include it in the archive.
235 -d "probe" and rmdir "probe";
237 WriteMakefile(%opts);
241 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
242 if ($IMAGER_LIBS{$name}) {
251 print "Libraries found:\n" if @good;
252 print " $_\n" for @good;
253 print "Libraries *not* found:\n" if @bad;
254 print " $_\n" for @bad;
261 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
264 my @ims = grep /\.im$/, keys %$mani;
266 dyntest.$(MYEXTLIB) : dynfilt/Makefile
267 cd dynfilt && $(MAKE) $(PASTHRU)
269 lib/Imager/Regops.pm : regmach.h regops.perl
270 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
272 imconfig.h : Makefile.PL
273 $(ECHO) "imconfig.h out-of-date with respect to $?"
274 $(PERLRUN) Makefile.PL
275 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
277 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
278 $perl apidocs.perl lib/Imager/APIRef.pod
280 !.join('', map _im_rule($perl, $_), @ims)
285 my ($perl, $im) = @_;
287 (my $c = $im) =~ s/\.im$/.c/;
290 $c: $im lib/Imager/Preprocess.pm
291 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
297 # manual configuration of helper libraries
302 Please answer the following questions about
303 which formats are avaliable on your computer
305 press <return> to continue
308 <STDIN>; # eat one return
310 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
312 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
313 print "Enable $frm support: ";
316 if ($gz =~ m/^(y|yes|n|no)/i) {
317 $gz=substr(lc($gz),0,1);
319 delete $formats{$frm};
326 # automatic configuration of helper libraries
329 print "Automatic probing:\n" if $VERBOSE;
330 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
331 delete $formats{$frm} if !checkformat($frm);
338 # print "checking path $path\n";
339 if ( !opendir(DH,$path) ) {
340 warn "Cannot open dir $path: $!\n";
343 my @l=grep { $chk->($_) } readdir(DH);
346 return map $path, @l;
350 my ($format, $frm) = @_;
352 my $lib_check=$formats{$frm}{'libcheck'};
353 my $inc_check=$formats{$frm}{'inccheck'};
358 push(@l, grep_directory($lp,$lib_check));
363 push(@i, $ip) if $inc_check->($ip,$frm);
366 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
367 $formats{$frm}{incdir} = \@i;
368 $formats{$frm}{libdir} = \@l;
369 return 1 if scalar(@i && @l);
372 printf("%10s: not available\n", $frm);
381 print " checkformat($frm)\n" if $VERBOSE;
383 my $format = $formats{$frm};
386 if (my $code = $format->{'code'}) {
387 if (ref $code eq 'ARRAY') {
388 push @probes, @$code;
394 push @probes, \&_probe_default;
396 print " Calling probe function\n" if $VERBOSE;
398 for my $func (@probes) {
399 if ($func->($format, $frm)) {
407 if ($format->{postcheck}) {
408 print " Calling postcheck function\n" if $VERBOSE;
409 $format->{postcheck}->($format, $frm)
420 print " Include paths:\n";
421 for (@incs) { print $_,"\n"; }
423 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
426 print "\nLibrary paths:\n";
427 for (@libs) { print $_,"\n"; }
429 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
434 # Format data initialization
436 # format definition is:
438 # default include path
439 # files needed for include (boolean perl code)
442 # files needed for link (boolean perl code)
443 # object files needed for the format
448 my @definc = qw(/usr/include);
449 @definc{@definc}=(1) x @definc;
452 split(/\Q$Config{path_sep}/, $INCPATH),
453 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
455 if ($Config{locincpth}) {
456 push @incs, grep -d, split ' ', $Config{locincpth};
458 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
459 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
461 if ($Config{incpath}) {
462 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
466 /usr/include/freetype2
467 /usr/local/include/freetype2
468 /usr/local/include/freetype1/freetype
469 /usr/include /usr/local/include /usr/include/freetype
470 /usr/local/include/freetype);
471 if ($Config{ccflags}) {
472 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
474 @definc{@hidden} = (1) x @hidden;
477 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
478 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
479 if ($Config{loclibpth}) {
480 push @libs, grep -d, split ' ', $Config{loclibpth};
483 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
484 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
485 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
486 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
488 if ($^O eq 'cygwin') {
489 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
490 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
492 if ($Config{ldflags}) {
493 # some builds of perl put -Ldir into ldflags without putting it in
494 # loclibpth, let's extract them
495 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
496 split ' ', $Config{ldflags};
498 # don't mark them as seen - EU::MM will remove any libraries
499 # it can't find and it doesn't look for -L in ldflags
500 #@deflib{@hidden} = @hidden;
502 push @libs, grep -d, qw(/usr/local/lib);
504 $formats{'TT-fonts'}=
508 inccheck=>sub { -e catfile($_[0], 'freetype.h')
509 && !-e catfile($_[0], 'fterrors.h') },
510 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
513 code => \&freetype1_probe,
515 Truetype fonts are scalable fonts. They can include
516 kerning and hinting information and generally yield good
517 visual quality esp on low resultions. The freetype library is
518 used to rasterize for us. The only drawback is that there
519 are alot of badly designed fonts out there.}
522 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
529 defined($V) ? $V : "";
533 # Get information from environment variables
545 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
557 # populate the environment so that sub-modules get the same info
559 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
560 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
561 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
567 open CONFIG, "> imconfig.h"
568 or die "Cannot create imconfig.h: $!\n";
570 /* This file is automatically generated by Makefile.PL.
571 Don't edit this file, since any changes will be lost */
573 #ifndef IMAGER_IMCONFIG_H
574 #define IMAGER_IMCONFIG_H
576 for my $define (@$defines) {
578 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
580 print CONFIG "#define $define->[0] $define->[1]\n";
582 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
586 Compiler supports the GCC __attribute__((format...)) syntax.
590 #define IMAGER_FORMAT_ATTR 1
595 if ($Config{d_snprintf}) {
597 /* We can use snprintf() */
598 #define IMAGER_SNPRINTF 1
603 if ($Config{d_vsnprintf}) {
605 /* We can use vsnprintf() */
606 #define IMAGER_VSNPRINTF 1
613 Type and format code for formatted output as with printf.
615 This is intended for formatting i_img_dim values.
617 typedef $Config{ivtype} i_dim_format_t;
618 #define i_DF $Config{ivdformat}
621 print CONFIG "\n#endif\n";
625 # probes for freetype1 by scanning @incs for the includes and
626 # @libs for the libs. This is done separately because freetype's headers
627 # are stored in a freetype or freetype1 directory under PREFIX/include.
629 # we could find the files with the existing mechanism, but it won't set
630 # -I flags correctly.
632 # This could be extended to freetype2 too, but freetype-config catches
634 sub freetype1_probe {
635 my ($frm, $frmkey) = @_;
639 for my $inc (@incs) {
640 for my $subdir (qw/freetype freetype1/) {
641 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
643 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
646 $found_inc = File::Spec->catdir($inc, $subdir);
653 for my $lib (@libs) {
654 my $a_path = File::Spec->catfile($lib, "libttf$aext");
655 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
656 if (-e $a_path || -e $l_path) {
662 return unless $found_inc && $found_lib;
663 printf("%10s: includes %s - libraries %s\n", $frmkey,
664 ($found_inc ? 'found' : 'not found'),
665 ($found_lib ? 'found' : 'not found'));
667 $frm->{cflags} = "-I$found_inc";
668 $frm->{libfiles} = "-lttf";
674 return File::Spec->catfile(@_);
679 Usage: $0 [--enable feature1,feature2,...] [other options]
680 $0 [--disable feature1,feature2,...] [other options]
682 Possible feature names are:
686 Verbose library probing (or set IM_VERBOSE in the environment)
688 Disable logging (or set IM_NOLOG in the environment)
690 Add to the include search path
692 Add to the library search path
694 Build for coverage testing.
696 Build with assertions active.
702 # generate the PM MM argument
703 # I'd prefer to modify the public version, but there doesn't seem to be
704 # a public API to do that
707 my $instbase = '$(INST_LIBDIR)';
709 # first the basics, .pm and .pod files
710 $pm{"Imager.pm"} = "$instbase/Imager.pm";
712 my $mani = maniread();
714 for my $filename (keys %$mani) {
715 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
716 (my $work = $filename) =~ s/^lib//;
717 $pm{$filename} = $instbase . $work;
722 $pm{typemap} = $instbase . '/Imager/typemap';
724 # and the core headers
725 for my $filename (keys %$mani) {
726 if ($filename =~ /^\w+\.h$/) {
727 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
731 # and the generated header
732 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
741 if ($path =~ m!^~[/\\]!) {
742 defined $home or $home = $ENV{HOME};
743 if (!defined $home && $^O eq 'MSWin32'
744 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
745 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
747 unless (defined $home) {
748 $home = eval { (getpwuid($<))[7] };
750 defined $home or die "You supplied $path, but I can't find your home directory\n";
752 $path = File::Spec->catdir($home, $path);