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