Skip to content

Add Linux build target (x64 + arm64, shared library) - #7

Merged
danglong78 merged 14 commits into
luminpdf/masterfrom
emdash/linux-build-iqgr7
Jul 3, 2026
Merged

danglong78 merged 14 commits into
luminpdf/masterfrom
emdash/linux-build-iqgr7

Conversation

@danglong78

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a Linux target to the build pipeline, producing libpdfium.so for x64 and arm64, following the same modules/*.py + make.py task pattern used for iOS/macOS/Android/WASM (modules/linux.py mirrors modules/android.py, since both are shared-library, multi-arch targets).
  • Portability across Linux distros relies on Chromium's own use_sysroot/use_custom_libcxx defaults for target_os="linux" rather than a custom base image — verified empirically against the real compiled binaries: readelf -d shows no dependency on libstdc++/libc++ (statically linked), and the glibc floor is 2.16 (x64) / 2.17 (arm64), well below even Ubuntu 20.04's. A regression guard for this was added to run_task_test.
  • Adds .github/workflows/linux.yml (native ubuntu-24.04 runner, no Docker, matching the other workflows) and docs/BUILD_LINUX.md, and updates the README roadmap/platforms list.
  • Along the way, found and documented a real Chromium/depot_tools limitation: PDFium's DEPS unconditionally fetches a buildtools/reclient CIPD package with no linux-arm64 build, so gclient sync fails outright on any arm64 Linux host (not project-specific — affects local dev via arm64 VMs, e.g. on Apple Silicon). Documented the amd64-VM workaround in docs/BUILD_LINUX.md.

Test plan

  • modules/config.py/modules/common.py build-arg changes verified via direct Python import/print checks
  • modules/linux.py + make.py wiring verified via python3 -c "import make" and python3 make.py -h
  • Real PDFium checkout for the Linux target completed successfully (gclient sync + both amd64/arm64 Chromium sysroots fetched)
  • Real compile: x64 built natively, arm64 cross-compiled — both produced valid ELF 64-bit shared objects (file confirmed x86-64 / ARM aarch64 respectively)
  • Real install-linux / test-linux / archive-linux run end-to-end, producing a real linux.tgz with lib/{x64,arm64}/libpdfium.so + include/ headers
  • Portability confirmed empirically via readelf -d (no libstdc++/libc++ dependency) and objdump -T (glibc floor 2.16/2.17)
  • .github/workflows/linux.yml YAML syntax validated
  • First real GitHub Actions run (not yet triggered — this PR will exercise it)

danglong78 and others added 14 commits July 3, 2026 11:28
Specs the shared-library, multi-arch (x64/arm64) build target mirroring
the Android module structure, with a portable-glibc build strategy for
distribution to arbitrary Linux app/server consumers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Research during plan-writing found the portable-glibc goal is already
met by Chromium's default use_sysroot/use_custom_libcxx behavior for
target_os=linux -- no pinned old base image or manual static-link
flags are needed, only an explicit arm64 sysroot fetch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Task-by-task plan mirroring the Android module structure, with an
empirical build spike (arm64 native, then x64 cross-compile) in the
existing OrbStack VM before wiring up install/test/archive/CI/docs,
so the arm64-sysroot and shared-library-naming assumptions get
validated early rather than assumed throughout.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds modules/linux.py mirroring modules/android.py, implementing the
six task functions (build_pdfium, patch, build, install, test,
archive) for Linux. Wires the module into make.py's import list,
docstring Tasks list, and task dispatch chain between the Android and
WASM sections.
Task 3's first execution attempt discovered that PDFium's DEPS
unconditionally fetches a buildtools/reclient CIPD package with no
linux-arm64 build for the pinned version, so gclient sync fails
outright on an arm64 Linux host regardless of target arch. Switched
the plan (and the OrbStack doc section it produces) to a fresh amd64
VM, which also matches CI's ubuntu-24.04 (x64) runner architecture.
Swapped Task 4/5's native/cross-compile arch assignments to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- modules/linux.py: run_task_test() now fails the build if libpdfium.so
  links against libstdc++ or libc++, guarding the static-libc++ linking
  guarantee (use_custom_libcxx) that was verified empirically against the
  build artifacts (readelf/objdump showed no libstdc++.so/libc++.so in
  NEEDED, glibc floor 2.16/2.17) but had no automated check.
- .github/workflows/linux.yml: install pkg-config and libglib2.0-dev
  explicitly, since the existing "PDFium build dependencies" step
  (echo n | install-build-deps.sh) always hits the script's confirmation
  prompt and aborts without installing anything — it provides no real
  guarantee these packages are present on the runner.
The design spec still said `orb create ubuntu`, which defaults to the
host's architecture (arm64 on Apple Silicon). Task 3's implementation
found that PDFium's DEPS unconditionally fetches a buildtools/reclient
CIPD package with no linux-arm64 build, so gclient sync fails on an
arm64 host. docs/BUILD_LINUX.md and the implementation plan were already
corrected to `orb create -a amd64 ubuntu`; this brings the design spec
in line and notes the correction.
This project's format task (make.py format) uses black; the readelf
check added in the portability regression guard wasn't yet formatted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@danglong78
danglong78 changed the base branch from master to luminpdf/master July 3, 2026 07:22
@danglong78
danglong78 merged commit 97e925a into luminpdf/master Jul 3, 2026
10 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.

1 participant