feat(pdftract-uyhq7): scaffold libpdftract cdylib+staticlib crate

Add pdftract-libpdftract as 4th workspace member with dual crate-type
configuration (cdylib + staticlib) for C/C++ SDK flexibility.

Changes:
- Create crates/pdftract-libpdftract/Cargo.toml with cdylib+staticlib
- Create crates/pdftract-libpdftract/src/lib.rs scaffold
- Update root Cargo.toml workspace.members
- Configure [lib] name="pdftract" for correct artifact naming

Artifacts produced:
- target/debug/libpdftract.so (shared, cdylib)
- target/debug/libpdftract.a (static, staticlib)

Acceptance criteria:
- PASS: cargo build -p pdftract-libpdftract produces libpdftract.so/.a
- PASS: Workspace cargo build builds all 4 crates without regression
- PASS: cargo metadata shows pdftract-libpdftract in workspace members
- PASS: nm -D shows no exported symbols (empty API scaffold)

References: pdftract-uyhq7, Phase SDK epic

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-05-23 07:29:29 -04:00
parent 29348ce21d
commit f26f9e3c0f
4 changed files with 104 additions and 1 deletions

View file

@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = ["crates/pdftract-core", "crates/pdftract-cli", "crates/pdftract-py"]
members = ["crates/pdftract-core", "crates/pdftract-cli", "crates/pdftract-py", "crates/pdftract-libpdftract"]
exclude = ["tests/fixtures/generate_lzw_fixtures.rs"]
[workspace.package]

View file

@ -0,0 +1,17 @@
[package]
name = "pdftract-libpdftract"
version.workspace = true
license.workspace = true
edition = "2021"
[lib]
name = "pdftract"
crate-type = ["cdylib", "staticlib"]
[dependencies]
pdftract-core = { path = "../pdftract-core" }
serde_json = "1"
libc = "0.2"
[build-dependencies]
cbindgen = "0.27"

View file

@ -0,0 +1,14 @@
//! pdftract-libpdftract — C/C++ FFI library for pdftract.
//!
//! This crate provides the extern "C" API surface for C/C++ integrations.
//! It compiles to both shared (cdylib) and static (staticlib) libraries,
//! allowing downstream projects to link dynamically or statically.
//!
//! ## Output artifacts
//!
//! - Linux: `target/debug/libpdftract.so` (shared), `target/debug/libpdftract.a` (static)
//! - macOS: `target/debug/libpdftract.dylib` (shared), `target/debug/libpdftract.a` (static)
//! - Windows: `target/debug/pdftract.dll` (shared), `target/debug/pdftract.lib` (static)
// Public API modules will be added here in sibling beads.
// This scaffold provides the minimal structure for cdylib + staticlib builds.

72
notes/pdftract-uyhq7.md Normal file
View file

@ -0,0 +1,72 @@
# pdftract-uyhq7: libpdftract cdylib + staticlib crate scaffold
## Summary
Created the `pdftract-libpdftract` crate as the fourth workspace member of the pdftract repo. This crate provides the FFI surface for C/C++ integrations, compiling to both shared (cdylib) and static (staticlib) libraries.
## Files Created
1. `crates/pdftract-libpdftract/Cargo.toml` - Crate manifest with:
- `crate-type = ["cdylib", "staticlib"]`
- `name = "pdftract"` in [lib] section (ensures libpdftract.so/.a naming)
- Dependencies: pdftract-core, serde_json, libc
- Build dependency: cbindgen 0.27
2. `crates/pdftract-libpdftract/src/lib.rs` - Empty scaffold with documentation
3. Updated `Cargo.toml` - Added `crates/pdftract-libpdftract` to workspace.members
## Verification Results
### PASS: cargo build -p pdftract-libpdftract produces expected artifacts
```bash
$ ls -la target/debug/libpdftract.a target/debug/libpdftract.so
-rw-r--r-- 2 coding users 21848552 May 23 07:28 target/debug/libpdftract.a
-rwxr-xr-x 2 coding users 4293504 May 23 07:28 target/debug/libpdftract.so
```
- `libpdftract.so` (4.3 MB) - shared library (cdylib)
- `libpdftract.a` (21.8 MB) - static library (staticlib)
- `readelf -h` confirms ELF64 shared library format
### PASS: Workspace cargo build builds all 4 crates
```bash
$ cargo build --workspace
Compiling pdftract-core v0.1.0
Compiling pdftract-cli v0.1.0
Compiling pdftract-py v0.1.0
Compiling pdftract-libpdftract v0.1.0
Finished `dev` profile [unoptimized + debuginfo] target(s) in 22.87s
```
All existing crates build successfully; no regressions.
### PASS: cargo metadata shows pdftract-libpdftract in workspace
```bash
$ cargo metadata --format-version 1 | python3 -c "import json,sys; w=json.load(sys.stdin); print(len(w['workspace_members']))"
4
```
Workspace members: pdftract-core, pdftract-cli, pdftract-py, pdftract-libpdftract
### PASS: Symbol table shows no exported symbols (expected for empty API)
```bash
$ nm -D target/debug/libpdftract.so | grep -E "^[0-9a-f]+ [TW]"
# (no output - no exported text symbols)
```
This is expected as the acceptance criteria states: "the API is empty in this bead; sibling bead populates"
## Artifact Naming Convention
The crate name `pdftract-libpdftract` produces artifacts named `libpdftract.so/.a` (not `libpdftract-libpdftract`) due to the `[lib] name = "pdftract"` directive in Cargo.toml. This matches the expected naming convention for the C/C++ SDK.
## Next Steps
- Sibling bead will populate the extern "C" API surface
- cbindgen will be configured to generate pdftract.h header
- pkg-config file will be added for downstream integrations