Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Ship a dataframe application

A compiled program that uses std.dataframe needs libplenty_dataframe_v1.so on Linux, libplenty_dataframe_v1.dylib on macOS, or plenty_dataframe_v1.dll on Windows at run time. Ship the same engine you compiled against, from the matching Plenty release, beside your executable. End users need the host C libraries, but no Plenty compiler, Rust, Cargo or cc. Programs without reachable dataframe operations need no engine.

Bundle the executable and engine

With a release compiler, the engine and its notices are already in bin/:

plenty --compile analysis.plenty --dist my-app
./my-app/analysis

my-app must not exist. Plenty stages and publishes the executable, the exact engine used for linking, and its packaged notices together. No reachable engine calls means no engine files; reachable linear algebra calls also add the linalg engine and its notices. See application distributions for metadata checks, supported input layouts, local-build packaging and CLI restrictions. A bare installed library without notices is not enough for --dist.

The resulting directory can be archived, installed elsewhere and renamed:

my-app/
  analysis
  libplenty_dataframe_v1.so
  dataframe-notices/
    engine.json
    LICENSE-MIT
    LICENSE-APACHE
    THIRD-PARTY-NOTICES.md
    licenses/rust/...

Keep the engine notices with distributions of the library, alongside any notices your own application needs. The release archive’s README contains the same distribution command for users who have no source checkout.

Test on the oldest supported system

The prebuilt engine targets x86-64 and ARM64 Linux, glibc 2.28 or later and libgcc_s.so.1. The experimental Windows x86-64 engine requires Windows 10 or Windows Server 2016 or later and the MSVC runtime. The experimental macOS ARM64 engine requires macOS 11 or later. musl/Alpine remains unsupported. Your executable links against the build machine’s C libraries and can require a newer glibc. Compile and test the application on the oldest distribution you support; a baseline-compatible engine alone does not make your executable portable. No particular memory bound is implied by the shared-library format.

Test the bundle in a clean machine or container without your original Plenty installation. Run it from a different working directory, then move the bundle and run it again. Test a missing-library failure too. The release smoke tests exercise app-only relocation and a native Parquet query on each supported test distribution after removing the compiler and original engine location.

How library lookup works

This applies to every native engine. On macOS ARM64, --dist produces analysis, libplenty_dataframe_v1.dylib and dataframe-notices/. Ordinary compilation also copies the dylib beside the executable. The dylib identifies itself as @rpath/libplenty_dataframe_v1.dylib; the executable searches @loader_path (its own directory). No original build directory is retained. Keep the linker-signed dylib unmodified. Loader environment variables such as DYLD_LIBRARY_PATH can affect lookup; remove them when testing relocation.

On Windows, --dist produces analysis.exe, plenty_dataframe_v1.dll and dataframe-notices/. Ordinary compilation also copies the DLL beside its executable. Windows loader search rules apply; the application directory supplies the bundled DLL. Test with the compiler directory removed from PATH.

On Linux, distribution output embeds an ELF RUNPATH of only the executable’s own directory ($ORIGIN), so a missing bundled library cannot fall back to the original engine directory. A sibling lib/ is not searched automatically.

For manual deployment with ordinary --compile analysis.plenty -o analysis, copy the exact selected library beside the executable and all the archive’s notices into dataframe-notices/, as in the layout above. Ordinary output still searches $ORIGIN then the build-time engine directory; that fallback can mask a missing bundled library on the development machine. Prefer --dist for shipping applications.

PLENTY_DATAFRAME_ENGINE chooses an engine at compile time; setting it when running an already-built application does not affect library lookup. LD_LIBRARY_PATH and LD_PRELOAD can override RUNPATH, so remove stale overrides when testing or switching releases. Keep the application directory and library search paths trusted. System-wide library installation is also possible through the operating system’s loader configuration.

The v1 filename denotes the C ABI generation, not a promise that every release exports every operation. New operations can add symbols without changing this name. Keep releases matched and do not substitute a differently built Polars library. engine.json records the engine’s origin; --dist checks release/target/ABI metadata and the copied library checksum. Ordinary compilation does not validate its version; matching metadata is not proof of same-source identity for local builds.

FailureWhat to check
cannot open shared object file naming libplenty_dataframe_v1.soPut the matching library beside the executable
undefined reference or symbol lookup error naming pldf_v1_Check for an old engine or a loader environment override
GLIBC_2.xx not foundCheck both the application and engine’s platform requirements; rebuild on the oldest supported system

Directly emitted object files need an appropriate external link command and loader configuration; the automatic RUNPATH described here applies to executables linked by Plenty.