#!/bin/sh # This script wraps docker-php-ext-install, properly configuring the system. # # Copyright (c) Michele Locati, 2018-2020 # # Source: https://github.com/mlocati/docker-php-extension-installer # # License: MIT - see https://github.com/mlocati/docker-php-extension-installer/blob/master/LICENSE # Let's set a sane environment set -o errexit set -o nounset if ! which docker-php-ext-configure >/dev/null || ! which docker-php-ext-enable >/dev/null || ! which docker-php-ext-install >/dev/null || ! which docker-php-source >/dev/null; then printf 'The script %s is meant to be used with official Docker PHP Images - https://hub.docker.com/_/php\n' "$0" >&2 exit 1 fi # Reset the Internal Field Separator resetIFS() { IFS=' ' } # Set these variables: # - DISTRO containing distribution name (eg 'alpine', 'debian') # - DISTO_VERSION containing distribution name and its version(eg 'alpine@3.10', 'debian@9') setDistro() { if ! test -r /etc/os-release; then printf 'The file /etc/os-release is not readable\n' >&2 exit 1 fi DISTRO="$(cat /etc/os-release | grep -E ^ID= | cut -d = -f 2)" DISTRO_VERSION_NUMBER="$(cat /etc/os-release | grep -E ^VERSION_ID= | cut -d = -f 2 | cut -d '"' -f 2 | cut -d . -f 1,2)" DISTRO_VERSION="$(printf '%s@%s' $DISTRO $DISTRO_VERSION_NUMBER)" DISTRO_MAJMIN_VERSION="$(echo "$DISTRO_VERSION_NUMBER" | awk -F. '{print $1*100+$2}')" } # Set the PHP_MAJMIN_VERSION variable containing the PHP Major-Minor version as an integer value, in format MMmm (example: 506 for PHP 5.6.15) setPHPMajorMinor() { PHP_MAJMIN_VERSION=$(php-config --version | awk -F. '{print $1*100+$2}') } # Normalize the name of a PHP extension # # Arguments: # $1: the name of the module to be normalized # # Output: # The normalized module name normalizePHPModuleName() { normalizePHPModuleName_name="$1" case "$normalizePHPModuleName_name" in *A* | *B* | *C* | *D* | *E* | *F* | *G* | *H* | *I* | *J* | *K* | *L* | *M* | *N* | *O* | *P* | *Q* | *R* | *S* | *T* | *U* | *V* | *W* | *X* | *Y* | *Z*) normalizePHPModuleName_name="$(LC_CTYPE=C printf '%s' "$normalizePHPModuleName_name" | tr '[:upper:]' '[:lower:]')" ;; esac case "$normalizePHPModuleName_name" in pecl_http) normalizePHPModuleName_name='http' ;; zend\ opcache) normalizePHPModuleName_name='opcache' ;; *\ *) printf '### WARNING Unrecognized module name: %s ###\n' "$1" >&2 ;; esac printf '%s' "$normalizePHPModuleName_name" } # Parse a module name (and optionally version) as received via command arguments, extracting the version and normalizing it # Example: # xdebug-2.9.8 # # Arguments: # $1: the name of the module to be normalized # # Set these variables: # - PROCESSED_PHP_MODULE_ARGUMENT # # Optionally set these variables: # - PHP_WANTEDMODULEVERSION_<...> (where <...> is the normalized module name) # # Output: # Nothing processPHPMuduleArgument() { PROCESSED_PHP_MODULE_ARGUMENT="${1%%-*}" if test -n "$PROCESSED_PHP_MODULE_ARGUMENT" && test "$PROCESSED_PHP_MODULE_ARGUMENT" != "$1"; then processPHPMuduleArgument_version="${1#*-}" else processPHPMuduleArgument_version='' fi PROCESSED_PHP_MODULE_ARGUMENT="$(normalizePHPModuleName "$PROCESSED_PHP_MODULE_ARGUMENT")" if test -n "$processPHPMuduleArgument_version"; then if printf '%s' "$PROCESSED_PHP_MODULE_ARGUMENT" | grep -Eq '^[a-zA-Z0-9_]+$'; then eval PHP_WANTEDMODULEVERSION_$PROCESSED_PHP_MODULE_ARGUMENT="$processPHPMuduleArgument_version" else printf 'Unable to parse the following module name:\n%s\n' "$PROCESSED_PHP_MODULE_ARGUMENT" >&2 fi fi } # Get the wanted PHP module version, as specified in the command line arguments. # # Arguments: # $1: the name of the module to be normalized # # Output: # The wanted version (if any) getWantedPHPModuleVersion() { if printf '%s' "$1" | grep -Eq '^[a-zA-Z0-9_]+$'; then eval printf '%s' "\${PHP_WANTEDMODULEVERSION_$1:-}" fi } # Set these variables: # - PHP_PREINSTALLED_MODULES the normalized list of PHP modules installed before running this script setPHPPreinstalledModules() { PHP_PREINSTALLED_MODULES='' IFS=' ' for getPHPInstalledModules_module in $(php -m); do getPHPInstalledModules_moduleNormalized='' case "$getPHPInstalledModules_module" in \[PHP\ Modules\]) ;; \[Zend\ Modules\]) break ;; *) getPHPInstalledModules_moduleNormalized="$(normalizePHPModuleName "$getPHPInstalledModules_module")" if ! stringInList "$getPHPInstalledModules_moduleNormalized" "$PHP_PREINSTALLED_MODULES"; then PHP_PREINSTALLED_MODULES="$PHP_PREINSTALLED_MODULES $getPHPInstalledModules_moduleNormalized" fi ;; esac done resetIFS PHP_PREINSTALLED_MODULES="${PHP_PREINSTALLED_MODULES# }" } # Get the handles of the modules to be installed # # Arguments: # $@: all module handles # # Set: # PHP_MODULES_TO_INSTALL # # Output: # Nothing processCommandArguments() { processCommandArguments_endArgs=0 PHP_MODULES_TO_INSTALL='' while :; do if test $# -lt 1; then break fi processCommandArguments_skip=0 if test $processCommandArguments_endArgs -eq 0; then case "$1" in --cleanup) printf '### WARNING the %s option is deprecated (we always cleanup everything) ###\n' "$1" >&2 processCommandArguments_skip=1 ;; --) processCommandArguments_skip=1 processCommandArguments_endArgs=1 ;; -*) printf 'Unrecognized option: %s\n' "$1" >&2 exit 1 ;; esac fi if test $processCommandArguments_skip -eq 0; then processPHPMuduleArgument "$1" processCommandArguments_name="$PROCESSED_PHP_MODULE_ARGUMENT" if stringInList "$processCommandArguments_name" "$PHP_MODULES_TO_INSTALL"; then printf '### WARNING Duplicated module name specified: %s ###\n' "$processCommandArguments_name" >&2 elif stringInList "$processCommandArguments_name" "$PHP_PREINSTALLED_MODULES"; then printf '### WARNING Module already installed: %s ###\n' "$processCommandArguments_name" >&2 else PHP_MODULES_TO_INSTALL="$PHP_MODULES_TO_INSTALL $processCommandArguments_name" fi fi shift done PHP_MODULES_TO_INSTALL="${PHP_MODULES_TO_INSTALL# }" } # Add a module that's required by another module # # Arguments: # $1: module that requires another module # $2: the required module # # Update: # PHP_MODULES_TO_INSTALL # # Output: # Nothing checkRequiredModule() { if ! stringInList "$1" "$PHP_MODULES_TO_INSTALL"; then return fi if stringInList "$2" "$PHP_PREINSTALLED_MODULES"; then return fi PHP_MODULES_TO_INSTALL="$(removeStringFromList "$1" "$PHP_MODULES_TO_INSTALL")" if ! stringInList "$2" "$PHP_MODULES_TO_INSTALL"; then PHP_MODULES_TO_INSTALL="$PHP_MODULES_TO_INSTALL $2" PHP_MODULES_TO_INSTALL="${PHP_MODULES_TO_INSTALL# }" fi PHP_MODULES_TO_INSTALL="$PHP_MODULES_TO_INSTALL $1" } # Sort the modules to be installed, in order to fix dependencies # # Update: # PHP_MODULES_TO_INSTALL # # Output: # Nothing sortModulesToInstall() { # apcu_bc requires apcu checkRequiredModule 'apcu_bc' 'apcu' # http requires propro and raphf checkRequiredModule 'http' 'propro' checkRequiredModule 'http' 'raphf' # Some module installation may use igbinary if available: move it before other modules if stringInList 'igbinary' "$PHP_MODULES_TO_INSTALL"; then PHP_MODULES_TO_INSTALL="$(removeStringFromList 'igbinary' "$PHP_MODULES_TO_INSTALL")" PHP_MODULES_TO_INSTALL="igbinary $PHP_MODULES_TO_INSTALL" PHP_MODULES_TO_INSTALL="${PHP_MODULES_TO_INSTALL% }" fi # Some module installation may use msgpack if available: move it before other modules if stringInList 'msgpack' "$PHP_MODULES_TO_INSTALL"; then PHP_MODULES_TO_INSTALL="$(removeStringFromList 'msgpack' "$PHP_MODULES_TO_INSTALL")" PHP_MODULES_TO_INSTALL="msgpack $PHP_MODULES_TO_INSTALL" PHP_MODULES_TO_INSTALL="${PHP_MODULES_TO_INSTALL% }" fi } # Get the required APT/APK packages for a specific PHP version and for the list of module handles # # Arguments: # $@: the PHP module handles # # Set: # PACKAGES_PERSISTENT # PACKAGES_VOLATILE # PACKAGES_PREVIOUS buildRequiredPackageLists() { buildRequiredPackageLists_persistent='' buildRequiredPackageLists_volatile='' case "$DISTRO" in alpine) apk update ;; esac case "$DISTRO_VERSION" in alpine@*) buildRequiredPackageLists_volatile="$PHPIZE_DEPS" if test -z "$(apk info 2>/dev/null | grep -E ^libssl)"; then buildRequiredPackageLists_libssl='libssl1.0' elif test -z "$(apk info 2>/dev/null | grep -E '^libressl.*-libtls')"; then buildRequiredPackageLists_libssl=$(apk search -q libressl*-libtls) else buildRequiredPackageLists_libssl='' fi ;; debian@9) buildRequiredPackageLists_libssldev='libssl1.0-dev' ;; debian@*) buildRequiredPackageLists_libssldev='libssl([0-9]+(\.[0-9]+)*)?-dev$' ;; esac while :; do if test $# -lt 1; then break fi case "$1@$DISTRO" in amqp@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent rabbitmq-c" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile rabbitmq-c-dev" ;; amqp@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent librabbitmq[0-9]" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile librabbitmq-dev libssh-dev" ;; bz2@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libbz2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile bzip2-dev" ;; bz2@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libbz2-dev" ;; cmark@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile cmake" ;; cmark@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile cmake" ;; decimal@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmpdec2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmpdec-dev" ;; enchant@alpine) if test $DISTRO_MAJMIN_VERSION -ge 312; then buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent enchant2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile enchant2-dev" else buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent enchant" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile enchant-dev" fi ;; enchant@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libenchant1c2a" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libenchant-dev" ;; ffi@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libffi" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libffi-dev" ;; ffi@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libffi-dev" ;; gd@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent freetype libjpeg-turbo libpng libxpm" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetype-dev libjpeg-turbo-dev libpng-dev libxpm-dev" if test $PHP_MAJMIN_VERSION -le 506; then buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libvpx" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libvpx-dev" else buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libwebp" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libwebp-dev" fi ;; gd@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libfreetype6 libjpeg62-turbo libpng[0-9]+-[0-9]+$ libxpm4" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libfreetype6-dev libjpeg62-turbo-dev libpng-dev libxpm-dev" if test $PHP_MAJMIN_VERSION -le 506; then buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libvpx[0-9]+$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libvpx-dev" else buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libwebp[0-9]+$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libwebp-dev" fi ;; gettext@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libintl" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile gettext-dev" ;; gmagick@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent graphicsmagick" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile graphicsmagick-dev libtool" ;; gmagick@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libgraphicsmagick(-q16-)?[0-9]*$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libgraphicsmagick1-dev" ;; gmp@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent gmp" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile gmp-dev" ;; gmp@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libgmp-dev" ;; grpc@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libstdc++" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zlib-dev linux-headers" ;; grpc@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zlib1g-dev" ;; http@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libevent" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zlib-dev curl-dev libevent-dev" if test $PHP_MAJMIN_VERSION -le 506; then buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libidn" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libidn-dev" else buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent icu-libs libidn" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile icu-dev libidn-dev" fi ;; http@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libcurl3-gnutls libevent[0-9\.\-]*$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zlib1g-dev libgnutls28-dev libcurl4-gnutls-dev libevent-dev" if test $PHP_MAJMIN_VERSION -le 506; then buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libidn1[0-9+]-dev$" else buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libicu[0-9]+$ libidn2-[0-9+]$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libicu-dev libidn2-[0-9+]-dev$" fi ;; imagick@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent imagemagick" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile imagemagick-dev" ;; imagick@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmagickwand-6.q16-[0-9]+ libmagickcore-6.q16-[0-9]+-extra$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmagickwand-dev" ;; imap@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent c-client $buildRequiredPackageLists_libssl" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile krb5-dev imap-dev libressl-dev" ;; imap@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libc-client2007e" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libkrb5-dev" case "$DISTRO_VERSION" in debian@9) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $buildRequiredPackageLists_libssldev comerr-dev krb5-multidev libc-client2007e libgssrpc4 libkadm5clnt-mit11 libkadm5srv-mit11 libkdb5-8 libpam0g-dev libssl-doc mlock" ;; *) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libc-client-dev" ;; esac ;; interbase@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile icu-dev ncurses-dev" ;; interbase@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libfbclient2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile firebird-dev libib-util" ;; intl@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent icu-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile icu-dev" ;; intl@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libicu[0-9]+$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libicu-dev" ;; ldap@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libldap" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile openldap-dev" ;; ldap@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libldap2-dev" ;; mcrypt@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmcrypt" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmcrypt-dev" ;; mcrypt@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmcrypt4" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmcrypt-dev" ;; memcache@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zlib-dev" ;; memcache@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zlib1g-dev" ;; memcached@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmemcached-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmemcached-dev zlib-dev" ;; memcached@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmemcachedutil2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmemcached-dev zlib1g-dev" ;; mongo@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libsasl $buildRequiredPackageLists_libssl" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libressl-dev cyrus-sasl-dev" ;; mongo@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $buildRequiredPackageLists_libssldev libsasl2-dev" ;; mongodb@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent icu-libs libsasl $buildRequiredPackageLists_libssl snappy" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile icu-dev cyrus-sasl-dev snappy-dev libressl-dev zlib-dev" ;; mongodb@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libsnappy[0-9]+(v[0-9]+)?$ libicu[0-9]+$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libicu-dev libsasl2-dev libsnappy-dev $buildRequiredPackageLists_libssldev zlib1g-dev" ;; mosquitto@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent mosquitto-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile mosquitto-dev" ;; mosquitto@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmosquitto1" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmosquitto-dev" ;; mssql@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent freetds" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; mssql@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libsybdb5" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; oauth@alpine) if test $PHP_MAJMIN_VERSION -ge 700; then buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile pcre-dev" fi ;; oauth@debian) if test $PHP_MAJMIN_VERSION -ge 700; then buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpcre3-dev" fi ;; odbc@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent unixodbc" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; odbc@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libodbc1" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pdo_dblib@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent freetds" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; pdo_dblib@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libsybdb5" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; pdo_firebird@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile icu-dev ncurses-dev" ;; pdo_firebird@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libfbclient2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile firebird-dev libib-util" ;; pdo_odbc@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent unixodbc" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pdo_odbc@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libodbc1" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pdo_pgsql@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent postgresql-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile postgresql-dev" ;; pdo_pgsql@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libpq5" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpq-dev" ;; pdo_sqlsrv@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libstdc++ unixodbc" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pdo_sqlsrv@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libodbc1 odbcinst" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pgsql@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent postgresql-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile postgresql-dev" ;; pgsql@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libpq5" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpq-dev" ;; pspell@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent aspell-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile aspell-dev" ;; pspell@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libaspell15" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpspell-dev" ;; rdkafka@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent librdkafka" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile librdkafka-dev" ;; rdkafka@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent librdkafka\+*[0-9]*$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile librdkafka-dev" ;; recode@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent recode" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile recode-dev" ;; recode@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent librecode0" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile librecode-dev" ;; redis@alpine) if test $PHP_MAJMIN_VERSION -ge 700; then case "$DISTRO_VERSION" in alpine@3.7) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent zstd" ;; *) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent zstd-libs" ;; esac buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zstd-dev" fi ;; redis@debian) if test $PHP_MAJMIN_VERSION -ge 700; then case "$DISTRO_VERSION" in debian@8) ## There's no APT package for libzstd ;; debian@9) ## libzstd is too old (available: 1.1.2, required: 1.3.0+) ;; *) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libzstd[0-9]*$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libzstd-dev" ;; esac fi ;; snuffleupagus@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent pcre" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile pcre-dev" ;; snuffleupagus@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpcre3-dev" ;; snmp@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent net-snmp-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile net-snmp-dev" ;; snmp@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent snmp" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libsnmp-dev" ;; soap@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; soap@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; solr@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile curl-dev libxml2-dev" ;; solr@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libcurl3-gnutls" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libcurl4-gnutls-dev libxml2-dev" ;; sqlsrv@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libstdc++ unixodbc" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; sqlsrv@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent unixodbc" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; ssh2@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libssh2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libssh2-dev" ;; ssh2@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libssh2-1-dev" ;; sybase_ct@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent freetds" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; sybase_ct@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libct4" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; tdlib@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libstdc++ $buildRequiredPackageLists_libssl" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile git cmake gperf zlib-dev libressl-dev linux-headers readline-dev" ;; tdlib@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile git cmake gperf zlib1g-dev $buildRequiredPackageLists_libssldev" ;; tidy@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent tidyhtml-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile tidyhtml-dev" ;; tidy@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libtidy5*" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libtidy-dev" ;; uuid@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libuuid" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile util-linux-dev" ;; uuid@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile uuid-dev" ;; wddx@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; wddx@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; xmlrpc@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; xmlrpc@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; xsl@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libxslt" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxslt-dev libgcrypt-dev" ;; xsl@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libxslt1.1" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxslt-dev" ;; yaml@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent yaml" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile yaml-dev" ;; yaml@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libyaml-0-2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libyaml-dev" ;; zip@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libzip" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile cmake gnutls-dev libzip-dev libressl-dev zlib-dev" ;; zip@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libzip[0-9]$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile cmake gnutls-dev $buildRequiredPackageLists_libssldev libzip-dev libbz2-dev zlib1g-dev" case "$DISTRO_VERSION" in debian@8) # Debian Jessie doesn't seem to provide libmbedtls ;; *) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmbedtls[0-9]*$" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmbedtls-dev" ;; esac ;; zookeeper@alpine) if ! test -f /usr/local/include/zookeeper/zookeeper.h; then buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile apache-ant automake libtool openjdk8" fi ;; zookeeper@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libzookeeper-mt2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libzookeeper-mt-dev" ;; esac shift done PACKAGES_PERSISTENT='' PACKAGES_VOLATILE='' PACKAGES_PREVIOUS='' if test -z "$buildRequiredPackageLists_persistent$buildRequiredPackageLists_volatile"; then return fi case "$DISTRO" in debian) DEBIAN_FRONTEND=noninteractive apt-get update -q ;; esac if test -n "$buildRequiredPackageLists_persistent"; then PACKAGES_PERSISTENT="$(expandPackagesToBeInstalled $buildRequiredPackageLists_persistent)" if test -s "$IPE_ERRFLAG_FILE"; then exit 1 fi fi if test -n "$buildRequiredPackageLists_volatile"; then buildRequiredPackageLists_packages="$(expandPackagesToBeInstalled $buildRequiredPackageLists_volatile)" if test -s "$IPE_ERRFLAG_FILE"; then exit 1 fi resetIFS for buildRequiredPackageLists_package in $buildRequiredPackageLists_packages; do if ! stringInList "$buildRequiredPackageLists_package" "$PACKAGES_PERSISTENT"; then PACKAGES_VOLATILE="$PACKAGES_VOLATILE $buildRequiredPackageLists_package" fi done PACKAGES_VOLATILE="${PACKAGES_VOLATILE# }" fi if test -n "$PACKAGES_PERSISTENT$PACKAGES_VOLATILE"; then case "$DISTRO" in debian) PACKAGES_PREVIOUS="$(dpkg --get-selections | grep -E '\sinstall$' | awk '{ print $1 }')" ;; esac fi } # Get the full list of APT/APK packages that will be installed, given the required packages # # Arguments: # $1: the list of required APT/APK packages # # Output: # Space-separated list of every APT/APK packages that will be installed expandPackagesToBeInstalled() { expandPackagesToBeInstalled_result='' case "$DISTRO" in alpine) expandPackagesToBeInstalled_log="$(apk add --simulate $@ 2>&1 || printf '\nERROR: apk failed\n')" if test -n "$(printf '%s' "$expandPackagesToBeInstalled_log" | grep -E '^ERROR:')"; then printf 'FAILED TO LIST THE WHOLE PACKAGE LIST FOR\n' >&2 printf '%s ' "$@" >&2 printf '\n\nCOMMAND OUTPUT:\n%s\n' "$expandPackagesToBeInstalled_log" >&2 echo 'y' >"$IPE_ERRFLAG_FILE" exit 1 fi IFS=' ' for expandPackagesToBeInstalled_line in $expandPackagesToBeInstalled_log; do if test -n "$(printf '%s' "$expandPackagesToBeInstalled_line" | grep -E '^\([0-9]*/[0-9]*) Installing ')"; then expandPackagesToBeInstalled_result="$expandPackagesToBeInstalled_result $(printf '%s' "$expandPackagesToBeInstalled_line" | cut -d ' ' -f 3)" fi done resetIFS ;; debian) expandPackagesToBeInstalled_log="$(DEBIAN_FRONTEND=noninteractive apt-get install -sy $@ 2>&1 || printf '\nE: apt-get failed\n')" if test -n "$(printf '%s' "$expandPackagesToBeInstalled_log" | grep -E '^E:')"; then printf 'FAILED TO LIST THE WHOLE PACKAGE LIST FOR\n' >&2 printf '%s ' "$@" >&2 printf '\n\nCOMMAND OUTPUT:\n%s\n' "$expandPackagesToBeInstalled_log" >&2 echo 'y' >"$IPE_ERRFLAG_FILE" exit 1 fi expandPackagesToBeInstalled_inNewPackages=0 IFS=' ' for expandPackagesToBeInstalled_line in $expandPackagesToBeInstalled_log; do if test $expandPackagesToBeInstalled_inNewPackages -eq 0; then if test "$expandPackagesToBeInstalled_line" = 'The following NEW packages will be installed:'; then expandPackagesToBeInstalled_inNewPackages=1 fi elif test "$expandPackagesToBeInstalled_line" = "${expandPackagesToBeInstalled_line# }"; then break else resetIFS for expandPackagesToBeInstalled_newPackage in $expandPackagesToBeInstalled_line; do expandPackagesToBeInstalled_result="$expandPackagesToBeInstalled_result $expandPackagesToBeInstalled_newPackage" done IFS=' ' fi done resetIFS ;; esac printf '%s' "${expandPackagesToBeInstalled_result# }" } # Retrieve the number of available cores (alternative to nproc if not available) # Output: # The number of processor cores available getProcessorCount() { if command -v nproc >/dev/null 2>&1; then nproc else getProcessorCount_tmp=$(cat /proc/cpuinfo | grep -E '^processor\s*:\s*\d+$' | wc -l) if test $getProcessorCount_tmp -ge 1; then echo $getProcessorCount_tmp else echo 1 fi fi } # Get the build target tripled # Output: # The target triplet (eg x86_64-linux-gnu, i686-linux-gnu, i386-linux-gnu, ...) getTargetTriplet() { getTargetTriplet_tmp="$(gcc -print-multiarch 2>/dev/null || true)" if test -z "$getTargetTriplet_tmp"; then getTargetTriplet_tmp="$(gcc -dumpmachine 2>/dev/null || true)" fi printf '%s' "$getTargetTriplet_tmp" } # Retrieve the number of processors to be used when compiling an extension # # Arguments: # $1: the handle of the PHP extension to be compiled # Output: # The number of processors to be used getCompilationProcessorCount() { case "$1" in amqp | bcmath | bz2 | calendar | exif | gd | gettext | grpc | imagick | intl | mysqli | opcache | pcntl | pdo_mysql | protobuf | redis | soap | sockets | tidy | xdebug | xsl | yaml | zip) getProcessorCount ;; *) echo 1 ;; esac } # Install the required APT/APK packages # # Arguments: # $@: the list of APT/APK packages to be installed installRequiredPackages() { printf '### INSTALLING REQUIRED PACKAGES ###\n' printf '# Packages to be kept after installation: %s\n' "$PACKAGES_PERSISTENT" printf '# Packages to be used only for installation: %s\n' "$PACKAGES_VOLATILE" case "$DISTRO" in alpine) apk add $PACKAGES_PERSISTENT $PACKAGES_VOLATILE ;; debian) DEBIAN_FRONTEND=noninteractive apt-get install -qq -y $PACKAGES_PERSISTENT $PACKAGES_VOLATILE ;; esac } # Get the version of an installed APT/APK package # # Arguments: # $1: the name of the installed package # # Output: # The numeric part of the package version, with from 1 to 3 numbers # # Example: # 1 # 1.2 # 1.2.3 getInstalledPackageVersion() { case "$DISTRO" in alpine) apk info "$1" | head -n1 | cut -c $((${#1} + 2))- | grep -o -E '^[0-9]+(\.[0-9]+){0,2}' ;; debian) dpkg-query --showformat='${Version}' --show "$1" 2>/dev/null | grep -o -E '^[0-9]+(\.[0-9]+){0,2}' ;; esac } # Compare two versions # # Arguments: # $1: the first version # $2: the second version # # Output # -1 if $1 is less than $2 # 0 if $1 is the same as $2 # 1 if $1 is greater than $2 compareVersions() { compareVersions_v1="$1.0.0" compareVersions_v2="$2.0.0" compareVersions_vMin="$(printf '%s\n%s' "$compareVersions_v1" "$compareVersions_v2" | sort -t '.' -n -k1,1 -k2,2 -k3,3 | head -n 1)" if test "$compareVersions_vMin" != "$compareVersions_v1"; then echo '1' elif test "$compareVersions_vMin" = "$compareVersions_v2"; then echo '0' else echo '-1' fi } # Install a bundled PHP module given its handle # # Arguments: # $1: the handle of the PHP module # # Set: # UNNEEDED_PACKAGE_LINKS # # Output: # Nothing installBundledModule() { printf '### INSTALLING BUNDLED MODULE %s ###\n' "$1" if test -n "$(getWantedPHPModuleVersion "$1")"; then printf '### WARNING the module "%s" is bundled with PHP, you can NOT specify a version for it\n' "$1" >&2 fi case "$1" in gd) if test $PHP_MAJMIN_VERSION -le 506; then docker-php-ext-configure gd --with-gd --with-jpeg-dir --with-png-dir --with-zlib-dir --with-xpm-dir --with-freetype-dir --enable-gd-native-ttf --with-vpx-dir elif test $PHP_MAJMIN_VERSION -le 701; then docker-php-ext-configure gd --with-gd --with-jpeg-dir --with-png-dir --with-zlib-dir --with-xpm-dir --with-freetype-dir --enable-gd-native-ttf --with-webp-dir elif test $PHP_MAJMIN_VERSION -le 703; then docker-php-ext-configure gd --with-gd --with-jpeg-dir --with-png-dir --with-zlib-dir --with-xpm-dir --with-freetype-dir --with-webp-dir else docker-php-ext-configure gd --enable-gd --with-webp --with-jpeg --with-xpm --with-freetype fi ;; gmp) if test $PHP_MAJMIN_VERSION -le 506; then if ! test -f /usr/include/gmp.h; then ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h UNNEEDED_PACKAGE_LINKS="$UNNEEDED_PACKAGE_LINKS /usr/include/gmp.h" fi fi ;; imap) case "$DISTRO_VERSION" in debian@9) installBundledModule_tmp="$(pwd)" cd /tmp apt-get download libc-client2007e-dev dpkg -i --ignore-depends=libssl-dev libc-client2007e-dev* rm libc-client2007e-dev* cd "$installBundledModule_tmp" ;; esac PHP_OPENSSL=yes docker-php-ext-configure imap --with-kerberos --with-imap-ssl ;; interbase | pdo_firebird) case "$DISTRO" in alpine) if ! test -d /tmp/src/firebird; then mv "$(getPackageSource https://github.com/FirebirdSQL/firebird/releases/download/R2_5_9/Firebird-2.5.9.27139-0.tar.bz2)" /tmp/src/firebird cd /tmp/src/firebird #Patch rwlock.h (this has been fixed in later release of firebird 3.x) sed -i '194s/.*/#if 0/' src/common/classes/rwlock.h ./configure --with-system-icu # -j option can't be used: make targets must be compiled sequentially make -s btyacc_binary gpre_boot libfbstatic libfbclient cp gen/firebird/lib/libfbclient.so /usr/lib/ ln -s /usr/lib/libfbclient.so /usr/lib/libfbclient.so.2 cd - >/dev/null fi CFLAGS='-I/tmp/src/firebird/src/jrd -I/tmp/src/firebird/src/include -I/tmp/src/firebird/src/include/gen' docker-php-ext-configure $1 ;; esac ;; ldap) case "$DISTRO" in debian) docker-php-ext-configure ldap --with-libdir=lib/$(getTargetTriplet) ;; esac ;; mssql | pdo_dblib) if ! test -f /usr/lib/libsybdb.so; then ln -s /usr/lib/x86_64-linux-gnu/libsybdb.so /usr/lib/libsybdb.so UNNEEDED_PACKAGE_LINKS="$UNNEEDED_PACKAGE_LINKS /usr/lib/libsybdb.so" fi ;; odbc) docker-php-source extract cd /usr/src/php/ext/odbc phpize sed -ri 's@^ *test +"\$PHP_.*" *= *"no" *&& *PHP_.*=yes *$@#&@g' configure ./configure --with-unixODBC=shared,/usr cd - >/dev/null ;; pdo_odbc) docker-php-ext-configure pdo_odbc --with-pdo-odbc=unixODBC,/usr ;; snmp) case "$DISTRO" in alpine) mkdir -p -m 0755 /var/lib/net-snmp/mib_indexes ;; esac ;; sybase_ct) docker-php-ext-configure sybase_ct --with-sybase-ct=/usr ;; tidy) case "$DISTRO" in alpine) if ! test -f /usr/include/buffio.h; then ln -s /usr/include/tidybuffio.h /usr/include/buffio.h UNNEEDED_PACKAGE_LINKS="$UNNEEDED_PACKAGE_LINKS /usr/include/buffio.h" fi ;; esac ;; zip) if test $PHP_MAJMIN_VERSION -le 505; then docker-php-ext-configure zip elif test $PHP_MAJMIN_VERSION -le 703; then docker-php-ext-configure zip --with-libzip else docker-php-ext-configure zip --with-zip fi ;; esac docker-php-ext-install -j$(getProcessorCount) "$1" case "$1" in imap) case "$DISTRO_VERSION" in debian@9) dpkg -r libc-client2007e-dev ;; esac ;; esac } # Fetch a tar.gz file, extract it and returns the path of the extracted folder. # # Arguments: # $1: the URL of the file to be downloaded # # Output: # The path of the extracted directory getPackageSource() { mkdir -p /tmp/src getPackageSource_tempFile=$(mktemp -p /tmp/src) curl -L -s -S -o "$getPackageSource_tempFile" "$1" getPackageSource_tempDir=$(mktemp -p /tmp/src -d) cd "$getPackageSource_tempDir" tar -xzf "$getPackageSource_tempFile" 2>/dev/null || tar -xf "$getPackageSource_tempFile" cd - >/dev/null unlink "$getPackageSource_tempFile" getPackageSource_outDir='' for getPackageSource_i in $(ls "$getPackageSource_tempDir"); do if test -n "$getPackageSource_outDir" || test -f "$getPackageSource_tempDir/$getPackageSource_i"; then getPackageSource_outDir='' break fi getPackageSource_outDir="$getPackageSource_tempDir/$getPackageSource_i" done if test -n "$getPackageSource_outDir"; then printf '%s' "$getPackageSource_outDir" else printf '%s' "$getPackageSource_tempDir" fi } # Install a PHP module given its handle from source code # # Arguments: # $1: the handle of the PHP module # $2: the URL of the module source code # $3: the options of the configure command # $4: the value of CFLAGS installModuleFromSource() { printf '### INSTALLING MODULE %s FROM SOURCE CODE ###\n' "$1" installModuleFromSource_dir="$(getPackageSource "$2")" case "$1" in snuffleupagus) cd "$installModuleFromSource_dir/src" ;; *) cd "$installModuleFromSource_dir" ;; esac phpize ./configure $3 CFLAGS="${4:-}" make -j$(getProcessorCount) install cd - >/dev/null docker-php-ext-enable "$1" case "$1" in snuffleupagus) cp -a "$installModuleFromSource_dir/config/default.rules" "$PHP_INI_DIR/conf.d/snuffleupagus.rules" printf 'sp.configuration_file=%s\n' "$PHP_INI_DIR/conf.d/snuffleupagus.rules" >>"$PHP_INI_DIR/conf.d/docker-php-ext-snuffleupagus.ini" ;; esac } # Install a PECL PHP module given its handle # # Arguments: # $1: the handle of the PHP module installPECLModule() { installPECLModule_module="$1" printf '### INSTALLING PECL MODULE %s ###\n' "$installPECLModule_module" installPECLModule_version="$(getWantedPHPModuleVersion "$installPECLModule_module")" rm -rf "$CONFIGURE_FILE" installPECLModule_manuallyInstalled=0 case "$installPECLModule_module" in amqp) case "$DISTRO_VERSION" in debian@8) if test -z "$installPECLModule_version"; then # in Debian Jessie we have librammitmq version 0.5.2 installPECLModule_version=1.9.3 fi ;; esac ;; apcu) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=4.0.11 fi fi ;; decimal) case "$DISTRO" in alpine) installPECLModule_src="$(getPackageSource https://codeload.github.com/bematech/libmpdec/tar.gz/master)" cd -- "$installPECLModule_src" ./configure CFLAGS='-w' make -j$(getProcessorCount) make install cd - >/dev/null ;; esac ;; gmagick) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=1.1.7RC3 else installPECLModule_version=beta fi fi ;; grpc) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=1.33.1 fi fi ;; http) installPECLModule_module=pecl_http if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=2.6.0 fi fi if test $PHP_MAJMIN_VERSION -ge 700; then if ! test -e /usr/local/lib/libidnkit.so; then installPECLModule_src="$(getPackageSource https://jprs.co.jp/idn/idnkit-2.3.tar.bz2)" cd -- "$installPECLModule_src" ./configure make -j$(getProcessorCount) install cd - >/dev/null fi fi ;; igbinary) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=2.0.8 fi fi ;; memcache) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=2.2.7 elif test $PHP_MAJMIN_VERSION -lt 800; then installPECLModule_version=4.0.5.2 fi fi ;; mailparse) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=2.1.6 fi fi ;; memcached) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=2.2.0 fi fi # Set the path to libmemcached install prefix addConfigureOption 'with-libmemcached-dir' 'no' if test -z "$installPECLModule_version" || test $(compareVersions "$installPECLModule_version" '3.0.0') -ge 0; then # Set the path to ZLIB install prefix addConfigureOption 'with-zlib-dir' 'no' # Use system FastLZ library addConfigureOption 'with-system-fastlz' 'no' # Enable memcached igbinary serializer support if php --ri igbinary >/dev/null 2>/dev/null; then addConfigureOption 'enable-memcached-igbinary' 'yes' else addConfigureOption 'enable-memcached-igbinary' 'no' fi # Enable memcached msgpack serializer support if php --ri msgpack >/dev/null 2>/dev/null; then addConfigureOption 'enable-memcached-msgpack' 'yes' else addConfigureOption 'enable-memcached-msgpack' 'no' fi # Enable memcached json serializer support addConfigureOption 'enable-memcached-json' 'yes' # Enable memcached protocol support addConfigureOption 'enable-memcached-protocol' 'no' # https://github.com/php-memcached-dev/php-memcached/issues/418#issuecomment-449587972 # Enable memcached sasl support addConfigureOption 'enable-memcached-sasl' 'yes' # Enable memcached session handler support addConfigureOption 'enable-memcached-session' 'yes' fi ;; mongo) # Build with Cyrus SASL (MongoDB Enterprise Authentication) support? addConfigureOption '-with-mongo-sasl' 'yes' ;; mongodb) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 505; then installPECLModule_version=1.5.5 elif test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=1.7.5 elif test $PHP_MAJMIN_VERSION -le 800; then installPECLModule_version=1.9.0 fi fi ;; mosquitto) if test -z "$installPECLModule_version"; then installPECLModule_version=0.4.0 fi ;; msgpack) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=0.5.7 fi fi ;; oauth) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=1.2.3 fi fi ;; opencensus) if test $PHP_MAJMIN_VERSION -le 702; then if test -z "$installPECLModule_version"; then installPECLModule_version=alpha fi else installPECLModule_manuallyInstalled=1 if test -z "$installPECLModule_version"; then installPECLModule_src="$(getPackageSource https://pecl.php.net/get/opencensus)" else installPECLModule_src="$(getPackageSource https://pecl.php.net/get/opencensus-$installPECLModule_version)" fi cd "$installPECLModule_src"/opencensus-* find . -name '*.c' -type f -exec sed -i 's/\bZVAL_DESTRUCTOR\b/zval_dtor/g' {} + phpize ./configure make install cd - >/dev/null fi ;; parallel) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 701; then installPECLModule_version=0.8.3 fi fi ;; pcov) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 701; then installPECLModule_version=0.9.0 fi fi ;; pdo_sqlsrv | sqlsrv) if test -z "$installPECLModule_version"; then # https://docs.microsoft.com/it-it/sql/connect/php/system-requirements-for-the-php-sql-driver?view=sql-server-2017 if test $PHP_MAJMIN_VERSION -le 700; then installPECLModule_version=5.3.0 elif test $PHP_MAJMIN_VERSION -le 701; then installPECLModule_version=5.6.1 fi fi ;; propro) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=1.0.2 fi fi ;; protobuf) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=3.12.4 else installPECLModule_version=3.13.0 fi fi ;; pthreads) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=2.0.10 fi fi ;; raphf) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=1.1.2 fi fi ;; rdkafka) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 505; then installPECLModule_version=3.0.5 else installPECLModule_tmp= case "$DISTRO" in alpine) installPECLModule_tmp='librdkafka' ;; debian) installPECLModule_tmp='librdkafka*' ;; esac if test -n "$installPECLModule_tmp"; then installPECLModule_tmp="$(getInstalledPackageVersion "$installPECLModule_tmp")" if test -n "$installPECLModule_tmp"; then if test $(compareVersions "$installPECLModule_tmp" '0.11.0') -lt 0; then installPECLModule_version=3.1.3 fi fi fi fi fi ;; redis) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=4.3.0 fi fi # Enable igbinary serializer support? if php --ri igbinary >/dev/null 2>/dev/null; then addConfigureOption 'enable-redis-igbinary' 'yes' else addConfigureOption 'enable-redis-igbinary' 'no' fi # Enable lzf compression support? addConfigureOption 'enable-redis-lzf' 'yes' if test -z "$installPECLModule_version" || test $(compareVersions "$installPECLModule_version" '5.0.0') -ge 0; then installPECLModule_machine=$(getTargetTriplet) if ! test -e /usr/include/zstd.h || ! test -e /usr/lib/libzstd.so -o -e "/usr/lib/$installPECLModule_machine/libzstd.so"; then installPECLModule_zstdVersion=1.4.4 installPECLModule_zstdVersionMajor=$(echo $installPECLModule_zstdVersion | cut -d. -f1) rm -rf /tmp/src/zstd mv "$(getPackageSource https://github.com/facebook/zstd/releases/download/v1.4.4/zstd-$installPECLModule_zstdVersion.tar.gz)" /tmp/src/zstd cd /tmp/src/zstd make V=0 -j$(getProcessorCount) lib cp -f lib/libzstd.so "/usr/lib/$installPECLModule_machine/libzstd.so.$installPECLModule_zstdVersion" ln -sf "/usr/lib/$installPECLModule_machine/libzstd.so.$installPECLModule_zstdVersion" "/usr/lib/$installPECLModule_machine/libzstd.so.$installPECLModule_zstdVersionMajor" ln -sf "/usr/lib/$installPECLModule_machine/libzstd.so.$installPECLModule_zstdVersion" "/usr/lib/$installPECLModule_machine/libzstd.so" ln -sf /tmp/src/zstd/lib/zstd.h /usr/include/zstd.h UNNEEDED_PACKAGE_LINKS="$UNNEEDED_PACKAGE_LINKS /usr/include/zstd.h" cd - >/dev/null fi # Enable zstd compression support? addConfigureOption 'enable-redis-zstd' 'yes' fi ;; solr) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=2.4.0 fi fi ;; ssh2) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=0.13 else installPECLModule_version=1.2 fi fi ;; tdlib) if ! test -f /usr/lib/libphpcpp.so || ! test -f /usr/include/phpcpp.h; then if test $PHP_MAJMIN_VERSION -le 701; then cd "$(getPackageSource https://codeload.github.com/CopernicaMarketingSoftware/PHP-CPP/tar.gz/v2.1.4)" elif test $PHP_MAJMIN_VERSION -le 703; then cd "$(getPackageSource https://codeload.github.com/CopernicaMarketingSoftware/PHP-CPP/tar.gz/v2.2.0)" else cd "$(getPackageSource https://codeload.github.com/CopernicaMarketingSoftware/PHP-CPP/tar.gz/444d1f90cf6b7f3cb5178fa0d0b5ab441b0389d0)" fi make -j$(getProcessorCount) make install cd - >/dev/null fi installPECLModule_tmp="$(mktemp -p /tmp/src -d)" git clone --depth=1 --recurse-submodules https://github.com/yaroslavche/phptdlib.git "$installPECLModule_tmp" mkdir "$installPECLModule_tmp/build" cd "$installPECLModule_tmp/build" cmake -D USE_SHARED_PHPCPP:BOOL=ON .. make make install rm "$PHP_INI_DIR/conf.d/tdlib.ini" installPECLModule_manuallyInstalled=1 ;; uuid) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=1.0.5 fi fi ;; xdebug) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 500; then installPECLModule_version=2.0.5 elif test $PHP_MAJMIN_VERSION -le 503; then installPECLModule_version=2.2.7 elif test $PHP_MAJMIN_VERSION -le 504; then installPECLModule_version=2.4.1 elif test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=2.5.5 elif test $PHP_MAJMIN_VERSION -le 700; then installPECLModule_version=2.6.1 elif test $PHP_MAJMIN_VERSION -le 701; then installPECLModule_version=2.9.8 fi fi if test $PHP_MAJMIN_VERSION -ge 800; then # Workaround for picke problem - see https://github.com/FriendsOfPHP/pickle/issues/188 and https://github.com/FriendsOfPHP/pickle/issues/191 if test -z "$installPECLModule_version"; then installPECLModule_version=3.0.1 fi installPECLModule_src="$(getPackageSource https://codeload.github.com/xdebug/xdebug/tar.gz/$installPECLModule_version)" cd -- "$installPECLModule_src" phpize ./configure --enable-xdebug make -j$(getProcessorCount) make install cd - >/dev/null installPECLModule_manuallyInstalled=1 fi ;; uopz) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=2.0.7 elif test $PHP_MAJMIN_VERSION -lt 701; then installPECLModule_version=5.0.2 fi fi ;; xhprof) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -le 506; then installPECLModule_version=0.9.4 fi fi ;; yaml) if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=1.3.1 elif test $PHP_MAJMIN_VERSION -lt 701; then installPECLModule_version=2.0.4 fi fi ;; zookeeper) case "$DISTRO" in alpine) if ! test -f /usr/local/include/zookeeper/zookeeper.h; then installPECLModule_tmp="$(curl -L -s -S -f https://downloads.apache.org/zookeeper/stable | sed -E 's/["<>]/\n/g' | grep -E '^(apache-)?zookeeper-[0-9]+\.[0-9]+\.[0-9]+\.(tar\.gz|tgz)$' | head -n1)" if test -z "$installPECLModule_tmp"; then echo 'Failed to detect the zookeeper library URL' >&2 exit 1 fi installPECLModule_src="$(getPackageSource https://downloads.apache.org/zookeeper/stable/$installPECLModule_tmp)" cd -- "$installPECLModule_src" ant compile_jute cd - >/dev/null cd -- "$installPECLModule_src/zookeeper-client/zookeeper-client-c" autoreconf -if ./configure --without-cppunit make -j$(getProcessorCount) CFLAGS='-Wno-stringop-truncation -Wno-format-overflow' make install cd - >/dev/null fi ;; esac if test -z "$installPECLModule_version"; then if test $PHP_MAJMIN_VERSION -lt 700; then installPECLModule_version=0.5.0 elif test $PHP_MAJMIN_VERSION -gt 702; then installPECLModule_version=0.7.2 fi fi ;; esac if test $installPECLModule_manuallyInstalled -eq 0; then if test -n "$installPECLModule_version"; then printf ' (installing version %s)\n' "$installPECLModule_version" fi installPeclPackage "$installPECLModule_module" "$installPECLModule_version" fi case "$installPECLModule_module" in apcu_bc) # apcu_bc must be loaded after apcu docker-php-ext-enable --ini-name "xx-php-ext-$installPECLModule_module.ini" apc ;; pecl_http) # http must be loaded after raphf and propro docker-php-ext-enable --ini-name "xx-php-ext-http.ini" http ;; memcached) # memcached must be loaded after msgpack docker-php-ext-enable --ini-name "xx-php-ext-$installPECLModule_module.ini" "$installPECLModule_module" ;; *) docker-php-ext-enable "$installPECLModule_module" ;; esac } # Configure the PECL package installed # If we'll use pickle, the zip extension will be added to PHP_MODULES_TO_INSTALL # # Updates: # PHP_MODULES_TO_INSTALL # Sets: # USE_PICKLE configureInstaller() { USE_PICKLE=0 for PHP_MODULE_TO_INSTALL in $PHP_MODULES_TO_INSTALL; do if ! stringInList "$PHP_MODULE_TO_INSTALL" "$BUNDLED_MODULES"; then if test $PHP_MAJMIN_VERSION -lt 800; then pecl channel-update pecl.php.net || true return fi curl -sSL https://github.com/FriendsOfPHP/pickle/releases/latest/download/pickle.phar -o /tmp/pickle chmod +x /tmp/pickle if ! stringInList 'zip' "$PHP_PREINSTALLED_MODULES"; then PHP_MODULES_TO_INSTALL="zip $(removeStringFromList 'zip' "$PHP_MODULES_TO_INSTALL")" fi USE_PICKLE=1 return fi done } # Add a configure option for the pecl/pickle install command # # Arguments: # $1: the option name # $2: the option value addConfigureOption() { if test $USE_PICKLE -eq 0; then printf -- '%s\n' "$2" >>"$CONFIGURE_FILE" else printf -- '--%s=%s\n' "$1" "$2" >>"$CONFIGURE_FILE" fi } # Actually installs a PECL package # # Arguments: # $1: the package to be installed # $2: the package version to be installed (optional) installPeclPackage() { if test -z "${2:-}"; then installPeclPackage_fullname="$1" else installPeclPackage_fullname="$1-$2" fi if ! test -f "$CONFIGURE_FILE"; then printf '\n' >"$CONFIGURE_FILE" fi if test $USE_PICKLE -eq 0; then cat "$CONFIGURE_FILE" | MAKE="make -j$(getCompilationProcessorCount $1)" pecl install "$installPeclPackage_fullname" else MAKE="make -j$(getCompilationProcessorCount $1)" /tmp/pickle install --tmp-dir=/tmp/pickle.tmp --no-interaction --with-configure-options "$CONFIGURE_FILE" -- "$installPeclPackage_fullname" fi } # Check if a string is in a list of space-separated string # # Arguments: # $1: the string to be checked # $2: the string list # # Return: # 0 (true): if the string is in the list # 1 (false): if the string is not in the list stringInList() { for stringInList_listItem in $2; do if test "$1" = "$stringInList_listItem"; then return 0 fi done return 1 } # Remove a word from a space-separated list # # Arguments: # $1: the word to be removed # $2: the string list # # Output: # The list without the word removeStringFromList() { removeStringFromList_result='' for removeStringFromList_listItem in $2; do if test "$1" != "$removeStringFromList_listItem"; then if test -z "$removeStringFromList_result"; then removeStringFromList_result="$removeStringFromList_listItem" else removeStringFromList_result="$removeStringFromList_result $removeStringFromList_listItem" fi fi done printf '%s' "$removeStringFromList_result" } # Cleanup everything at the end of the execution cleanup() { if test -n "$UNNEEDED_PACKAGE_LINKS"; then printf '### REMOVING UNNEEDED PACKAGE LINKS ###\n' for cleanup_link in $UNNEEDED_PACKAGE_LINKS; do if test -L "$cleanup_link"; then rm -f "$cleanup_link" fi done fi if test -n "$PACKAGES_VOLATILE"; then printf '### REMOVING UNNEEDED PACKAGES ###\n' case "$DISTRO" in alpine) apk del --purge $PACKAGES_VOLATILE ;; debian) DEBIAN_FRONTEND=noninteractive apt-get remove --purge -y $PACKAGES_VOLATILE ;; esac fi if test -n "$PACKAGES_PREVIOUS"; then case "$DISTRO" in debian) printf '### RESTORING PREVIOUSLY INSTALLED PACKAGES ###\n' DEBIAN_FRONTEND=noninteractive apt-get install --no-upgrade -qqy $PACKAGES_PREVIOUS ;; esac fi case "$DISTRO" in alpine) rm -rf /var/cache/apk/* ;; debian) rm -rf /var/lib/apt/lists/* ;; esac docker-php-source delete rm -rf /tmp/pear rm -rf /tmp/src rm -rf /tmp/pickle rm -rf /tmp/pickle.tmp rm -rf "$CONFIGURE_FILE" } resetIFS mkdir -p /tmp/src mkdir -p /tmp/pickle.tmp IPE_ERRFLAG_FILE="$(mktemp -p /tmp/src)" CONFIGURE_FILE=/tmp/configure-options setDistro setPHPMajorMinor setPHPPreinstalledModules case "$PHP_MAJMIN_VERSION" in 505 | 506 | 700 | 701 | 702 | 703 | 704 | 800) ;; *) printf "### ERROR: Unsupported PHP version: %s.%s ###\n" $((PHP_MAJMIN_VERSION / 100)) $((PHP_MAJMIN_VERSION % 100)) ;; esac UNNEEDED_PACKAGE_LINKS='' processCommandArguments "$@" if test -z "$PHP_MODULES_TO_INSTALL"; then exit 0 fi sortModulesToInstall docker-php-source extract BUNDLED_MODULES="$(find /usr/src/php/ext -mindepth 2 -maxdepth 2 -type f -name 'config.m4' | xargs -n1 dirname | xargs -n1 basename | xargs)" configureInstaller buildRequiredPackageLists $PHP_MODULES_TO_INSTALL if test -n "$PACKAGES_PERSISTENT$PACKAGES_VOLATILE"; then installRequiredPackages fi for PHP_MODULE_TO_INSTALL in $PHP_MODULES_TO_INSTALL; do if stringInList "$PHP_MODULE_TO_INSTALL" "$BUNDLED_MODULES"; then installBundledModule "$PHP_MODULE_TO_INSTALL" else MODULE_SOURCE='' MODULE_SOURCE_CONFIGOPTIONS='' MODULE_SOURCE_CFLAGS='' case "$PHP_MODULE_TO_INSTALL" in cmark) MODULE_VERSION="$(getWantedPHPModuleVersion "$PHP_MODULE_TO_INSTALL")" if test -z "$MODULE_VERSION"; then MODULE_VERSION='1.0.0' fi MODULE_SOURCE=https://github.com/krakjoe/cmark/archive/v$MODULE_VERSION.tar.gz cd "$(getPackageSource https://github.com/commonmark/cmark/archive/0.28.3.tar.gz)" make install cd - >/dev/null MODULE_SOURCE_CONFIGOPTIONS=--with-cmark ;; snuffleupagus) MODULE_VERSION="$(getWantedPHPModuleVersion "$PHP_MODULE_TO_INSTALL")" if test -z "$MODULE_VERSION"; then MODULE_VERSION='0.5.0' fi MODULE_SOURCE=https://codeload.github.com/jvoisin/snuffleupagus/tar.gz/v$MODULE_VERSION MODULE_SOURCE_CONFIGOPTIONS=--enable-snuffleupagus ;; esac if test -n "$MODULE_SOURCE"; then installModuleFromSource "$PHP_MODULE_TO_INSTALL" "$MODULE_SOURCE" "$MODULE_SOURCE_CONFIGOPTIONS" "$MODULE_SOURCE_CFLAGS" else installPECLModule "$PHP_MODULE_TO_INSTALL" fi fi done cleanup