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);
173 'VERSION_FROM' => 'Imager.pm',
174 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
175 'DEFINE' => "$OSDEF $CFLAGS",
176 'INC' => "$lib_cflags $DFLAGS $F_INC",
177 'OBJECT' => join(' ', @objs, $F_OBJECT),
178 clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
182 'Test::More' => 0.47,
183 'Scalar::Util' => 1.00,
188 if ($Config{gccversion}) {
189 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
190 $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
193 die "Don't know the coverage C flags for your compiler\n";
197 # eval to prevent warnings about versions with _ in them
198 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
199 if ($MM_ver > 6.06) {
200 $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
201 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
204 if ($MM_ver >= 6.46) {
209 "Parse::RecDescent" => 0
228 homepage => "http://imager.perl.org/",
229 repository => "git://git.imager.perl.org/imager.git",
230 bugtracker => "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager",
235 make_imconfig(\@defines);
237 if ($VERBOSE) { print Dumper(\%opts); }
238 mkdir('testout',0777); # since we cannot include it in the archive.
240 -d "probe" and rmdir "probe";
242 WriteMakefile(%opts);
246 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
247 if ($IMAGER_LIBS{$name}) {
256 print "Libraries found:\n" if @good;
257 print " $_\n" for @good;
258 print "Libraries *not* found:\n" if @bad;
259 print " $_\n" for @bad;
266 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
269 my @ims = grep /\.im$/, keys %$mani;
271 dyntest.$(MYEXTLIB) : dynfilt/Makefile
272 cd dynfilt && $(MAKE) $(PASTHRU)
274 lib/Imager/Regops.pm : regmach.h regops.perl
275 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
277 imconfig.h : Makefile.PL
278 $(ECHO) "imconfig.h out-of-date with respect to $?"
279 $(PERLRUN) Makefile.PL
280 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
282 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
283 $perl apidocs.perl lib/Imager/APIRef.pod
285 !.join('', map _im_rule($perl, $_), @ims)
290 my ($perl, $im) = @_;
292 (my $c = $im) =~ s/\.im$/.c/;
295 $c: $im lib/Imager/Preprocess.pm
296 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
302 # manual configuration of helper libraries
307 Please answer the following questions about
308 which formats are avaliable on your computer
310 press <return> to continue
313 <STDIN>; # eat one return
315 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
317 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
318 print "Enable $frm support: ";
321 if ($gz =~ m/^(y|yes|n|no)/i) {
322 $gz=substr(lc($gz),0,1);
324 delete $formats{$frm};
331 # automatic configuration of helper libraries
334 print "Automatic probing:\n" if $VERBOSE;
335 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
336 delete $formats{$frm} if !checkformat($frm);
343 # print "checking path $path\n";
344 if ( !opendir(DH,$path) ) {
345 warn "Cannot open dir $path: $!\n";
348 my @l=grep { $chk->($_) } readdir(DH);
351 return map $path, @l;
355 my ($format, $frm) = @_;
357 my $lib_check=$formats{$frm}{'libcheck'};
358 my $inc_check=$formats{$frm}{'inccheck'};
363 push(@l, grep_directory($lp,$lib_check));
368 push(@i, $ip) if $inc_check->($ip,$frm);
371 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
372 $formats{$frm}{incdir} = \@i;
373 $formats{$frm}{libdir} = \@l;
374 return 1 if scalar(@i && @l);
377 printf("%10s: not available\n", $frm);
386 print " checkformat($frm)\n" if $VERBOSE;
388 my $format = $formats{$frm};
391 if (my $code = $format->{'code'}) {
392 if (ref $code eq 'ARRAY') {
393 push @probes, @$code;
399 push @probes, \&_probe_default;
401 print " Calling probe function\n" if $VERBOSE;
403 for my $func (@probes) {
404 if ($func->($format, $frm)) {
412 if ($format->{postcheck}) {
413 print " Calling postcheck function\n" if $VERBOSE;
414 $format->{postcheck}->($format, $frm)
425 print " Include paths:\n";
426 for (@incs) { print $_,"\n"; }
428 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
431 print "\nLibrary paths:\n";
432 for (@libs) { print $_,"\n"; }
434 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
439 # Format data initialization
441 # format definition is:
443 # default include path
444 # files needed for include (boolean perl code)
447 # files needed for link (boolean perl code)
448 # object files needed for the format
453 my @definc = qw(/usr/include);
454 @definc{@definc}=(1) x @definc;
457 split(/\Q$Config{path_sep}/, $INCPATH),
458 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
460 if ($Config{locincpth}) {
461 push @incs, grep -d, split ' ', $Config{locincpth};
463 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
464 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
466 if ($Config{incpath}) {
467 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
471 /usr/include/freetype2
472 /usr/local/include/freetype2
473 /usr/local/include/freetype1/freetype
474 /usr/include /usr/local/include /usr/include/freetype
475 /usr/local/include/freetype);
476 if ($Config{ccflags}) {
477 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
479 @definc{@hidden} = (1) x @hidden;
482 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
483 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
484 if ($Config{loclibpth}) {
485 push @libs, grep -d, split ' ', $Config{loclibpth};
488 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
489 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
490 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
491 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
493 if ($^O eq 'cygwin') {
494 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
495 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
497 if ($Config{ldflags}) {
498 # some builds of perl put -Ldir into ldflags without putting it in
499 # loclibpth, let's extract them
500 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
501 split ' ', $Config{ldflags};
503 # don't mark them as seen - EU::MM will remove any libraries
504 # it can't find and it doesn't look for -L in ldflags
505 #@deflib{@hidden} = @hidden;
507 push @libs, grep -d, qw(/usr/local/lib);
509 $formats{'TT-fonts'}=
513 inccheck=>sub { -e catfile($_[0], 'freetype.h')
514 && !-e catfile($_[0], 'fterrors.h') },
515 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
518 code => \&freetype1_probe,
520 Truetype fonts are scalable fonts. They can include
521 kerning and hinting information and generally yield good
522 visual quality esp on low resultions. The freetype library is
523 used to rasterize for us. The only drawback is that there
524 are alot of badly designed fonts out there.}
527 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
534 defined($V) ? $V : "";
538 # Get information from environment variables
550 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
562 # populate the environment so that sub-modules get the same info
564 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
565 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
566 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
572 open CONFIG, "> imconfig.h"
573 or die "Cannot create imconfig.h: $!\n";
575 /* This file is automatically generated by Makefile.PL.
576 Don't edit this file, since any changes will be lost */
578 #ifndef IMAGER_IMCONFIG_H
579 #define IMAGER_IMCONFIG_H
581 for my $define (@$defines) {
583 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
585 print CONFIG "#define $define->[0] $define->[1]\n";
587 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
591 Compiler supports the GCC __attribute__((format...)) syntax.
595 #define IMAGER_FORMAT_ATTR 1
600 if ($Config{d_snprintf}) {
602 /* We can use snprintf() */
603 #define IMAGER_SNPRINTF 1
608 if ($Config{d_vsnprintf}) {
610 /* We can use vsnprintf() */
611 #define IMAGER_VSNPRINTF 1
618 Type and format code for formatted output as with printf.
620 This is intended for formatting i_img_dim values.
622 typedef $Config{ivtype} i_dim_format_t;
623 #define i_DF $Config{ivdformat}
626 print CONFIG "\n#endif\n";
630 # probes for freetype1 by scanning @incs for the includes and
631 # @libs for the libs. This is done separately because freetype's headers
632 # are stored in a freetype or freetype1 directory under PREFIX/include.
634 # we could find the files with the existing mechanism, but it won't set
635 # -I flags correctly.
637 # This could be extended to freetype2 too, but freetype-config catches
639 sub freetype1_probe {
640 my ($frm, $frmkey) = @_;
644 for my $inc (@incs) {
645 for my $subdir (qw/freetype freetype1/) {
646 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
648 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
651 $found_inc = File::Spec->catdir($inc, $subdir);
658 for my $lib (@libs) {
659 my $a_path = File::Spec->catfile($lib, "libttf$aext");
660 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
661 if (-e $a_path || -e $l_path) {
667 return unless $found_inc && $found_lib;
668 printf("%10s: includes %s - libraries %s\n", $frmkey,
669 ($found_inc ? 'found' : 'not found'),
670 ($found_lib ? 'found' : 'not found'));
672 $frm->{cflags} = "-I$found_inc";
673 $frm->{libfiles} = "-lttf";
679 return File::Spec->catfile(@_);
684 Usage: $0 [--enable feature1,feature2,...] [other options]
685 $0 [--disable feature1,feature2,...] [other options]
687 Possible feature names are:
691 Verbose library probing (or set IM_VERBOSE in the environment)
693 Disable logging (or set IM_NOLOG in the environment)
695 Add to the include search path
697 Add to the library search path
699 Build for coverage testing.
701 Build with assertions active.
707 # generate the PM MM argument
708 # I'd prefer to modify the public version, but there doesn't seem to be
709 # a public API to do that
712 my $instbase = '$(INST_LIBDIR)';
714 # first the basics, .pm and .pod files
715 $pm{"Imager.pm"} = "$instbase/Imager.pm";
717 my $mani = maniread();
719 for my $filename (keys %$mani) {
720 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
721 (my $work = $filename) =~ s/^lib//;
722 $pm{$filename} = $instbase . $work;
727 $pm{typemap} = $instbase . '/Imager/typemap';
729 # and the core headers
730 for my $filename (keys %$mani) {
731 if ($filename =~ /^\w+\.h$/) {
732 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
736 # and the generated header
737 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
746 if ($path =~ m!^~[/\\]!) {
747 defined $home or $home = $ENV{HOME};
748 if (!defined $home && $^O eq 'MSWin32'
749 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
750 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
752 unless (defined $home) {
753 $home = eval { (getpwuid($<))[7] };
755 defined $home or die "You supplied $path, but I can't find your home directory\n";
757 $path = File::Spec->catdir($home, $path);