diff --git a/.cargo/config.toml b/.cargo/config.toml index b86e955..5577111 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -12,6 +12,11 @@ rustflags = [ "-C", "link-arg=dynamic_lookup", ] +[target.'cfg(all(target_os = "windows", target_env = "msvc"))'] +# A static PDFium leaves its Windows API imports to the final link, including pdfium-render's +# own DLL link, which core/build.rs can't reach. Unused import libraries cost nothing. +rustflags = ["-l", "dylib=gdi32", "-l", "dylib=user32", "-l", "dylib=advapi32"] + # pdfium's renderer is not thread-safe; run all tests sequentially to avoid # heap corruption (SIGABRT) when multiple tests exercise pdfium concurrently. [env] diff --git a/.github/workflows/_php-binding-tests.yml b/.github/workflows/_php-binding-tests.yml index 4330ac0..7d248d2 100644 --- a/.github/workflows/_php-binding-tests.yml +++ b/.github/workflows/_php-binding-tests.yml @@ -50,9 +50,8 @@ jobs: uses: actions/cache@v6 with: path: core/.pdfium_cache - key: pdfium-${{ runner.os }}-${{ hashFiles('core/build.rs') }} - restore-keys: | - pdfium-${{ runner.os }}- + # Keyed on the release itself, with no fallback: an older release must never be restored. + key: pdfium-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('core/pdfium-release') }} - uses: extractions/setup-just@v4 diff --git a/.github/workflows/_php-static-check.yml b/.github/workflows/_php-static-check.yml new file mode 100644 index 0000000..5eb363a --- /dev/null +++ b/.github/workflows/_php-static-check.yml @@ -0,0 +1,202 @@ +name: PHP binding tests (static lib build) + +on: + workflow_call: + workflow_dispatch: + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + php-binding-tests: + name: Test static PHP binding (${{ matrix.platform.pdfium_target }}, PHP ${{ matrix.php }} ${{ matrix.thread_safety }}) + runs-on: ${{ matrix.platform.runner }} + strategy: + fail-fast: false + matrix: + platform: + - { runner: ubuntu-latest, pdfium_target: linux-x64-glibc } + - { runner: ubuntu-24.04-arm, pdfium_target: linux-arm64-glibc } + - { runner: macos-latest, pdfium_target: mac-arm64 } + - { runner: macos-15-intel, pdfium_target: mac-x64 } + php: [ "8.1", "8.2", "8.3", "8.4", "8.5" ] + thread_safety: [ "zts", "nts" ] + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Download static PDFium + env: + GH_TOKEN: ${{ github.token }} + run: | + bash tools/pdfium-static/download.sh ${{ matrix.platform.pdfium_target }} "$RUNNER_TEMP/pdfium-static" + echo "PDFIUM_STATIC_LIB_PATH=$RUNNER_TEMP/pdfium-static" >> "$GITHUB_ENV" + + - uses: extractions/setup-just@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@1.99.0 + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + with: + key: php-static-${{ matrix.platform.pdfium_target }}-php${{ matrix.php }}-${{ matrix.thread_safety }} + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + env: + phpts: ${{ matrix.thread_safety }} + + - name: Build and test (static PDFium) + run: just php test-static + + - name: Check the extension doesn't load PDFium dynamically (macOS) + if: runner.os == 'macOS' + run: | + deps="$(otool -L target/release/libbernard_ledit_php.dylib)" + echo "$deps" + if grep -qi pdfium <<< "$deps"; then + echo "::error::The extension links PDFium dynamically" + exit 1 + fi + + # The extension must load on the oldest glibc the static PDFium was built against. + - name: Check the extension doesn't load PDFium dynamically and runs on glibc 2.35 (Linux) + if: runner.os == 'Linux' + run: | + ext=target/release/libbernard_ledit_php.so + deps="$(ldd "$ext")" + echo "$deps" + if grep -qi pdfium <<< "$deps"; then + echo "::error::The extension links PDFium dynamically" + exit 1 + fi + newest_glibc="$(objdump -T "$ext" | grep -oE 'GLIBC_[0-9]+(\.[0-9]+)*' | sed 's/GLIBC_//' | sort -Vu | tail -n 1)" + echo "Newest glibc symbol version required: $newest_glibc" + if [ "$(printf '%s\n' "$newest_glibc" 2.35 | sort -V | tail -n 1)" != 2.35 ]; then + echo "::error::The extension requires glibc $newest_glibc, newer than 2.35" + exit 1 + fi + + # Alpine runs through `docker run` rather than a job container: GitHub can't run JavaScript + # actions inside Alpine containers on arm64 runners. + php-binding-tests-musl: + name: Test static PHP binding (${{ matrix.platform.pdfium_target }}, PHP ${{ matrix.php }} ${{ matrix.thread_safety }}) + runs-on: ${{ matrix.platform.runner }} + strategy: + fail-fast: false + matrix: + platform: + - { runner: ubuntu-latest, pdfium_target: linux-x64-musl } + - { runner: ubuntu-24.04-arm, pdfium_target: linux-arm64-musl } + php: [ "8.1", "8.2", "8.3", "8.4", "8.5" ] + thread_safety: [ "zts", "nts" ] + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Download static PDFium + env: + GH_TOKEN: ${{ github.token }} + run: bash tools/pdfium-static/download.sh ${{ matrix.platform.pdfium_target }} .pdfium-static + + # Rust links the C runtime statically on musl by default, which a PHP extension must not do. + - name: Build and test in Alpine + env: + IMAGE: php:${{ matrix.php }}-${{ matrix.thread_safety == 'zts' && 'zts' || 'cli' }}-alpine + run: | + docker run --rm -v "$PWD:/w" -w /w \ + -e PDFIUM_STATIC_LIB_PATH=/w/.pdfium-static \ + -e RUSTFLAGS="-C target-feature=-crt-static" \ + "$IMAGE" sh -euc ' + apk add --no-cache bash git curl unzip build-base cmake nasm clang-dev linux-headers just rustup libstdc++ + rustup-init -y --default-toolchain none --profile minimal + . "$HOME/.cargo/env" + curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer + just php test-static + deps="$(ldd target/release/libbernard_ledit_php.so 2>/dev/null || true)" + echo "$deps" + if echo "$deps" | grep -qi pdfium; then + echo "The extension links PDFium dynamically" >&2 + exit 1 + fi + ' + + php-binding-tests-windows: + name: Test static PHP binding (${{ matrix.pdfium_target }}, PHP ${{ matrix.php }} ${{ matrix.thread_safety }}) + runs-on: windows-latest + env: + # ext-php-rs needs nightly on Windows (vectorcall ABI); this overrides rust-toolchain.toml. + RUSTUP_TOOLCHAIN: nightly + strategy: + fail-fast: false + matrix: + php: [ "8.1", "8.2", "8.3", "8.4", "8.5" ] + thread_safety: [ "zts", "nts" ] + # The extension must link with the MSVC toolset its PHP version was built with. + include: + - { php: "8.1", msvc: "14.29", pdfium_target: win-x64-v142 } + - { php: "8.2", msvc: "14.29", pdfium_target: win-x64-v142 } + - { php: "8.3", msvc: "14.29", pdfium_target: win-x64-v142 } + - { php: "8.4", msvc: "14.44", pdfium_target: win-x64-v143 } + - { php: "8.5", msvc: "14.44", pdfium_target: win-x64-v143 } + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + + - name: Download static PDFium + env: + GH_TOKEN: ${{ github.token }} + run: | + bash tools/pdfium-static/download.sh ${{ matrix.pdfium_target }} "$RUNNER_TEMP/pdfium-static" + echo "PDFIUM_STATIC_LIB_PATH=$RUNNER_TEMP/pdfium-static" >> "$GITHUB_ENV" + + - uses: extractions/setup-just@v4 + + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@nightly + + - name: Cache Rust dependencies + uses: Swatinem/rust-cache@v2 + with: + key: php-static-${{ matrix.pdfium_target }}-php${{ matrix.php }}-${{ matrix.thread_safety }} + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + env: + phpts: ${{ matrix.thread_safety }} + + - name: Pin the MSVC toolset of the PHP build + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + toolset: ${{ matrix.msvc }} + + # Git Bash puts its GNU link.exe ahead of MSVC's on PATH, where Rust looks up the linker. + - name: Remove Git's GNU link.exe + run: rm -f "/c/Program Files/Git/usr/bin/link.exe" + + - name: Build and test (static PDFium) + run: just php test-static + + - name: Check the extension doesn't load PDFium dynamically + run: | + imports="$("/c/Program Files/LLVM/bin/llvm-readobj.exe" --coff-imports target/release/bernard_ledit_php.dll | grep -i '^ *Name:' || true)" + echo "$imports" + if grep -qi pdfium <<< "$imports"; then + echo "::error::The extension links PDFium dynamically" + exit 1 + fi diff --git a/.github/workflows/build-static-pdfium.yml b/.github/workflows/build-static-pdfium.yml new file mode 100644 index 0000000..30c0d7f --- /dev/null +++ b/.github/workflows/build-static-pdfium.yml @@ -0,0 +1,196 @@ +name: Static PDFium +on: + workflow_dispatch: + inputs: + force: + description: "Rebuild and overwrite targets that are already published" + type: boolean + default: false + push: + branches: [ add-php-ext-publish ] +permissions: + contents: write +# Runs queue instead of building and publishing the same targets side by side. +concurrency: + group: static-pdfium-${{ github.ref }} + cancel-in-progress: false + +jobs: + # Targets live in tools/pdfium-static/targets.json. win-arm64 builds on windows-2022: the + # VS 2026 image behind windows-latest has no ARM64 libraries for the 14.44 toolset. + plan: + name: Find the targets to build + runs-on: ubuntu-latest + outputs: + release: ${{ steps.plan.outputs.release }} + targets: ${{ steps.plan.outputs.targets }} + steps: + - uses: actions/checkout@v6 + + # A target is up to date once both its library and its checksum are published. + - name: List the unpublished targets + id: plan + env: + GH_TOKEN: ${{ github.token }} + FORCE: ${{ inputs.force }} + run: | + release="pdfium-static-$(tr -d '[:space:]' < core/pdfium-release)" + release="${release//\//_}" + published="$(gh release view "$release" --json assets --jq '[.assets[].name]' 2>/dev/null || echo '[]')" + targets="$(jq -c --argjson published "$published" --arg force "$FORCE" ' + def is_published($name): $published | any(.[]; . == $name); + map(select( + "libpdfium-\(.target).\(if .os == "win" then "lib" else "a" end)" as $asset + | $force == "true" or ((is_published($asset) and is_published($asset + ".sha256")) | not) + ))' tools/pdfium-static/targets.json)" + echo "release=$release" >> "$GITHUB_OUTPUT" + echo "targets=$targets" >> "$GITHUB_OUTPUT" + echo "To build: $(jq -r 'map(.target) | join(", ")' <<< "$targets")" + + build: + name: Build ${{ matrix.target }} + needs: plan + if: needs.plan.outputs.targets != '[]' + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + # googlesource throttles parallel gclient syncs. + max-parallel: 2 + matrix: + include: ${{ fromJSON(needs.plan.outputs.targets) }} + defaults: + run: + shell: bash + env: + PDFIUM_OS: ${{ matrix.os }} + PDFIUM_CPU: ${{ matrix.cpu }} + PDFIUM_ENV: ${{ matrix.env }} + MSVC_TOOLSET: ${{ matrix.msvc }} + # Makes depot_tools use the runner's Visual Studio instead of Google's internal toolchain. + DEPOT_TOOLS_WIN_TOOLCHAIN: "0" + WORK_DIR: ${{ matrix.os == 'win' && 'C:/pdfium-static' || '/tmp/pdfium-static' }} + OUT_DIR: ${{ github.workspace }}/out + LIB_NAME: ${{ matrix.os == 'win' && 'pdfium.lib' || 'libpdfium.a' }} + ASSET: libpdfium-${{ matrix.target }}.${{ matrix.os == 'win' && 'lib' || 'a' }} + steps: + - uses: actions/checkout@v6 + + # Sources only: Ninja could reuse stale objects from a cached out/ after a toolchain change. + - name: Cache the PDFium sources + uses: actions/cache@v6 + with: + path: | + ${{ env.WORK_DIR }}/pdfium-binaries/pdfium + !${{ env.WORK_DIR }}/pdfium-binaries/pdfium/out + key: pdfium-src-${{ hashFiles('core/pdfium-release') }}-${{ matrix.target }} + + # Chromium's checkout has paths beyond Windows' default length limit. The runner's LLVM is the + # namespacer's fallback for tools that Chromium's LLVM package lacks. + - name: Prepare the Windows build + if: runner.os == 'Windows' + run: | + git config --global core.longpaths true + echo "C:/Program Files/LLVM/bin" >> "$GITHUB_PATH" + + - name: Set up Python (Windows) + if: runner.os == 'Windows' + uses: actions/setup-python@v6 + with: + python-version: "3.12" + + # Retries the build when it fails on a network error, which googlesource returns under load. + - name: Build + run: | + max_attempts=5 + for attempt in $(seq "$max_attempts"); do + if bash tools/pdfium-static/build.sh 2>&1 | tee build.log; then + exit 0 + fi + if ! tail -n 60 build.log | grep -qE 'HTTP 5[0-9]{2}|RPC failed|Could not resolve host'; then + exit 1 + fi + if [ "$attempt" -lt "$max_attempts" ]; then + delay=$((attempt * 120 + RANDOM % 60)) + echo "::warning::Network failure on attempt $attempt/$max_attempts, retrying in ${delay}s" + sleep "$delay" + fi + done + echo "::error::Network failures persisted after $max_attempts attempts" + exit 1 + + # The Linux build runs as root in Docker; the cache can only save files the runner user can read. + - name: Fix ownership (Linux) + if: runner.os == 'Linux' + run: sudo chown -R "$(id -u):$(id -g)" "$WORK_DIR" + + - name: Pin the target MSVC toolset (Windows) + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.cpu == 'arm64' && 'amd64_arm64' || 'x64' }} + toolset: ${{ matrix.msvc }} + + # Links a throwaway DLL that pulls in the PDFium API bernard-ledit uses, with the target + # toolset's link.exe and runtime libraries. This entry-point-less link also leaves the C + # runtime's startup objects unresolved, so only symbols referenced from pdfium.lib count. + # The full path avoids Git Bash's GNU `link`. + - name: Check the library links with the target toolset (Windows) + if: runner.os == 'Windows' + env: + MACHINE: ${{ matrix.cpu == 'arm64' && 'ARM64' || 'X64' }} + run: | + link_exe="$(cygpath -u "$VCToolsInstallDir")/bin/Hostx64/$PDFIUM_CPU/link.exe" + [ -f "$link_exe" ] || { echo "::error::link.exe not found at $link_exe"; exit 1; } + MSYS_NO_PATHCONV=1 "$link_exe" /NOLOGO /DLL /NOENTRY "/MACHINE:$MACHINE" /OUT:linktest.dll \ + /INCLUDE:FPDF_InitLibraryWithConfig /INCLUDE:FPDF_LoadMemDocument64 \ + /INCLUDE:FPDF_RenderPageBitmap /INCLUDE:FPDFText_LoadPage \ + /INCLUDE:FPDFPage_GenerateContent /INCLUDE:FPDF_SaveAsCopy \ + "$(cygpath -w "$OUT_DIR/$LIB_NAME")" msvcrt.lib msvcprt.lib vcruntime.lib ucrt.lib \ + gdi32.lib user32.lib advapi32.lib > linktest.log 2>&1 || true + if grep -E '(^|[\\/])pdfium\.lib\(.*unresolved external symbol' linktest.log; then + echo "::error::pdfium.lib needs symbols that toolset $MSVC_TOOLSET doesn't provide" + exit 1 + fi + if grep -E 'fatal error LNK' linktest.log | grep -v LNK1120; then + cat linktest.log + echo "::error::The link test stopped before resolving pdfium.lib's symbols" + exit 1 + fi + echo "pdfium.lib links with toolset $MSVC_TOOLSET" + + # Matrix jobs publish in parallel, so each asset gets its own checksum file, and a job that + # loses the race to create the release uploads to the one its sibling created. + - name: Publish + env: + GH_TOKEN: ${{ github.token }} + RELEASE: ${{ needs.plan.outputs.release }} + run: | + cp "$OUT_DIR/$LIB_NAME" "$ASSET" + if command -v sha256sum >/dev/null; then + sha256sum "$ASSET" > "$ASSET.sha256" + else + shasum -a 256 "$ASSET" > "$ASSET.sha256" + fi + if ! gh release view "$RELEASE" >/dev/null 2>&1; then + gh release create "$RELEASE" --prerelease --title "$RELEASE" \ + --notes "Static PDFium for bernard-ledit: a build input for CI and local static builds, not a product release." || + gh release view "$RELEASE" >/dev/null + fi + gh release upload "$RELEASE" "$ASSET" "$ASSET.sha256" --clobber + + - name: Upload the build log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: build-log-${{ matrix.target }} + path: build.log + + # Tests the PHP extension against the published libraries, on the commit that built them. Also + # runs when every target was already published (build skipped), but not after a failed build. + test: + name: Test + needs: [ plan, build ] + if: ${{ !cancelled() && !failure() }} + permissions: + contents: read + uses: ./.github/workflows/_php-static-check.yml diff --git a/.gitignore b/.gitignore index 3fe52a8..3187ac8 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,7 @@ $RECYCLE.BIN/ # Tools .rtk -local_test \ No newline at end of file +local_test + +# Build +tools/pdfium-static/pdfium-static-namespaced/ diff --git a/Cargo.lock b/Cargo.lock index e9819e1..a21b50f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,11 +95,11 @@ dependencies = [ [[package]] name = "askama" -version = "0.14.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" +checksum = "6024d73179f43f15ccd2b881bfea6fee7f3a46ec53f33b52210dea749ebebaa4" dependencies = [ - "askama_derive", + "askama_macros", "itoa", "percent-encoding", "serde", @@ -108,31 +108,42 @@ dependencies = [ [[package]] name = "askama_derive" -version = "0.14.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" +checksum = "071ee5ebf2138e3ad180e0aacf6940c2cab5e6d8333741d9925c7bee2b153f39" dependencies = [ "askama_parser", "basic-toml", + "glob", "memchr", "proc-macro2", "quote", "rustc-hash", "serde", "serde_derive", - "syn 2.0.119", + "syn 3.0.9", +] + +[[package]] +name = "askama_macros" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643e1c7cbb6aec1d920332fe51a7c0d8219e273dcb8602db03f5263e4d16487b" +dependencies = [ + "askama_derive", ] [[package]] name = "askama_parser" -version = "0.14.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" +checksum = "2c5ae75772275d268b03ab8bdccdd12117b6169ee23256942b34e46c9f476583" dependencies = [ - "memchr", + "rustc-hash", "serde", "serde_derive", - "winnow 0.7.15", + "unicode-ident", + "winnow", ] [[package]] @@ -156,7 +167,7 @@ dependencies = [ "num-traits", "pastey", "rayon", - "thiserror", + "thiserror 2.0.21", "v_frame", "y4m", ] @@ -209,16 +220,14 @@ dependencies = [ name = "bernard-ledit" version = "0.1.0" dependencies = [ - "cargo-husky", "flate2", "image", - "log", "mozjpeg", "pdfium-render", "serde", "tar", "test-case", - "thiserror", + "thiserror 2.0.21", "ureq", ] @@ -382,52 +391,57 @@ dependencies = [ ] [[package]] -name = "cargo-husky" -version = "1.5.0" +name = "cargo-platform" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] [[package]] name = "cargo-platform" -version = "0.1.9" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba" dependencies = [ "serde", + "serde_core", ] [[package]] name = "cargo_metadata" -version = "0.14.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", - "cargo-platform", + "cargo-platform 0.1.9", "semver", "serde", "serde_json", + "thiserror 1.0.69", ] [[package]] name = "cargo_metadata" -version = "0.19.2" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" dependencies = [ "camino", - "cargo-platform", + "cargo-platform 0.3.3", "semver", "serde", "serde_json", - "thiserror", + "thiserror 2.0.21", ] [[package]] name = "cc" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6651c9ed80effdc7db0ff72512157f901af5e3549e341e24b1dd4887d836d838" +checksum = "877bf67ac8e52449eb2f9e98a344ea163beb70dd1f9eebe3cc5357dcfeaee4df" dependencies = [ "find-msvc-tools", "jobserver", @@ -450,6 +464,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + [[package]] name = "chrono" version = "0.4.45" @@ -498,9 +518,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "combine" -version = "4.6.8" +version = "4.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +checksum = "4356eba6976435498d05a311ee9fc486da3bc81c200d3f0d7dd9703b41913f92" dependencies = [ "bytes", "memchr", @@ -534,9 +554,12 @@ checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" -version = "0.4.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +checksum = "9eb6feb175df65d0a3ccd3e73484e940d0ac664e8034f0519fd49a93db3071d9" +dependencies = [ + "rustversion", +] [[package]] name = "convert_case" @@ -772,15 +795,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "error-chain" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" -dependencies = [ - "version_check", -] - [[package]] name = "exr" version = "1.74.2" @@ -800,9 +814,9 @@ dependencies = [ [[package]] name = "ext-php-rs" -version = "0.16.1" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fa5549b3473b5c9f66fdb47a888ec014083a426b197184c3dd174277d29d6ea" +checksum = "f1279870fe6585ac0ba42ed6af0c5c5477b2b7f44dc073d4a6586a5b4a9c4aa0" dependencies = [ "anyhow", "bindgen", @@ -817,7 +831,7 @@ dependencies = [ "once_cell", "parking_lot", "skeptic", - "thiserror", + "thiserror 2.0.21", "ureq", "zip", ] @@ -833,9 +847,9 @@ dependencies = [ [[package]] name = "ext-php-rs-derive" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c273fd80ca04dd6cdfe0cb6b48ec91bb7174bd3525c7b3549dc32d432d6879a" +checksum = "d31fcc898471e5ab9f4495a8772408f1219f2caa7e1dd36244598a76c0a868cf" dependencies = [ "convert_case 0.12.0", "darling", @@ -884,9 +898,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" +checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" [[package]] name = "flate2" @@ -916,9 +930,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "fs-err" -version = "2.11.0" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +checksum = "b5c95b673b8f6f7235229ae11c5642d81b04c2e64c1e2fb417bc0cf73ca45f29" dependencies = [ "autocfg", ] @@ -1151,9 +1165,9 @@ dependencies = [ [[package]] name = "inout" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +checksum = "3b5cf4372d022092674a83b8febf5865f7a573cc0c5baec5e49c879b6a20978f" dependencies = [ "hybrid-array", ] @@ -1214,7 +1228,7 @@ dependencies = [ "jni-sys", "log", "simd_cesu8", - "thiserror", + "thiserror 2.0.21", "walkdir", "windows-link", ] @@ -1286,9 +1300,9 @@ checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" [[package]] name = "libc" -version = "0.2.190" +version = "0.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" [[package]] name = "libfuzzer-sys" @@ -1358,9 +1372,9 @@ dependencies = [ [[package]] name = "lzma-rust2" -version = "0.16.5" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca93e534d1142d1d0dcca6d25fe302508a5dfb40b302802904577725ea0b695b" +checksum = "7277c9742229dc25243236d578b6471a798c554512c6f6a04365ec2e87c2a3bb" dependencies = [ "sha2", ] @@ -1538,6 +1552,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "no_std_io2" version = "0.9.4" @@ -1824,9 +1850,9 @@ checksum = "4a6394b9e965e73d0a289ee54f589087e2c676aedf60885baf52c76b771e4958" [[package]] name = "ppmd-rust" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196a7c80b9a7652aba7cc070827516c2abe4ccdf53d128e1944003cf5726cff1" +checksum = "494b4379484fc92217cc7d9e3a532375b1d01a61889ec8333025dc3b0377af56" [[package]] name = "ppv-lite86" @@ -2057,7 +2083,7 @@ dependencies = [ "rand", "rand_chacha", "simd_helpers", - "thiserror", + "thiserror 2.0.21", "v_frame", "wasm-bindgen", ] @@ -2227,9 +2253,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.15" +version = "0.103.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" +checksum = "4443b1b6d39d7c663139942cc4558262562d2c84123bb6282ef177009ca8b281" dependencies = [ "ring", "rustls-pki-types", @@ -2253,9 +2279,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +checksum = "9cb23c424d8ee841bb4d813677ca237e2a610067d594fec130f87d6093495ab5" dependencies = [ "windows-sys 0.61.2", ] @@ -2438,16 +2464,18 @@ checksum = "33f4fe9184a62d842c9ef383018f3306d8ba224fd9d836f56d7288308847c256" [[package]] name = "skeptic" -version = "0.13.7" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" +checksum = "d82adb9b794e23afb98bb1c89fd84b1971dc74d07b476a3967a8c95b13c2f678" dependencies = [ "bytecount", - "cargo_metadata 0.14.2", - "error-chain", + "cargo_metadata 0.15.4", "glob", "pulldown-cmark", + "serde", + "serde_json", "tempfile", + "thiserror 1.0.69", "walkdir", ] @@ -2588,13 +2616,33 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09e52cb86a36cede5cb101bf8908837b3e4c6e5e59fe7fd85c23fb56200d189e" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.21", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -2644,18 +2692,18 @@ checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "tokio" -version = "1.53.3" +version = "1.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce3335fa71841cda333a58d7615b03901380ecf09d59b3296d21f8bbac0dde4e" +checksum = "a0c168a474b95bfecfe908a65d4bdffc523144b649a74c09c286afb35d53e0bc" dependencies = [ "pin-project-lite", ] [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" +version = "1.1.8+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +checksum = "20489e00e4d8741d6be680764cc12e270655e375a20d1011e844a9c3379e678d" dependencies = [ "indexmap", "serde_core", @@ -2663,14 +2711,14 @@ dependencies = [ "toml_datetime", "toml_parser", "toml_writer", - "winnow 0.7.15", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "2b86d767906c6c42421dcba507eb9d203e779497710a47782a224bb871653053" dependencies = [ "serde_core", ] @@ -2681,7 +2729,7 @@ version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa693a8032d7e1cada7d0041e96126df243179ff061456783ac7f12bda4744c" dependencies = [ - "winnow 1.0.4", + "winnow", ] [[package]] @@ -2692,9 +2740,9 @@ checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" [[package]] name = "typed-path" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" +checksum = "54ec2755506471f54baf5e4bb5499d8e510cc1caf271270e778a736bd2d7336c" [[package]] name = "typenum" @@ -2728,12 +2776,12 @@ checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "uniffi" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46eefd5468602930da46b1f49d3448c6dfc2e81295f93120f23f8174fd70267f" +checksum = "76407f5f396a2c949a069eff4a9fca9ce462410eb872bffef4c2b7b89804a77a" dependencies = [ "anyhow", - "cargo_metadata 0.19.2", + "cargo_metadata 0.23.1", "uniffi_bindgen", "uniffi_build", "uniffi_core", @@ -2743,14 +2791,14 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a0c9b375d32e1365cdb2bdd7cb495eecf6fac851ddbad077412b4ee1888514" +checksum = "3df3ced8f0eda3de99f6d50820e8628f443da8e4f447f477d1403ceba29dacbd" dependencies = [ "anyhow", "askama", "camino", - "cargo_metadata 0.19.2", + "cargo_metadata 0.23.1", "fs-err", "glob", "goblin", @@ -2769,9 +2817,9 @@ dependencies = [ [[package]] name = "uniffi_build" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744fe15bcd3e2b1712a4573a45ce749af19cf28d69027ca5789619014955668c" +checksum = "925be5c36297fff0d416fa2f03585ace718b6e6c635466754128d00f0862d5f1" dependencies = [ "anyhow", "camino", @@ -2780,9 +2828,9 @@ dependencies = [ [[package]] name = "uniffi_core" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eec017b112701681f6fbbe5d92014b5c468eb0b177a94389de03ceec40665095" +checksum = "f7530ae8efeaaa488622865966763fe0294832779fff80508c36d69c6a874a6a" dependencies = [ "anyhow", "bytes", @@ -2792,9 +2840,9 @@ dependencies = [ [[package]] name = "uniffi_internal_macros" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4641669b48fefbc5e80ff08c5004d9c7617fb91232131a6734ab6712779cb04c" +checksum = "0f4bad017164375d99450d70495014810d15a84ba9da6ed14b9628b1424223ba" dependencies = [ "anyhow", "indexmap", @@ -2805,9 +2853,9 @@ dependencies = [ [[package]] name = "uniffi_macros" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb8617ee814de22caf7417bf514715ba0b3f46bd9d5a5d794413fd8282cb737" +checksum = "5b855a58da153739ce6e863f6e296edc3716a093768c4d3d957f17f5e4317c60" dependencies = [ "camino", "fs-err", @@ -2822,9 +2870,9 @@ dependencies = [ [[package]] name = "uniffi_meta" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58d5b94fc92803d21b2928bd15c6f06e57609b95caf98ea561c99cda1b6d2a25" +checksum = "af0c88664a9cb9559856f5a250283c9708923b303170e2e5c7db8f4ad65e9459" dependencies = [ "anyhow", "siphasher", @@ -2834,9 +2882,9 @@ dependencies = [ [[package]] name = "uniffi_pipeline" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "032739b3ec725576914c15899dedaf080163ced86b6934566c20ec2b20ce90ca" +checksum = "d00f5c044b4a3dca0b1226c92ddaeea626f337470e22180dd182160c87a06b0b" dependencies = [ "anyhow", "heck", @@ -2847,9 +2895,9 @@ dependencies = [ [[package]] name = "uniffi_udl" -version = "0.31.2" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a1d0a0252ce1af9e8ce78ba67ac0d8937fb2bedaf10cbddd43d3614d06ec6" +checksum = "55dfd9c778d6b39cb5acd541d9ff63431974035d2bad83c897b766a6ee3152ac" dependencies = [ "anyhow", "textwrap", @@ -2885,9 +2933,9 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f86fd172ccca569e458f61b6bdd6220965a9ef36e672a6852953b51a0e1583be" +checksum = "841583fc36089d7d59419568ae157f43a5a03a2e5a81ba87c77d1596ef46e922" dependencies = [ "base64", "http", @@ -3035,18 +3083,18 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" +checksum = "58ec80e73fd8baf57bf0d9615554c75348bda990d6d5bbeab964dd068319fecb" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +checksum = "1c1c8e20c8a38fc7d65abfe74eb7280e4aa667e8eec8bc84996d2874810748d9" dependencies = [ "rustls-pki-types", ] @@ -3218,19 +3266,13 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.15" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" - [[package]] name = "wit-bindgen" version = "0.57.1" @@ -3281,9 +3323,9 @@ checksum = "e13084392c5e4bc371903e2935a5eaeed24905a7511356b883835e18a78f6879" [[package]] name = "zip" -version = "8.6.0" +version = "9.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b" +checksum = "6e04976da629d3b04204ba8105b396a193af8ad2583b2c79bfb3ab8af580a11e" dependencies = [ "aes", "bzip2", @@ -3296,6 +3338,7 @@ dependencies = [ "indexmap", "lzma-rust2", "memchr", + "nix", "pbkdf2", "ppmd-rust", "sha1", @@ -3332,27 +3375,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.3" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +checksum = "db3ae9bf90af6e40197bef767eeefc46ad6397420fe873830bd85e5fbbfb3c70" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.3.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d80649ab6db9d9f6f9c80a40becd948eda4714a0a5ac8c4d157a32231c7882" +checksum = "ded520f16b29e1a9b771c722221b2b0a0398c2316d9bb3c42b458a5414d7434b" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.1.1+zstd.1.5.7" +version = "2.1.2+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeec9eaf2dffbbd09201e23bd0ffcbaa33bb8e9266a10734fd7ed90a85eca078" +checksum = "481ada9c543b2323cbb7bbdbb5249177fbf0188ed959ed2c15e4b22421c84ed3" dependencies = [ "cc", "pkg-config", diff --git a/bindings/dotnet/Cargo.toml b/bindings/dotnet/Cargo.toml index e5493a0..04439f0 100644 --- a/bindings/dotnet/Cargo.toml +++ b/bindings/dotnet/Cargo.toml @@ -18,10 +18,10 @@ crate-type = ["cdylib"] [dependencies] bernard-ledit = { path = "../../core", features = ["full"] } -uniffi = { version = "0.31.1" } +uniffi = { version = "0.32.1" } [build-dependencies] -uniffi = { version = "0.31.1", features = ["build"] } +uniffi = { version = "0.32.1", features = ["build"] } [lints] workspace = true diff --git a/bindings/php/Cargo.toml b/bindings/php/Cargo.toml index c645343..44b5e82 100644 --- a/bindings/php/Cargo.toml +++ b/bindings/php/Cargo.toml @@ -18,13 +18,16 @@ crate-type = ["cdylib"] [dependencies] bernard-ledit = { path = "../../core", features = ["full"] } -ext-php-rs = "=0.16.1" +ext-php-rs = "=0.16.3" [build-dependencies] -ext-php-rs = { version = "=0.16.1", features = ["closure"] } +ext-php-rs = { version = "=0.16.3", features = ["closure"] } [lints] workspace = true [features] -static-pdfium = ["bernard-ledit/static-pdfium"] +static-link = ["bernard-ledit/static-link"] +static-pdfium = ["static-link", "bernard-ledit/static-pdfium"] +static-pdfium-libcxx = ["static-link", "bernard-ledit/static-pdfium-libcxx"] +static-pdfium-msvc = ["static-link", "bernard-ledit/static-pdfium-msvc"] diff --git a/bindings/php/justfile b/bindings/php/justfile index 5801039..921502a 100644 --- a/bindings/php/justfile +++ b/bindings/php/justfile @@ -1,36 +1,16 @@ set shell := ["bash", "-c"] -# List the default tasks -[private] -default: - @just --list - -[private] -php-ext-dir: - #!/usr/bin/env bash - set -euo pipefail - php -r 'echo ini_get("extension_dir");' - ext_name := if os() == "macos" { "libbernard_ledit_php.dylib" } else if os() == "windows" { "bernard_ledit_php.dll" } else { "libbernard_ledit_php.so" } ext_debug := "../../target/debug/" + ext_name ext_release := "../../target/release/" + ext_name +# `php -n` skips php.ini, so the extensions the test suite needs are loaded explicitly. php_test_exts := "-d extension=dom -d extension=xml -d extension=mbstring -d extension=tokenizer -d extension=ctype -d extension=xmlwriter" -# Builds the PHP extension (debug, dynamic pdfium) - fast inner dev loop -build: - cargo build -p bernard-ledit-php +static_feature := if os() == "macos" { "static-pdfium-libcxx" } else if os() == "windows" { "static-pdfium-msvc" } else { "static-pdfium" } -# Builds the PHP extension in release mode (dynamic pdfium) -build-release: - cargo build -p bernard-ledit-php --release - -# Builds the PHP extension in release mode with pdfium statically linked. -# Requires PDFIUM_STATIC_LIB_PATH=