diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 1949d1a..532581b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -12,5 +12,5 @@ } }, "dockerComposeFile": "./../compose.yaml", - "service": "dev" -} \ No newline at end of file + "service": "shell" +} diff --git a/.devcontainer/local/devcontainer.json b/.devcontainer/local/devcontainer.json index 3dd62e4..9e89dba 100644 --- a/.devcontainer/local/devcontainer.json +++ b/.devcontainer/local/devcontainer.json @@ -1,24 +1,24 @@ { - "name": "pskel (for Local)", - "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "maelvalais.autoconf", - "ms-azuretools.vscode-docker", - "editorconfig.editorconfig" - ] - } - }, - "dockerComposeFile": "./../../compose.yaml", - "service": "dev", - "mounts": [ - { - "type": "bind", - "source": "./", - "target": "/workspace/pskel" - } - ], - "workspaceFolder": "/workspace/pskel" + "name": "pskel (for Local)", + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cpptools-extension-pack", + "maelvalais.autoconf", + "ms-azuretools.vscode-docker", + "editorconfig.editorconfig" + ] + } + }, + "dockerComposeFile": "./../../compose.yaml", + "service": "shell", + "mounts": [ + { + "type": "bind", + "source": "./", + "target": "/workspace/pskel" + } + ], + "workspaceFolder": "/workspace/pskel" } diff --git a/.dockerignore b/.dockerignore index 6b8710a..723dc5c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,4 @@ -.git +**/.git +**/README.md +**/LICENSE +**/.editorconfig diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 639d51c..7d348e1 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - arch: ["amd64", "arm64v8", "s390x"] + platform: ["linux/amd64", "linux/arm64/v8", "linux/s390x"] version: ["8.1", "8.2", "8.3"] type: ["cli", "zts"] distro: ["bookworm", "alpine"] @@ -20,30 +20,30 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Build container run: | - docker compose build --pull --no-cache --build-arg IMAGE=${{ matrix.arch }}/php --build-arg TAG=${{ matrix.version }}-${{ matrix.type }}-${{ matrix.distro }} --build-arg PSKEL_SKIP_DEBUG=${{ matrix.arch != 'amd64' && '1' || '' }} + docker compose build --pull --no-cache --build-arg PLATFORM="${{ matrix.platform }}" --build-arg IMAGE="php" --build-arg TAG="${{ matrix.version }}-${{ matrix.type }}-${{ matrix.distro }}" - name: Run tests run: | - docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION=1 dev + docker compose run --rm shell pskel test - name: Test extension with PHP Debug Build - if: matrix.arch == 'amd64' + if: matrix.platform == 'linux/amd64' run: | - docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION_DEBUG=1 dev + docker compose run --rm shell pskel test debug - name: Test extension with Valgrind - if: matrix.arch == 'amd64' + if: matrix.platform == 'linux/amd64' run: | - docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION_VALGRIND=1 dev + docker compose run --rm shell pskel test valgrind - name: Test extension with LLVM Sanitizer (MemorySanitizer) - if: matrix.arch == 'amd64' && matrix.distro != 'alpine' + if: matrix.platform == 'linux/amd64' && matrix.distro != 'alpine' run: | - docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION_MSAN=1 dev + docker compose run --rm shell pskel test msan - name: Test extension with LLVM Sanitizer (AddressSanitizer) - if: matrix.arch == 'amd64' && matrix.distro != 'alpine' + if: matrix.platform == 'linux/amd64' && matrix.distro != 'alpine' run: | - docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION_ASAN=1 dev + docker compose run --rm shell pskel test asan - name: Test extension with LLVM Sanitizer (UndefinedBehaviorSanitizer) - if: matrix.arch == 'amd64' && matrix.distro != 'alpine' + if: matrix.platform == 'linux/amd64' && matrix.distro != 'alpine' run: | - docker compose run --rm --entrypoint=/usr/bin/pskel_test --env TEST_EXTENSION_UBSAN=1 dev + docker compose run --rm shell pskel test ubsan # Windows: # runs-on: windows-2022 # defaults: @@ -51,7 +51,7 @@ jobs: # shell: cmd # strategy: # matrix: - # arch: ["x64"] + # .platform: ["x64"] # version: ["8.1", "8.2", "8.3"] # ts: ["nts", "ts"] # steps: @@ -61,20 +61,20 @@ jobs: # id: setup-php # uses: php/setup-php-sdk@v0.8 # with: - # arch: ${{ matrix.arch }} + # .platform: ${{ matrix.platform }} # version: ${{ matrix.version }} # ts: ${{ matrix.ts }} # - name: Enable developer command prompt # uses: ilammy/msvc-dev-cmd@v1 # with: - # arch: ${{ matrix.arch }} + # .platform: ${{ matrix.platform }} # toolset: ${{ steps.setup-php.outputs.toolset }} # - name: phpize # working-directory: ext # run: phpize # - name: configure # working-directory: ext - # run: configure --enable-skeleton --with-prefix=${{ steps.setup-php.outputs.prefix }} + # run: configure --enable-SKELETON_NAME --with-prefix=${{ steps.setup-php.outputs.prefix }} # - name: make # working-directory: ext # run: nmake diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index abf07c8..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**", - "/usr/local/include/php", - "/usr/local/include/php/TSRM", - "/usr/local/include/php/Zend", - "/usr/local/include/php/ext", - "/usr/local/include/php/include", - "/usr/local/include/php/main", - "/usr/local/include/php/sapi" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c99" - } - ], - "version": 4 -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 00c85c7..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "files.associations": { - "*.phpt": "php", - "*.c": "c", - "*.h": "c", - "*.cpp": "cpp", - "*.hpp": "cpp", - "*.cc": "cpp", - "*.cxx": "cpp" - }, - "editor.tabSize": 4, - "editor.insertSpaces": false, - "editor.detectIndentation": false -} diff --git a/Dockerfile b/Dockerfile index 883dc20..9a188dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,129 +1,30 @@ +ARG PLATFORM=${BUILDPLATFORM:-linux/amd64} ARG IMAGE=php -ARG TAG=8.3-cli +ARG TAG=8.3-zts-bookworm -FROM ${IMAGE}:${TAG} +FROM --platform=${PLATFORM} ${IMAGE}:${TAG} -ARG PSKEL_SKIP_DEBUG="" -ARG PSKEL_EXTRA_CONFIGURE_OPTIONS="" +COPY ./pskel.sh /usr/local/bin/pskel ENV USE_ZEND_ALLOC=0 +ENV USE_TRACKED_ALLOC=1 ENV ZEND_DONT_UNLOAD_MODULES=1 -ENV PSKEL_SKIP_DEBUG=${PSKEL_SKIP_DEBUG} -ENV PSKEL_EXTRA_CONFIGURE_OPTIONS=${PSKEL_EXTRA_CONFIGURE_OPTIONS} -RUN if test -f "/etc/debian_version"; then \ - apt-get update && \ - DEBIAN_FRONTEND="noninteractive" apt-get install -y \ - "build-essential" "bison" "valgrind" "llvm" "clang" "zlib1g-dev" "libsqlite3-dev" "git" && \ - if test "${PSKEL_SKIP_DEBUG}" = ""; then \ - docker-php-source extract && \ - cd "/usr/src/php" && \ - CFLAGS="-fpic -fpie -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-pie" ./configure --disable-all \ - --includedir="/usr/local/include/gcc-valgrind-php" --program-prefix="gcc-valgrind-" \ - --disable-cgi --disable-fpm --enable-cli \ - --enable-mysqlnd --enable-pdo --with-pdo-mysql --with-pdo-sqlite \ - --enable-debug --without-pcre-jit "$(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';")" \ - --with-valgrind \ - ${PSKEL_EXTRA_CONFIGURE_OPTIONS} \ - --enable-option-checking=fatal && \ - make -j$(nproc) && \ - make install && \ - cd - && \ - docker-php-source delete && \ - docker-php-source extract && \ - cd "/usr/src/php" && \ - CC=clang CXX=clang++ CFLAGS="-fsanitize=memory -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=memory" ./configure \ - --includedir="/usr/local/include/clang-msan-php" --program-prefix="clang-msan-" \ - --disable-cgi --disable-all --disable-fpm --enable-cli \ - --enable-mysqlnd --enable-pdo --with-pdo-mysql --with-pdo-sqlite \ - --enable-debug --without-pcre-jit "$(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';")" \ - --enable-memory-sanitizer \ - ${PSKEL_EXTRA_CONFIGURE_OPTIONS} \ - --enable-option-checking=fatal && \ - make -j$(nproc) && \ - make install && \ - cd - && \ - docker-php-source delete && \ - docker-php-source extract && \ - cd "/usr/src/php" && \ - CC=clang CXX=clang++ CFLAGS="-fsanitize=address -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=address" ./configure \ - --includedir="/usr/local/include/clang-asan-php" --program-prefix="clang-asan-" \ - --disable-cgi --disable-all --disable-fpm --enable-cli \ - --enable-mysqlnd --enable-pdo --with-pdo-mysql --with-pdo-sqlite \ - --enable-debug --without-pcre-jit "$(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';")" \ - --enable-address-sanitizer \ - ${PSKEL_EXTRA_CONFIGURE_OPTIONS} \ - --enable-option-checking=fatal && \ - make -j$(nproc) && \ - make install && \ - cd - && \ - docker-php-source delete && \ - docker-php-source extract && \ - cd "/usr/src/php" && \ - CC=clang CXX=clang++ CFLAGS="-fsanitize=undefined -fno-sanitize-recover -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined" ./configure \ - --includedir="/usr/local/include/clang-ubsan-php" --program-prefix="clang-ubsan-" \ - --disable-cgi --disable-all --disable-fpm --enable-cli \ - --enable-mysqlnd --enable-pdo --with-pdo-mysql --with-pdo-sqlite \ - --enable-debug --without-pcre-jit "$(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';")" \ - --enable-undefined-sanitizer \ - ${PSKEL_EXTRA_CONFIGURE_OPTIONS} \ - --enable-option-checking=fatal && \ - make -j$(nproc) && \ - make install && \ - cd - && \ - docker-php-source delete && \ - docker-php-source extract && \ - cd "/usr/src/php" && \ - CFLAGS="-fpic -fpie -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-pie" ./configure --disable-all \ - --includedir="/usr/local/include/debug-php" --program-prefix="debug-" \ - --disable-cgi --disable-fpm --enable-cli \ - --enable-mysqlnd --enable-pdo --with-pdo-mysql --with-pdo-sqlite \ - --enable-debug "$(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';")" \ - ${PSKEL_EXTRA_CONFIGURE_OPTIONS} \ - --enable-option-checking=fatal && \ - make -j$(nproc) && \ - make install && \ - cd - && \ - docker-php-source delete; \ - fi; \ - elif test -f "/etc/alpine-release"; then \ - apk add --no-cache ${PHPIZE_DEPS} "bison" "valgrind" "valgrind-dev" "zlib-dev" "sqlite-dev" "git" && \ - if test "${PSKEL_SKIP_DEBUG}" = ""; then \ - docker-php-source extract && \ - cd "/usr/src/php" && \ - CFLAGS="-fpic -fpie -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-pie" ./configure --disable-all \ - --includedir="/usr/local/include/gcc-valgrind-php" --program-prefix="gcc-valgrind-" \ - --disable-cgi --disable-fpm --enable-cli \ - --enable-mysqlnd --enable-pdo --with-pdo-mysql --with-pdo-sqlite \ - --enable-debug --without-pcre-jit "$(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';")" \ - --with-valgrind \ - ${PSKEL_EXTRA_CONFIGURE_OPTIONS} \ - --enable-option-checking=fatal && \ - make -j$(nproc) && \ - make install && \ - cd - && \ - docker-php-source delete && \ - docker-php-source extract && \ - cd "/usr/src/php" && \ - CFLAGS="-fpic -fpie -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-pie" ./configure --disable-all \ - --includedir="/usr/local/include/debug-php" --program-prefix="debug-" \ - --disable-cgi --disable-fpm --enable-cli \ - --enable-mysqlnd --enable-pdo --with-pdo-mysql --with-pdo-sqlite \ - --enable-debug "$(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';")" \ - ${PSKEL_EXTRA_CONFIGURE_OPTIONS} \ - --enable-option-checking=fatal && \ - make -j$(nproc) && \ - make install && \ - cd - && \ - docker-php-source delete; \ - fi; \ - fi && \ - docker-php-source extract && \ - ln -s "/usr/src/php/build/gen_stub.php" "/usr/local/bin/gen_stub.php" - -WORKDIR "/usr/src/php" - -COPY ./pskel_test.sh /usr/bin/pskel_test -COPY ./pskel_init_extension.sh /usr/bin/pskel_init_extension +RUN docker-php-source extract \ + && if test -f "/etc/debian_version"; then \ + echo "deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm main" > "/etc/apt/sources.list.d/llvm.list" \ + && echo "deb-src http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm main" >> "/etc/apt/sources.list.d/llvm.list" \ + && curl -fsSL "https://apt.llvm.org/llvm-snapshot.gpg.key" -o "/etc/apt/trusted.gpg.d/apt.llvm.org.asc" \ + && apt-get update \ + && DEBIAN_FRONTEND="noninteractive" apt-get install -y "bison" "re2c" "zlib1g-dev" "libsqlite3-dev" "libxml2-dev" \ + "autoconf" "pkg-config" "make" "gcc" "valgrind" "git" \ + "clang-20" \ + && update-alternatives --install "/usr/bin/clang" clang "/usr/bin/clang-20" 100 \ + && update-alternatives --install "/usr/bin/clang++" clang++ "/usr/bin/clang++-20" 100; \ + else \ + apk add --no-cache "bison" "zlib-dev" "sqlite-dev" "libxml2-dev" \ + "autoconf" "pkgconfig" "make" "gcc" "g++" "valgrind" "valgrind-dev" \ + "musl-dev" "git"; \ + fi COPY ./ext /ext diff --git a/README.md b/README.md index 22c9e21..8ddb61b 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ A skeleton project for quickly setting up an environment to develop extensions f 1. Install [Visual Studio Code](https://code.visualstudio.com/) and Docker Desktop (or an alternative engine). 1. Install the [Remote Container](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension in VSCode. 1. Open the directory and open it with the `Remote Container` extension. -1. Run `pskel_init_extension` command. -2. Run `pskel_test` command for testing. +1. Run `pskel init ` . +2. Run `pskel test [debug|valgrind|msan|asan|ubsan]` command for testing. ### Q&A @@ -16,32 +16,12 @@ A skeleton project for quickly setting up an environment to develop extensions f Yes. Pskel comes pre-setup with MySQL as a example. If you want to add something, you can easily do so by editing the `compose.yaml`. -#### Can I use a debug version of PHP? - -A debug build of PHP is included in advance. Debug builds using GCC and Clang are available, and Valgrind support is enabled. With the Clang build, you can also use MemorySanitizer. - -They each have the following binary prefixes. The build toolchains are the same. - -- `debug-php` -- `gcc-valgrind-php` -- `clang-msan-php` -- `clang-asan-php` -- `clang-ubsan-php` - -For example, the method to test the extension using GCC + Valgrind is as follows: - -``` -# gcc-valgrind-phpize -# ./configure --with-php-config=$(which gcc-valgrind-php-config) -# TEST_PHP_ARGS="-q -m --show-diff" make -j$(nproc) test -``` - #### Can I debug using gdb? Yes. Build using the debug version of PHP and run as follows: ``` -# gdb --args gcc-valgrind-php -dextension=./modules/your_extension_name.so example.php +# gdb --args -dextension=./modules/your_extension_name.so example.php ``` #### Can I develop using something other than Visual Studio Code? diff --git a/compose.yaml b/compose.yaml index 3e408ca..5903779 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,15 +1,14 @@ services: - dev: + shell: build: context: ./ dockerfile: ./Dockerfile cap_add: - - SYS_PTRACE + - SYS_ADMIN security_opt: - seccomp:unconfined privileged: true tty: true - command: ["sleep", "infinity"] # depends_on: # - mysql # mysql: diff --git a/ext/.gitkeep b/ext/.gitkeep index 54793b1..f1eaf86 100644 --- a/ext/.gitkeep +++ b/ext/.gitkeep @@ -1 +1 @@ -pskel_uninitialized \ No newline at end of file +pskel_uninitialized diff --git a/pskel.sh b/pskel.sh new file mode 100755 index 0000000..5394697 --- /dev/null +++ b/pskel.sh @@ -0,0 +1,146 @@ +#!/bin/sh -e + +cmd_usage() { + cat << EOF +Usage: ${0} [task] ... + +Available commands: + init create new extension + test test extension + build build PHP runtime +EOF +} + +cmd_init() { + if test "${1}" = "-h" || test "${1}" = "--help" || test "${#}" -lt 1; then + cat << EOF +Usage: $0 init [extension_name] [ext_skel.php options...] +EOF + return 0 + fi + + PSKEL_EXT_DIR="/ext" + + if test -d "/workspace/pskel/ext"; then + echo "[Pskel] Development containers workspace detected, use \"/workspace/pskel/ext\"." >&2 + PSKEL_EXT_DIR="/workspace/pskel/ext" + fi + + /usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --ext "${1}" --dir "/tmp" ${@} + rm -rf "${PSKEL_EXT_DIR}" + mv "/tmp/${1}" "${PSKEL_EXT_DIR}" +} + +cmd_test() { + if test "${1}" = "-h" || test "${1}" = "--help"; then + cat << EOF +Usage: ${0} test [test_type|php_binary_name] +env: + CFLAGS, CPPFLAGS: Compile flags + TEST_PHP_ARGS: Test flags +EOF + return 0 + fi + + if test "x${1}" = "x"; then + CC="$(which "gcc")"; CXX="$(which "g++")"; CMD="php" + else + case "${1}" in + debug) + if ! type "debug-php" > /dev/null 2>&1; then + CC="$(which "gcc")" CXX="$(which "g++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers" cmd_build "debug" + fi && \ + CC="$(which "gcc")"; CXX="$(which "g++")"; CMD="debug-php";; + valgrind) + if ! type "gcc-valgrind-php" > /dev/null 2>&1; then + CC="$(which "gcc")" CXX="$(which "g++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --with-valgrind" cmd_build "gcc-valgrind" + fi && \ + TEST_PHP_ARGS="${TEST_PHP_ARGS} -m" CC="$(which "gcc")"; CXX="$(which "g++")"; CMD="gcc-valgrind-php";; + msan) + if ! type "clang-msan-php" > /dev/null 2>&1; then + CC="$(which "clang")" CXX="$(which "clang++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS} -fsanitize=memory" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --enable-memory-sanitizer" cmd_build "clang-msan" + fi && \ + CFLAGS="${CFLAGS} -fsanitize=memory"; CPPFLAGS="${CPPFLAGS}"; LDFLAGS="-fsanitize=memory"; CC="$(which "clang")"; CXX="$(which "clang++")"; CMD="clang-msan-php";; + asan) + if ! type "clang-asan-php" > /dev/null 2>&1; then + CC="$(which "clang")" CXX="$(which "clang++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS} -fsanitize=address" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --enable-address-sanitizer" cmd_build "clang-asan" + fi && \ + CFLAGS="${CFLAGS} -fsanitize=address"; CPPFLAGS="${CPPFLAGS}"; LDFLAGS="-fsanitize=address"; CC="$(which "clang")"; CXX="$(which "clang++")"; CMD="clang-asan-php";; + ubsan) + if ! type "clang-ubsan-php" > /dev/null 2>&1; then + CC="$(which "clang")" CXX="$(which "clang++")" CFLAGS="-DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS} -fsanitize=undefined" CONFIGURE_OPTS="--enable-debug $(php -r "echo PHP_ZTS === 1 ? '--enable-zts' : '';") --enable-option-checking=fatal --disable-phpdbg --disable-cgi --disable-fpm --enable-cli --without-pcre-jit --disable-opcache-jit --disable-zend-max-execution-timers --enable-undefined-sanitizer" cmd_build "clang-ubsan" + fi && \ + CFLAGS="${CFLAGS} -fsanitize=undefined"; CPPFLAGS="${CPPFLAGS}"; LDFLAGS="-fsanitize=undefined"; CC="$(which "clang")"; CXX="$(which "clang++")"; CMD="clang-ubsan-php";; + *) CMD="${1}" + esac + fi + + for BIN in "${CMD}" "${CMD}ize" "${CMD}-config"; do + if ! type "${BIN}" > /dev/null 2>&1; then + echo "Invalid argument: '${CMD}', executable file not found" >&2 + exit 1 + fi + done + + PSKEL_EXT_DIR="/ext" + + if test -d "/workspace/pskel/ext"; then + echo "[Pskel] Development containers workspace detected, use \"/workspace/pskel/ext\"." >&2 + PSKEL_EXT_DIR="/workspace/pskel/ext" + else + if test -f "/ext/.gitkeep" && test $(cat "/ext/.gitkeep") = "pskel_uninitialized"; then + echo "[Pskel] Uninitialized project detected, initialize default skeleton." >&2 + cmd_init "skeleton" + fi + fi + + cd "${PSKEL_EXT_DIR}" + "${CMD}ize" + CC=${CC} CXX=${CXX} CFLAGS="${CFLAGS}" CPPFLAGS="${CPPFLAGS}" LDFLAGS="${LDFLAGS}" ./configure --with-php-config="$(which "${CMD}-config")" + make clean + make -j"$(nproc)" + TEST_PHP_ARGS="${TEST_PHP_ARGS} --show-diff -q" make test + cd - +} + +cmd_build() { + if test "${1}" = "-h" || test "${1}" = "--help"; then + cat << EOF +Usage: ${0} build [php_binary_prefix] +env: + CFLAGS, CPPFLAGS: Compile flags + CONFIGURE_OPTS: ./configure options +EOF + return 0 + fi + + if ! test "x${1}" = "x"; then + CONFIGURE_OPTS="--program-prefix="${1}-" --includedir="/usr/local/include/${1}-php" ${CONFIGURE_OPTS}" + fi + + cd "/usr/src/php" + ./buildconf --force + ./configure ${CONFIGURE_OPTS} + make clean + make -j"$(nproc)" + make install + make clean + cd - +} + +if [ $# -eq 0 ]; then + cmd_usage + exit 1 +fi + +case "${1}" in + help) shift && cmd_usage;; + init) shift && cmd_init "${@}";; + test) shift && cmd_test "${@}";; + build) shift && cmd_build "${@}";; + *) + echo "${0} error: invalid command: '${1}'" >&2 + cmd_usage + exit 1 + ;; +esac diff --git a/pskel_init_extension.sh b/pskel_init_extension.sh deleted file mode 100755 index b9fae92..0000000 --- a/pskel_init_extension.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -if test ${#} -lt 1; then - echo "Usage: pskel_init_extension --auhor [--onlyunix|--onlywindows] ..." - exit 1 -fi - -/usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --ext ${1} --dir "/tmp" ${@} && \ -rm -rf "/work/ext" && \ -mv "/tmp/${1}" "/work/ext" diff --git a/pskel_test.sh b/pskel_test.sh deleted file mode 100755 index 696c931..0000000 --- a/pskel_test.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/sh -e - -case "${1}" in - "") ;; - "test") TEST_EXTENSION=1;; - "debug") TEST_EXTENSION_DEBUG=1;; - "valgrind") TEST_EXTENSION_VALGRIND=1;; - "msan") TEST_EXTENSION_MSAN=1;; - "asan") TEST_EXTENSION_ASAN=1;; - "ubsan") TEST_EXTENSION_UBSAN=1;; - *) printf "Pskel Test\nUsage:\n\t\t%s\t\t: %s\n\t\t%s\t\t: %s\n\t\t%s\t: %s\n\t\t%s\t\t: %s\n\t\t%s\t\t: %s\n\t\t%s\t\t: %s\n" "test" "Test extension with pre-installed PHP binary. [bin: $(which "php")]" "debug" "Test extension with Debug Build (GCC) binary. [bin: $(which "debug-php")]" "valgrind" "Test extension with GCC binary with Valgrind. [bin: $(which "gcc-valgrind-php")]" "msan" "Test extension with Clang binary with MemorySanitizer. [bin: $(which "clang-msan-php")]" "asan" "Test extension with Clang binary with AddressSanitizer. [bin: $(which "clang-asan-php")]" "ubsan" "Test extension with Clang binary with UndefinedBehaviorSanitizer. [bin: $(which "clang-ubsan-php")]"; exit 0;; -esac - -if test -f "/ext/.gitkeep" && test $(cat "/ext/.gitkeep") = "pskel_uninitialized"; then - echo "[Pskel Test] Uninitialized project detected, initialize default skeleton" - rm -rf "/ext" - /usr/local/bin/php "/usr/src/php/ext/ext_skel.php" --ext "ext" --dir "/" -fi - -PSKEL_WORKDIR="/ext" - -if test -d "/work/ext"; then - echo "[Pskel Test] DevContainer workspace detected, use \"/work/ext\"." - PSKEL_WORKDIR="/work/ext" -fi - -echo "[Pskel Test] BEGIN TEST" - -if test "${TEST_EXTENSION}" != ""; then - cd "${PSKEL_WORKDIR}" - phpize - ./configure --with-php-config="$(which php-config)" - make clean - make -j"$(nproc)" - TEST_PHP_ARGS="--show-diff -q" make test -else - echo "[Pskel Test] skip: TEST_EXTENSION is not set" -fi - -if test "${TEST_EXTENSION_DEBUG}" != ""; then - cd "${PSKEL_WORKDIR}" - debug-phpize - ./configure --with-php-config="$(which debug-php-config)" - make clean - make -j"$(nproc)" - TEST_PHP_ARGS="--show-diff -q" make test -else - echo "[Pskel Test] skip: TEST_EXTENSION_DEBUG is not set" -fi - -if test "${TEST_EXTENSION_VALGRIND}" != ""; then - if type "gcc-valgrind-php" > /dev/null 2>&1; then - cd "${PSKEL_WORKDIR}" - gcc-valgrind-phpize - ./configure --with-php-config="$(which gcc-valgrind-php-config)" - make clean - make -j"$(nproc)" - TEST_PHP_ARGS="--show-diff -q -m" make test - else - echo "[Pskel Test] missing gcc-valgrind-php" - exit 1 - fi -else - echo "[Pskel Test] skip: TEST_EXTENSION_VALGRIND is not set" -fi - -if test "${TEST_EXTENSION_MSAN}" != ""; then - if type "clang-msan-php" > /dev/null 2>&1; then - cd "${PSKEL_WORKDIR}" - clang-msan-phpize - CC="clang" CXX="clang++" CFLAGS="-fsanitize=memory -DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="-fsanitize=memory -DZEND_TRACK_ARENA_ALLOC ${CPPFLAGS}" LDFLAGS="-fsanitize=memory" ./configure --with-php-config="$(which clang-msan-php-config)" - make clean - CFLAGS="-fsanitize=memory -DZEND_TRACK_ARENA_ALLOC ${CFLAGS}" CPPFLAGS="-fsanitize=memory -DZEND_TRACK_ARENA_ALLOC ${CPPFLAGS}" LDFLAGS="-fsanitize=memory" make -j"$(nproc)" - TEST_PHP_ARGS="--show-diff -q --msan" make test - else - echo "[Pskel Test] missing clang-msan-php" - exit 1 - fi -else - echo "[Pskel Test] skip: TEST_EXTENSION_MSAN is not set" -fi - -if test "${TEST_EXTENSION_ASAN}" != ""; then - if type "clang-asan-php" > /dev/null 2>&1; then - cd "${PSKEL_WORKDIR}" - clang-asan-phpize - CC="clang" CXX="clang++" CFLAGS="-fsanitize=address -DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="-fsanitize=address -DZEND_TRACK_ARENA_ALLOC ${CPPFLAGS}" LDFLAGS="-fsanitize=address" ./configure --with-php-config="$(which clang-asan-php-config)" - make clean - CFLAGS="-fsanitize=address -DZEND_TRACK_ARENA_ALLOC ${CFLAGS}" CPPFLAGS="-fsanitize=address -DZEND_TRACK_ARENA_ALLOC ${CPPFLAGS}" LDFLAGS="-fsanitize=address" make -j"$(nproc)" - TEST_PHP_ARGS="--show-diff -q --asan" make test - else - echo "[Pskel Test] missing clang-asan-php" - exit 1 - fi -else - echo "[Pskel Test] skip: TEST_EXTENSION_ASAN is not set" -fi - -if test "${TEST_EXTENSION_UBSAN}" != ""; then - if type "clang-ubsan-php" > /dev/null 2>&1; then - cd "${PSKEL_WORKDIR}" - clang-ubsan-phpize - CC="clang" CXX="clang++" CFLAGS="-fsanitize=undefined -DZEND_TRACK_ARENA_ALLOC" CPPFLAGS="-fsanitize=undefined -DZEND_TRACK_ARENA_ALLOC ${CPPFLAGS}" LDFLAGS="-fsanitize=undefined" ./configure --with-php-config="$(which clang-ubsan-php-config)" - make clean - CFLAGS="-fsanitize=undefined -DZEND_TRACK_ARENA_ALLOC ${CFLAGS}" CPPFLAGS="-fsanitize=undefined -DZEND_TRACK_ARENA_ALLOC ${CPPFLAGS}" LDFLAGS="-fsanitize=undefined" make -j"$(nproc)" - TEST_PHP_ARGS="--show-diff -q" make test - else - echo "[Pskel Test] missing clang-ubsan-php" - exit 1 - fi -else - echo "[Pskel Test] skip: TEST_EXTENSION_UBSAN is not set" -fi - -echo "[Pskel Test] END TEST" -exit 0