1use ExtUtils::MakeMaker qw(prompt WriteMakefile);
2use ExtUtils::Constant 'WriteConstants';
3use Config;
4use strict;
5
6require 5.6.0;
7
8unless (@ARGV) {
9warn <<END;
10Notice: Type perl Makefile.PL -h for command-line option summary.
11
12END
13}
14
15
16# =====> PATHS: CHECK AND ADJUST <=====
17my (@INC,@LIBPATH,@LIBS,$LIBGD_VERSION);
18my $AUTOCONFIG = 0;      # global set by try_to_autoconfigure() below
19
20my ($options,$lib_gd_path,$lib_ft_path,$lib_png_path,$lib_jpeg_path,$lib_xpm_path,
21    $lib_zlib_path,$lib_fontconfig_path,$force,$FCGI,$gdlib_config_path);
22
23unless (try_to_autoconfigure() || $force) {
24    die <<END;
25**UNRECOVERABLE ERROR**
26Could not find gdlib-config nor pkgconfig/gdlib.pc. Please install libgd 2.0.28 or higher.
27In Debian and its derivatives (e.g. Ubuntu), it is provided by the libgd-dev or
28libgd2-xpm-dev package. Their libgd3 is the latest 2.2.5 (which has a severe security bug).
29On Redhat and derivatives or OpenSUSE you need gd-devel.
30On FreeBSD it is installed by the graphics/gd port.
31Mandriva has libgd2-devel, libgd-devel or lib64gd-devel.
32If you want to try to compile anyway, please rerun this script with the option --ignore_missing_gd.
33END
34}
35
36@INC     = qw(-I/usr/include -I/usr/include/gd) unless @INC;
37@LIBPATH = qw(-L/usr/lib/X11 -L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib) unless @LIBPATH;
38@LIBS    = qw(-lgd) unless @LIBS;
39
40# support for AMD64 libraries
41if (-d '/usr/lib64') {
42  my @libs64 = map {my $a = $_; $a=~ s/lib$/lib64/; $a} @LIBPATH;
43  @LIBPATH = (@LIBPATH,@libs64);
44}
45
46if( defined($options) )
47{
48    print "Included Features:          $options\n";
49}
50if( defined($lib_gd_path) )
51{
52    print "GD library used from:       $lib_gd_path\n";
53}
54if( defined($lib_ft_path) )
55{
56    print "FreeType library used from: $lib_ft_path\n";
57    @INC     = ("-I$lib_ft_path/include", @INC);
58    @LIBPATH = ("-L$lib_ft_path/lib", @LIBPATH);
59}
60if( defined($lib_png_path) )
61{
62    print "PNG library used from:      $lib_png_path\n";
63    @INC     = ("-I$lib_png_path/include", @INC);
64    @LIBPATH = ("-L$lib_png_path/lib", @LIBPATH);
65}
66if( defined($lib_jpeg_path) )
67{
68    print "JPEG library used from:      $lib_jpeg_path\n";
69    @INC     = ("-I$lib_jpeg_path/include", @INC);
70    @LIBPATH = ("-L$lib_jpeg_path/lib", @LIBPATH);
71}
72if( defined($lib_xpm_path) )
73{
74    print "XPM library used from:      $lib_xpm_path\n";
75    @INC     = ("-I$lib_xpm_path/include", @INC);
76    @LIBPATH = ("-L$lib_xpm_path/lib", @LIBPATH);
77}
78if( defined($lib_zlib_path) )
79{
80    print "Zlib library used from:     $lib_zlib_path\n";
81    @INC     = ("-I$lib_zlib_path/include", @INC);
82    @LIBPATH = ("-L$lib_zlib_path/lib", @LIBPATH);
83}
84if( defined($lib_fontconfig_path) )
85{
86    print "Fontconfig library used from:     $lib_fontconfig_path\n";
87    @INC     = ("-I$lib_fontconfig_path/include", @INC);
88    @LIBPATH = ("-L$lib_fontconfig_path/lib", @LIBPATH);
89}
90if( defined($gdlib_config_path) )
91{
92    print "gdlib-config used:          $gdlib_config_path\n";
93}
94else
95{
96    $gdlib_config_path = "gdlib-config";
97    print "$gdlib_config_path used from the PATH\n";
98}
99#############################################################################################
100
101push @LIBS, '-lfcgi' if $FCGI;
102
103if ($^O eq 'VMS'){
104  warn "This is a build on OpenVMS. In case of problems with the build\n";
105  warn "do not bother Lincoln Stein but get in touch with\n";
106  warn "Martin P.J. Zinser (zinser\@decus.de)\n\n";
107
108  if ($ENV{"LIB_ROOT"} eq "") {
109    warn "Define lib_root as a concealed logical pointing to the\n";
110    warn "Top directory where you have your libraries installed\n";
111    warn "E.g. define/job/trans=conc lib_root public\$device:[public.util.libs.]\n";
112    warn "Also define the logical pubbin to point to the location\n";
113    warn "of the object libraries\n";
114    warn "Then re-invoke Makefile.PL\n";
115    warn "Exiting now...\n";
116    exit;
117  }
118
119  @INC     = qw(-I/lib_root/gd -I/lib_root/libpng -I/lib_root/zlib);
120  @LIBPATH = qw(-Lpubbin);
121  @LIBS    = qw(-llibgd.olb -llibpng.olb -llibz.olb);
122}
123
124# workaround for solaris and other systems
125elsif ($^O =~ /(solaris|hpux)/i) {
126    push @LIBS,'-liconv';
127}
128
129###################################################################
130# path to libgd, skip prompt if passed in from above
131###################################################################
132my $PREFIX = $lib_gd_path;
133if( ! defined($lib_gd_path) )
134{
135  warn "\n";
136  $PREFIX = prompt('Where is libgd installed?','/usr/lib');
137}
138
139unless ($AUTOCONFIG || $PREFIX eq '/usr/lib') {
140  $PREFIX =~ s!/lib$!!;
141  unshift @INC,"-I$PREFIX/include";
142  unshift @LIBPATH,"-L$PREFIX/lib";
143}
144
145# FEATURE FLAGS
146
147##################################################################################################################
148# If build options have not been passed in then prompt for settings
149##################################################################################################################
150my ($JPEG, $FT, $XPM, $GIF,$ANIMGIF,$UNCLOSEDPOLY,$FONTCONFIG,$PNG,$FTCIRCLE,$VERSION_33);
151if( defined($options) )
152{
153  # WBMP is builtin since at least 1.8.0
154  $JPEG      = $options =~ m/JPEG/i;
155  $FT        = $options =~ m/FT|FREETYPE/i;
156  $XPM       = $options =~ m/XPM/i;
157  $GIF       = $options =~ m/GIF/i;
158  $PNG       = $options =~ m/PNG/i;
159  $ANIMGIF   = $GIF && $options =~ m/ANIMGIF/i;
160  $VERSION_33= $options =~ m/VERSION_33/i; # i.e. 2.0.33 or higher
161  $UNCLOSEDPOLY  = $options =~ m/UNCLOSEDPOLY/i;
162  $FONTCONFIG  = $options =~ m/FONTCONFIG/i;
163  $FTCIRCLE  = $options =~ m/FTCIRCLE/i;
164}
165else
166{
167    warn "\nPlease choose the features that match how libgd was built:\n";
168    $JPEG    = lc prompt('Build JPEG support?','y') eq 'y';
169    $PNG     = lc prompt('Build PNG support?','y') eq 'y';
170    $FT      = lc prompt('Build FreeType support?','y') eq 'y';
171    if ($FT) {
172      $FONTCONFIG = lc prompt('Build fontconfig support?','y') eq 'y';
173      $FTCIRCLE   = lc prompt('Build with FTCircle support?','y') eq 'y';
174    }
175    $GIF     = lc prompt('Build GIF support?','y') eq 'y';
176    $ANIMGIF = $GIF && lc prompt('Build support for animated GIFs?','y') eq 'y';
177    $XPM     = $^O !~ /^freebsd|MSWin32$/ && lc prompt('Build XPM support?','y') eq 'y';
178}
179##################################################################################################################
180
181#### no user-serviceable parts below #####
182
183if (!$AUTOCONFIG) {
184  warn "\nIf you experience compile problems, please check the \@INC, \@LIBPATH and \@LIBS\n",
185       "arrays defined in Makefile.PL and manually adjust, if necessary.\n\n";
186
187  push @LIBS,'-lfreetype'      if $FT;
188  push @LIBS,'-ljpeg'          if $JPEG;
189  push @LIBS,'-lpng','-lz'     if $PNG;
190  push @LIBS,'-lm'             unless $^O eq 'MSWin32';
191  push @INC, '-I/lib_root/libjpeg' if ($JPEG && $^O eq 'VMS');
192  push @INC, '-I/lib_root/ft2/include/freetype' if ($FT && $^O eq 'VMS');
193  push @INC, '-I/X11' if ($XPM && $^O eq 'VMS');
194
195  # FreeBSD 3.3 with libgd built from ports croaks if -lXpm is specified
196  if ($^O ne 'freebsd' && $^O ne 'MSWin32') {
197    push @LIBS,'-lX11','-lXpm' if $XPM;
198  }
199}
200
201my $CAPI = defined $ExtUtils::MakeMaker::CAPI_support;
202my $DEFINES = '';
203$DEFINES    .= ' -DHAVE_JPEG'    if $JPEG;
204$DEFINES    .= ' -DHAVE_FT'      if $FT;
205$DEFINES    .= ' -DHAVE_XPM'     if $XPM;
206$DEFINES    .= ' -DHAVE_GIF'     if $GIF;
207$DEFINES    .= ' -DHAVE_PNG'     if $PNG;
208$DEFINES    .= ' -DFCGI'         if $FCGI;
209$DEFINES    .= ' -DHAVE_ANIMGIF' if $ANIMGIF;
210$DEFINES    .= ' -DVERSION_33'   if $VERSION_33;
211$DEFINES    .= ' -DHAVE_UNCLOSEDPOLY' if $UNCLOSEDPOLY;
212$DEFINES    .= ' -DHAVE_FONTCONFIG'   if $FONTCONFIG;
213$DEFINES    .= ' -DHAVE_FTCIRCLE'  if $FTCIRCLE;
214$DEFINES    .= " -DLIBGD_VERSION=\"$LIBGD_VERSION\"" if defined($LIBGD_VERSION);
215open F,">.config.cache";
216print F $DEFINES,"\n";
217close F;
218
219my $CCFLAGS = $Config{ccflags};
220$CCFLAGS .= " -Wall -Wextra -Wformat=1" if $Config{gccversion} and $] > 5.020;
221# hardened CFLAGS for testing
222#$CCFLAGS .= ' -D_GNU_SOURCE -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches';
223
224my %WriteMakefileArgs = (
225    'NAME'	=> 'GD',
226    'ABSTRACT'  => 'Perl interface to the gd2 graphics library',
227    'VERSION_FROM'	=> 'lib/GD.pm',
228    'PREREQ_PM' => {
229        'Math::Trig' => 0,
230    },
231    'CONFIGURE_REQUIRES' => {
232        'ExtUtils::Constant' => 0.22,
233        'ExtUtils::PkgConfig' => 0,
234    },
235    'TEST_REQUIRES' => {
236        'Test::More' => 0.88,
237        'Test::Fork' => 0.02,
238    },
239    'PL_FILES'  => {'bdf_scripts/bdf2gdfont_pl.PL' => 'bdf_scripts/bdf2gdfont.pl',
240                    'lib/GD/Image_pm.PL' => 'lib/GD/Image.pm'},
241    'LIBS'      => [join(' ',$ENV{'GD_LIBS'},@LIBPATH,@LIBS)],
242    'INC'       => join(' ',$ENV{'GD_INC'},@INC),
243
244    'CCFLAGS'   => $CCFLAGS,
245    'EXE_FILES' => ['bdf_scripts/bdf2gdfont.pl'],
246    'AUTHOR'    => 'Lincoln Stein <lincoln.stein@gmail.com>',
247     # Maintained by Reini Urban now
248     $CAPI ? ('CAPI'      => 'TRUE') : (),
249    'DEFINE'	=> $DEFINES,
250    'clean'     => {
251        FILES => '.config.cache cover_db MANIFEST.git *.gcov GD.gcda GD.gcno'
252                .' META.yml META.json'
253     },
254    'LICENSE'   => 'perl_5',
255
256    'META_MERGE' => {
257         recommends => {
258            'ExtUtils::Constant'=> '0.23',
259            'Test::More'        => '0.88',
260            'Test::Kwalitee'    => 0,
261            'Class::XSAccessor' => 0,
262            'Text::CSV_XS'      => 0,
263            'List::MoreUtils'   => 0,
264            'Pod::Spell::CommonMistakes' => 0,
265            'Test::Pod'         => '1.00',
266         },
267         resources => {
268             repository => 'http://github.com/lstein/Perl-GD',
269             license    => 'http://dev.perl.org/licenses/',
270         },
271    },
272    SIGN => 1,
273);
274
275unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) {
276  my $br = delete $WriteMakefileArgs{BUILD_REQUIRES};
277  my $pp = $WriteMakefileArgs{PREREQ_PM};
278  for my $mod ( keys %$br ) {
279    if ( exists $pp->{$mod} ) {
280      $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod};
281    }
282    else {
283      $pp->{$mod} = $br->{$mod};
284    }
285  }
286}
287
288delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
289  unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
290delete $WriteMakefileArgs{TEST_REQUIRES}
291  unless eval { ExtUtils::MakeMaker->VERSION(6.52) };
292delete $WriteMakefileArgs{META_MERGE}
293  unless eval { ExtUtils::MakeMaker->VERSION(6.46) };
294
295WriteMakefile(%WriteMakefileArgs);
296
297my @constants_iv = qw(
298  GD_CMP_IMAGE
299  GD_CMP_NUM_COLORS
300  GD_CMP_COLOR
301  GD_CMP_SIZE_X
302  GD_CMP_SIZE_Y
303  GD_CMP_TRANSPARENT
304  GD_CMP_BACKGROUND
305  GD_CMP_INTERLACE
306  GD_CMP_TRUECOLOR
307  GD_PIXELATE_UPPERLEFT
308  GD_PIXELATE_AVERAGE
309
310  gdBrushed
311  gdDashSize
312  gdMaxColors
313  gdStyled
314  gdStyledBrushed
315  gdTiled
316  gdTransparent
317  gdAntiAliased
318  gdArc
319  gdPie
320  gdChord
321  gdNoFill
322  gdEdged
323
324  gdEffectReplace
325  gdEffectAlphaBlend
326  gdEffectNormal
327  gdEffectOverlay
328  gdEffectMultiply
329
330  gdAlphaMax
331  gdAlphaOpaque
332  gdAlphaTransparent
333  gdRedMax
334  gdGreenMax
335  gdBlueMax
336
337  GD_MAJOR_VERSION
338  GD_MINOR_VERSION
339  GD_RELEASE_VERSION
340
341  GD_FLIP_HORINZONTAL
342  GD_FLIP_VERTICAL
343  GD_FLIP_BOTH
344  GD_RESOLUTION
345
346  GD_DEFAULT
347  GD_BELL
348  GD_BESSEL
349  GD_BILINEAR_FIXED
350  GD_BICUBIC
351  GD_BICUBIC_FIXED
352  GD_BLACKMAN
353  GD_BOX
354  GD_BSPLINE
355  GD_CATMULLROM
356  GD_GAUSSIAN
357  GD_GENERALIZED_CUBIC
358  GD_HERMITE
359  GD_HAMMING
360  GD_HANNING
361  GD_MITCHELL
362  GD_NEAREST_NEIGHBOUR
363  GD_POWER
364  GD_QUADRATIC
365  GD_SINC
366  GD_TRIANGLE
367  GD_WEIGHTED4
368  GD_LINEAR
369  GD_METHOD_COUNT
370
371  GD_AFFINE_TRANSLATE
372  GD_AFFINE_SCALE
373  GD_AFFINE_ROTATE
374  GD_AFFINE_SHEAR_HORIZONTAL
375  GD_AFFINE_SHEAR_VERTICAL
376  );
377
378# Note that ExtUtils::Constant::ProxySubs creates code incompatible
379# with <5.14. Only 0.23_04 has that fixed.
380if (!-e 'const-xs.inc' or !-e"const-c.inc") {
381  WriteConstants(
382    #PROXYSUBS => {autoload => 1},
383    NAME => 'GD',
384    NAMES => \@constants_iv,
385    DEFAULT_TYPE => 'IV');
386}
387
388exit 0;
389
390sub try_to_autoconfigure {
391  #my ($options,$lib_gd_path,$INC,$LIBPATH,$LIBS) = @_;
392  my ($version, $cflags, $ldflags, $libs, $libdir, $features, $includedir);
393  # perl Makefile.PL --lib_gd_path /opt/libgd/2.1.1/lib
394  my ($prefix) = $lib_gd_path ? ($lib_gd_path =~ m|(^.*)/lib|) : "";
395  my $bindir = $prefix ? "$prefix/bin/" : $lib_gd_path ? "$lib_gd_path/bin/" : "";
396  my $config = `${bindir}gdlib-config --all` if -e "${bindir}gdlib-config";
397  if (!$config
398      and !-e "$prefix/lib/pkgconfig/gdlib.pc"
399      and !-e "/usr/lib/pkgconfig/gdlib.pc")
400  {
401    $gdlib_config_path = "gdlib-config" unless defined($gdlib_config_path);
402    $config = `$gdlib_config_path --all`;
403  }
404  unless ($config) {
405      my %config;
406      require ExtUtils::PkgConfig;
407      %config = ExtUtils::PkgConfig->find ("$prefix/lib/pkgconfig/gdlib.pc") if $prefix;
408      %config = ExtUtils::PkgConfig->find ("gdlib") unless %config;
409      return unless %config;
410      $version  = $config{modversion};
411      warn "Configuring for libgd version $version.\n";
412      $cflags   = $config{cflags};
413      $libs     = $config{libs};
414      ($libdir, $libs) = $libs =~ m/-L(.*) (-lgd.*)/;
415      # Requires.private:   zlib  libpng  freetype2 >= 9.8.3  fontconfig  libjpeg  xpm  libtiff-4
416      # Libs.private:   -L/opt/local/lib -lz  -L/opt/local/lib -lpng16  -L/opt/local/lib -lfreetype  -L/opt/local/lib -lfontconfig -lfreetype   -ljpeg  -L/opt/local/lib -lXpm -lX11  -L/opt/local/lib -ltiff   -lwebp
417      # not in the hash!
418      $features = 'GD_GIF GD_OPENPOLYGON GD_ZLIB GD_PNG GD_FREETYPE GD_FONTCONFIG GD_JPEG GD_XPM GD_TIFF GD_WEBP';
419      $AUTOCONFIG++;
420  } else {
421      $AUTOCONFIG++;
422
423      ($version) = $config =~ /^GD library\s+(\S+)/m;
424      warn "Configuring for libgd version $version.\n";
425
426      ($includedir) = $config =~ /^includedir:\s*(.+)$/m;
427      ($cflags)     = $config =~ /^cflags:\s*(.+)$/m;
428      ($ldflags)    = $config =~ /^ldflags:\s*(.+)$/m;
429      ($libs)       = $config =~ /^libs:\s*(.+)$/m;
430      ($libdir)     = $config =~ /^libdir:\s*(.+)$/m;
431      ($features)   = $config =~ /^features:\s*(.+)$/m;
432      ($includedir) = $config =~ /^includedir:\s*(.+)$/m;
433  }
434
435  $LIBGD_VERSION = $version;
436  @INC           = map {s/^-I// && "-I$_"} split /\s+/,$cflags;
437  @LIBS          = split /\s+/,$libs;
438  if ($libdir) {
439      if ($config) {
440          @LIBPATH      = map {s/^-L// && "-L$_"} split /\s+/,$ldflags;
441          ($lib_gd_path = $libdir) =~ s!/[^/]+$!!;
442      } else {
443          $lib_gd_path = $libdir;
444      }
445      push @LIBPATH,"-L$libdir";
446  }
447  push @LIBS,"-lgd" unless $libs =~ /-lgd/;
448  if (!$options) {
449    $options = $features;
450
451    my ($release, $major, $minor) = $version =~ /^(\d+)\.(\d+)\.(\d+)/;
452    $options     .= " GD_UNCLOSEDPOLY GD_ANIMGIF GD_FTCIRCLE VERSION_33"
453      if defined($minor)
454      && ($release > 2
455          || ($release == 2 && $major > 0)
456          || ($release == 2 && $major == 0 && $minor >= 33));
457  }
458
459  if ($config) {
460      my @correct_inc = map {s/^-I// && $_} split /\s+/,$cflags;
461      check_for_stray_headers($includedir,@correct_inc);
462  }
463  return 1;
464}
465
466sub check_for_stray_headers {
467  my @official_libraries = @_;
468  my %official_libraries = map {$_=>1} @official_libraries;
469  print STDERR "Checking for stray libgd header files...";
470  my $cc          = $Config{'cc'};
471  my $data        = `$cc -print-search-dirs 2>/dev/null`;
472  $data         ||= '';
473  my ($libraries)    = $data =~ /^libraries: =(.+)/m;
474  my @cc_libs        = split /:/,$libraries;
475  foreach (@cc_libs) { s/\/$//; }
476
477  my %libraries   = map {$_=>1} (@cc_libs,'/include','/usr/include',
478				 '/usr/local/include','/opt/include',
479				 '/usr/X11R6/include');
480  my $problems;
481  my $o = $official_libraries[0];
482  foreach (keys %libraries) {
483
484    s/\blib\b/include/;
485    next if $official_libraries{$_};
486    next unless -e "$_/gd.h";
487    if (-l "$_/gd.h" or -l "$o/gd.h") {
488      next if (stat("$_/gd.h"))[1] == (stat("$o/gd.h"))[1];
489    }
490
491    warn "\n\n** WARNING: found gd.h header file in ${_}/gd.h, but it is expected at $official_libraries[0]/gd.h. This may cause compile errors! **\n";
492    $problems++;
493  }
494  print STDERR $problems ? "** Possible problems found **\n" : "none found.\n";
495  print STDERR "\n";
496}
497
498sub MY::postamble {
499    my $postamble = <<'END';
500html: lib/GD.pm
501	pod2html --outfile=GD.html lib/GD.pm
502
503END
504    $postamble;
505}
506
507package MY;
508
509# Ignore templates
510sub libscan {
511    return 0 if $_[1] =~ /_p[ml].PL$/;
512    return $_[1];
513}
514
515
516sub processPL {
517    my $inherited = shift->SUPER::processPL(@_);
518    $inherited    =~ s/(:: lib\/GD\/Image_pm\.PL)/$1 .config.cache/;
519    $inherited;
520}
521
522sub depend {
523  "
524release : dist
525	git tag release_\$(VERSION_SYM)
526	cpan-upload \$(DISTVNAME).tar\$(SUFFIX)
527	git push
528	git push --tags
529
530const-c.inc const-xs.inc : Makefile.PL
531
532GCOV = gcov
533test_cover :: pure_all
534	\$(RM_RF) cover_db
535	+\$(PERLRUNINST) -S cover -test
536
537test_coveralls :: pure_all
538	+\$(PERLRUNINST) -S cover -test -report coveralls
539
540gcov : \$(BASEEXT).c.gcov \$(BASEEXT).gcov cover_db/\$(BASEEXT)-xs.html
541
542\$(BASEEXT).c.gcov \$(BASEEXT).xs.gcov : \$(BASEEXT).xs
543	\$(MAKE) CCFLAGS=\"\$(CCFLAGS) -fprofile-arcs -ftest-coverage\" LDDLFLAGS=\"\$(LDDLFLAGS) -fprofile-arcs -ftest-coverage\"
544	\$(GCOV) \$(BASEEXT).c \$(BASEEXT).xs
545
546cover_db/\$(BASEEXT)-xs.html : \$(BASEEXT).xs.gcov
547	PERL5OPT=-MDevel::Cover make test
548	-$^X -S gcov2perl \$(BASEEXT).c.gcov \$(BASEEXT).xs.gcov
549	$^X -S cover
550
551gprof :
552	\$(MAKE) CCFLAGS=\"\$(CCFLAGS) -pg\" LDDLFLAGS=\"\$(LDDLFLAGS) -pg\"
553"
554}
555