Skip to content

refactor(c/sedona-proj): replace C dynamic loading with pure Rust using libloading#672

Merged
Kontinuation merged 6 commits intoapache:mainfrom
Kontinuation:refactor/proj-dyn-loading
Mar 3, 2026
Merged

refactor(c/sedona-proj): replace C dynamic loading with pure Rust using libloading#672
Kontinuation merged 6 commits intoapache:mainfrom
Kontinuation:refactor/proj-dyn-loading

Conversation

@Kontinuation
Copy link
Member

@Kontinuation Kontinuation commented Feb 28, 2026

Summary

Replace the C-based dlopen/dlsym dynamic PROJ loading (proj_dyn.c/proj_dyn.h) with a pure Rust implementation using the libloading crate. This eliminates ~250 lines of C code while maintaining the same ProjApi struct-of-function-pointers architecture used by all existing call sites.

Approach

The libloading crate provides safe, cross-platform dynamic library loading (dlopen/LoadLibrary). Each PROJ symbol is loaded via a load_fn! macro that:

  1. Loads the symbol as a raw *const () pointer
  2. Transmutes it to the expected function pointer type
  3. Stores it in the existing ProjApi #[repr(C)] struct

The Library handle is stored as _lib: Option<Library> in the Rust ProjApi wrapper — Some when loaded from a shared library, None when using proj-sys. This ensures the library stays loaded for the lifetime of the function pointers.

Tests

Temporarily enabled python-wheels test and passed on all major platforms: https://github.com/apache/sedona-db/actions/runs/22518558723

Upcoming Changes

We'll implement c/sedona-gdal using similar approach.

… libloading

Replace the C-based dlopen/dlsym dynamic PROJ loading (proj_dyn.c/h) with
a pure Rust implementation using the libloading crate. This eliminates the
cc build dependency and ~250 lines of C code while maintaining the same
ProjApi struct-of-function-pointers architecture.

Changes:
- Add dyn_load.rs with load_fn! macro and load_proj_from_path()
- Remove build.rs, proj_dyn.c, proj_dyn.h
- Remove extern C { proj_dyn_api_init } from proj_dyn_bindgen.rs
- Update ProjApi to hold Option<Library> for shared library lifetime
- Replace C release callback in Drop with automatic Library drop
- Replace cc build-dependency with libloading in dependencies
@Kontinuation Kontinuation marked this pull request as ready for review February 28, 2026 11:43
@Kontinuation Kontinuation requested a review from Copilot February 28, 2026 11:43
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors sedona-proj’s dynamic PROJ loading by removing the C-based dlopen/dlsym shim and replacing it with a Rust-only loader built on libloading, while preserving the existing ProjApi function-pointer table consumed by the rest of the crate.

Changes:

  • Removed the C dynamic loader (proj_dyn.c/proj_dyn.h) and the Rust FFI entrypoint that initialized it.
  • Added a Rust dyn_load module that loads required PROJ symbols via libloading and returns (Library, ProjApi) to keep the library alive.
  • Updated crate/workspace dependencies: removed cc build dependency and added libloading.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
c/sedona-proj/src/proj_dyn_bindgen.rs Removes the FFI declaration for the old C initializer.
c/sedona-proj/src/proj_dyn.h Deletes the C header for the old dynamic loader API.
c/sedona-proj/src/proj_dyn.c Deletes the old C implementation of symbol loading and library lifetime management.
c/sedona-proj/src/proj.rs Switches shared-library initialization to the new Rust loader and keeps the Library handle alive in ProjApi.
c/sedona-proj/src/lib.rs Adds the new dyn_load module.
c/sedona-proj/src/dyn_load.rs New Rust implementation of symbol loading using libloading.
c/sedona-proj/build.rs Removes the build script that compiled the deleted C code.
c/sedona-proj/Cargo.toml Drops cc build-dependency and adds libloading.
Cargo.toml Adds libloading to workspace dependencies.
Cargo.lock Locks libloading and updates sedona-proj dependency set accordingly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Kontinuation Kontinuation force-pushed the refactor/proj-dyn-loading branch from b8aeb74 to 3b05eac Compare February 28, 2026 12:00
Copy link
Member

@paleolimbot paleolimbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@paleolimbot paleolimbot changed the title refactor(sedona-proj): replace C dynamic loading with pure Rust using libloading refactor(c/sedona-proj): replace C dynamic loading with pure Rust using libloading Mar 3, 2026
@Kontinuation Kontinuation merged commit a875098 into apache:main Mar 3, 2026
17 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.

3 participants