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
282 homepage => "http://imager.perl.org/",
285 url => "git://git.imager.perl.org/imager.git",
286 web => "http://git.imager.perl.org/imager.git",
291 web => "https://rt.cpan.org/Dist/Display.html?Name=Imager",
297 make_imconfig(\@defines);
299 if ($VERBOSE) { print Dumper(\%opts); }
300 mkdir('testout',0777); # since we cannot include it in the archive.
302 -d "probe" and rmdir "probe";
304 WriteMakefile(%opts);
308 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
309 if ($IMAGER_LIBS{$name}) {
318 print "Libraries found:\n" if @good;
319 print " $_\n" for @good;
320 print "Libraries *not* found:\n" if @bad;
321 print " $_\n" for @bad;
328 my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
331 my @ims = grep /\.im$/, keys %$mani;
333 dyntest.$(MYEXTLIB) : dynfilt/Makefile
334 cd dynfilt && $(MAKE) $(PASTHRU)
336 lib/Imager/Regops.pm : regmach.h regops.perl
337 $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
339 imconfig.h : Makefile.PL
340 $(ECHO) "imconfig.h out-of-date with respect to $?"
341 $(PERLRUN) Makefile.PL
342 $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
344 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
345 $perl apidocs.perl lib/Imager/APIRef.pod
347 !.join('', map _im_rule($perl, $_), @ims)
352 my ($perl, $im) = @_;
354 (my $c = $im) =~ s/\.im$/.c/;
357 $c: $im lib/Imager/Preprocess.pm
358 $perl -Ilib -MImager::Preprocess -epreprocess $im $c
364 # manual configuration of helper libraries
369 Please answer the following questions about
370 which formats are avaliable on your computer
372 Warning: if you use manual configuration you are responsible for
373 configuring extra include/library directories as necessary using
374 INC and LIBS command-line assignments.
376 press <return> to continue
379 <STDIN>; # eat one return
381 for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
383 if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
384 print "Enable $frm support: ";
387 if ($gz =~ m/^(y|yes|n|no)/i) {
389 $formats{$frm}{enabled} = 1;
390 $IMAGER_LIBS{$frm} = 1;
397 # automatic configuration of helper libraries
400 print "Automatic probing:\n" if $VERBOSE;
402 if (grep $_ eq "FT1", @enabled_bundled) {
406 inccheck => sub { -e File::Spec->catfile($_[0], "ftnameid.h") },
408 testcode => _ft1_test_code(),
409 testcodeheaders => [ "freetype.h", "stdio.h" ],
410 incpaths => \@incpaths,
411 libpaths => \@libpaths,
415 incsuffix => "freetype",
420 my $probe_res = Imager::Probe->probe(\%probe);
421 $IMAGER_LIBS{FT1} = defined $probe_res;
423 $formats{FT1}{enabled} = 1;
424 @{$formats{FT1}}{qw/DEFINE INC LIBS/} =
425 @$probe_res{qw/DEFINE INC LIBS/};
433 print " Include paths:\n";
434 for (@incs) { print $_,"\n"; }
436 @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
439 print "\nLibrary paths:\n";
440 for (@libs) { print $_,"\n"; }
442 @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
447 # Format data initialization
449 # format definition is:
451 # default include path
452 # files needed for include (boolean perl code)
455 # files needed for link (boolean perl code)
456 # object files needed for the format
461 my @definc = qw(/usr/include);
462 @definc{@definc}=(1) x @definc;
465 split(/\Q$Config{path_sep}/, $INCPATH),
466 map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths
468 if ($Config{locincpth}) {
469 push @incs, grep -d, split ' ', $Config{locincpth};
471 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
472 push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
474 if ($Config{incpath}) {
475 push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
479 /usr/include/freetype2
480 /usr/local/include/freetype2
481 /usr/local/include/freetype1/freetype
482 /usr/include /usr/local/include /usr/include/freetype
483 /usr/local/include/freetype);
484 if ($Config{ccflags}) {
485 my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
487 @definc{@hidden} = (1) x @hidden;
490 @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
491 map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
492 if ($Config{loclibpth}) {
493 push @libs, grep -d, split ' ', $Config{loclibpth};
496 push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'});
497 push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
498 if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
499 push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
501 if ($^O eq 'cygwin') {
502 push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
503 push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
505 if ($Config{ldflags}) {
506 # some builds of perl put -Ldir into ldflags without putting it in
507 # loclibpth, let's extract them
508 my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
509 split ' ', $Config{ldflags};
511 # don't mark them as seen - EU::MM will remove any libraries
512 # it can't find and it doesn't look for -L in ldflags
513 #@deflib{@hidden} = @hidden;
515 push @libs, grep -d, qw(/usr/local/lib);
521 objfiles=>'fontft1.o',
524 Freetype 1.x supports Truetype fonts and is obsoleted by Freetype 2.x.
526 It's probably insecure.
530 for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; }
537 print " $_[0]: '$V'\n"
538 if $VERBOSE && defined $V;
539 defined($V) ? $V : "";
543 # Get information from environment variables
547 $VERBOSE ||= gen("IM_VERBOSE");
549 print "Environment config:\n" if $VERBOSE;
558 $DFLAGS) = map { gen $_ } qw(IM_INCPATH
568 # populate the environment so that sub-modules get the same info
570 $ENV{IM_VERBOSE} = 1 if $VERBOSE;
571 $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
572 $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
578 open CONFIG, "> imconfig.h"
579 or die "Cannot create imconfig.h: $!\n";
581 /* This file is automatically generated by Makefile.PL.
582 Don't edit this file, since any changes will be lost */
584 #ifndef IMAGER_IMCONFIG_H
585 #define IMAGER_IMCONFIG_H
587 for my $define (@$defines) {
589 print CONFIG "\n/*\n $define->[2]\n*/\n\n";
591 print CONFIG "#define $define->[0] $define->[1]\n";
593 if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
597 Compiler supports the GCC __attribute__((format...)) syntax.
601 #define IMAGER_FORMAT_ATTR 1
606 if ($Config{d_snprintf}) {
608 /* We can use snprintf() */
609 #define IMAGER_SNPRINTF 1
614 if ($Config{d_vsnprintf}) {
616 /* We can use vsnprintf() */
617 #define IMAGER_VSNPRINTF 1
624 Type and format code for formatted output as with printf.
626 This is intended for formatting i_img_dim values.
628 typedef $Config{ivtype} i_dim_format_t;
629 #define i_DF $Config{ivdformat}
632 print CONFIG "\n#endif\n";
638 Usage: $0 [--enable feature1,feature2,...] [other options]
639 $0 [--disable feature1,feature2,...] [other options]
641 Possible feature names are:
645 Verbose library probing (or set IM_VERBOSE in the environment)
647 Disable logging (or set IM_NOLOG in the environment)
649 Add to the include search path
651 Add to the library search path
653 Build for coverage testing.
655 Build with assertions active.
661 # generate the PM MM argument
662 # I'd prefer to modify the public version, but there doesn't seem to be
663 # a public API to do that
666 my $instbase = '$(INST_LIBDIR)';
668 # first the basics, .pm and .pod files
669 $pm{"Imager.pm"} = "$instbase/Imager.pm";
671 my $mani = maniread();
673 for my $filename (keys %$mani) {
674 if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
675 (my $work = $filename) =~ s/^lib//;
676 $pm{$filename} = $instbase . $work;
681 $pm{typemap} = $instbase . '/Imager/typemap';
683 # and the core headers
684 for my $filename (keys %$mani) {
685 if ($filename =~ /^\w+\.h$/) {
686 $pm{$filename} = $instbase . '/Imager/include/' . $filename;
690 # and the generated header
691 $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
700 if ($path =~ m!^~[/\\]!) {
701 defined $home or $home = $ENV{HOME};
702 if (!defined $home && $^O eq 'MSWin32'
703 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
704 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
706 unless (defined $home) {
707 $home = eval { (getpwuid($<))[7] };
709 defined $home or die "You supplied $path, but I can't find your home directory\n";
711 $path = File::Spec->catdir($home, $path);
722 error = TT_Init_FreeType(&engine);
724 printf("FT1: Could not initialize engine\n");
735 @names = map { split /,/ } @names;
738 for my $name (@names) {
739 push @outnames, $name;
740 push @outnames, $bundled_names{$name}
741 if $bundled_names{$name};