From ada1ce86b7bc7395aca633cb141316f60add1b7d Mon Sep 17 00:00:00 2001 From: Shivam Mathur Date: Sat, 3 Apr 2021 05:13:18 +0530 Subject: [PATCH] Refactor and improve extension support Add support for APCu on macOS from shivammathur/homebrew-extensions Improve support for geos to compile on PHP 8.0 and 8.1 Fix pecl setup to avoid unnecessary callbacks Use GitHub releases for all couchbase versions Use add_extension_from_source for all custom supported extensions Remove bintray and use shivammathur/intl-icu releases Add patch for protobuf for installing from source Move patches from custom extension scripts to patches directory Add support to build extension from GitHub and pecl tar archives (Internal API) Refactor regex in extension.ts Move add_pecl_extension to common.sh Refactor remove_extension in darwin.sh Fix shellcheck warning in darwin.sh Improve switch_version in linux.sh to accept parameters --- __tests__/extensions.test.ts | 3 +- dist/index.js | 51 ++++++------- src/extensions.ts | 51 ++++++------- src/scripts/common.sh | 25 ++++++- src/scripts/darwin.sh | 38 ++++------ src/scripts/ext/couchbase.sh | 19 ++--- src/scripts/ext/cubrid.sh | 20 +++-- src/scripts/ext/firebird.sh | 19 +---- src/scripts/ext/geos.sh | 40 +--------- src/scripts/ext/http.sh | 110 ++++++++-------------------- src/scripts/ext/oci.sh | 65 ++-------------- src/scripts/ext/patches/firebird.sh | 11 +++ src/scripts/ext/patches/geos.sh | 7 ++ src/scripts/ext/patches/http.sh | 11 +++ src/scripts/ext/patches/pdo_oci.sh | 6 ++ src/scripts/ext/patches/phpize.sh | 26 +++++++ src/scripts/ext/patches/protobuf.sh | 4 + src/scripts/ext/source.sh | 109 ++++++++++++++++++++------- src/scripts/linux.sh | 35 +++------ 19 files changed, 301 insertions(+), 349 deletions(-) create mode 100644 src/scripts/ext/patches/firebird.sh create mode 100644 src/scripts/ext/patches/geos.sh create mode 100644 src/scripts/ext/patches/http.sh create mode 100644 src/scripts/ext/patches/pdo_oci.sh create mode 100644 src/scripts/ext/patches/phpize.sh create mode 100644 src/scripts/ext/patches/protobuf.sh diff --git a/__tests__/extensions.test.ts b/__tests__/extensions.test.ts index 700fa35e..63b530b3 100644 --- a/__tests__/extensions.test.ts +++ b/__tests__/extensions.test.ts @@ -160,11 +160,12 @@ describe('Extension tests', () => { it('checking addExtensionOnDarwin', async () => { let darwin: string = await extensions.addExtension( - 'amqp, Xdebug, pcov, grpc, igbinary, imagick, imap, msgpack, protobuf, redis, swoole, sqlite, oci8, pdo_oci, :intl, ast-beta, grpc-1.2.3', + 'amqp, apcu, Xdebug, pcov, grpc, igbinary, imagick, imap, msgpack, protobuf, redis, swoole, sqlite, oci8, pdo_oci, :intl, ast-beta, grpc-1.2.3', '7.2', 'darwin' ); expect(darwin).toContain('add_brew_extension amqp extension'); + expect(darwin).toContain('add_brew_extension apcu extension'); expect(darwin).toContain('add_brew_extension xdebug zend_extension'); expect(darwin).toContain('add_brew_extension pcov extension'); expect(darwin).toContain('add_brew_extension grpc extension'); diff --git a/dist/index.js b/dist/index.js index b73c733f..45c1630b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1810,18 +1810,18 @@ async function addExtensionDarwin(extension_csv, version) { case /^:/.test(ext_name): remove_script += '\nremove_extension ' + ext_name.slice(1); return; - // match extensions for compiling from source. + // match extensions for compiling from source case /.+-.+\/.+@.+/.test(extension): add_script += await utils.parseExtensionSource(extension, ext_prefix); return; // match 5.3blackfire...8.0blackfire // match 5.3blackfire-(semver)...8.0blackfire-(semver) - // match couchbase, pdo_oci, oci8, http, pecl_http - // match 5.3ioncube...7.4ioncube, 5.3geos...7.4geos + // match couchbase, geos, pdo_oci, oci8, http, pecl_http + // match 5.3ioncube...7.4ioncube // match 7.0phalcon3...7.3phalcon3 and 7.2phalcon4...7.4phalcon4 case /^(5\.[3-6]|7\.[0-4]|8\.0)blackfire(-\d+\.\d+\.\d+)?$/.test(version_extension): - case /^couchbase$|^pdo_oci$|^oci8$|^http|^pecl_http|^pdo_firebird$/.test(extension): - case /^(5\.[3-6]|7\.[0-4])(ioncube|geos)$/.test(version_extension): + case /^couchbase$|^geos$|^pdo_oci$|^oci8$|^(pecl_)?http|^pdo_firebird$/.test(extension): + case /^(5\.[3-6]|7\.[0-4])ioncube$/.test(version_extension): case /^7\.[0-3]phalcon3$|^7\.[2-4]phalcon4$/.test(version_extension): add_script += await utils.customPackage(ext_name, 'ext', extension, 'darwin'); return; @@ -1837,12 +1837,12 @@ async function addExtensionDarwin(extension_csv, version) { case /(5\.[3-6]|7\.0)pcov/.test(version_extension): add_script += await utils.getUnsupportedLog('pcov', version, 'darwin'); return; - // match 5.6 to 8.9 for amqp, grpc, igbinary, imagick, imap, msgpack, protobuf, raphf, redis, swoole, xdebug, xdebug2, zmq - // match 7.1 to 8.9 for pcov - // match 5.6 to 7.4 for propro - case /(5\.6|7\.[0-4]|8\.[0-9])(amqp|grpc|igbinary|imagick|imap|msgpack|protobuf|raphf|redis|swoole|xdebug|xdebug2|zmq)/.test(version_extension): + // match 5.6 and newer - amqp, apcu, grpc, igbinary, imagick, imap, msgpack, protobuf, raphf, redis, swoole, xdebug, xdebug2, zmq + // match 7.1 and newer - pcov + // match 5.6 to 7.4 - propro + case /(?/dev/null || ! command -v pear >/dev/null; then - add_pecl >/dev/null 2>&1 - fi for script in pear pecl; do sudo "$script" config-set php_ini "${pecl_file:-${ini_file[@]}}" sudo "$script" channel-update "$script".php.net @@ -172,10 +169,30 @@ get_pecl_version() { # Function to install PECL extensions and accept default options pecl_install() { local extension=$1 - configure_pecl >/dev/null 2>&1 + add_pecl >/dev/null 2>&1 yes '' 2>/dev/null | sudo pecl install -f "$extension" >/dev/null 2>&1 } +# Function to install a specific version of PECL extension. +add_pecl_extension() { + extension=$1 + pecl_version=$2 + prefix=$3 + enable_extension "$extension" "$prefix" + if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then + pecl_version=$(get_pecl_version "$extension" "$pecl_version") + fi + ext_version=$(php -r "echo phpversion('$extension');") + if [ "$ext_version" = "$pecl_version" ]; then + add_log "${tick:?}" "$extension" "Enabled" + else + disable_extension "$extension" >/dev/null 2>&1 + delete_extension "$extension" >/dev/null 2>&1 + pecl_install "$extension-$pecl_version" + add_extension_log "$extension-$pecl_version" "Installed and enabled" + fi +} + # Function to setup pre-release extensions using PECL. add_unstable_extension() { extension=$1 diff --git a/src/scripts/darwin.sh b/src/scripts/darwin.sh index 796c634e..b8179e6d 100644 --- a/src/scripts/darwin.sh +++ b/src/scripts/darwin.sh @@ -7,12 +7,24 @@ self_hosted_helper() { fi } +# Function to delete extension +delete_extension() { + extension=$1 + sudo rm -rf "${scan_dir:?}"/*"$extension"* "${ext_dir:?}"/"$extension".so >/dev/null 2>&1 +} + +# Function to disable extension +disable_extension() { + extension=$1 + sudo sed -Ei '' "/=(.*\/)?\"?$extension(.so)?$/d" "${ini_file:?}" +} + # Function to remove extensions. remove_extension() { extension=$1 if check_extension "$extension"; then - sudo sed -Ei '' "/=(.*\/)?\"?$extension(.so)?$/d" "${ini_file:?}" - sudo rm -rf "${scan_dir:?}"/*"$extension"* "${ext_dir:?}"/"$extension".so >/dev/null 2>&1 + disable_extension "$extension" + delete_extension "$extension" (! check_extension "$extension" && add_log "${tick:?}" ":$extension" "Removed") || add_log "${cross:?}" ":$extension" "Could not remove $extension on PHP ${semver:?}" else @@ -20,25 +32,6 @@ remove_extension() { fi } -# Function to install a specific version of PECL extension. -add_pecl_extension() { - extension=$1 - pecl_version=$2 - prefix=$3 - enable_extension "$extension" "$prefix" - if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then - pecl_version=$(get_pecl_version "$extension" "$pecl_version") - fi - ext_version=$(php -r "echo phpversion('$extension');") - if [ "$ext_version" = "$pecl_version" ]; then - add_log "${tick:?}" "$extension" "Enabled" - else - remove_extension "$extension" >/dev/null 2>&1 - pecl_install "$extension-$pecl_version" - add_extension_log "$extension-$pecl_version" "Installed and enabled" - fi -} - # Function to fetch a brew tap fetch_brew_tap() { tap=$1 @@ -107,6 +100,7 @@ add_devtools() { # Function to handle request to add PECL. add_pecl() { + configure_pecl >/dev/null 2>&1 pecl_version=$(get_tool_version "pecl" "version") add_log "${tick:?}" "PECL" "Found PECL $pecl_version" } @@ -119,7 +113,7 @@ link_libraries() { for lib in "$formula_prefix"/lib/*.dylib; do lib_name=$(basename "$lib") sudo cp -a "$lib" "$brew_prefix/lib/old_$lib_name" 2>/dev/null || true - sudo ln -sf "$brew_prefix"/lib/old_$lib_name "$brew_prefix/lib/$lib_name" + sudo ln -sf "$brew_prefix"/lib/old_"$lib_name" "$brew_prefix/lib/$lib_name" done } diff --git a/src/scripts/ext/couchbase.sh b/src/scripts/ext/couchbase.sh index 94d9030e..c37f4912 100644 --- a/src/scripts/ext/couchbase.sh +++ b/src/scripts/ext/couchbase.sh @@ -1,22 +1,17 @@ # Function to install libraries required by couchbase add_couchbase_libs() { if [ "$(uname -s)" = "Linux" ]; then + trunk="https://github.com/couchbase/libcouchbase/releases" if [[ ${version:?} =~ 5.[3-6]|7.[0-1] ]]; then release="2.10.9" - trunk="https://github.com/couchbase/libcouchbase/releases/download" - package="libcouchbase-${release}_ubuntu${DISTRIB_RELEASE/./}_${DISTRIB_CODENAME}_amd64.tar" - get -q -n /tmp/libcouchbase.tar "$trunk/$release/$package" - sudo tar -xf /tmp/libcouchbase.tar -C /tmp - install_packages libev4 - sudo dpkg -i /tmp/libcouchbase-*/*.deb else - trunk="http://packages.couchbase.com/clients/c/repos/deb" - list="deb $trunk/ubuntu${DISTRIB_RELEASE/./} ${DISTRIB_CODENAME:?} ${DISTRIB_CODENAME:?}/main" - get -s -n "" "$trunk/couchbase.key" | sudo apt-key add - echo "$list" | sudo tee /etc/apt/sources.list.d/couchbase.list - sudo apt-get update + release="$(curl -sL $trunk/latest | grep -Eo "libcouchbase-[0-9]+\.[0-9]+\.[0-9]+" | head -n 1 | cut -d'-' -f 2)" fi - ${apt_install:?} libcouchbase-dev + deb_url="$trunk/download/$release/libcouchbase-${release}_ubuntu${DISTRIB_RELEASE/./}_${DISTRIB_CODENAME}_amd64.tar" + get -q -n /tmp/libcouchbase.tar "$deb_url" + sudo tar -xf /tmp/libcouchbase.tar -C /tmp + install_packages libev4 libevent-dev + sudo dpkg -i /tmp/libcouchbase-*/*.deb else if [[ ${version:?} =~ 5.[3-6]|7.[0-1] ]]; then brew install libcouchbase@2 diff --git a/src/scripts/ext/cubrid.sh b/src/scripts/ext/cubrid.sh index 36e8d6d4..72d9370b 100644 --- a/src/scripts/ext/cubrid.sh +++ b/src/scripts/ext/cubrid.sh @@ -40,16 +40,11 @@ add_cubrid_helper() { set_cubrid_repo set_cubrid_branch [ "$DISTRIB_RELEASE" = "16.04" ] && setup_compiler - ( - git clone -b "$cubrid_branch" --recursive "https://github.com/CUBRID/$cubrid_repo" "/tmp/$cubrid_repo" - cd "/tmp/$cubrid_repo" || exit - ! [[ "$version" =~ ${old_versions:?} ]] && add_devtools - phpize - sudo ./configure --with-php-config="$(command -v php-config)" --with-"${ext/_/-}"=shared - make -j"$(nproc)" - sudo make install - ) - echo "extension=$ext.so" | sudo tee "${scan_dir:?}/$ext.ini" + patch_phpize + read -r "${ext}_PREFIX_CONFIGURE_OPTS" <<< "CFLAGS=-Wno-implicit-function-declaration" + read -r "${ext}_CONFIGURE_OPTS" <<< "--with-php-config=$(command -v php-config)" + add_extension_from_source "$ext" https://github.com CUBRID "$cubrid_repo" . "$cubrid_branch" extension + restore_phpize fi } @@ -60,4 +55,7 @@ add_cubrid() { add_cubrid_helper "$ext" >/dev/null 2>&1 add_extension_log "$ext" "$status" check_extension "$ext" && add_license_log -} \ No newline at end of file +} + +# shellcheck source=. +. "${scripts:?}"/ext/patches/phpize.sh diff --git a/src/scripts/ext/firebird.sh b/src/scripts/ext/firebird.sh index 2b2ac5ce..27cbe684 100644 --- a/src/scripts/ext/firebird.sh +++ b/src/scripts/ext/firebird.sh @@ -10,18 +10,9 @@ add_firebird_client_darwin() { add_firebird_helper() { firebird_dir=$1 tag="$(php_src_tag)" - get -s -n "" https://github.com/php/php-src/archive/"$tag".tar.gz | tar -xzf - -C /tmp - ( - cd /tmp/php-src-"$tag"/ext/pdo_firebird || exit - if [[ "${version:?}" =~ ${old_versions:?} ]]; then - sudo sed -i '' '/PHP_CHECK_PDO_INCLUDES/d' config.m4 2>/dev/null || sudo sed -i '/PHP_CHECK_PDO_INCLUDES/d' config.m4 - fi - sudo phpize - sudo ./configure --with-pdo-firebird="$firebird_dir" - sudo make -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu)" - sudo make install - enable_extension pdo_firebird extension - ) + export PDO_FIREBIRD_CONFIGURE_OPTS="--with-pdo-firebird=$firebird_dir" + export PDO_FIREBIRD_LINUX_LIBS="firebird-dev" + add_extension_from_source pdo_firebird https://github.com php php-src ext/pdo_firebird "$tag" extension get } add_firebird() { @@ -29,10 +20,6 @@ add_firebird() { if ! check_extension pdo_firebird; then if [ "$(uname -s)" = "Linux" ]; then if [[ "${version:?}" =~ 5.3|${nightly_versions:?} ]]; then - lib_arch=$(gcc -dumpmachine) - install_packages firebird-dev >/dev/null 2>&1 - sudo ln -sf /usr/lib/"$lib_arch"/libfbclient.so.2 /usr/lib/libfbclient.so >/dev/null 2>&1 - sudo ln -sf /usr/lib/"$lib_arch"/libib_util.so /usr/lib/ >/dev/null 2>&1 add_firebird_helper /usr >/dev/null 2>&1 else add_pdo_extension firebird >/dev/null 2>&1 diff --git a/src/scripts/ext/geos.sh b/src/scripts/ext/geos.sh index 36db800f..54d57b26 100644 --- a/src/scripts/ext/geos.sh +++ b/src/scripts/ext/geos.sh @@ -1,46 +1,12 @@ -# Helper function install geos library and headers -add_geos_libs() { - if [ "$(uname -s)" = "Darwin" ]; then - brew install geos - else - sudo apt-get install libgeos-dev - if [ "${runner:?}" = "self-hosted" ]; then - ${apt_install:?} --no-upgrade --no-install-recommends autoconf automake gcc g++ - fi - fi -} - -# Patch geos for PHP 7 -patch_geos() { - if [ "$(php -r "echo PHP_VERSION_ID;")" -ge 70000 ]; then - sed -i~ -e "s/, ce->name/, ZSTR_VAL(ce->name)/; s/ulong /zend_ulong /" /tmp/php-geos-"$geos_tag"/geos.c - fi -} - -# Get geos source -get_geos() { - curl -o /tmp/geos.tar.gz -sL https://github.com/libgeos/php-geos/archive/"$geos_tag".tar.gz - tar -xzf /tmp/geos.tar.gz -C /tmp - patch_geos -} - # Helper function to compile and install geos add_geos_helper() { - get_geos - ( - cd /tmp/php-geos-"$geos_tag" || exit - phpize - ./configure --enable-geos --with-geos-config="$(command -v geos-config)" - sudo make -j"$(nproc)" - sudo make install - enable_extension geos extension - ) + export GEOS_LINUX_LIBS='libgeos-dev' + export GEOS_DARWIN_LIBS='geos' + add_extension_from_source geos https://github.com libgeos php-geos . 1.0.0 extension get } # Function to add geos add_geos() { - geos_tag='1.0.0' - add_geos_libs >/dev/null 2>&1 enable_extension "geos" "extension" if check_extension "geos"; then add_log "${tick:?}" "geos" "Enabled" diff --git a/src/scripts/ext/http.sh b/src/scripts/ext/http.sh index 49ec3edf..918ed900 100644 --- a/src/scripts/ext/http.sh +++ b/src/scripts/ext/http.sh @@ -19,48 +19,30 @@ enable_http() { fi } -# Function to install linux dependencies. -add_http_dependencies_linux() { - ! [[ ${version:?} =~ ${nightly_versions:?} ]] && add_devtools phpize - install_packages zlib1g libbrotli-dev libcurl4-openssl-dev libevent-dev libicu-dev libidn2-dev +# Function to install extensions. +add_extension_helper() { + if [ "$os" = "Linux" ]; then + add_extension "$1" extension + else + add_brew_extension "$1" extension + fi +} + +# Function to install http dependencies. +add_http_dependencies() { if [[ ${version:?} =~ ${old_versions:?} ]]; then add_pecl_extension raphf 1.1.2 extension add_pecl_extension propro 1.0.2 extension - elif [[ ${version:?} =~ 5.6|7.[0-4] ]]; then - add_extension propro extension - add_extension raphf extension + elif [[ ${version:?} =~ 5.6|7.[0-4] ]]; then + add_extension_helper propro + add_extension_helper raphf else - add_extension raphf extension - fi -} - -# Function to install darwin dependencies. -add_http_dependencies_darwin() { - brew install brotli curl icu4c libevent libidn2 - if ! [[ ${version:?} =~ ${old_versions:?} ]]; then - if [[ ${version:?} =~ 5.6|7.[0-4] ]]; then - add_brew_extension propro extension - fi - add_brew_extension raphf extension - else - add_pecl_extension raphf 1.1.2 extension - add_pecl_extension propro 1.0.2 extension - fi -} - -# Function to install the dependencies. -add_http_dependencies() { - os=$1 - if [ "$os" = 'Linux' ]; then - add_http_dependencies_linux - else - add_http_dependencies_darwin + add_extension_helper raphf fi } # Function to get configure options for http. get_http_configure_opts() { - os=$1 if [ "$os" = 'Linux' ]; then for lib in zlib libbrotli libcurl libevent libicu libidn2 libidn libidnkit2 libidnkit; do http_opts+=( "--with-http-$lib-dir=/usr" ) @@ -75,59 +57,31 @@ get_http_configure_opts() { fi } -patch_http_source() { - ext=$1 - os=$2 - if [ "$os" = 'Darwin' ] && ! [[ ${version:?} =~ ${old_versions:?} ]]; then - if [[ ${version:?} =~ 5.6|7.[0-4] ]]; then - sed -i '' -e "s|ext/propro|$(brew --prefix propro@"${version:?}")/include/php/ext/propro@${version:?}|" "/tmp/pecl_http-${ext##*-}/src/php_http_api.h" - fi - sed -i '' -e "s|ext/raphf|$(brew --prefix raphf@"${version:?}")/include/php/ext/raphf@${version:?}|" "/tmp/pecl_http-${ext##*-}/src/php_http_api.h" - if [ "${version:?}" = "5.6" ]; then - sed -i '' -e "s|\$abs_srcdir|\$abs_srcdir ${brew_prefix:?}/include|" -e "s|/ext/propro|/php/ext/propro@5.6|" -e "s|/ext/raphf|/php/ext/raphf@5.6|" "/tmp/pecl_http-${ext##*-}/config9.m4" - fi - fi -} - -# Helper function to compile and install http. -build_http() { - ext=$1 - os=$2 - ( - http_opts=() && get_http_configure_opts "$os" - c_opts="CFLAGS=-Wno-implicit-function-declaration" - cd /tmp/pecl_http-"${ext##*-}" || exit - sudo phpize - sudo "$c_opts" ./configure --with-http --with-php-config="$(command -v php-config)" "${http_opts[@]}" - sudo make -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu)" - sudo make install - ) -} - # Compile and install http explicitly. # This is done as pecl compiles raphf and propro as well. add_http_helper() { ext=$1 - os=$2 - add_http_dependencies "$os" - get -q -n /tmp/http.tgz https://pecl.php.net/get/pecl_http-"${ext##*-}".tgz - tar -xzf /tmp/http.tgz -C /tmp - patch_http_source "$ext" "$os" - build_http "$ext" "$os" - enable_extension http extension + http_opts=() && get_http_configure_opts + export HTTP_PREFIX_CONFIGURE_OPTS="CFLAGS=-Wno-implicit-function-declaration" + http_configure_opts="--with-http --with-php-config=$(command -v php-config) ${http_opts[*]}" + export HTTP_CONFIGURE_OPTS="$http_configure_opts" + export HTTP_LINUX_LIBS="zlib1g libbrotli-dev libcurl4-openssl-dev libevent-dev libicu-dev libidn2-dev" + export HTTP_DARWIN_LIBS="brotli curl icu4c libevent libidn2" + if [[ "${version:?}" =~ ${nightly_versions:?} ]]; then + add_extension_from_source http https://github.com m6w6 ext-http . master extension + else + add_extension_from_source pecl_http https://pecl.php.net http http . "${ext##*-}" extension pecl + fi } # Function to setup latest http extension. add_http_latest() { - os=$1 enable_http if ! check_extension http; then + add_http_dependencies if [ "$os" = "Linux" ]; then if ! [[ "${version:?}" =~ ${old_versions:?}|${nightly_versions:?} ]]; then - if [[ ${version:?} =~ 5.6|7.[0-4] ]]; then - install_packages "php$version-propro" - fi - install_packages "php$version-raphf" "php$version-http" + install_packages "php$version-http" else add_http_helper "$(get_http_version)" "$os" fi @@ -143,7 +97,6 @@ add_http_latest() { # Function to setup http extension given a version. add_http_version() { ext=$1 - os=$2 enable_http if [ "x$(php -r "echo phpversion('http');")" != "x${ext##*-}" ]; then remove_extension http >/dev/null @@ -155,12 +108,13 @@ add_http_version() { # Function to setup http extension add_http() { ext=$1 - os="$(uname -s)" status="Enabled" if [[ "$ext" =~ ^(pecl_http|http)$ ]]; then - add_http_latest "$os" >/dev/null 2>&1 + add_http_latest >/dev/null 2>&1 else - add_http_version "$ext" "$os" >/dev/null 2>&1 + add_http_version "$ext" >/dev/null 2>&1 fi add_extension_log "http" "$status" } + +os="$(uname -s)" diff --git a/src/scripts/ext/oci.sh b/src/scripts/ext/oci.sh index cddaa590..c7e13f96 100644 --- a/src/scripts/ext/oci.sh +++ b/src/scripts/ext/oci.sh @@ -31,71 +31,16 @@ add_client() { fi } -# Function to get PHP source. -get_php() { - [ ! -d "/opt/oracle/php-src-$tag" ] && get -s -n "" "https://github.com/php/php-src/archive/$tag.tar.gz" | tar xzf - -C "$oracle_home/" -} - -# Function to get phpize location on darwin. -get_phpize() { - if [[ "${version:?}" =~ 5.[3-5] ]]; then - echo '/opt/local/bin/phpize' - else - echo "/usr/local/bin/$(readlink /usr/local/bin/phpize)" - fi -} - -# Function to patch phpize to link to php headers on darwin. -patch_phpize() { - if [ "$os" = "Darwin" ]; then - sudo cp "$phpize_orig" "$phpize_orig.bck" - sudo sed -i '' 's~includedir=.*~includedir="$(xcrun --show-sdk-path)/usr/include/php"~g' "$phpize_orig" - fi -} - -# Function to restore phpize. -restore_phpize() { - if [ "$os" = "Darwin" ]; then - sudo mv "$phpize_orig.bck" "$phpize_orig" || true - fi -} - -# Function to patch pdo_oci. -patch_pdo_oci_config() { - get -q -n config.m4 https://raw.githubusercontent.com/php/php-src/PHP-8.0/ext/pdo_oci/config.m4 - if [[ ${version:?} =~ 5.[3-6] ]]; then - sudo sed -i '' "/PHP_CHECK_PDO_INCLUDES/d" config.m4 2>/dev/null || sudo sed -i "/PHP_CHECK_PDO_INCLUDES/d" config.m4 - fi -} - -# Function to install the dependencies. -add_dependencies() { - if [ "$os" = 'Linux' ]; then - if [ "${runner:?}" = "self-hosted" ]; then - ${apt_install:?} --no-upgrade --no-install-recommends libaio-dev - fi - ! [[ ${version:?} =~ $nightly_versions ]] && add_devtools phpize - fi -} - # Function to install oci8 and pdo_oci. add_oci_helper() { if ! [ -e "${ext_dir:?}/$ext.so" ]; then status='Installed and enabled' - phpize_orig=$(get_phpize) - tag=$(php_src_tag) - get_php + read -r "${ext}_LINUX_LIBS" <<< "libaio-dev" + read -r "${ext}_CONFIGURE_OPTS" <<< "--with-php-config=$(command -v php-config) --with-${ext/_/-}=instantclient,$oracle_client" patch_phpize - ( - cd "/opt/oracle/php-src-$tag/ext/$ext" || exit 1 - [ "$ext" = "pdo_oci" ] && patch_pdo_oci_config - sudo phpize && ./configure --with-php-config="$(command -v php-config)" --with-"${ext/_/-}"=instantclient,"$oracle_client" - sudo make -j"$(nproc 2>/dev/null || sysctl -n hw.ncpu)" - sudo cp ./modules/* "$ext_dir/" - ) + add_extension_from_source "$ext" https://github.com php php-src ext/"$ext" "$(php_src_tag)" extension get restore_phpize fi - echo "extension=$ext.so" | sudo tee "${scan_dir:?}/99-$ext.ini" } # Function to add oci extension oci8 and pdo_oci. @@ -106,8 +51,10 @@ add_oci() { oracle_client=$oracle_home/instantclient os=$(uname -s) add_client >/dev/null 2>&1 - add_dependencies >/dev/null 2>&1 add_oci_helper >/dev/null 2>&1 add_extension_log "$ext" "$status" check_extension "$ext" && add_license_log } + +# shellcheck source=. +. "${scripts:?}"/ext/patches/phpize.sh diff --git a/src/scripts/ext/patches/firebird.sh b/src/scripts/ext/patches/firebird.sh new file mode 100644 index 00000000..0007d610 --- /dev/null +++ b/src/scripts/ext/patches/firebird.sh @@ -0,0 +1,11 @@ +patch_firebird() { + if [[ "${version:?}" =~ ${old_versions:?} ]]; then + sudo sed -i '' '/PHP_CHECK_PDO_INCLUDES/d' config.m4 2>/dev/null || sudo sed -i '/PHP_CHECK_PDO_INCLUDES/d' config.m4 + fi + lib_arch=$(gcc -dumpmachine) + lib_dir=/usr/lib/"$lib_arch" + if [ -d "$lib_dir" ]; then + sudo ln -sf "$lib_dir"/libfbclient.so.2 /usr/lib/libfbclient.so + sudo ln -sf "$lib_dir"/libib_util.so /usr/lib/ + fi +} diff --git a/src/scripts/ext/patches/geos.sh b/src/scripts/ext/patches/geos.sh new file mode 100644 index 00000000..5141a00b --- /dev/null +++ b/src/scripts/ext/patches/geos.sh @@ -0,0 +1,7 @@ +patch_geos() { + if [ "$(php -r "echo PHP_VERSION_ID;")" -ge 70000 ]; then + sed -i~ -e "s/, ce->name/, ZSTR_VAL(ce->name)/; s/ulong /zend_ulong /" geos.c + fi + get -q -n /tmp/php8.patch https://git.remirepo.net/cgit/rpms/php/php-geos.git/plain/0003-add-all-arginfo-and-fix-build-with-PHP-8.patch + patch -p1 < /tmp/php8.patch 2>/dev/null || true +} diff --git a/src/scripts/ext/patches/http.sh b/src/scripts/ext/patches/http.sh new file mode 100644 index 00000000..ca8bfac6 --- /dev/null +++ b/src/scripts/ext/patches/http.sh @@ -0,0 +1,11 @@ +patch_pecl_http() { + if [ "$(uname -s)" = 'Darwin' ] && ! [[ ${version:?} =~ ${old_versions:?} ]]; then + if [[ ${version:?} =~ 5.6|7.[0-4] ]]; then + sed -i '' -e "s|ext/propro|$(brew --prefix propro@"${version:?}")/include/php/ext/propro@${version:?}|" "./src/php_http_api.h" + fi + sed -i '' -e "s|ext/raphf|$(brew --prefix raphf@"${version:?}")/include/php/ext/raphf@${version:?}|" "./src/php_http_api.h" + if [ "${version:?}" = "5.6" ]; then + sed -i '' -e "s|\$abs_srcdir|\$abs_srcdir ${brew_prefix:?}/include|" -e "s|/ext/propro|/php/ext/propro@5.6|" -e "s|/ext/raphf|/php/ext/raphf@5.6|" "./config9.m4" + fi + fi +} diff --git a/src/scripts/ext/patches/pdo_oci.sh b/src/scripts/ext/patches/pdo_oci.sh new file mode 100644 index 00000000..3eb903aa --- /dev/null +++ b/src/scripts/ext/patches/pdo_oci.sh @@ -0,0 +1,6 @@ +patch_pdo_oci() { + get -q -n config.m4 https://raw.githubusercontent.com/php/php-src/PHP-8.0/ext/pdo_oci/config.m4 + if [[ ${version:?} =~ 5.[3-6] ]]; then + sudo sed -i '' "/PHP_CHECK_PDO_INCLUDES/d" config.m4 2>/dev/null || sudo sed -i "/PHP_CHECK_PDO_INCLUDES/d" config.m4 + fi +} diff --git a/src/scripts/ext/patches/phpize.sh b/src/scripts/ext/patches/phpize.sh new file mode 100644 index 00000000..1db2ace3 --- /dev/null +++ b/src/scripts/ext/patches/phpize.sh @@ -0,0 +1,26 @@ +# Function to get phpize location on darwin. +get_phpize() { + if [[ "${version:?}" =~ 5.[3-5] ]]; then + echo '/opt/local/bin/phpize' + else + echo "/usr/local/bin/$(readlink /usr/local/bin/phpize)" + fi +} + +# Function to patch phpize to link to php headers on darwin. +patch_phpize() { + if [ "$(uname -s)" = "Darwin" ]; then + sudo cp "$phpize_orig" "$phpize_orig.bck" + sudo sed -i '' 's~includedir=.*~includedir="$(xcrun --show-sdk-path)/usr/include/php"~g' "$phpize_orig" + fi +} + +# Function to restore phpize. +restore_phpize() { + if [ "$os" = "Darwin" ]; then + sudo mv "$phpize_orig.bck" "$phpize_orig" || true + fi +} + +os="$(uname -s)" +phpize_orig="$(get_phpize)" diff --git a/src/scripts/ext/patches/protobuf.sh b/src/scripts/ext/patches/protobuf.sh new file mode 100644 index 00000000..1289115e --- /dev/null +++ b/src/scripts/ext/patches/protobuf.sh @@ -0,0 +1,4 @@ +patch_protobuf() { + mkdir -p third_party/wyhash + cp ../../../../third_party/wyhash/* third_party/wyhash +} diff --git a/src/scripts/ext/source.sh b/src/scripts/ext/source.sh index 9c34d75e..5387dd8d 100644 --- a/src/scripts/ext/source.sh +++ b/src/scripts/ext/source.sh @@ -1,11 +1,12 @@ # Function to parse extension environment variables parse_args() { extension=$1 - suffix=$2 - up_extension=$(echo "$extension" | tr '[:lower:]' '[:upper:]') + suffix=$(echo "$2" | tr '[:lower:]' '[:upper:]') + up_ext_name=$(echo "$extension" | tr '[:lower:]' '[:upper:]') var="${extension}_${suffix}" - up_var="${up_extension}_${suffix}" - output=$(echo "${!var} ${!up_var}" | sed "s/, */ /g") + up_var="${up_ext_name}_${suffix}" + ! [[ "$suffix" =~ .*PREFIX|LIBS.* ]] && hyp='-' + output=$(echo "${!var} ${!up_var}" | sed "s/, *$hyp/ $hyp/g" | sed -E "s/^,|,$//g") echo "$output" | xargs -n 1 | sort | uniq | xargs } @@ -20,16 +21,45 @@ add_lib_log() { fi } +# Function to check if a library is installed +check_lib() { + lib=$1 + if [ "$(uname -s)" = "Linux" ]; then + [ "x$(dpkg -s "$lib" 2>/dev/null | grep Status)" != "x" ] + else + [ "x$(find "${brew_prefix:?}"/Cellar -maxdepth 1 -name "$lib")" != "x" ] + fi +} + +# Function to add a library on linux +add_linux_libs() { + lib=$1 + if ! check_lib "$lib"; then + install_packages "$lib" >/dev/null 2>&1 || true + fi + add_lib_log "$lib" +} + +# Function to add a library on macOS +add_darwin_libs() { + lib=$1 + if ! check_lib "$lib"; then + brew install "$lib" >/dev/null 2>&1 || true + if [[ "$lib" = *@* ]]; then + brew link --overwrite --force "$lib" >/dev/null 2>&1 || true + fi + fi + add_lib_log "$lib" +} + # Function to add required libraries add_libs() { - libs=("$@") - for lib in "${libs[@]}"; do + all_libs=("$@") + for lib in "${all_libs[@]}"; do if [ "$(uname -s)" = "Linux" ]; then - install_packages "$lib" >/dev/null 2>&1 - add_lib_log "$lib" "$(dpkg -s "$lib" 2>/dev/null | grep Status)" + add_linux_libs "$lib" else - brew install "$lib" >/dev/null 2>&1 - add_lib_log "$lib" "$(find "${brew_cellar:?}" -maxdepth 1 -name "$lib")" + add_darwin_libs "$lib" fi done } @@ -45,36 +75,65 @@ run_group() { echo "::endgroup::" } +patch_extension() { + extension=$1 + if [ -e "${scripts:?}"/ext/patches/"$extension".sh ]; then + # shellcheck source=. + . "${scripts:?}"/ext/patches/"$extension".sh + patch_"${extension}" + fi +} + +fetch_extension() { + fetch=$1 + if [ "$fetch" = "clone" ]; then + run_group "git clone -nv $url/$org/$repo /tmp/$repo-$release" "git clone" + cd /tmp/"$repo-$release" || exit 1 + git checkout -q "$release" + cd "$sub_dir" || exit 1 + if [ -e .gitmodules ]; then + jobs="$(grep -c "\[submodule" .gitmodules)" + run_group "git submodule update --jobs $jobs --init --recursive" "git submodule" + fi + elif [ "$fetch" = "get" ]; then + get -q -n /tmp/"$extension".tar.gz "$url/$org/$repo/archive/$release.tar.gz" + tar -xzf /tmp/"$extension".tar.gz -C /tmp + cd /tmp/"$repo"-"$release"/"$sub_dir" || exit + elif [ "$fetch" = "pecl" ]; then + source="pecl" + pecl_name=${extension/http/pecl_http} + get -q -n /tmp/"$pecl_name".tgz https://pecl.php.net/get/"$pecl_name"-"$release".tgz + tar -xzf /tmp/"$pecl_name".tgz -C /tmp + cd /tmp/"$pecl_name"-"$release" || exit + fi +} + # Function to install extension from a git repository add_extension_from_source() { - extension=$1 - domain=$2 + extension="${1/pecl_/}" + url=$2 org=$3 repo=$4 sub_dir=$5 release=$6 prefix=$7 + fetch=${8:-clone} slug="$extension-$release" - libraries="$(parse_args "$extension" LIBS)" + source="$url/$org/$repo" + libraries="$(parse_args "$extension" LIBS) $(parse_args "$extension" "$(uname -s)"_LIBS)" opts="$(parse_args "$extension" CONFIGURE_OPTS)" prefix_opts="$(parse_args "$extension" CONFIGURE_PREFIX_OPTS)" suffix_opts="$(parse_args "$extension" CONFIGURE_SUFFIX_OPTS)" step_log "Setup $slug" ( - add_devtools phpize >/dev/null + add_devtools phpize >/dev/null 2>&1 delete_extension "$extension" - run_group "git clone -nv $domain/$org/$repo /tmp/$repo-$release" "git clone" - cd /tmp/"$repo-$release" || exit 1 - git checkout -q "$release" - cd $sub_dir || exit 1 + fetch_extension "$fetch" if ! [ "$(find . -maxdepth 1 -name '*.m4' -exec grep -H 'PHP_NEW_EXTENSION' {} \; | wc -l)" != "0" ]; then - add_log "${cross:?}" "$domain/$org/$repo" "$domain/$org/$repo does not have a PHP extension" + add_log "${cross:?}" "$source" "$source does not have a PHP extension" else - if [ -e .gitmodules ]; then - jobs="$(grep -c "\[submodule" .gitmodules)" - run_group "git submodule update --jobs $jobs --init --recursive" "git submodule" - fi - [ "x$libraries" != "x" ] && run_group "add_libs $libraries" "add libraries" + [[ -n "${libraries// }" ]] && run_group "add_libs $libraries" "add libraries" + patch_extension "$extension" >/dev/null 2>&1 run_group "phpize" "phpize" run_group "sudo $prefix_opts ./configure $suffix_opts $opts" "configure" run_group "sudo make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu)" "make" @@ -82,5 +141,5 @@ add_extension_from_source() { enable_extension "$extension" "$prefix" fi ) - add_extension_log "$slug" "Installed from $domain/$org/$repo and enabled" + add_extension_log "$slug" "Installed from $source and enabled" } diff --git a/src/scripts/linux.sh b/src/scripts/linux.sh index a172ca75..04570869 100644 --- a/src/scripts/linux.sh +++ b/src/scripts/linux.sh @@ -89,8 +89,10 @@ add_pdo_extension() { else ext=$1 ext_name=$1 - disable_extension pdo - echo "extension=pdo.so" | sudo tee "${ini_file[@]/php.ini/conf.d/10-pdo.ini}" >/dev/null 2>&1 + if [ -e "$ext_dir"/pdo.so ]; then + disable_extension pdo + echo "extension=pdo.so" | sudo tee "${ini_file[@]/php.ini/conf.d/10-pdo.ini}" >/dev/null 2>&1 + fi if [ "$ext" = "mysql" ]; then enable_extension "mysqlnd" "extension" ext_name='mysqli' @@ -128,34 +130,13 @@ add_extension() { sudo chmod 777 "${ini_file[@]}" } -# Function to install a PECL version. -add_pecl_extension() { - extension=$1 - pecl_version=$2 - prefix=$3 - if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then - pecl_version=$(get_pecl_version "$extension" "$pecl_version") - fi - enable_extension "$extension" "$prefix" - ext_version=$(php -r "echo phpversion('$extension');") - if [ "$ext_version" = "$pecl_version" ]; then - add_log "${tick:?}" "$extension" "Enabled" - else - delete_extension "$extension" - pecl_install "$extension-$pecl_version" - add_extension_log "$extension-$pecl_version" "Installed and enabled" - fi -} - # Function to setup phpize and php-config. add_devtools() { tool=$1 if ! command -v "$tool$version" >/dev/null; then install_packages "php$version-dev" "php$version-xml" fi - sudo update-alternatives --set php-config /usr/bin/php-config"$version" >/dev/null 2>&1 - sudo update-alternatives --set phpize /usr/bin/phpize"$version" >/dev/null 2>&1 - configure_pecl >/dev/null 2>&1 + switch_version "phpize" "php-config" add_log "${tick:?}" "$tool" "Added $tool $semver" } @@ -183,9 +164,11 @@ add_pecl() { # Function to switch versions of PHP binaries. switch_version() { - for tool in pear pecl php phar phar.phar php-cgi php-config phpize phpdbg; do + tools=("$@") && ! (( ${#tools[@]} )) && tools+=(pear pecl php phar phar.phar php-cgi php-config phpize phpdbg) + to_wait=() + for tool in "${tools[@]}"; do if [ -e "/usr/bin/$tool$version" ]; then - sudo update-alternatives --set $tool /usr/bin/"$tool$version" & + sudo update-alternatives --set "$tool" /usr/bin/"$tool$version" & to_wait+=($!) fi done