public static function createM4Extension($packageName, $m4Path)
{
if (!file_exists($m4Path)) {
return;
}
$m4 = file_get_contents($m4Path);
// PHP_NEW_EXTENSION(extname, sources [, shared [, sapi_class [, extra-cflags [, cxx [, zend_ext]]]]])
if (preg_match('/PHP_NEW_EXTENSION \\( \\s*
\\[?
(\\w+) # The extension name
\\]?
\\s*,\\s*
\\[?
([^,]*) # Source files
\\]?
(?:
\\s*,\\s* ([^,\\)]*) # Ext Shared
(?:
\\s*,\\s* ([^,\\)]*) # SAPI class
(?:
\\s*,\\s* ([^,\\)]*) # Extra cflags
(?:
\\s*,\\s* ([^,\\)]*) # CXX
\\s*,\\s* ([^,\\)]*) # zend extension
)?
)?
)?
)?
/x', $m4, $matches)) {
$fullmatched = array_shift($matches);
$ext = new M4Extension($packageName);
$ext->setExtensionName($matches[0]);
$ext->setSharedLibraryName($matches[0] . '.so');
if (isset($matches[6]) && strpos($matches[6], 'yes') !== false) {
$ext->setZend(true);
}
$ext->setSourceDirectory(dirname($m4Path));
/*
PHP_ARG_ENABLE(calendar,whether to enable calendar conversion support,
[ --enable-calendar Enable support for calendar conversion])
*/
if (preg_match_all('/
PHP_ARG_ENABLE\\(
\\s*([^,]*)
(?:
\\s*,\\s*
(
[^,\\)]*
)
(?:
\\s*,\\s*
\\[
\\s*
([^\\s]+)
\\s+
([^,\\)]*)
\\s*
\\]
)?
)?/x', $m4, $allMatches)) {
for ($i = 0; $i < count($allMatches[0]); ++$i) {
$name = $allMatches[1][$i];
$desc = $allMatches[2][$i];
$option = $allMatches[3][$i];
$optionDesc = $allMatches[4][$i];
$ext->addConfigureOption(new ConfigureOption($option ?: '--enable-' . $name, $desc ?: $optionDesc));
}
}
/*
PHP_ARG_WITH(gd, for GD support,
[ --with-gd[=DIR] Include GD support. DIR is the GD library base
install directory [BUNDLED]])
Possible option formats:
--with-libxml-dir=DIR
--with-recode[=DIR]
--with-yaml[[=DIR]]
--with-mysql-sock[=SOCKPATH]
*/
if (preg_match_all('/
PHP_ARG_WITH\\(
\\s*
([^,]*)
(?:
\\s*,\\s*
\\[?
([^,\\)]*)
\\]?
(?:
\\s*,\\s*
\\[
\\s*
# simple match (\\S+)
([a-zA-Z0-9-]+) # option
(?:
=?
\\[?
=?([^\\s\\]]*?)
\\]?
)? # option value hint
\\s+
([^,\\)]*) # option description
\\s*
\\]
(?:
\\s*,\\s*
([^,\\)]*)
(?:
\\s*,\\s*
([^,\\)]*)
)?
)?
)?
)?/x', $m4, $allMatches)) {
// Parsing the M4 statement:
//
// dnl PHP_ARG_WITH(arg-name, check message, help text[, default-val[, extension-or-not]])
//
for ($i = 0; $i < count($allMatches[0]); ++$i) {
$name = $allMatches[1][$i];
$desc = $allMatches[2][$i];
$option = $allMatches[3][$i];
$optionValueHint = $allMatches[4][$i];
$optionDesc = $allMatches[5][$i];
$defaultValue = $allMatches[6][$i];
$opt = new ConfigureOption($option ?: '--with-' . $name, $desc ?: $optionDesc, $optionValueHint);
if ($defaultValue) {
$opt->setDefaultValue($opt);
}
$ext->addConfigureOption($opt);
}
}
return $ext;
} else {
throw new Exception("Can not parse config.m4: {$m4Path}");
}
}
public function execute() { $buildDir = Config::getCurrentBuildDir(); $extDir = $buildDir . DIRECTORY_SEPARATOR . 'ext'; // list for extensions which are not enabled $extensions = array(); $extensionNames = array(); // some extension source not in root directory $lookupDirectories = array('', 'ext', 'extension'); if (file_exists($extDir) && is_dir($extDir)) { $this->logger->debug("Scanning {$extDir}..."); foreach (scandir($extDir) as $extName) { if ($extName == "." || $extName == "..") { continue; } $dir = $extDir . DIRECTORY_SEPARATOR . $extName; foreach ($lookupDirectories as $lookupDirectory) { $extensionDir = $dir . (empty($lookupDirectory) ? '' : DIRECTORY_SEPARATOR . $lookupDirectory); if ($m4files = ExtensionFactory::configM4Exists($extensionDir)) { $this->logger->debug("Loading extension information {$extName} from {$extensionDir}"); foreach ($m4files as $m4file) { try { $ext = ExtensionFactory::createM4Extension($extName, $m4file); // $ext = ExtensionFactory::createFromDirectory($extName, $dir); $extensions[$ext->getExtensionName()] = $ext; $extensionNames[] = $extName; break; } catch (Exception $e) { } } break; } } } } $this->logger->info('Loaded extensions:'); foreach ($extensions as $extName => $ext) { if (extension_loaded($extName)) { $this->describeExtension($ext); } } $this->logger->info('Available local extensions:'); foreach ($extensions as $extName => $ext) { if (extension_loaded($extName)) { continue; } $this->describeExtension($ext); } }