1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! Raw FFI bindings to `libempyrean`, the C shared library for empyrean's
//! astrodynamics engine.
//!
//! Prefer the safe wrapper crate [`empyrean`](https://docs.rs/empyrean)
//! unless you need direct access to the C ABI.
//!
//! # How `libempyrean` is loaded
//!
//! The library is opened at run time with [`libloading`] — there is **no**
//! link-time native dependency and no `install_name_tool` / `patchelf` / rpath /
//! `LD_LIBRARY_PATH` setup. Its path is resolved on first use, in order:
//!
//! 1. `EMPYREAN_LIB` — an explicit path to the library, passed straight to
//! `dlopen` (override / offline use / a locally built engine). A bare name
//! defers to the OS loader search; pass a full path for an exact file.
//! 2. A `libempyrean.{dylib,so}` sitting next to the **currently loaded module**
//! — the `.so`/`.dylib`/executable that statically links this crate — located
//! via `dladdr`. This makes prebuilt, relocatable artifacts self-contained:
//! a Python wheel can bundle the engine beside its extension and it is found
//! with no build-machine path baked in.
//! 3. The absolute path recorded at build time (`LIB_PATH`): a sibling
//! `../target/release` build, an `EMPYREAN_LIB_DIR` override, or a
//! version-matched, checksum-pinned prebuilt downloaded (in pure Rust — no
//! `curl`/`tar`) into `~/.cache/empyrean`. This covers `cargo add empyrean`,
//! where the build script runs on the consumer's own machine.
//!
//! The bindings are pre-generated and committed, so building needs no C header
//! and no `libclang` / `bindgen`. Callers use the free `empyrean_*` functions
//! exactly as with a statically linked library; each delegates to the loaded
//! [`EmpyreanLib`].
// The generated dynamic-loading methods call the loaded fn pointers directly in
// their (unsafe) bodies; this is generated FFI, so allow the 2024 granularity lint.
// The generated bindings and the free-function shims are `pub unsafe fn`s without
// per-function `# Safety` sections, and mirror the C ABI's wide argument lists;
// they are generated FFI, not hand-authored API.
use ;
use OnceLock;
// Dynamic-loading bindings: `struct EmpyreanLib` + per-function methods + the
// shared type/const definitions.
include!;
// Absolute path to libempyrean recorded by the build script — resolution
// fallback #3 (see the module docs).
include!;
static LIB: = new;
/// Platform file name of the engine library.
const LIB_FILENAME: &str = if cfg! else if cfg! else ;
// A data symbol whose address lands in *this* module, so `dladdr` reports the
// shared object / executable that statically links empyrean-sys.
static SELF_MARKER: u8 = 0;
/// Directory of the currently loaded module — the `.so`/`.dylib`/executable that
/// links this crate — via `dladdr`. `None` if it cannot be determined.
/// Resolve the engine library path at run time (see the module docs for the
/// full resolution order).
/// The loaded `libempyrean`, opened lazily on first use.
///
/// Panics if the library cannot be opened. The path is resolved from the host
/// environment and the build, so a failure here means a broken or incomplete
/// install (e.g. a prebuilt artifact missing its bundled engine) — surfaced
/// loudly rather than papered over.
pub use *;