I initially found the module difficult to install (and others with me, e.g. here, and here). PHP::Interpreter obviously depends on having both PHP and the PHP sources installed, and some of the difficulty lays in how to locate the local PHP binaries (if at all present).
PHP is renowned for its' low barrier of entry, so I figured a PHP interface to perl should install as easily as possible. This motivates the attempt of making PHP::Interpreter easier to install.
The current Makefile.PL has a number of unfortunate properties:
The above error is a almost certain indication that the install is likely to fail. Instead of seeing this error, the user will get lots of confusing output from the compiler, as can be seen in the bug reports.Can't exec "/usr/local/bin/php-config": No such file or directory at Makefile.PL.org line 12.
The module PHP uses another approach to determine the underlying PHP install: It's Makefile.PL calls `php-config` and simply dies if it's not in path. I like this die hard approach, since it makes it very clear what is missing as soon as a (possible) problem is detected.
Please comment the below attempt to improve on Makefile.PL. I'll probably contact the maintainer later on.
use strict; use warnings; use ExtUtils::MakeMaker; use Config; use File::Spec::Functions qw(catdir); # Check if File::Find is present eval { use File::Find; }; my $filefind = (!$@) ? 1 : 0; # These header files must be present for PHP::Interpreter to compile my %headers = (); $headers{$_}++ for qw ( php_config.h php.h php_ini.h php_main.h zend.h zend_API.h zend_compile.h zend_ini.h SAPI.h TSRM.h ); # Return true if files in headers hash are found, otherwise die sub check_headers { my $inc = shift; die "Need an argument" if !$inc; print "Checking header files...\n"; # Replace -I at beginning of string and chop of newline character my @incdirs = map { s/^-I//g; chomp; $_ } split(/ /, $inc); for (@incdirs) { die "No such directory: '$_'" if (!-d); print "using incdir '$_'\n"; } # Make sure header files are present my $finder = sub { return if (!-f $_ or !exists($headers{$_})); print "Found $File::Find::name\n"; delete $headers{$_}; }; # Try to find all files in headers - delete hash entries when found. # Any remaining hash key indicates a necessary file is missing. find(\&$finder, @incdirs); die "Missing header files: " . join(q{, }, keys %headers) if (keys % +headers); return 1; } # Execute 'php-config' for each variable. Dies if executable is not # in path. my %conf = map { my $a = `php-config --$_`; die "Error: php-config --$_ failed\n" unless $a; chomp $a; $_ => $a; } qw(includes prefix version ldflags); # Get php version print "using php version $conf{version}\n"; $conf{version} =~ s/^(\d+).*/$1/; # Need major version only die "Unsupported PHP version" if ($conf{version} != 5); # Get prefix. Use script argument as prefix, otherwise use value from # 'php-config' my $prefix = shift @ARGV || ($conf{prefix}); die "Failed to find php root" if (!defined($prefix) or !-d $prefix); print "using prefix $prefix\n"; # Get include directories my $includes = "-I" . catdir($prefix, 'include') . " " . $conf{include +s}; print "using includes $includes\n"; # Get libraries my @lddlflags = ($Config{lddlflags}, $conf{ldflags}); push @lddlflags, "-L" . catdir $prefix, "lib"; my $php_embedlib_path = "-L" . catdir $prefix, "lib"; push @lddlflags, $php_embedlib_path; print "using lddlflags " . join(q{ }, @lddlflags) . "\n"; # Libs = lddlflags + php-version my @libs = ("$php_embedlib_path"); push @libs, "-lphp$conf{version}"; print "using libs " . join(q{ }, @libs) . "\n"; my @ofiles = ('PHP.o', 'phpinterp.o', 'phpfuncs.o'); # Check that header files are present if File::Find is installed ($filefind) ? check_headers($includes) : print "Module File::Find not installed. Header files check skipped +.\n"; WriteMakefile( CCFLAGS => '-g', OBJECT => join(' ', @ofiles), NAME => 'PHP::Interpreter', LIBS => join(' ', @libs), LDDLFLAGS => join(' ', @lddlflags), INC => $includes, VERSION_FROM => 'lib/PHP/Interpreter.pm', PREREQ_PM => { # Just required for testing. 'Test::More' => 0, 'IO::File' => 0 }, ); __END__ =pod =head1 NAME Makefile.PL - Makefile for PHP::Interpreter =head1 SYNOPSIS perl Makefile.PL [prefix] =head1 OPTIONS prefix - directory root for PHP install, e.g. /usr/local or C:\\Program Files\\PHP =head1 DESCRIPTION This creates a makefile for PHP::Interpreter. PHP::Interpreter depends on having both PHP and PHP sources installed. This script uses the executable I<php-config> to determine how PHP is configured. This script will die unless I<php-config> is installed. PHP::Interpreter works with PHP5 only. This script will perform header files check if module I<File::Find> is installed =head1 SEE ALSO php php-config =cut
Tue Nov 11 21:51:28 CET 2008: See also Re: use PHP::Interpreter throws undefined symbol: zend_ce_traversable for PHP installation notes.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Making PHP::Interpreter easier to install
by almut (Canon) on May 07, 2008 at 12:54 UTC | |
|
Re: Making PHP::Interpreter easier to install
by olus (Curate) on May 07, 2008 at 14:21 UTC | |
|
Re: Making PHP::Interpreter easier to install
by dk (Chaplain) on May 11, 2008 at 21:22 UTC | |
by andreas1234567 (Vicar) on May 13, 2008 at 12:18 UTC | |
by ettechfletch (Initiate) on Apr 08, 2009 at 15:28 UTC | |
|
Re: Making PHP::Interpreter easier to install
by Theory (Beadle) on Oct 29, 2008 at 18:56 UTC |