diff --git a/.github/workflows/linux-glibc.yml b/.github/workflows/linux-glibc.yml new file mode 100644 index 0000000000..c1431e318c --- /dev/null +++ b/.github/workflows/linux-glibc.yml @@ -0,0 +1,150 @@ +name: build-swoole-cli-linux-glibc-x86_64 + +on: [ push, pull_request ] + +jobs: + linux-glibc: + if: ${{ 0 && !contains(github.event.head_commit.message, '--filter=') || contains(github.event.head_commit.message, '[linux-glibc]') }} + strategy: + fail-fast: false + matrix: + os: [ ubuntu-22.04, ubuntu-22.04-arm ] + name: linux-glibc-${{ matrix.os }} + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Show Environment Info + run: | + echo $PATH + env + docker info + id -u + id -g + who + cat /etc/os-release + hostnamectl + uname -s + uname -m + uname -r + + cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c + cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l + cat /proc/cpuinfo | grep "cpu cores" | uniq + cat /proc/cpuinfo| grep "processor"| wc -l + lscpu + + export IPV6=$(ip -6 address show | grep inet6 | awk '{print $2}' | cut -d'/' -f1 | sed -n '2p') + export IPV4=$(ip -4 address show | grep inet | grep -v 127.0.0 | awk '{print $2}' | cut -d'/' -f1 | sed -n '1p') + echo $IPV4 + echo $IPV6 + echo "X_IPV6=${IPV6}" >> $GITHUB_ENV + echo "X_IPV4=${IPV4}" >> $GITHUB_ENV + + - name: Prepare Build Environment + run: | + git submodule update --init + + sudo mkdir -p /usr/local/swoole-cli + uid=$(id -u) && gid=$(id -g) && sudo chown -R ${uid}:${gid} /usr/local/swoole-cli + + mkdir -p ${{ github.workspace }}/var/build-github-action-container/ + + - name: Cache PHP Runtime + uses: actions/cache@v4 + id: php-runtime-cache-x86_64 + with: + path: ${{ github.workspace }}/runtime + key: ${{ runner.os }}-x86_64-php-runtime + + - name: Cache PHP Vendor + uses: actions/cache@v4 + id: php-vendor-cache-x86_64 + with: + path: ${{ github.workspace }}/vendor + key: ${{ runner.os }}-x86_64-php-vendor + + - name: Cache Dependency Source Code Tarball + uses: actions/cache@v4 + id: pool-cache + with: + path: ${{ github.workspace }}/pool/ + key: source-code-tarball-pool + + - name: Cache all-library + uses: actions/cache@v4 + id: all-library-cache-x86_64 + with: + path: /usr/local/swoole-cli + key: ${{ github.head_ref || github.ref_name }}-${{ runner.os }}-x86_64-all-library + + - name: Prepare Runtime and Libraries and Extensions + run: | + set -x + mkdir -p pool/lib + mkdir -p pool/ext + mkdir -p bin/ + mkdir -p runtime/ + test -f runtime/php && rm -f runtime/php + if [ ! -f runtime/php/php ] ; then + bash setup-php-runtime.sh + fi + bash sapi/download-box/download-box-get-archive-from-server.sh + ls -A pool/lib/ + ls -A /usr/local/swoole-cli/ + + - name: Build + run: | + set -eux + uname -m + composer install --no-interaction --no-autoloader --no-scripts --profile + composer dump-autoload --optimize --profile + + php prepare.php --with-libavif + + sudo apt update + bash ./sapi/scripts/install-deps-on-ubuntu.sh + bash ./ext/swoole/scripts/install-deps-on-ubuntu.sh + bash ./sapi/scripts/build-swoole-cli-with-linux-gcc.sh + + ./bin/swoole-cli -v + ./bin/swoole-cli -m + ./bin/swoole-cli --ri curl + ./bin/swoole-cli --ri gd + ./bin/swoole-cli --ri imagick + ./bin/swoole-cli --ri swoole + { ldd ./bin/swoole-cli ; } || { echo $? ; } ; + file ./bin/swoole-cli + + - name: Make nfpm package + run: | + ARCH=$(uname -m) + if [ "$ARCH" = "aarch64" ]; then + NFPM_ARCH="arm64" + else + NFPM_ARCH="amd64" + fi + wget https://github.com/goreleaser/nfpm/releases/download/v2.43.4/nfpm_2.43.4_${NFPM_ARCH}.deb + sudo dpkg -i nfpm_2.43.4_${NFPM_ARCH}.deb + strip ./bin/swoole-cli + ./make.sh nfpm-pkg + ls -ls ./*.deb + ls -ls ./*.rpm + + - name: upload artifacts to cloud object storage + if: ${{ (github.repository == 'swoole/swoole-cli') && (startsWith(github.ref, 'refs/tags/')) }} + env: + OSS_SECRET_ID: ${{ secrets.QCLOUD_OSS_SECRET_ID }} + OSS_SECRET_KEY: ${{ secrets.QCLOUD_OSS_SECRET_KEY }} + OSS_BUCKET: ${{ vars.QCLOUD_OSS_BUCKET }} + OSS_REGION: ${{ vars.QCLOUD_OSS_REGION }} + run: | + ARCH=$(uname -m) + if [ "$ARCH" = "aarch64" ]; then + FILE_ARCH="arm64" + else + FILE_ARCH="x64" + fi + SWOOLE_VERSION=$(awk 'NR==1{ print $1 }' "sapi/SWOOLE-VERSION.conf") + OS="linux" + bash sapi/scripts/tencent-cloud-object-storage.sh --upload-file ${{ github.workspace }}/swoole-cli-"${SWOOLE_VERSION}-${OS}-${FILE_ARCH}"-glibc.deb + bash sapi/scripts/tencent-cloud-object-storage.sh --upload-file ${{ github.workspace }}/swoole-cli-"${SWOOLE_VERSION}-${OS}-${FILE_ARCH}"-glibc.rpm diff --git a/.github/workflows/windows-cygwin.yml b/.github/workflows/windows-cygwin.yml index 88484f8b8f..df59e5ad53 100644 --- a/.github/workflows/windows-cygwin.yml +++ b/.github/workflows/windows-cygwin.yml @@ -95,7 +95,7 @@ jobs: - name: Prepare shell: C:\cygwin\bin\bash.EXE --noprofile --norc -e -o pipefail -o igncr {0} run: | - bash ./sapi/scripts/cygwin/cygwin-config-ext.sh --php-version ${{ env.BUILD_PHP_VERSION }} --swoole-version master + bash ./sapi/scripts/cygwin/cygwin-config-ext.sh --php-version ${{ env.BUILD_PHP_VERSION }} - name: Configure shell: C:\cygwin\bin\bash.EXE --noprofile --norc -e -o pipefail -o igncr {0} diff --git a/.github/workflows/windows-msys2.yml b/.github/workflows/windows-msys2.yml index f5a3075105..118e7c55f1 100644 --- a/.github/workflows/windows-msys2.yml +++ b/.github/workflows/windows-msys2.yml @@ -69,11 +69,12 @@ jobs: shell: msys2 {0} run: | bash ./sapi/scripts/msys2/install-deps-lib.sh + bash sapi/download-box/download-box-get-archive-from-server.sh - name: Prepare shell: msys2 {0} run: | - bash ./sapi/scripts/msys2/config-ext.sh --php-version ${{ env.BUILD_PHP_VERSION }} --swoole-version master + bash ./sapi/scripts/msys2/config-ext.sh --php-version ${{ env.BUILD_PHP_VERSION }} - name: Configure shell: msys2 {0} diff --git a/.gitignore b/.gitignore index 252612a464..be47032128 100644 --- a/.gitignore +++ b/.gitignore @@ -349,3 +349,6 @@ php-fpm-* !/runtime/.gitkeep /APP_NAME /APP_VERSION +*.deb +*.rpm +nfpm-pkg.yaml diff --git a/prepare.php b/prepare.php index be67076ec7..32af572111 100755 --- a/prepare.php +++ b/prepare.php @@ -90,6 +90,7 @@ // Sync code from php-src $p->setPhpSrcDir($p->getWorkDir() . '/var/php-' . BUILD_PHP_VERSION); + // Compile directly on the host machine, not in the docker container if ($p->getInputOption('without-docker') || ($p->isMacos())) { $p->setWorkDir(__DIR__); @@ -108,12 +109,10 @@ //设置PHP 安装目录 define("BUILD_PHP_INSTALL_PREFIX", $p->getRootDir() . '/bin/php-' . BUILD_PHP_VERSION); - if ($p->getInputOption('with-override-default-enabled-ext')) { $p->setExtEnabled([]); } - if ($p->getInputOption('with-global-prefix')) { $p->setGlobalPrefix($p->getInputOption('with-global-prefix')); } diff --git a/sapi/scripts/build-swoole-cli-with-linux-gcc.sh b/sapi/scripts/build-swoole-cli-with-linux-gcc.sh index a5155870f6..ed76758c6c 100755 --- a/sapi/scripts/build-swoole-cli-with-linux-gcc.sh +++ b/sapi/scripts/build-swoole-cli-with-linux-gcc.sh @@ -1,4 +1,9 @@ -./configure --prefix=/usr --disable-all \ +if [ ! -f ./configure ]; then + ./buildconf --force +fi + +./configure --prefix=/usr/local/swoole-cli \ + --disable-all \ --enable-zts \ --without-pcre-jit \ --with-openssl --enable-openssl \ @@ -31,17 +36,20 @@ --with-sodium \ --enable-xml --enable-simplexml --enable-xmlreader --enable-xmlwriter --enable-dom --with-libxml \ --enable-gd --with-jpeg --with-freetype \ - --enable-swoole --enable-sockets --enable-mysqlnd --enable-swoole-curl --enable-cares \ + --enable-swoole \ + --enable-swoole-curl \ + --enable-cares \ --enable-swoole-pgsql \ --enable-swoole-sqlite \ + --with-swoole-odbc=unixODBC,/usr \ --enable-swoole-thread \ + --enable-swoole-stdext \ --enable-brotli \ --enable-zstd \ - --enable-swoole-stdext \ --enable-redis \ --with-imagick \ --with-yaml \ --with-readline \ --enable-opcache -make -j "$(nproc)" \ No newline at end of file +make -j "$(nproc)" diff --git a/sapi/scripts/copy-depend-libs.php b/sapi/scripts/copy-depend-libs.php new file mode 100644 index 0000000000..a1d7a8703f --- /dev/null +++ b/sapi/scripts/copy-depend-libs.php @@ -0,0 +1,99 @@ + (typical ldd output) + if (preg_match('/^\s*.*\s+=>\s+(\/.*)\s+\(0x[0-9a-f]+\)$/', $line, $matches)) { + $libPath = trim($matches[1]); + if (file_exists($libPath)) { + $dependencies[] = $libPath; + } + } + // Match lines without => (statically linked or direct paths) + elseif (preg_match('/^\s+(\/.*)\s+\(0x[0-9a-f]+\)$/', $line, $matches)) { + $libPath = trim($matches[1]); + if (file_exists($libPath)) { + $dependencies[] = $libPath; + } + } +} + +// Remove duplicates +$dependencies = array_unique($dependencies); + +// Filter out ignored libraries +$filteredDependencies = []; +foreach ($dependencies as $libPath) { + $fileName = basename($libPath); + foreach ($ignoredLibraries as $ignoredLib) { + if (strpos($fileName, $ignoredLib) !== false) { + echo "Skipping system library: $fileName\n"; + continue 2; + } + } + $filteredDependencies[] = $libPath; +} + +echo "Found " . count($filteredDependencies) . " dependencies (excluding system libraries)\n"; + +// Copy each dependency to target directory +$successCount = 0; +foreach ($filteredDependencies as $libPath) { + $fileName = basename($libPath); + $targetPath = "$targetDir/$fileName"; + + echo "Copying $libPath to $targetPath... "; + + if (copy($libPath, $targetPath)) { + echo "SUCCESS\n"; + $successCount++; + } else { + echo "FAILED\n"; + } +} + +echo "Successfully copied $successCount out of " . count($filteredDependencies) . " dependencies\n"; diff --git a/sapi/scripts/download-swoole-src-archive.sh b/sapi/scripts/download-swoole-src-archive.sh new file mode 100755 index 0000000000..9818ba63e7 --- /dev/null +++ b/sapi/scripts/download-swoole-src-archive.sh @@ -0,0 +1,48 @@ +__DIR__=$( + cd "$(dirname "$0")" || exit + pwd +) + +WORKDIR=$( + cd "${__DIR__}"/../../ || exit + pwd +) + +ORIGIN_SWOOLE_VERSION=$(awk 'NR==1{ print $1 }' "sapi/SWOOLE-VERSION.conf") +SWOOLE_VERSION=$(echo "${ORIGIN_SWOOLE_VERSION}" | sed 's/[^a-zA-Z0-9]/_/g') +CURRENT_SWOOLE_VERSION='' + +cd "${WORKDIR}" || exit + +TGZ_FILE="${WORKDIR}/pool/ext/swoole-${ORIGIN_SWOOLE_VERSION}.tgz" +SWOOLE_DIR="${WORKDIR}/ext/swoole/" + +if [ -f "ext/swoole/CMakeLists.txt" ] ;then + CURRENT_SWOOLE_VERSION=$(grep 'set(SWOOLE_VERSION' ext/swoole/CMakeLists.txt | awk '{ print $2 }' | sed 's/)//') + if [[ "${CURRENT_SWOOLE_VERSION}" =~ "-dev" ]]; then + echo 'swoole version master' + if [ -n "${GITHUB_ACTION}" ]; then + test -f "$TGZ_FILE" && rm -f "$TGZ_FILE" + CURRENT_SWOOLE_VERSION='' + fi + fi +fi + +if [ "${SWOOLE_VERSION}" != "${CURRENT_SWOOLE_VERSION}" ] ;then + if [ ! -f "$TGZ_FILE" ] ;then + echo "downloading swoole-${ORIGIN_SWOOLE_VERSION}.tgz" + test -d /tmp/swoole && rm -rf /tmp/swoole + git clone -b "${ORIGIN_SWOOLE_VERSION}" https://github.com/swoole/swoole-src.git /tmp/swoole + status=$? + if [[ $status -ne 0 ]]; then { echo $status ; exit 1 ; } fi + cd /tmp/swoole || exit + rm -rf /tmp/swoole/.git/ + tar -czvf "$TGZ_FILE" . + fi + + if [ ! -d "$SWOOLE_DIR" ] ;then + echo "unpacking swoole-${ORIGIN_SWOOLE_VERSION}.tgz" + mkdir -p "${SWOOLE_DIR}" + tar --strip-components=1 -C "${SWOOLE_DIR}" -xf "$TGZ_FILE" + fi +fi diff --git a/sapi/scripts/install-deps-on-ubuntu.sh b/sapi/scripts/install-deps-on-ubuntu.sh new file mode 100755 index 0000000000..6f4a7e73d7 --- /dev/null +++ b/sapi/scripts/install-deps-on-ubuntu.sh @@ -0,0 +1,36 @@ +# build tools +sudo apt install gcc g++ make autoconf libtool pkg-config re2c + +# libraries +sudo apt install libyaml-dev \ + libssl-dev \ + libxml2-dev \ + libmagic-dev \ + libpng-dev \ + libjpeg-dev \ + libfreetype-dev \ + libc-ares-dev \ + libpcre2-dev \ + libsodium-dev \ + libcurl4-openssl-dev \ + libmariadb-dev \ + libaio-dev \ + zlib1g \ + mime-support \ + tzdata \ + ucf \ + libargon2-dev \ + libsqlite3-dev \ + libbrotli-dev \ + libpq-dev \ + unixodbc-dev \ + firebird-dev \ + libzstd-dev \ + libssh-dev \ + liburing-dev \ + libedit-dev \ + libreadline-dev \ + libmagic-dev \ + libonig-dev \ + libxslt-dev \ + libzip-dev diff --git a/sapi/src/Preprocessor.php b/sapi/src/Preprocessor.php index 77a6fbd5f4..7ab281a09c 100644 --- a/sapi/src/Preprocessor.php +++ b/sapi/src/Preprocessor.php @@ -48,6 +48,7 @@ class Preprocessor protected string $libraryDir; protected string $extensionDir; protected array $pkgConfigPaths = []; + protected array $nfpmDepends = []; protected string $phpSrcDir; protected string $dockerVersion = 'latest'; /** @@ -169,6 +170,19 @@ public function getSystemArch(): string } } + public function getDebArch(): string + { + $uname = posix_uname(); + switch ($uname['machine']) { + case 'x86_64': + return 'amd64'; + case 'aarch64': + return 'arm64'; + default: + return $uname['machine']; + } + } + public function getImageTag(): string { $arch = $this->getSystemArch(); @@ -249,6 +263,11 @@ public function getBuildDir(): string return $this->buildDir; } + public function getSwooleVersion(): string + { + return trim(file_get_contents($this->rootDir . '/sapi/SWOOLE-VERSION.conf')); + } + public function getWorkDir(): string { return $this->workDir; @@ -1187,6 +1206,7 @@ public function execute(): void $this->mkdirIfNotExists($this->rootDir . '/bin'); $this->generateFile(__DIR__ . '/template/license.php', $this->rootDir . '/bin/LICENSE'); $this->generateFile(__DIR__ . '/template/credits.php', $this->rootDir . '/bin/credits.html'); + $this->generateFile(__DIR__ . '/template/nfpm-yaml.php', $this->rootDir . '/nfpm-pkg.yaml'); copy($this->rootDir . '/sapi/scripts/pack-sfx.php', $this->rootDir . '/bin/pack-sfx.php'); diff --git a/sapi/src/builder/extension/swoole.php b/sapi/src/builder/extension/swoole.php index 70f859dd23..9493f145bc 100644 --- a/sapi/src/builder/extension/swoole.php +++ b/sapi/src/builder/extension/swoole.php @@ -99,6 +99,10 @@ $p->withExportVariable('ZSTD_LIBS', '$(pkg-config --libs --static libzstd)'); $p->withExportVariable('SWOOLE_ODBC_LIBS', '$(pkg-config --libs-only-L --libs-only-l --static odbc odbccr odbcinst readline ncursesw ) ' . " -L{$libiconv_prefix}/lib -liconv "); + + // Download swoole-src + # shell_exec(__DIR__ . '/sapi/scripts/download-swoole-src-archive.sh'); + /* $p->withBeforeConfigureScript('swoole', function () use ($p) { $workDir = $p->getWorkDir(); @@ -140,6 +144,7 @@ return $shell; }); */ + $p->withBeforeConfigureScript('swoole', function () use ($p) { $workDir = $p->getWorkDir(); $phpSrcDir = $p->getPhpSrcDir(); @@ -157,4 +162,5 @@ return $shell; }); + }; diff --git a/sapi/src/template/make.php b/sapi/src/template/make.php index 29e0d12edd..c93b67cd53 100755 --- a/sapi/src/template/make.php +++ b/sapi/src/template/make.php @@ -483,6 +483,23 @@ exit 0 } +make_swoole_cli_with_linux_gcc() { + if [ ! -f bin/swoole-cli ] ;then + ./buildconf --force + ./sapi/scripts/build-swoole-cli-with-linux-gcc.sh + fi +} + +make_nfpm_pkg() { + make_swoole_cli_with_linux_gcc + ./bin/swoole-cli sapi/scripts/copy-depend-libs.php + patchelf --force-rpath --set-rpath '/usr/local/swoole-cli/lib' bin/swoole-cli + NFPM_PKG_FILENAME=swoole-cli-getSwooleVersion()?>-linux-getSystemArch()?>-glibc + nfpm pkg --config nfpm-pkg.yaml --target "${NFPM_PKG_FILENAME}.rpm" + nfpm pkg --config nfpm-pkg.yaml --target "${NFPM_PKG_FILENAME}.deb" + return 0 +} + help() { echo "./make.sh docker-build [ china | ustc | tuna ]" echo "./make.sh docker-bash" @@ -506,6 +523,7 @@ echo "./make.sh list-swoole-branch" echo "./make.sh switch-swoole-branch" echo "./make.sh [library-name]" + echo "./make.sh nfpm-pkg" echo "./make.sh clean-[library-name]" echo "./make.sh clean-[library-name]-cached" echo "./make.sh clean" @@ -642,6 +660,8 @@ echo "name ?>" exit 0 +elif [ "$1" = "nfpm-pkg" ] ;then + make_nfpm_pkg elif [ "$1" = "clean" ] ;then make_clean exit 0 diff --git a/sapi/src/template/nfpm-yaml.php b/sapi/src/template/nfpm-yaml.php new file mode 100644 index 0000000000..430f68e3a1 --- /dev/null +++ b/sapi/src/template/nfpm-yaml.php @@ -0,0 +1,24 @@ +name: "swoole-cli" +arch: "getDebArch()?>" +platform: "getOsType()?>" +version: "getSwooleVersion()?>" +section: "default" +priority: "extra" +maintainer: "service " +description: | + SWOOLE-CLI is a php binary distribution composed swoole & php-core & cli & fpm and mostly of common extensions +homepage: "https://github.com/swoole/swoole-cli" + +overrides: + deb: + depends: + - libc6 (>=2.35) + rpm: + depends: + - glibc >= 2.35 + +contents: + - src: "bin/swoole-cli" + dst: "/usr/local/bin/swoole-cli" + - src: "runtime/libs/" + dst: "/usr/local/swoole-cli/lib/"