6 my @alt_transfer = qw/altname incsuffix libbase/;
9 my ($class, $req) = @_;
11 $req->{verbose} ||= $ENV{IM_VERBOSE};
13 my $name = $req->{name};
16 $result = _probe_code($req);
18 if (!$result && $req->{pkg}) {
19 $result = _probe_pkg($req);
21 if (!$result && $req->{inccheck} && ($req->{libcheck} || $req->{libbase})) {
22 $req->{altname} ||= "main";
23 $result = _probe_check($req);
25 if (!$result && $req->{alternatives}) {
28 for my $alt (@{$req->{alternatives}}) {
29 $req->{altname} ||= "alt $index";
31 and print "$req->{name}: Trying alternative $index\n";
33 for my $key (@alt_transfer) {
34 exists $alt->{$key} and $work{$key} = $alt->{$key};
36 $result = _probe_check(\%work)
42 if (!$result && $req->{testcode}) {
43 $result = _probe_fake($req);
47 if ($req->{testcode}) {
48 $result = _probe_test($req, $result);
59 my $code = $req->{code};
60 my @probes = ref $code eq "ARRAY" ? @$code : $code;
63 for my $probe (@probes) {
64 $result = $probe->($req)
74 my @exe_suffix = $Config{_exe};
75 if ($^O eq 'MSWin32') {
76 push @exe_suffix, qw/.bat .cmd/;
79 for my $dir (File::Spec->path) {
80 for my $suffix (@exe_suffix) {
81 -x File::Spec->catfile($dir, "$name$suffix")
92 # Setup pkg-config's environment variable to search non-standard paths
93 # which may be provided by --libdirs.
94 my @pkgcfg_paths = map { "$_/pkgconfig" } _lib_paths( $req );
95 push @pkgcfg_paths, $ENV{ 'PKG_CONFIG_PATH' } if $ENV{ 'PKG_CONFIG_PATH' };
97 local $ENV{ 'PKG_CONFIG_PATH' } = join $Config{path_sep}, @pkgcfg_paths;
99 is_exe('pkg-config') or return;
100 my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
102 my @pkgs = @{$req->{pkg}};
103 for my $pkg (@pkgs) {
104 if (!system("pkg-config $pkg --exists $redir")) {
105 # if we find it, but the following fail, then pkg-config is too
106 # broken to be useful
107 my $cflags = `pkg-config $pkg --cflags`
110 my $lflags = `pkg-config $pkg --libs`
115 print "$req->{name}: Found via pkg-config $pkg\n";
124 print "$req->{name}: Not found via pkg-config\n";
132 my $libcheck = $req->{libcheck};
133 my $libbase = $req->{libbase};
134 if (!$libcheck && $req->{libbase}) {
135 # synthesize a libcheck
136 my $lext=$Config{'so'}; # Get extensions of libraries
137 my $aext=$Config{'_a'};
139 -e File::Spec->catfile($_[0], "lib$libbase$aext")
140 || -e File::Spec->catfile($_[0], "lib$libbase.$lext")
145 my @lib_search = _lib_paths($req);
146 print "$req->{name}: Searching directories for libraries:\n"
148 for my $path (@lib_search) {
149 print "$req->{name}: $path\n" if $req->{verbose};
150 if ($libcheck->($path)) {
151 print "$req->{name}: Found!\n" if $req->{verbose};
152 $found_libpath = $path;
158 my $inccheck = $req->{inccheck};
159 my @inc_search = _inc_paths($req);
160 print "$req->{name}: Searching directories for headers:\n"
162 for my $path (@inc_search) {
163 print "$req->{name}: $path\n" if $req->{verbose};
164 if ($inccheck->($path)) {
165 print "$req->{name}: Found!\n" if $req->{verbose};
166 $found_incpath = $path;
172 if ($req->{alternatives}) {
173 $alt = " $req->{altname}:";
175 print "$req->{name}:$alt includes ", $found_incpath ? "" : "not ",
176 "found - libraries ", $found_libpath ? "" : "not ", "found\n";
178 $found_libpath && $found_incpath
181 my @libs = "-L$found_libpath";
182 if ($req->{libopts}) {
183 push @libs, $req->{libopts};
186 push @libs, "-l$libbase";
189 die "$req->{name}: inccheck but no libbase or libopts";
194 INC => "-I$found_incpath",
202 # the caller provided test code, and the compiler may look in
203 # places we don't, see Imager-Screenshot ticket 56793,
204 # so fake up a result so the test code can
206 if ($req->{libopts}) {
207 $lopts = $req->{libopts};
209 elsif (defined $req->{libbase}) {
210 # might not need extra libraries, eg. Win32 perl already links
212 $lopts = $req->{libbase} ? "-l$req->{libbase}" : "";
214 if (defined $lopts) {
215 print "$req->{name}: Checking if the compiler can find them on its own\n";
223 print "$req->{name}: Can't fake it - no libbase or libopts\n"
230 my ($req, $result) = @_;
232 require Devel::CheckLib;
233 # setup LD_RUN_PATH to match link time
234 my ($extra, $bs_load, $ld_load, $ld_run_path) =
235 ExtUtils::Liblist->ext($result->{LIBS}, $req->{verbose});
236 local $ENV{LD_RUN_PATH};
239 print "Setting LD_RUN_PATH=$ld_run_path for $req->{name} probe\n"
241 $ENV{LD_RUN_PATH} = $ld_run_path;
244 Devel::CheckLib::check_lib
246 debug => $req->{verbose},
247 LIBS => [ $result->{LIBS} ],
248 INC => $result->{INC},
249 header => $req->{testcodeheaders},
250 function => $req->{testcode},
251 prologue => $req->{testcodeprologue},
254 print "$req->{name}: Test code failed: $@";
258 print "$req->{name}: Passed code check\n";
272 @Config{qw/loclibpth libpth libspath/}
274 $^O eq "MSWin32" ? $ENV{LIB} : "",
275 $^O eq "cygwin" ? "/usr/lib/w32api" : "",
288 $^O eq "MSWin32" ? $ENV{INCLUDE} : "",
289 $^O eq "cygwin" ? "/usr/include/w32api" : "",
293 @Config{qw/locincpth incpath/}
296 "/usr/local/include",
299 if ($req->{incsuffix}) {
300 @paths = map File::Spec->catdir($_, $req->{incsuffix}), @paths;
311 # expand any array refs
312 @in = map { ref() ? @$_ : $_ } @in;
316 $path = _tilde_expand($path);
318 push @out, grep -d $_, split /\Q$Config{path_sep}/, $path;
328 if ($path =~ m!^~[/\\]!) {
329 defined $home or $home = $ENV{HOME};
330 if (!defined $home && $^O eq 'MSWin32'
331 && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
332 $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
334 unless (defined $home) {
335 $home = eval { (getpwuid($<))[7] };
337 defined $home or die "You supplied $path, but I can't find your home directory\n";
339 $path = File::Spec->catdir($home, $path);
351 Imager::Probe - hot needle of inquiry for libraries
355 require Imager::Probe;
359 # short name of what we're looking for (displayed to user)
362 pkg => [ qw/name1 name2 name3/ ],
363 # perl subs that probe for the library
364 code => [ \&foo_probe1, \&foo_probe2 ],
365 # or just: code => \&foo_probe,
366 inccheck => sub { ... },
367 libcheck => sub { ... },
368 # search for this library if libcheck not supplied
370 # library link time options, uses libbase to build options otherwise
372 # C code to check the library is sane
374 # header files needed
375 testcodeheaders => [ "stdio.h", "foo.h" ],
377 my $result = Imager::Probe->probe(\%probe)
378 or print "Foo library not found: ",Imager::Probe->error;
382 Does the probes that were hidden in Imager's F<Makefile.PL>, pulled
383 out so the file format libraries can be externalized.
385 The return value is either nothing if the probe fails, or a hash
392 C<INC> - C<-I> and other C options
396 C<LIBS> - C<-L>, C<-l> and other link-time options
400 The possible values for the hash supplied to the probe() method are:
406 C<pkg> - an array of F<pkg-config> names to probe for. If the
407 F<pkg-config> checks pass, C<inccheck> and C<libcheck> aren't used.
411 C<inccheck> - a code reference that checks if the supplied include
412 directory contains the required header files.
416 C<libcheck> - a code reference that checks if the supplied library
417 directory contains the required library files. Note: the
418 F<Makefile.PL> version of this was supplied all of the library file
423 C<libbase> - if C<inccheck> is supplied, but C<libcheck> isn't, then a
424 C<libcheck> that checks for C<lib>I<libbase>I<$Config{_a}> and
425 C<lib>I<libbase>.I<$Config{so}> is created. If C<libopts> isn't
426 supplied then that can be synthesized as C<-l>C<<I<libbase>>>.
430 C<libopts> - if the libraries are found via C<inccheck>/C<libcheck>,
431 these are the C<-l> options to supply during the link phase.
435 C<code> - a code reference to perform custom checks. Returns the
436 probe result directly. Can also be an array ref of functions to call.
440 C<testcode> - test C code that is run with Devel::CheckLib. You also
441 need to set C<testcodeheaders>.
445 C<testcodeprologue> - C code to insert between the headers and the
450 C<incpath> - C<$Config{path_sep}> separated list of header file
451 directories to check, or a reference to an array of such.
455 C<libpath> - C<$Config{path_sep}> separated list of library file
456 directories to check, or a reference to an array of such.