1 # Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization 2 # dedicated to making software imaging solutions freely available. 3 # 4 # You may not use this file except in compliance with the License. You may 5 # obtain a copy of the License at 6 # 7 # https://imagemagick.org/script/license.php 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # 15 # Exercise all regression tests: 16 # 17 # make test 18 # 19 # Exersise one regression test: 20 # 21 # make TEST_VERBOSE=1 TEST_FILES=t/filter.t test 22 # 23 24 use ExtUtils::MakeMaker; 25 use Config; 26 use File::Spec::Functions qw/catfile catdir devnull catpath splitpath/; 27 use Cwd; 28 29 sub AutodetectWin32gcc { 30 my $wrkdir = getcwd(); 31 my $devnull = devnull(); 32 33 my @incdir = (); 34 my @libdir = ($wrkdir); 35 my @bindir = (); 36 37 #try to get configuration info via identify or convert utilities 38 my $conf = `identify -list Configure 2>$devnull` || `convert -list Configure 2>$devnull`; 39 foreach my $line (split '\n', $conf) { 40 if ($line =~ /^Path:\s+(.*)/) { 41 my ($vol,$dir,$file) = splitpath($1); 42 next unless $dir; 43 my $dirpath = catpath( $vol, $dir); 44 my (@l,@b,@i) = ( (),(),() ); 45 46 # try to detect 'lib' dir 47 push @l, catfile($dirpath,'lib'); 48 push @l, catfile($dirpath,'..','lib'); 49 push @l, catfile($dirpath,'..','..','lib'); 50 push @l, catfile($dirpath,'..','..','..','lib'); 51 foreach (@l) { push @libdir, $_ if (-d $_) }; 52 53 # try to detect 'bin' dir 54 push @b, catfile($dirpath); 55 push @b, catfile($dirpath,'bin'); 56 push @b, catfile($dirpath,'..'); 57 push @b, catfile($dirpath,'..','bin'); 58 push @b, catfile($dirpath,'..','..'); 59 push @b, catfile($dirpath,'..','..','bin'); 60 push @b, catfile($dirpath,'..','..','..'); 61 push @b, catfile($dirpath,'..','..','..','bin'); 62 foreach (@b) { push @bindir, $_ if (-e "$_/convert.exe" || -e "$_/identify.exe") }; 63 64 # try to detect 'include' dir 65 push @i, catfile($dirpath,'include'); 66 push @i, catfile($dirpath,'include','ImageMagick'); 67 push @i, catfile($dirpath,'..','include'); 68 push @i, catfile($dirpath,'..','include','ImageMagick'); 69 push @i, catfile($dirpath,'..','..','include'); 70 push @i, catfile($dirpath,'..','..','include','ImageMagick'); 71 push @i, catfile($dirpath,'..','..','..','include'); 72 push @i, catfile($dirpath,'..','..','..','include','ImageMagick'); 73 foreach (@i) { push @incdir, $_ if (-e "$_/MagickCore/MagickCore.h") }; 74 } 75 }; 76 77 foreach my $bin (@bindir) { 78 opendir(my $bindir, $bin) or die qq{Cannot opendir $bin: $!}; 79 my @dlls = map {catfile($bin, $_)} grep /^\S*magick[^\+]\S*?\.dll$/i, readdir $bindir; 80 foreach my $d (@dlls) { 81 unlink "$wrkdir/libMagickCore.def", "$wrkdir/libMagickCore.a"; 82 system("pexports \"$d\" >\"$wrkdir/libMagickCore.def\" 2>$devnull"); 83 open(DEF, "<$wrkdir/libMagickCore.def"); 84 my @found = grep(/MagickCoreGenesis/, <DEF>); #checking if we have taken the right DLL 85 close(DEF); 86 next unless(@found); 87 print STDERR "Gonna create 'libMagickCore.a' from '$d'\n"; 88 system("dlltool -D \"$d\" -d \"$wrkdir/libMagickCore.def\" -l \"$wrkdir/libMagickCore.a\" 2>$devnull"); 89 last if -s "$wrkdir/libMagickCore.a"; 90 } 91 last if -s "$wrkdir/libMagickCore.a"; 92 } 93 94 unless(@incdir && @libdir && @bindir && (-s "$wrkdir/libMagickCore.a")) { 95 print STDERR <<EOF 96 ################################### WARNING! ################################### 97 # It seems that you are trying to install Perl::Magick on a MS Windows box with 98 # perl + gcc compiler (e.g. strawberry perl), however we cannot find ImageMagick 99 # binaries installed on your system. 100 # 101 # Please check the following prerequisites: 102 # 103 # 1) You need to have installed ImageMagick Windows binaries from 104 # https://imagemagick.org/script/binary-releases.php#windows 105 # 106 # 2) We only support dynamic (DLL) ImageMagick binaries 107 # note: it is not possible to mix 32/64-bit binaries of perl and ImageMagick 108 # 109 # 3) During installation select that you want to install ImageMagick's 110 # development files (libraries+headers) 111 # 112 # 4) You also need to have ImageMagick's directory in your PATH 113 # note: we are checking the presence of convert.exe and/or identify.exe tools 114 # 115 # 5) You might need Visual C++ Redistributable Package installed on your system 116 # see instructions on ImageMagick's Binary Release webpage 117 # 118 # We are gonna continue, but chances for successful build are very low! 119 ################################################################################ 120 EOF 121 } 122 123 my $inc = join ' ', map "-I\"$_\"", @incdir; 124 my $lib = join ' ', map "-L\"$_\"", @libdir; 125 126 return ($inc, $lib); 127 } 128 129 sub AutodetectDelegates { 130 #try to get configuration info via identify or convert utilities 131 my $devnull = devnull(); 132 my $conf = `identify -list Configure 2>$devnull` || `convert -list Configure 2>$devnull`; 133 my @delegates = (); 134 foreach my $line (split '\n', $conf) { 135 next unless $line =~ /^DELEGATES\s+/; 136 (undef, @delegates) = split /\s+/, $line; 137 last; 138 }; 139 return @delegates; 140 } 141 142 # Compute test specification 143 my $delegate_tests='t/*.t'; 144 my @tested_delegates = qw/bzlib djvu fftw fontconfig freetype jpeg jng jp2 lcms png rsvg tiff x11 xml wmf zlib/; 145 my @supported_delegates = AutodetectDelegates(); 146 # find the intersection of tested and supported delegates 147 my %seen_delegates = (); 148 $seen_delegates{$_}++ for @supported_delegates; 149 foreach my $delegate (@tested_delegates) { 150 if ( $seen_delegates{$delegate} ) { 151 if ( -d "t/$delegate" ) { 152 if ( defined($ENV{'DISPLAY'}) && ($^O ne 'MSWin32') ) { 153 if ( defined $ENV{'DISPLAY'} ) { 154 $delegate_tests .= " t/$delegate/*.t"; 155 } 156 next; 157 } 158 $delegate_tests .= " t/$delegate/*.t"; 159 } 160 } 161 } 162 163 # defaults for LIBS & INC & CCFLAGS params that we later pass to Writemakefile 164 my $INC_magick = '-I../../ -I@top_srcdir@ @CPPFLAGS@ -I"' . $Config{'usrinc'} . '/ImageMagick"'; 165 my $LIBS_magick = '-L../../MagickCore/.libs -lMagickCore-@MAGICK_MAJOR_VERSION@.@MAGICK_ABI_SUFFIX@ -lperl @MATH_LIBS@'; 166 my $CCFLAGS_magick = "$Config{'ccflags'} @CFLAGS@"; 167 my $LDFLAGS_magick = "-L../../MagickCore/.libs -lMagickCore-@MAGICK_MAJOR_VERSION@.@MAGICK_ABI_SUFFIX@ $Config{'ldflags'} @LDFLAGS@"; 168 my $LDDLFLAGS_magick = "-L../../MagickCore/.libs -lMagickCore-@MAGICK_MAJOR_VERSION@.@MAGICK_ABI_SUFFIX@ $Config{'lddlflags'} @LDFLAGS@"; 169 170 if (($^O eq 'MSWin32') && ($Config{cc} =~ /gcc/)) { 171 my($Ipaths, $Lpaths) = AutodetectWin32gcc(); 172 173 # 174 # Setup for strawberry perl. 175 # 176 $INC_magick = "$Ipaths"; 177 $LIBS_magick = "-lMagickCore-@MAGICK_MAJOR_VERSION@.@MAGICK_ABI_SUFFIX@"; 178 $CCFLAGS_magick = "$Config{'ccflags'}"; 179 $LDFLAGS_magick = "$Config{'ldflags'} $Lpaths "; 180 $LDDLFLAGS_magick = "$Config{'lddlflags'} $Lpaths "; 181 } 182 183 # See lib/ExtUtils/MakeMaker.pm for details of how to influence 184 # the contents of the Makefile that is written. 185 WriteMakefile 186 ( 187 # Module description 188 'ABSTRACT' => 'ImageMagick PERL Extension (@MAGICK_ABI_SUFFIX@)', 189 190 # Perl module name is Image::Magick 191 'NAME' => 'Image::Magick::@MAGICK_ABI_SUFFIX@', 192 193 # Module author 194 'AUTHOR' => 'ImageMagick Studio LLC', 195 196 # Module version 197 'VERSION' => '@PACKAGE_PERL_VERSION@', 198 199 # Preprocessor defines 200 'DEFINE' => '@LFS_CPPFLAGS@ @DEFS@', # e.g., '-DHAVE_SOMETHING' 201 202 # Header search specfication and preprocessor flags 203 'INC' => $INC_magick, 204 205 # C compiler 206 #'CC' => '@CC@', 207 208 # C pre-processor flags (e.g. -I & -D options) 209 # 'CPPFLAGS' => "$Config{'cppflags'} @CPPFLAGS@", 210 211 # C compiler flags (e.g. -O -g) 212 'CCFLAGS' => $CCFLAGS_magick, 213 214 # Linker 215 #'LD' => $Config{'ld'} == $Config{'cc'} ? '@CC@' : $Config{'ld'}, 216 217 # Linker flags for building an executable 218 'LDFLAGS' => $LDFLAGS_magick, 219 220 # Linker flags for building a dynamically loadable module 221 'LDDLFLAGS' => $LDDLFLAGS_magick, 222 223 # Install PerlMagick binary into ImageMagick bin directory 224 'INSTALLBIN' => '@BIN_DIR@', 225 226 # Library specification 227 'LIBS' => [ $LIBS_magick ], 228 229 # Perl binary name (if a Perl binary is built) 230 'MAP_TARGET' => 'PerlMagick', 231 232 # Let CFLAGS drive optimization flags by setting OPTIMIZE to empty 233 # 'OPTIMIZE' => '', 234 235 # Use same compiler as ImageMagick 236 'PERLMAINCC' => '@PERLMAINCC@ @OPENMP_CFLAGS@', 237 'PM' => { '@MAGICK_ABI_SUFFIX@.pm' => '$(INST_LIBDIR)/@MAGICK_ABI_SUFFIX@.pm' }, 238 'XS' => { '@MAGICK_ABI_SUFFIX@.xs' => '@MAGICK_ABI_SUFFIX@.xs' }, 239 'AR' => '@AR@', 240 'LD' => '@PERLMAINCC@', 241 242 # Set Perl installation prefix to ImageMagick installation prefix 243 # 'PREFIX' => '@prefix@', 244 245 # Include delegate directories in tests 246 test => { TESTS => $delegate_tests}, 247 248 ($Config{'archname'} =~ /-object$/i ? ('CAPI' => 'TRUE') : ()), 249 250 # sane vesion 251 depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' } 252 ); 253 254 255 # 256 # Substitutions for "makeaperl" section. 257 # 258 sub MY::makeaperl { 259 package MY; # so that "SUPER" works right 260 my $inherited = shift->SUPER::makeaperl(@_); 261 262 # Stinky ExtUtils::MM_Unix likes to append its own library path to $(CC), 263 # prior to any user-specified library path so that an installed library is 264 # used rather than the library just built. This substitution function 265 # tries to insert our library path first. Also, use the same compiler used 266 # to build perlmain.c to link so that a C++ compiler may be used if 267 # necessary. 268 $inherited =~ s:MAP_LINKCMD\s.*\s*\$\(CC\):MAP_LINKCMD = \$(PERLMAINCC) -L@MAGICKCORE_PATH@: ; 269 $inherited; 270 } 271