#!/bin/sh # This script wraps docker-php-ext-install, properly configuring the system. # # Copyright (c) Michele Locati, 2018 # # 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 # Reset the Internal Field Separator resetIFS () { IFS=' ' } # Get the distribution name # # Output: # alpine|debian getDistro () { getDistro_os_id='' if test -r /etc/os-release; then getDistro_os_id="$(cat /etc/os-release | grep -E ^ID= | cut -d = -f 2)" case "$getDistro_os_id" in alpine|debian) ;; *) getDistro_os_id='' ;; esac fi if test -n "$getDistro_os_id"; then printf '%s' "$getDistro_os_id" else printf '%s' 'debian' fi } # Get the PHP Major-Minor version as an integer value, in format MMmm (example: 506 for PHP 5.6.15) # # Output: # The PHP numeric Major-Minor version getPHPMajorMinor () { php -r '$v = explode(".", PHP_VERSION); echo $v[0] * 100 + $v[1];' } # Get the normalized list of already installed PHP modules # # Output: # Space-separated list of module handles getPHPInstalledModules () { getPHPInstalledModules_result='' IFS=' ' for getPHPInstalledModules_module in $(php -m); do getPHPInstalledModules_moduleNormalized='' case "$getPHPInstalledModules_module" in \[PHP\ Modules\]) ;; \[Zend\ Modules\]) break ;; Core|PDO|PDO_*|Phar|Reflection|SimpleXML|SPL|SQLite|Xdebug) getPHPInstalledModules_moduleNormalized=$(LC_CTYPE=C printf '%s' "$getPHPInstalledModules_module" | tr '[:upper:]' '[:lower:]') ;; Zend\ OPcache) getPHPInstalledModules_moduleNormalized='opcache' ;; *\ *|*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*) printf '### WARNING Unrecognized module name: %s ###\n' "$getPHPInstalledModules_module" >&2 ;; *) getPHPInstalledModules_moduleNormalized="$getPHPInstalledModules_module" ;; esac if test -n "$getPHPInstalledModules_moduleNormalized"; then if ! stringInList "$getPHPInstalledModules_moduleNormalized" "$getPHPInstalledModules_result"; then getPHPInstalledModules_result="$getPHPInstalledModules_result $getPHPInstalledModules_moduleNormalized" fi fi done resetIFS printf '%s' "${getPHPInstalledModules_result# }" } # Get the handles of the modules to be installed # # Arguments: # $@: all module handles # # Set: # PHP_MODULES_TO_INSTALL # # Output: # Nothing processCommandArguments () { processCommandArguments_alreadyInstalled="$(getPHPInstalledModules)" 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 --cleanup 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 if stringInList "$1" "$PHP_MODULES_TO_INSTALL"; then printf '### WARNING Duplicated module name specified: %s ###\n' "$1" >&2 elif stringInList "$1" "$processCommandArguments_alreadyInstalled"; then printf '### WARNING Module already installed: %s ###\n' "$1" >&2 else PHP_MODULES_TO_INSTALL="$PHP_MODULES_TO_INSTALL $1" fi fi shift done PHP_MODULES_TO_INSTALL="${PHP_MODULES_TO_INSTALL# }" } # Sort the modules to be installed, in order to fix dependencies # # Update: # PHP_MODULES_TO_INSTALL # # Output: # Nothing sortModulesToInstall () { if stringInList 'igbinary' "$PHP_MODULES_TO_INSTALL"; then PHP_MODULES_TO_INSTALL="$(removeStringFromList 'igbinary' "$PHP_MODULES_TO_INSTALL")" if test -z "$PHP_MODULES_TO_INSTALL"; then PHP_MODULES_TO_INSTALL='igbinary' else PHP_MODULES_TO_INSTALL="igbinary $PHP_MODULES_TO_INSTALL" fi fi if stringInList 'msgpack' "$PHP_MODULES_TO_INSTALL"; then PHP_MODULES_TO_INSTALL="$(removeStringFromList 'msgpack' "$PHP_MODULES_TO_INSTALL")" if test -z "$PHP_MODULES_TO_INSTALL"; then PHP_MODULES_TO_INSTALL='msgpack' else PHP_MODULES_TO_INSTALL="msgpack $PHP_MODULES_TO_INSTALL" fi fi } # Get the required APT/APK packages for a specific PHP version and for the list of module handles # # Arguments: # $1: the numeric PHP Major-Minor version # $@: the PHP module handles # # Set: # PACKAGES_PERSISTENT # PACKAGES_VOLATILE # # Return: # 0 (true): if we to install some package # 1 (false): if no package is required buildRequiredPackageLists () { buildRequiredPackageLists_persistent='' buildRequiredPackageLists_volatile='' buildRequiredPackageLists_distro="$(getDistro)" buildRequiredPackageLists_phpv=$1 while :; do if test $# -lt 2; then break fi shift case "$1@$buildRequiredPackageLists_distro" in amqp@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent rabbitmq-c" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $PHPIZE_DEPS rabbitmq-c-dev" ;; amqp@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent librabbitmq4" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile librabbitmq-dev libssh-dev" ;; apcu@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $PHPIZE_DEPS" ;; 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 $PHPIZE_DEPS" ;; cmark@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile cmake" ;; enchant@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent enchant" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile enchant-dev" ;; enchant@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libenchant1c2a" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libenchant-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 $buildRequiredPackageLists_phpv -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 libpng16-16 libxpm4" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libfreetype6-dev libjpeg62-turbo-dev libpng-dev libxpm-dev" if test $buildRequiredPackageLists_phpv -le 506; then buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libvpx?" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libvpx-dev" else buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libwebp6" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libwebp-dev" fi ;; gettext@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libintl" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile gettext-dev" ;; gmp@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent gmp" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile gmp-dev" ;; gmp@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libgmp-dev" ;; igbinary@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $PHPIZE_DEPS" ;; imagick@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent imagemagick" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $PHPIZE_DEPS imagemagick-dev" ;; imagick@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmagickwand-6.q16-?" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmagickwand-dev" ;; imap@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent c-client" if test -z "$(apk info | grep -E ^libssl)"; then buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libssl1.0" fi buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile krb5-dev imap-dev openssl openssl-dev" ;; imap@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libc-client2007e" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libc-client-dev libkrb5-dev" ;; interbase@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $PHPIZE_DEPS 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_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 $PHPIZE_DEPS 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 $PHPIZE_DEPS zlib-dev" ;; memcache@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile zlib1g-dev" ;; memcached@alpine) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmemcached-libs" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $PHPIZE_DEPS libmemcached-dev zlib-dev" ;; memcached@debian) buildRequiredPackageLists_persistent="$buildRequiredPackageLists_persistent libmemcachedutil2" buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libmemcached-dev zlib1g-dev" ;; msgpack@alpine) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile $PHPIZE_DEPS" ;; 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" ;; odbc@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pdo_dblib@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; pdo_firebird@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile firebird-dev libib-util" ;; pdo_pgsql@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpq-dev" ;; pdo_odbc@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pdo_sqlsrv@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; pgsql@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpq-dev" ;; pspell@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libpspell-dev" ;; recode@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile librecode-dev" ;; ssh2@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libssh2-1-dev" ;; snmp@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile snmp libsnmp-dev" ;; soap@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; solr@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libcurl4-gnutls-dev libxml2-dev" ;; sqlsrv@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile unixodbc-dev" ;; sybase_ct@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile freetds-dev" ;; tidy@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libtidy-dev" ;; uuid@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile uuid-dev" ;; wddx@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; xmlrpc@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxml2-dev" ;; xsl@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libxslt-dev" ;; yaml@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile libyaml-dev" ;; zip@debian) buildRequiredPackageLists_volatile="$buildRequiredPackageLists_volatile cmake zlib1g-dev libbz2-dev libmbedtls-dev" ;; esac done PACKAGES_PERSISTENT='' PACKAGES_VOLATILE='' if test -z "$buildRequiredPackageLists_persistent$buildRequiredPackageLists_volatile"; then return 0 fi case "$buildRequiredPackageLists_distro" in alpine) apk update ;; debian) DEBIAN_FRONTEND=noninteractive apt-get update DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -y ;; esac if test -n "$buildRequiredPackageLists_persistent"; then PACKAGES_PERSISTENT="$(expandPackagesToBeInstalled $buildRequiredPackageLists_persistent)" fi if test -n "$buildRequiredPackageLists_volatile"; then resetIFS for buildRequiredPackageLists_package in $(expandPackagesToBeInstalled $buildRequiredPackageLists_volatile); do if ! stringInList "$buildRequiredPackageLists_package" "$PACKAGES_PERSISTENT"; then PACKAGES_VOLATILE="$PACKAGES_VOLATILE $buildRequiredPackageLists_package" fi done PACKAGES_VOLATILE="${PACKAGES_VOLATILE# }" 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 "$(getDistro)" in alpine) IFS=' ' for expandPackagesToBeInstalled_line in $(apk add --simulate $@); 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_inNewPackages=0 IFS=' ' for expandPackagesToBeInstalled_line in $(DEBIAN_FRONTEND=noninteractive apt-get install -sy $@); 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# }" } # Install the required APT/APK packages # # Arguments: # $@: the list of APT/APK packages to be installed installRequiredPackages () { printf '### INSTALLING REQUIRED PACKAGES ###\n' case "$(getDistro)" in alpine) apk add $PACKAGES_PERSISTENT $PACKAGES_VOLATILE ;; debian) DEBIAN_FRONTEND=noninteractive apt-get install -y $PACKAGES_PERSISTENT $PACKAGES_VOLATILE ;; esac } # Install a bundled PHP module given its handle # # Arguments: # $1: the numeric PHP Major-Minor version # $2: the handle of the PHP module # # Set: # UNNEEDED_PACKAGE_LINKS # # Output: # Nothing installBundledModule () { printf '### INSTALLING BUNDLED MODULE %s ###\n' "$2" case "$2" in gd) if test $1 -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 $1 -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 $1 -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) case "$1" in 506) 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 ;; esac ;; imap) PHP_OPENSSL=yes docker-php-ext-configure imap --with-kerberos --with-imap-ssl ;; interbase) case "$(getDistro)" 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 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 - 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 $2 ;; esac ;; ldap) docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine) ;; mssql|pdo_dblib) case "$1" in 506|700|701|702|703|704) 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 ;; esac ;; odbc) case "$1" in 506|700|701|702|703|704) 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 - ;; esac ;; pdo_odbc) docker-php-ext-configure pdo_odbc --with-pdo-odbc=unixODBC,/usr ;; sybase_ct) docker-php-ext-configure sybase_ct --with-sybase-ct=/usr ;; zip) libZipSrc="$(getPackageSource https://libzip.org/download/libzip-1.5.2.tar.gz)" mkdir "$libZipSrc/build" cd "$libZipSrc/build" cmake .. make -j$(nproc) install cd - if test $1 -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$(nproc) "$2" } # 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")" cd "$installModuleFromSource_dir" phpize ./configure $3 CFLAGS="${4:-}" make -j$(nproc) install cd -- docker-php-ext-enable "$1" } # Install a PECL PHP module given its handle # # Arguments: # $1: the numeric PHP Major-Minor version # $2: the handle of the PHP module installPECLModule () { printf '### INSTALLING PECL MODULE %s ###\n' "$2" installPECLModule_actual="$2" installPECLModule_stdin='\n' case "$2" in apcu) if test $1 -le 506; then installPECLModule_actual="$2-4.0.11" fi ;; memcached) if test $1 -lt 700; then installPECLModule_actual="$2-2.2.0" # --with-libmemcached-dir (default: no) Set the path to libmemcached install prefix else installPECLModule_stdin='' # --with-libmemcached-dir (default: no) Set the path to libmemcached install prefix installPECLModule_stdin="${installPECLModule_stdin}\n" # --with-zlib-dir (default: no) Set the path to ZLIB install prefix installPECLModule_stdin="${installPECLModule_stdin}\n" # --with-system-fastlz (default: no) Use system FastLZ library installPECLModule_stdin="${installPECLModule_stdin}no\n" # --enable-memcached-igbinary (default: no) Enable memcached igbinary serializer support php --ri igbinary >/dev/null 2>/dev/null && installPECLModule_stdin="${installPECLModule_stdin}yes\n" || installPECLModule_stdin="${installPECLModule_stdin}no\n" # --enable-memcached-msgpack (default: no) Enable memcached msgpack serializer support php --ri msgpack >/dev/null 2>/dev/null && installPECLModule_stdin="${installPECLModule_stdin}yes\n" || installPECLModule_stdin="${installPECLModule_stdin}no\n" # --enable-memcached-json (default: no) Enable memcached json serializer support installPECLModule_stdin="${installPECLModule_stdin}yes\n" # --enable-memcached-protocol (default: no) Enable memcached protocol support installPECLModule_stdin="${installPECLModule_stdin}no\n" # https://github.com/php-memcached-dev/php-memcached/issues/418#issuecomment-449587972 # --enable-memcached-sasl (default: yes) Enable memcached sasl support installPECLModule_stdin="${installPECLModule_stdin}yes\n" # --enable-memcached-session (default: yes) Enable memcached session handler support installPECLModule_stdin="${installPECLModule_stdin}yes\n" fi ;; msgpack) if test $1 -le 506; then installPECLModule_actual="$2-0.5.7" fi ;; parallel) if test $1 -le 701; then installPECLModule_actual="$2-0.8.3" fi ;; pcov) if test $1 -lt 701; then installPECLModule_actual="$2-0.9.0" fi ;; pdo_sqlsrv | sqlsrv) # https://docs.microsoft.com/it-it/sql/connect/php/system-requirements-for-the-php-sql-driver?view=sql-server-2017 if test $1 -le 700; then installPECLModule_actual="$2-5.3.0" elif test $1 -ge 704; then installPECLModule_actual="$2-5.7.0preview" fi ;; pthreads) if test $1 -lt 700; then installPECLModule_actual="$2-2.0.10" fi ;; redis) if test $1 -le 506; then installPECLModule_actual="$2-4.3.0" fi # enable-redis-igbinary? enable-redis-lzf? php --ri igbinary >/dev/null 2>/dev/null && installPECLModule_stdin='yes\nyes\n' || installPECLModule_stdin='no\nyes\n' ;; solr) if test $1 -le 506; then installPECLModule_actual="$2-2.4.0" fi ;; ssh2) if test $1 -le 506; then installPECLModule_actual="$2-0.13" else # see https://bugs.php.net/bug.php?id=78560 installPECLModule_actual='https://pecl.php.net/get/ssh2' fi ;; xdebug) if test $1 -lt 501; then installPECLModule_actual="$2-2.0.5" elif test $1 -lt 504; then installPECLModule_actual="$2-2.2.7" elif test $1 -lt 505; then installPECLModule_actual="$2-2.4.1" elif test $1 -lt 700; then installPECLModule_actual="$2-2.5.5" elif test $1 -ge 704; then installPECLModule_actual="$2-2.8.0beta2" fi ;; uopz) if test $1 -lt 700; then installPECLModule_actual="$2-2.0.7" elif test $1 -lt 701; then installPECLModule_actual="$2-5.0.2" fi ;; yaml) if test $1 -lt 700; then installPECLModule_actual="$2-1.3.1" fi ;; esac if test "$2" != "$installPECLModule_actual"; then printf ' (installing version %s)\n' "$installPECLModule_actual" fi printf "$installPECLModule_stdin" | pecl install "$installPECLModule_actual" docker-php-ext-enable "$2" } # 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 () { cleanup_distro="$(getDistro)" 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 "$cleanup_distro" in alpine) apk del --purge $PACKAGES_VOLATILE ;; debian) DEBIAN_FRONTEND=noninteractive apt-get remove --purge -y $PACKAGES_VOLATILE ;; esac fi case "$cleanup_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 } resetIFS PHP_MAJMIN_VERSION=$(getPHPMajorMinor) case "$PHP_MAJMIN_VERSION" in 506|700|701|702|703|704) ;; *) 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 if buildRequiredPackageLists $PHP_MAJMIN_VERSION $PHP_MODULES_TO_INSTALL; then installRequiredPackages fi 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)" for PHP_MODULE_TO_INSTALL in $PHP_MODULES_TO_INSTALL; do if stringInList "$PHP_MODULE_TO_INSTALL" "$BUNDLED_MODULES"; then installBundledModule $PHP_MAJMIN_VERSION "$PHP_MODULE_TO_INSTALL" else MODULE_SOURCE='' MODULE_SOURCE_CONFIGOPTIONS='' MODULE_SOURCE_CFLAGS='' case "$PHP_MODULE_TO_INSTALL" in cmark) MODULE_SOURCE=https://github.com/krakjoe/cmark/archive/v1.0.0.tar.gz cd "$(getPackageSource https://github.com/commonmark/cmark/archive/0.28.3.tar.gz)" make install cd - MODULE_SOURCE_CONFIGOPTIONS=--with-cmark ;; igbinary) if test $PHP_MAJMIN_VERSION -lt 700; then MODULE_SOURCE="https://github.com/igbinary/igbinary/archive/2.0.8.tar.gz" else MODULE_SOURCE="https://github.com/igbinary/igbinary/archive/3.0.1.tar.gz" fi MODULE_SOURCE_CONFIGOPTIONS=--enable-igbinary MODULE_SOURCE_CFLAGS='-O2 -g' ;; esac if test -n "$MODULE_SOURCE"; then installModuleFromSource "$PHP_MODULE_TO_INSTALL" "$MODULE_SOURCE" "$MODULE_SOURCE_CONFIGOPTIONS" "$MODULE_SOURCE_CFLAGS" else installPECLModule $PHP_MAJMIN_VERSION "$PHP_MODULE_TO_INSTALL" fi fi done cleanup