#70/#74 switched the Linux release arm to erpl-proto, statically linked. macOS and Windows still bundle the SAP NW RFC SDK. This is the plan to finish the job.
Where we actually stand
Worth stating plainly, because the gap is bigger than "flip two matrix entries":
- erpl-proto's CI is Ubuntu-only.
scripts/check-cross-targets.sh exists but is not run in CI, and it is cargo check anyway — the shim has never been compiled for macOS or Windows, let alone linked or run.
- erpl-rev's CI covers Linux and Windows, both on the SDK. macOS is only built in the release workflow.
- Live SAP verification exists only on Linux, against the local A4H trial. GitHub-hosted macOS/Windows runners cannot reach it.
One thing is better than feared: the shim's dependency tree is just erpl-proto → erpl-proto-wire + serde. No TLS, no async runtime, no platform-specific crates. The portable surface is small.
Phase 0 — make erpl-proto build on those platforms (erpl-proto)
Nothing downstream is worth attempting until this is green.
- Add macOS and Windows jobs to erpl-proto's CI:
cargo build --release -p erpl-proto-nwrfc (both staticlib and cdylib) and cargo test --workspace.
- Actually run
scripts/check-cross-targets.sh in CI — today it never runs.
- Record
cargo rustc -- --print native-static-libs per platform. Linux prints -lgcc_s -lutil -lrt -lpthread -lm -ldl -lc, all implicit, which is why Linux linked with no extra work. Windows will not be so kind, and Phase 1 needs this list rather than a guess.
- Run
tools/abi_probe.c and scripts/check-header-abi.sh / check-header-symbols.sh per platform. This is the highest-value check in the whole plan: it compares 96 sizes, offsets and constants against SAP's own header. It needs the SAP SDK headers on those runners, which the S3/OIDC path already used by erpl-rev can supply.
The specific thing to watch: erpl-proto's header defines SAP_UC as uint16_t unconditionally, while SAP's Windows header uses wchar_t. Both are 16-bit on Windows so it should agree — but "should" is exactly what the probe is for.
Phase 1 — link it (erpl-rev)
- CMake: append the platform's native-static-libs to
SAP_LIBS under RFC_LINK=static, taken from Phase 0's output. The archive is currently linked alone, which only works because Linux needs nothing extra.
- Windows CRT: erpl-rev builds with vcpkg
x64-windows-static-md (dynamic CRT) and Rust's MSVC target defaults to the dynamic CRT, so they should match. Verify rather than assume — a mismatch produces duplicate-symbol noise that is easy to misread.
- Make the bundle assertion portable.
ldd (Linux) / otool -L (macOS) / dumpbin /dependents (Windows), all asserting no sapnwrfc, sapucum or ICU. As written it would simply fail on macOS.
bundle.ps1 needs the equivalent of the - sentinel stage_runtime.sh already accepts, so the Windows payload can be duckdb.dll alone.
- Flip
rfc: proto for the osx and windows matrix entries and drop their SDK fetch and AWS steps, exactly as the Linux arm did.
Phase 2 — what evidence justifies shipping
This is the real decision, not the code.
| Evidence |
Proves |
Available? |
CI build + link + --smoke |
it loads, one call works |
yes, cheap |
| erpl-proto conformance suite per platform |
the wire codec, capture-driven |
yes, no SAP needed |
| ABI probe per platform |
the C ABI matches SAP's header |
yes, needs SDK headers |
| Live 13-stage e2e |
it actually replicates from SAP |
no — not from a hosted runner |
The first three are necessary and not sufficient. The registered-server path — gateway registration, the RFC callback loop — is the product, and none of the three exercises it.
Options for the last row, in increasing order of effort: a self-hosted macOS runner; exposing the A4H trial over a tailnet so hosted runners can reach it (erpl_tunnel already does this trick); or one manual live run per platform on a real Mac and a real Windows box.
Recommendation: the first three as the CI gate, plus one manual live e2e per platform before flipping the release default. Shipping an RFC stack whose first contact with a real SAP system is a customer's is not a trade worth making for two platforms.
Phase 3 — release and bundles
Payloads become DuckDB alone on all three. Update the release-notes body, which currently states that macOS and Windows bundle the SDK. Keep the per-platform --smoke with no external libraries on the loader path.
Phase 4 — blog post
The published caveat is accurate today (Linux switched, macOS/Windows deliberately not). Once all three ship it needs a final pass: the SDK is gone everywhere, and it should say what evidence stands behind each platform rather than implying they are equally proven.
Rough effort
Phase 0 ~half a day, Phase 1 ~half a day, Phase 3/4 small. Phase 2 dominates and depends on the evidence decision above.
#70/#74 switched the Linux release arm to
erpl-proto, statically linked. macOS and Windows still bundle the SAP NW RFC SDK. This is the plan to finish the job.Where we actually stand
Worth stating plainly, because the gap is bigger than "flip two matrix entries":
scripts/check-cross-targets.shexists but is not run in CI, and it iscargo checkanyway — the shim has never been compiled for macOS or Windows, let alone linked or run.One thing is better than feared: the shim's dependency tree is just
erpl-proto→erpl-proto-wire+serde. No TLS, no async runtime, no platform-specific crates. The portable surface is small.Phase 0 — make erpl-proto build on those platforms (erpl-proto)
Nothing downstream is worth attempting until this is green.
cargo build --release -p erpl-proto-nwrfc(bothstaticlibandcdylib) andcargo test --workspace.scripts/check-cross-targets.shin CI — today it never runs.cargo rustc -- --print native-static-libsper platform. Linux prints-lgcc_s -lutil -lrt -lpthread -lm -ldl -lc, all implicit, which is why Linux linked with no extra work. Windows will not be so kind, and Phase 1 needs this list rather than a guess.tools/abi_probe.candscripts/check-header-abi.sh/check-header-symbols.shper platform. This is the highest-value check in the whole plan: it compares 96 sizes, offsets and constants against SAP's own header. It needs the SAP SDK headers on those runners, which the S3/OIDC path already used by erpl-rev can supply.The specific thing to watch: erpl-proto's header defines
SAP_UCasuint16_tunconditionally, while SAP's Windows header useswchar_t. Both are 16-bit on Windows so it should agree — but "should" is exactly what the probe is for.Phase 1 — link it (erpl-rev)
SAP_LIBSunderRFC_LINK=static, taken from Phase 0's output. The archive is currently linked alone, which only works because Linux needs nothing extra.x64-windows-static-md(dynamic CRT) and Rust's MSVC target defaults to the dynamic CRT, so they should match. Verify rather than assume — a mismatch produces duplicate-symbol noise that is easy to misread.ldd(Linux) /otool -L(macOS) /dumpbin /dependents(Windows), all asserting nosapnwrfc,sapucumor ICU. As written it would simply fail on macOS.bundle.ps1needs the equivalent of the-sentinelstage_runtime.shalready accepts, so the Windows payload can beduckdb.dllalone.rfc: protofor theosxandwindowsmatrix entries and drop their SDK fetch and AWS steps, exactly as the Linux arm did.Phase 2 — what evidence justifies shipping
This is the real decision, not the code.
--smokeThe first three are necessary and not sufficient. The registered-server path — gateway registration, the RFC callback loop — is the product, and none of the three exercises it.
Options for the last row, in increasing order of effort: a self-hosted macOS runner; exposing the A4H trial over a tailnet so hosted runners can reach it (
erpl_tunnelalready does this trick); or one manual live run per platform on a real Mac and a real Windows box.Recommendation: the first three as the CI gate, plus one manual live e2e per platform before flipping the release default. Shipping an RFC stack whose first contact with a real SAP system is a customer's is not a trade worth making for two platforms.
Phase 3 — release and bundles
Payloads become DuckDB alone on all three. Update the release-notes body, which currently states that macOS and Windows bundle the SDK. Keep the per-platform
--smokewith no external libraries on the loader path.Phase 4 — blog post
The published caveat is accurate today (Linux switched, macOS/Windows deliberately not). Once all three ship it needs a final pass: the SDK is gone everywhere, and it should say what evidence stands behind each platform rather than implying they are equally proven.
Rough effort
Phase 0 ~half a day, Phase 1 ~half a day, Phase 3/4 small. Phase 2 dominates and depends on the evidence decision above.