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.99,
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 if (eval { ExtUtils::MakeMaker->VERSION('6.06'); 1 }) {
243 $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
244 $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
247 if (eval { ExtUtils::MakeMaker->VERSION('6.46'); 1 }) {
248 $opts{LICENSE} = "perl_5";
254 url => "https://metacpan.org/pod/CPAN::Meta::Spec",
262 "Parse::RecDescent" => 0
266 'Scalar::Util' => "1.00",
281 'Test::More' => "0.99",
301 homepage => "http://imager.perl.org/",
304 url => "git://github.com/tonycoz/imager.git",
305 web => "https://github.com/tonycoz/imager.git",
310 web => "https://rt.cpan.org/Dist/Display.html?Name=Imager",
311 mailto => 'bug-Imager@rt.cpan.org',
317 make_imconfig(\@defines);
319 if ($VERBOSE) { print Dumper(\%opts); }
320 mkdir('testout',0777); # since we cannot include it in the archive.
322 -d "probe" and rmdir "probe";
324 WriteMakefile(%opts);
328 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
329 if ($IMAGER_LIBS{$name}) {
338 print "Libraries found:\n" if @good;
339 print " $_\n" for @good;
340 print "Libraries *not* found:\n" if @bad;
341 print " $_\n" for @bad;
348 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
351 my @ims = grep /\.im$/, keys %$mani;
353 dyntest.$(MYEXTLIB) : dynfilt/Makefile
354 cd dynfilt && $(MAKE) $(PASTHRU)
356 lib/Imager/Regops.pm : regmach.h regops.perl
357 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
359 imconfig.h : Makefile.PL
360 $(ECHO) "imconfig.h out-of-date with respect to $?"
361 $(PERLRUN) Makefile.PL
362 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
364 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
365 $perl apidocs.perl lib/Imager/APIRef.pod
367 !.join('', map _im_rule($perl, $_), @ims)
372 my ($perl, $im) = @_;
374 (my $c = $im) =~ s/\.im$/.c/;
377 $c: $im lib/Imager/Preprocess.pm
378 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
384 # manual configuration of helper libraries
389 Please answer the following questions about
390 which formats are avaliable on your computer
392 Warning: if you use manual configuration you are responsible for
393 configuring extra include/library directories as necessary using
394 INC and LIBS command-line assignments.
396 press <return> to continue
399 <STDIN>; # eat one return
401 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
403 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
404 print "Enable $frm support: ";
407 if ($gz =~ m/^(y|yes|n|no)/i) {
409 $formats{$frm}{enabled} = 1;
410 $IMAGER_LIBS{$frm} = 1;
417 # automatic configuration of helper libraries
420 print "Automatic probing:\n" if $VERBOSE;
422 if (grep $_ eq "FT1", @enabled_bundled) {
426 inccheck => sub { -e File::Spec->catfile($_[0], "ftnameid.h") },
428 testcode => _ft1_test_code(),
429 testcodeheaders => [ "freetype.h", "stdio.h" ],
430 incpaths => \@incpaths,
431 libpaths => \@libpaths,
435 incsuffix => "freetype",
440 my $probe_res = Imager::Probe->probe(\%probe);
441 $IMAGER_LIBS{FT1} = defined $probe_res;
443 $formats{FT1}{enabled} = 1;
444 @{$formats{FT1}}{qw/DEFINE INC LIBS/} =
445 @$probe_res{qw/DEFINE INC LIBS/};
453 print " Include paths:\n";
454 for (@incs) { print $_,"\n"; }
456 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
459 print "\nLibrary paths:\n";
460 for (@libs) { print $_,"\n"; }
462 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
467 # Format data initialization
469 # format definition is:
471 # default include path
472 # files needed for include (boolean perl code)
475 # files needed for link (boolean perl code)
476 # object files needed for the format
481 my @definc = qw(/usr/include);
482 @definc{@definc}=(1) x @definc;
485 split(/\Q$Config{path_sep}/, $INCPATH),
486 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
488 if ($Config{locincpth}) {
489 push @incs, grep -d, split ' ', $Config{locincpth};
491 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
492 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
494 if ($Config{incpath}) {
495 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
499 /usr/include/freetype2
500 /usr/local/include/freetype2
501 /usr/local/include/freetype1/freetype
502 /usr/include /usr/local/include /usr/include/freetype
503 /usr/local/include/freetype);
504 if ($Config{ccflags}) {
505 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
507 @definc{@hidden} = (1) x @hidden;
510 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
511 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
512 if ($Config{loclibpth}) {
513 push @libs, grep -d, split ' ', $Config{loclibpth};
516 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
517 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
518 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
519 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
521 if ($^O eq 'cygwin') {
522 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
523 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
525 if ($Config{ldflags}) {
526 # some builds of perl put -Ldir into ldflags without putting it in
527 # loclibpth, let's extract them
528 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
529 split ' ', $Config{ldflags};
531 # don't mark them as seen - EU::MM will remove any libraries
532 # it can't find and it doesn't look for -L in ldflags
533 #@deflib{@hidden} = @hidden;
535 push @libs, grep -d, qw(/usr/local/lib);
541 objfiles=>'fontft1.o',
544 Freetype 1.x supports Truetype fonts and is obsoleted by Freetype 2.x.
546 It's probably insecure.
550 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
557 print " $_[0]: '$V'\n"
558 if $VERBOSE && defined $V;
559 defined($V) ? $V : "";
563 # Get information from environment variables
567 $VERBOSE ||= gen("IM_VERBOSE");
569 print "Environment config:\n" if $VERBOSE;
578 $DFLAGS) = map { gen $_ } qw(IM_INCPATH
588 # populate the environment so that sub-modules get the same info
590 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
591 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
592 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
598 open CONFIG, "> imconfig.h"
599 or die "Cannot create imconfig.h: $!\n";
601 /* This file is automatically generated by Makefile.PL.
602 Don't edit this file, since any changes will be lost */
604 #ifndef IMAGER_IMCONFIG_H
605 #define IMAGER_IMCONFIG_H
607 for my $define (@$defines) {
609 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
611 print CONFIG "#define $define->[0] $define->[1]\n";
613 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
617 Compiler supports the GCC __attribute__((format...)) syntax.
621 #define IMAGER_FORMAT_ATTR 1
626 if ($Config{d_snprintf}) {
628 /* We can use snprintf() */
629 #define IMAGER_SNPRINTF 1
634 if ($Config{d_vsnprintf}) {
636 /* We can use vsnprintf() */
637 #define IMAGER_VSNPRINTF 1
644 Type and format code for formatted output as with printf.
646 This is intended for formatting i_img_dim values.
648 typedef $Config{ivtype} i_dim_format_t;
649 #define i_DF $Config{ivdformat}
652 print CONFIG "\n#endif\n";
658 Usage: $0 [--enable feature1,feature2,...] [other options]
659 $0 [--disable feature1,feature2,...] [other options]
661 Possible feature names are:
665 Verbose library probing (or set IM_VERBOSE in the environment)
667 Disable logging (or set IM_NOLOG in the environment)
669 Add to the include search path
671 Add to the library search path
673 Build for coverage testing.
675 Build with assertions active.
681 # generate the PM MM argument
682 # I'd prefer to modify the public version, but there doesn't seem to be
683 # a public API to do that
686 my $instbase = '$(INST_LIBDIR)';
688 # first the basics, .pm and .pod files
689 $pm{"Imager.pm"} = "$instbase/Imager.pm";
691 my $mani = maniread();
693 for my $filename (keys %$mani) {
694 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
695 (my $work = $filename) =~ s/^lib//;
696 $pm{$filename} = $instbase . $work;
701 $pm{typemap} = $instbase . '/Imager/typemap';
703 # and the core headers
704 for my $filename (keys %$mani) {
705 if ($filename =~ /^\w+\.h$/) {
706 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
710 # and the generated header
711 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
720 if ($path =~ m!^~[/\\]!) {
721 defined $home or $home = $ENV{HOME};
722 if (!defined $home && $^O eq 'MSWin32'
723 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
724 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
726 unless (defined $home) {
727 $home = eval { (getpwuid($<))[7] };
729 defined $home or die "You supplied $path, but I can't find your home directory\n";
731 $path = File::Spec->catdir($home, $path);
742 error = TT_Init_FreeType(&engine);
744 printf("FT1: Could not initialize engine\n");
755 @names = map { split /,/ } @names;
758 for my $name (@names) {
759 push @outnames, $name;
760 push @outnames, $bundled_names{$name}
761 if $bundled_names{$name};