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 my $trace_context; # trace context management to stderr
52 GetOptions("help" => \$help,
53 "enable=s" => \@enable,
54 "disable=s" => \@disable,
55 "incpath=s", \@incpaths,
56 "libpath=s" => \@libpaths,
57 "verbose|v" => \$VERBOSE,
59 'coverage' => \$coverage,
60 "assert|a" => \$assert,
61 "tracecontext" => \$trace_context);
65 if ($ENV{AUTOMATED_TESTING}) {
70 print "Verbose mode\n";
72 import Data::Dumper qw(Dumper);
81 if ($NOLOG) { print "Logging not compiled into module\n"; }
83 push @defines, [ IMAGER_LOG => 1, "Logging system" ];
87 push @defines, [ IM_ASSERT => 1, "im_assert() are effective" ];
91 push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
92 print "Malloc debugging enabled\n";
95 if (@enable && @disable) {
96 print STDERR "Only --enable or --disable can be used, not both, try --help\n";
102 my @incs; # all the places to look for headers
103 my @libs; # all the places to look for libraries
105 init(); # initialize global data
106 pathcheck(); # Check if directories exist
108 if (exists $ENV{IM_ENABLE}) {
109 my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
110 for my $key (keys %formats) {
111 delete $formats{$key} unless $en{$key};
115 my %en = map { $_ => 1 } map { split /,/ } @enable;
116 for my $key (keys %formats) {
117 delete $formats{$key} unless $en{$key};
121 delete @formats{map { split /,/ } @disable};
124 # Pick what libraries are used
135 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
136 my $frm = $formats{$frmkey};
137 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
138 $F_OBJECT .= ' ' .$frm->{objfiles};
139 if ($frm->{cflags}) {
140 $lib_cflags .= ' ' .$frm->{cflags};
141 ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
142 grep /^-I./, split ' ', $frm->{cflags};
144 if ($frm->{lflags}) {
145 $lib_lflags .= ' ' . $frm->{lflags};
148 $F_LIBS .= ' ' .$frm->{libfiles};
153 my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_,
154 grep !$definc{$_}, @incs;
155 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_,
156 grep !$deflib{$_}++, @libs) . $F_LIBS;
159 my $OSDEF = "-DOS_$^O";
161 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
162 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
164 my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
165 log.o gaussian.o conv.o pnm.o raw.o feat.o combine.o
166 filters.o dynaload.o stackmach.o datatypes.o
167 regmach.o trans2.o quant.o error.o convert.o
168 map.o tags.o palimg.o maskimg.o img8.o img16.o rotate.o
169 bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
170 imext.o scale.o rubthru.o render.o paste.o compose.o flip.o
173 if ($Config{useithreads}) {
174 if ($Config{i_pthread}) {
175 print "POSIX threads\n";
176 push @objs, "mutexpthr.o";
178 elsif ($^O eq 'MSWin32') {
179 print "Win32 threads\n";
180 push @objs, "mutexwin.o";
183 print "Unsupported threading model\n";
184 push @objs, "mutexnull.o";
185 if ($ENV{AUTOMATED_TESTING}) {
186 die "OS unsupported: no threading support code for this platform\n";
191 print "No threads\n";
192 push @objs, "mutexnull.o";
195 my @typemaps = qw(typemap.local typemap);
197 unshift @typemaps, "typemap.oldperl";
200 if ($trace_context) {
201 $CFLAGS .= " -DIMAGER_TRACE_CONTEXT";
207 'VERSION_FROM' => 'Imager.pm',
208 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
209 'DEFINE' => "$OSDEF $CFLAGS",
210 'INC' => "$lib_cflags $DFLAGS $F_INC",
211 'OBJECT' => join(' ', @objs, $F_OBJECT),
212 clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
216 'Test::More' => 0.47,
217 'Scalar::Util' => 1.00,
220 TYPEMAPS => \@typemaps,
224 if ($Config{gccversion}) {
225 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
226 $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
229 die "Don't know the coverage C flags for your compiler\n";
233 # eval to prevent warnings about versions with _ in them
234 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
235 if ($MM_ver > 6.06) {
236 $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
237 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
240 if ($MM_ver >= 6.46) {
245 "Parse::RecDescent" => 0
264 homepage => "http://imager.perl.org/",
265 repository => "git://git.imager.perl.org/imager.git",
266 bugtracker => "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager",
271 make_imconfig(\@defines);
273 if ($VERBOSE) { print Dumper(\%opts); }
274 mkdir('testout',0777); # since we cannot include it in the archive.
276 -d "probe" and rmdir "probe";
278 WriteMakefile(%opts);
282 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
283 if ($IMAGER_LIBS{$name}) {
292 print "Libraries found:\n" if @good;
293 print " $_\n" for @good;
294 print "Libraries *not* found:\n" if @bad;
295 print " $_\n" for @bad;
302 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
305 my @ims = grep /\.im$/, keys %$mani;
307 dyntest.$(MYEXTLIB) : dynfilt/Makefile
308 cd dynfilt && $(MAKE) $(PASTHRU)
310 lib/Imager/Regops.pm : regmach.h regops.perl
311 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
313 imconfig.h : Makefile.PL
314 $(ECHO) "imconfig.h out-of-date with respect to $?"
315 $(PERLRUN) Makefile.PL
316 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
318 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
319 $perl apidocs.perl lib/Imager/APIRef.pod
321 !.join('', map _im_rule($perl, $_), @ims)
326 my ($perl, $im) = @_;
328 (my $c = $im) =~ s/\.im$/.c/;
331 $c: $im lib/Imager/Preprocess.pm
332 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
338 # manual configuration of helper libraries
343 Please answer the following questions about
344 which formats are avaliable on your computer
346 press <return> to continue
349 <STDIN>; # eat one return
351 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
353 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
354 print "Enable $frm support: ";
357 if ($gz =~ m/^(y|yes|n|no)/i) {
358 $gz=substr(lc($gz),0,1);
360 delete $formats{$frm};
367 # automatic configuration of helper libraries
370 print "Automatic probing:\n" if $VERBOSE;
371 for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
372 delete $formats{$frm} if !checkformat($frm);
379 # print "checking path $path\n";
380 if ( !opendir(DH,$path) ) {
381 warn "Cannot open dir $path: $!\n";
384 my @l=grep { $chk->($_) } readdir(DH);
387 return map $path, @l;
391 my ($format, $frm) = @_;
393 my $lib_check=$formats{$frm}{'libcheck'};
394 my $inc_check=$formats{$frm}{'inccheck'};
399 push(@l, grep_directory($lp,$lib_check));
404 push(@i, $ip) if $inc_check->($ip,$frm);
407 printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
408 $formats{$frm}{incdir} = \@i;
409 $formats{$frm}{libdir} = \@l;
410 return 1 if scalar(@i && @l);
413 printf("%10s: not available\n", $frm);
422 print " checkformat($frm)\n" if $VERBOSE;
424 my $format = $formats{$frm};
427 if (my $code = $format->{'code'}) {
428 if (ref $code eq 'ARRAY') {
429 push @probes, @$code;
435 push @probes, \&_probe_default;
437 print " Calling probe function\n" if $VERBOSE;
439 for my $func (@probes) {
440 if ($func->($format, $frm)) {
448 if ($format->{postcheck}) {
449 print " Calling postcheck function\n" if $VERBOSE;
450 $format->{postcheck}->($format, $frm)
461 print " Include paths:\n";
462 for (@incs) { print $_,"\n"; }
464 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
467 print "\nLibrary paths:\n";
468 for (@libs) { print $_,"\n"; }
470 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
475 # Format data initialization
477 # format definition is:
479 # default include path
480 # files needed for include (boolean perl code)
483 # files needed for link (boolean perl code)
484 # object files needed for the format
489 my @definc = qw(/usr/include);
490 @definc{@definc}=(1) x @definc;
493 split(/\Q$Config{path_sep}/, $INCPATH),
494 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
496 if ($Config{locincpth}) {
497 push @incs, grep -d, split ' ', $Config{locincpth};
499 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
500 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
502 if ($Config{incpath}) {
503 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
507 /usr/include/freetype2
508 /usr/local/include/freetype2
509 /usr/local/include/freetype1/freetype
510 /usr/include /usr/local/include /usr/include/freetype
511 /usr/local/include/freetype);
512 if ($Config{ccflags}) {
513 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
515 @definc{@hidden} = (1) x @hidden;
518 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
519 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
520 if ($Config{loclibpth}) {
521 push @libs, grep -d, split ' ', $Config{loclibpth};
524 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
525 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
526 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
527 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
529 if ($^O eq 'cygwin') {
530 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
531 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
533 if ($Config{ldflags}) {
534 # some builds of perl put -Ldir into ldflags without putting it in
535 # loclibpth, let's extract them
536 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
537 split ' ', $Config{ldflags};
539 # don't mark them as seen - EU::MM will remove any libraries
540 # it can't find and it doesn't look for -L in ldflags
541 #@deflib{@hidden} = @hidden;
543 push @libs, grep -d, qw(/usr/local/lib);
545 $formats{'TT-fonts'}=
549 inccheck=>sub { -e catfile($_[0], 'freetype.h')
550 && !-e catfile($_[0], 'fterrors.h') },
551 libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
553 objfiles=>'fontft1.o',
554 code => \&freetype1_probe,
556 Truetype fonts are scalable fonts. They can include
557 kerning and hinting information and generally yield good
558 visual quality esp on low resultions. The freetype library is
559 used to rasterize for us. The only drawback is that there
560 are alot of badly designed fonts out there.}
563 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
570 defined($V) ? $V : "";
574 # Get information from environment variables
586 $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
598 # populate the environment so that sub-modules get the same info
600 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
601 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
602 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
608 open CONFIG, "> imconfig.h"
609 or die "Cannot create imconfig.h: $!\n";
611 /* This file is automatically generated by Makefile.PL.
612 Don't edit this file, since any changes will be lost */
614 #ifndef IMAGER_IMCONFIG_H
615 #define IMAGER_IMCONFIG_H
617 for my $define (@$defines) {
619 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
621 print CONFIG "#define $define->[0] $define->[1]\n";
623 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
627 Compiler supports the GCC __attribute__((format...)) syntax.
631 #define IMAGER_FORMAT_ATTR 1
636 if ($Config{d_snprintf}) {
638 /* We can use snprintf() */
639 #define IMAGER_SNPRINTF 1
644 if ($Config{d_vsnprintf}) {
646 /* We can use vsnprintf() */
647 #define IMAGER_VSNPRINTF 1
654 Type and format code for formatted output as with printf.
656 This is intended for formatting i_img_dim values.
658 typedef $Config{ivtype} i_dim_format_t;
659 #define i_DF $Config{ivdformat}
662 print CONFIG "\n#endif\n";
666 # probes for freetype1 by scanning @incs for the includes and
667 # @libs for the libs. This is done separately because freetype's headers
668 # are stored in a freetype or freetype1 directory under PREFIX/include.
670 # we could find the files with the existing mechanism, but it won't set
671 # -I flags correctly.
673 # This could be extended to freetype2 too, but freetype-config catches
675 sub freetype1_probe {
676 my ($frm, $frmkey) = @_;
680 for my $inc (@incs) {
681 for my $subdir (qw/freetype freetype1/) {
682 my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
684 $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
687 $found_inc = File::Spec->catdir($inc, $subdir);
694 for my $lib (@libs) {
695 my $a_path = File::Spec->catfile($lib, "libttf$aext");
696 my $l_path = File::Spec->catfile($lib, "libttf.$lext");
697 if (-e $a_path || -e $l_path) {
703 return unless $found_inc && $found_lib;
704 printf("%10s: includes %s - libraries %s\n", $frmkey,
705 ($found_inc ? 'found' : 'not found'),
706 ($found_lib ? 'found' : 'not found'));
708 $frm->{cflags} = "-I$found_inc";
709 $frm->{libfiles} = "-lttf";
715 return File::Spec->catfile(@_);
720 Usage: $0 [--enable feature1,feature2,...] [other options]
721 $0 [--disable feature1,feature2,...] [other options]
723 Possible feature names are:
727 Verbose library probing (or set IM_VERBOSE in the environment)
729 Disable logging (or set IM_NOLOG in the environment)
731 Add to the include search path
733 Add to the library search path
735 Build for coverage testing.
737 Build with assertions active.
743 # generate the PM MM argument
744 # I'd prefer to modify the public version, but there doesn't seem to be
745 # a public API to do that
748 my $instbase = '$(INST_LIBDIR)';
750 # first the basics, .pm and .pod files
751 $pm{"Imager.pm"} = "$instbase/Imager.pm";
753 my $mani = maniread();
755 for my $filename (keys %$mani) {
756 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
757 (my $work = $filename) =~ s/^lib//;
758 $pm{$filename} = $instbase . $work;
763 $pm{typemap} = $instbase . '/Imager/typemap';
765 # and the core headers
766 for my $filename (keys %$mani) {
767 if ($filename =~ /^\w+\.h$/) {
768 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
772 # and the generated header
773 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
782 if ($path =~ m!^~[/\\]!) {
783 defined $home or $home = $ENV{HOME};
784 if (!defined $home && $^O eq 'MSWin32'
785 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
786 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
788 unless (defined $home) {
789 $home = eval { (getpwuid($<))[7] };
791 defined $home or die "You supplied $path, but I can't find your home directory\n";
793 $path = File::Spec->catdir($home, $path);