Skip to content

Ship the iOS and web PDFium binaries inside the published artefacts - #13

Merged
kdroidFilter merged 2 commits into
masterfrom
fix/packaged-ios-web-binaries
Aug 30, 2026
Merged

Ship the iOS and web PDFium binaries inside the published artefacts#13
kdroidFilter merged 2 commits into
masterfrom
fix/packaged-ios-web-binaries

Conversation

@kdroidFilter

Copy link
Copy Markdown
Collaborator

Closes #11.

Summary

Consumers of dev.nucleusframework:pdfium hit ld: library 'pdfium' not found on iOS and Can't resolve './pdfium_glue.mjs' on web — the published klibs shipped the Kotlin bindings but not the binaries the linker and the bundler need. Android and JVM already embedded theirs.

iOS — a static archive packed into the klib

  • pdfium.def declares staticLibraries = libpdfium.a with per-target libraryPaths, so cinterop packs the archive into default/targets/<target>/included/. The machine code travels with the artefact: no -L, no ThirdParty/ drop, no pdfium.framework to embed, nothing to codesign, no extra Xcode build phase.
  • bblanchon publishes Apple platforms as a .dylib only, and a dylib cannot be carried this way. The one prebuilt static archive available (paulocoutinhox/pdfium-lib) is compiled against Chromium's bundled libc++ but ships none of its objects, so it fails to link against Apple's libc++ with undefined std::__Cr:: symbols.
  • NucleusFramework/pdfium-binaries therefore runs bblanchon's own build harness with build_type=static — which sets pdf_is_complete_lib = true and use_custom_libcxx = false, the combination that makes the archive self-contained. It syncs from upstream daily and publishes an ios-static-<build> release per PDFium version (stripped: 16 MB per slice instead of 268 MB). :pdfium:installPdfiumIos downloads the one matching the pdfium-bblanchon pin.
  • pdfium-auto-release now defers a version bump until the matching static build exists, so master never points at a version the iOS cinterop cannot resolve.

Web — assets at the archive root

  • pdfium.wasm, pdfium_worker.mjs, pdfium_runtime.mjs and pdfium_glue.mjs are published at the resource root instead of a nested pdfium/ directory, and the glue is eval'd from Kotlin rather than imported, so webpack no longer has to resolve ./pdfium_glue.mjs and consumers need no copy task.

Removed

  • The dev.nucleusframework.pdfium Gradle plugin and its includeBuild, its CI publishing steps, EmbedPdfiumDylibTask, the klib zip-surgery task, and the LIBRARY_SEARCH_PATHS workaround in Config.xcconfig. The Xcode phase is back to the stock embedAndSignAppleFrameworkForXcode.

Test plan

  • :pdfium:check passes (includes the new packagingTest)
  • packagingTest asserts libpdfium.a inside both published cinterop klibs, no -lpdfium in the manifest, and the four web assets at the archive root — wired to the …Cinterop-pdfiumKlib packing tasks so it reads the artefacts consumers actually get
  • Published klibs are 7.0 MB each with the archive inside
  • :example:linkDebugFrameworkIosArm64 and …IosSimulatorArm64 link with isStatic = true
  • Same with isStatic = false (the configuration reported in Missing binaries #11); otool -L shows no libpdfium dependency and the FPDF code is inside the binary
  • Run the example app on a device

Note

Upstream builds the iOS objects with minos 17.0, so apps targeting below iOS 17 get a benign ld: warning: object file was built for newer iOS version. That was already the case with the dylib.

Maven consumers got `ld: library 'pdfium' not found` on iOS and
`Can't resolve './pdfium_glue.mjs'` on web: the published klibs carried the
Kotlin bindings but none of the binaries the linker and the bundler need.

iOS now links a static libpdfium.a that cinterop packs into the klib
(`staticLibraries` in pdfium.def), so nothing has to be embedded, signed or
pointed at with -L. bblanchon ships Apple platforms as a dylib only, and the
one prebuilt static archive available (paulocoutinhox/pdfium-lib) is compiled
against Chromium's bundled libc++ without shipping its objects, so it fails to
link with undefined `std::__Cr::` symbols. NucleusFramework/pdfium-binaries
therefore runs bblanchon's own harness with `build_type=static`
(`pdf_is_complete_lib = true`, `use_custom_libcxx = false`) and publishes an
`ios-static-<build>` release per PDFium version, which installPdfiumIos
downloads for the current pin.

Web serves pdfium.wasm, the worker, the runtime and the glue from the archive
root and evals the glue from Kotlin, so webpack no longer has to resolve
`./pdfium_glue.mjs` and consumers need no copy task.

PackagedBinariesTest locks both in, and the auto-release defers a version bump
until the matching static iOS build is published.
Apple cinterop cannot run on a Linux host — KGP disables cross compilation for
targets that declare cinterops — so :pdfium:check on ubuntu produced no iOS
klibs and PackagedBinariesTest failed on an empty file collection. The iOS half
now reports as skipped there and runs in a dedicated macOS pre-merge job, which
is also the host that publishes.

pdfium.dll.lib was tracked only because the `*.dll` ignore rule doesn't match
it; installPdfiumJvmResources stages both Windows import libraries from the
bblanchon archive on every build, so they were pure churn on each version bump.
@kdroidFilter
kdroidFilter merged commit 3101c8f into master Aug 30, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing binaries

1 participant