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 # make sure --verbose will dump environment settings
40 if (grep $_ =~ /^--?v(?:erbose)?$/, @ARGV) {
44 # modules/features bundled with Imager that can be enabled/disabled
45 # withs --enable/--disable
46 my @bundled = qw(FT1 FT2 GIF JPEG PNG T1 TIFF W32);
48 # extra modules bundled with Imager not available on CPAN
49 my @extras = qw(CountColor DynTest ICO SGI Mandelbrot Flines);
51 # alternate names for modules
52 my %bundled_names = qw(win32 w32 tt ft1);
54 getenv(); # get environment variables
56 my $lext=$Config{'so'}; # Get extensions of libraries
57 my $aext=$Config{'_a'};
59 my $help; # display help if set
60 my @enable; # list of drivers to enable
61 my @disable; # or list of drivers to disable
62 my @incpaths; # places to look for headers
63 my @libpaths; # places to look for libraries
64 my $coverage; # build for coverage testing
65 my $assert; # build with assertions
66 my $trace_context; # trace context management to stderr
67 GetOptions("help" => \$help,
68 "enable=s" => \@enable,
69 "disable=s" => \@disable,
70 "incpath=s", \@incpaths,
71 "libpath=s" => \@libpaths,
72 "verbose|v" => \$VERBOSE,
74 'coverage' => \$coverage,
75 "assert|a" => \$assert,
76 "tracecontext" => \$trace_context);
80 if ($ENV{AUTOMATED_TESTING}) {
85 print "Verbose mode\n";
87 import Data::Dumper qw(Dumper);
96 if ($NOLOG) { print "Logging not compiled into module\n"; }
98 push @defines, [ IMAGER_LOG => 1, "Logging system" ];
102 push @defines, [ IM_ASSERT => 1, "im_assert() are effective" ];
106 push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
107 print "Malloc debugging enabled\n";
110 if (@enable && @disable) {
111 print STDERR "Only --enable or --disable can be used, not both, try --help\n";
117 my @incs; # all the places to look for headers
118 my @libs; # all the places to look for libraries
120 init(); # initialize global data
121 pathcheck(); # Check if directories exist
124 if (exists $ENV{IM_ENABLE}) {
125 push @enable, split ' ', $ENV{IM_ENABLE};
128 my %en = map { lc $_ => 1 } map_bundled(@enable);
129 @enabled_bundled = grep $en{lc $_}, @bundled;
132 my %dis = map { lc $_ => 1 } map_bundled(@disable);
133 @enabled_bundled = grep !$dis{lc $_}, @bundled;
136 @enabled_bundled = @bundled;
139 # Pick what libraries are used
146 my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
147 log.o gaussian.o conv.o pnm.o raw.o feat.o combine.o
148 filters.o dynaload.o stackmach.o datatypes.o
149 regmach.o trans2.o quant.o error.o convert.o
150 map.o tags.o palimg.o maskimg.o img8.o img16.o rotate.o
151 bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
152 imext.o scale.o rubthru.o render.o paste.o compose.o flip.o
158 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
159 my $frm = $formats{$frmkey};
160 if ($frm->{enabled}) {
161 push @defines, [ $frm->{def}, 1, "$frmkey available" ];
162 push @objs, $frm->{objfiles};
163 $lib_define .= " $frm->{DEFINE}" if $frm->{DEFINE};
164 $lib_inc .= " $frm->{INC}" if $frm->{INC};
165 $lib_libs .= " $frm->{LIBS}" if $frm->{LIBS};
170 my $OSDEF = "-DOS_$^O";
172 if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; }
173 if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; }
175 if ($Config{useithreads}) {
176 if ($Config{i_pthread}) {
177 print "POSIX threads\n";
178 push @objs, "mutexpthr.o";
180 elsif ($^O eq 'MSWin32') {
181 print "Win32 threads\n";
182 push @objs, "mutexwin.o";
185 print "Unsupported threading model\n";
186 push @objs, "mutexnull.o";
187 if ($ENV{AUTOMATED_TESTING}) {
188 die "OS unsupported: no threading support code for this platform\n";
193 print "No threads\n";
194 push @objs, "mutexnull.o";
197 my @typemaps = qw(typemap.local typemap);
199 unshift @typemaps, "typemap.oldperl";
202 if ($trace_context) {
203 $CFLAGS .= " -DIMAGER_TRACE_CONTEXT";
206 my $tests = 't/*.t t/*/*.t';
207 if (-d "xt" && scalar(() = glob("xt/*.t"))) {
214 VERSION_FROM => 'Imager.pm',
215 LIBS => "$LFLAGS -lm $lib_libs $OSLIBS",
216 DEFINE => "$OSDEF $lib_define $CFLAGS",
217 INC => "$lib_inc $DFLAGS",
218 OBJECT => join(' ', @objs),
219 DIR => [ sort grep -d, @enabled_bundled, @extras ],
220 clean => { FILES=>'testout rubthru.c scale.c conv.c filters.c gaussian.c render.c rubthru.c' },
224 'Test::More' => 0.47,
225 'Scalar::Util' => 1.00,
228 TYPEMAPS => \@typemaps,
229 test => { TESTS => $tests },
233 if ($Config{gccversion}) {
234 push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
235 $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
238 die "Don't know the coverage C flags for your compiler\n";
242 # eval to prevent warnings about versions with _ in them
243 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
244 if ($MM_ver > 6.06) {
245 $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
246 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
249 if ($MM_ver >= 6.46) {
254 "Parse::RecDescent" => 0
273 homepage => "http://imager.perl.org/",
274 repository => "git://git.imager.perl.org/imager.git",
275 bugtracker => "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager",
280 make_imconfig(\@defines);
282 if ($VERBOSE) { print Dumper(\%opts); }
283 mkdir('testout',0777); # since we cannot include it in the archive.
285 -d "probe" and rmdir "probe";
287 WriteMakefile(%opts);
291 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
292 if ($IMAGER_LIBS{$name}) {
301 print "Libraries found:\n" if @good;
302 print " $_\n" for @good;
303 print "Libraries *not* found:\n" if @bad;
304 print " $_\n" for @bad;
311 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
314 my @ims = grep /\.im$/, keys %$mani;
316 dyntest.$(MYEXTLIB) : dynfilt/Makefile
317 cd dynfilt && $(MAKE) $(PASTHRU)
319 lib/Imager/Regops.pm : regmach.h regops.perl
320 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
322 imconfig.h : Makefile.PL
323 $(ECHO) "imconfig.h out-of-date with respect to $?"
324 $(PERLRUN) Makefile.PL
325 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
327 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
328 $perl apidocs.perl lib/Imager/APIRef.pod
330 !.join('', map _im_rule($perl, $_), @ims)
335 my ($perl, $im) = @_;
337 (my $c = $im) =~ s/\.im$/.c/;
340 $c: $im lib/Imager/Preprocess.pm
341 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
347 # manual configuration of helper libraries
352 Please answer the following questions about
353 which formats are avaliable on your computer
355 Warning: if you use manual configuration you are responsible for
356 configuring extra include/library directories as necessary using
357 INC and LIBS command-line assignments.
359 press <return> to continue
362 <STDIN>; # eat one return
364 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
366 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
367 print "Enable $frm support: ";
370 if ($gz =~ m/^(y|yes|n|no)/i) {
372 $formats{$frm}{enabled} = 1;
373 $IMAGER_LIBS{$frm} = 1;
380 # automatic configuration of helper libraries
383 print "Automatic probing:\n" if $VERBOSE;
385 if (grep $_ eq "FT1", @enabled_bundled) {
389 inccheck => sub { -e File::Spec->catfile($_[0], "ftnameid.h") },
391 testcode => _ft1_test_code(),
392 testcodeheaders => [ "freetype.h", "stdio.h" ],
393 incpaths => \@incpaths,
394 libpaths => \@libpaths,
398 incsuffix => "freetype",
403 my $probe_res = Imager::Probe->probe(\%probe);
404 $IMAGER_LIBS{FT1} = defined $probe_res;
406 $formats{FT1}{enabled} = 1;
407 @{$formats{FT1}}{qw/DEFINE INC LIBS/} =
408 @$probe_res{qw/DEFINE INC LIBS/};
416 print " Include paths:\n";
417 for (@incs) { print $_,"\n"; }
419 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
422 print "\nLibrary paths:\n";
423 for (@libs) { print $_,"\n"; }
425 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
430 # Format data initialization
432 # format definition is:
434 # default include path
435 # files needed for include (boolean perl code)
438 # files needed for link (boolean perl code)
439 # object files needed for the format
444 my @definc = qw(/usr/include);
445 @definc{@definc}=(1) x @definc;
448 split(/\Q$Config{path_sep}/, $INCPATH),
449 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
451 if ($Config{locincpth}) {
452 push @incs, grep -d, split ' ', $Config{locincpth};
454 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
455 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
457 if ($Config{incpath}) {
458 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
462 /usr/include/freetype2
463 /usr/local/include/freetype2
464 /usr/local/include/freetype1/freetype
465 /usr/include /usr/local/include /usr/include/freetype
466 /usr/local/include/freetype);
467 if ($Config{ccflags}) {
468 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
470 @definc{@hidden} = (1) x @hidden;
473 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
474 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
475 if ($Config{loclibpth}) {
476 push @libs, grep -d, split ' ', $Config{loclibpth};
479 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
480 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
481 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
482 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
484 if ($^O eq 'cygwin') {
485 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
486 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
488 if ($Config{ldflags}) {
489 # some builds of perl put -Ldir into ldflags without putting it in
490 # loclibpth, let's extract them
491 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
492 split ' ', $Config{ldflags};
494 # don't mark them as seen - EU::MM will remove any libraries
495 # it can't find and it doesn't look for -L in ldflags
496 #@deflib{@hidden} = @hidden;
498 push @libs, grep -d, qw(/usr/local/lib);
504 objfiles=>'fontft1.o',
507 Freetype 1.x supports Truetype fonts and is obsoleted by Freetype 2.x.
509 It's probably insecure.
513 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
520 print " $_[0]: '$V'\n"
521 if $VERBOSE && defined $V;
522 defined($V) ? $V : "";
526 # Get information from environment variables
530 $VERBOSE ||= gen("IM_VERBOSE");
532 print "Environment config:\n" if $VERBOSE;
541 $DFLAGS) = map { gen $_ } qw(IM_INCPATH
551 # populate the environment so that sub-modules get the same info
553 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
554 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
555 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
561 open CONFIG, "> imconfig.h"
562 or die "Cannot create imconfig.h: $!\n";
564 /* This file is automatically generated by Makefile.PL.
565 Don't edit this file, since any changes will be lost */
567 #ifndef IMAGER_IMCONFIG_H
568 #define IMAGER_IMCONFIG_H
570 for my $define (@$defines) {
572 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
574 print CONFIG "#define $define->[0] $define->[1]\n";
576 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
580 Compiler supports the GCC __attribute__((format...)) syntax.
584 #define IMAGER_FORMAT_ATTR 1
589 if ($Config{d_snprintf}) {
591 /* We can use snprintf() */
592 #define IMAGER_SNPRINTF 1
597 if ($Config{d_vsnprintf}) {
599 /* We can use vsnprintf() */
600 #define IMAGER_VSNPRINTF 1
607 Type and format code for formatted output as with printf.
609 This is intended for formatting i_img_dim values.
611 typedef $Config{ivtype} i_dim_format_t;
612 #define i_DF $Config{ivdformat}
615 print CONFIG "\n#endif\n";
621 Usage: $0 [--enable feature1,feature2,...] [other options]
622 $0 [--disable feature1,feature2,...] [other options]
624 Possible feature names are:
628 Verbose library probing (or set IM_VERBOSE in the environment)
630 Disable logging (or set IM_NOLOG in the environment)
632 Add to the include search path
634 Add to the library search path
636 Build for coverage testing.
638 Build with assertions active.
644 # generate the PM MM argument
645 # I'd prefer to modify the public version, but there doesn't seem to be
646 # a public API to do that
649 my $instbase = '$(INST_LIBDIR)';
651 # first the basics, .pm and .pod files
652 $pm{"Imager.pm"} = "$instbase/Imager.pm";
654 my $mani = maniread();
656 for my $filename (keys %$mani) {
657 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
658 (my $work = $filename) =~ s/^lib//;
659 $pm{$filename} = $instbase . $work;
664 $pm{typemap} = $instbase . '/Imager/typemap';
666 # and the core headers
667 for my $filename (keys %$mani) {
668 if ($filename =~ /^\w+\.h$/) {
669 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
673 # and the generated header
674 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
683 if ($path =~ m!^~[/\\]!) {
684 defined $home or $home = $ENV{HOME};
685 if (!defined $home && $^O eq 'MSWin32'
686 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
687 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
689 unless (defined $home) {
690 $home = eval { (getpwuid($<))[7] };
692 defined $home or die "You supplied $path, but I can't find your home directory\n";
694 $path = File::Spec->catdir($home, $path);
705 error = TT_Init_FreeType(&engine);
707 printf("FT1: Could not initialize engine\n");
718 @names = map { split /,/ } @names;
721 for my $name (@names) {
722 push @outnames, $name;
723 push @outnames, $bundled_names{$name}
724 if $bundled_names{$name};