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