forked from denzp/rustc-llvm-proxy
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathlib.rs
110 lines (104 loc) · 3.48 KB
/
lib.rs
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
#![deny(warnings)]
#![allow(
non_snake_case,
unused_imports,
unused_macros,
deprecated,
clippy::missing_safety_doc
)]
//! This is a **fork** of the [rustc-llvm-proxy](https://github.com/denzp/rustc-llvm-proxy) crate.
//!
//! Dynamically proxy LLVM calls into Rust own shared library! 🎉
//!
//! ## Use cases
//! Normally there is no much need for the crate, except a couple of exotic cases:
//!
//! * Your crate is some kind build process helper that leverages LLVM (e.g. [bpf-linker](https://github.com/aya-rs/bpf-linker)),
//! * Your crate needs to stay up to date with Rust LLVM version (again [bpf-linker](https://github.com/aya-rs/bpf-linker)),
//! * You would prefer not to have dependencies on host LLVM libs (as always [bpf-linker](https://github.com/aya-rs/bpf-linker)).
//!
//! ## Usage
//! First, you need to make sure no other crate links your binary against system LLVM library.
//! In case you are using `llvm-sys`, this can be achieved with a special feature:
//!
//! ``` toml
//! [dependencies.llvm-sys]
//! version = "70"
//! features = ["no-llvm-linking"]
//! ```
//!
//! Then all you need to do is to include the crate into your project:
//!
//! ``` toml
//! [dependencies]
//! rustc-llvm-proxy = "0.4"
//! ```
//!
//! ``` rust
//! extern crate aya_rustc_llvm_proxy;
//! ```
use libloading::Library;
pub mod init;
static SHARED_LIB: std::sync::LazyLock<Library> = std::sync::LazyLock::new(|| {
for (var, is_bin) in [
("LD_LIBRARY_PATH", false),
("DYLD_FALLBACK_LIBRARY_PATH", false),
("PATH", true),
] {
let Some(unparsed) = std::env::var_os(var) else {
continue;
};
let paths = std::env::split_paths(&unparsed);
for mut path in paths {
if is_bin {
path.pop();
path.push("lib");
}
let files = match path.read_dir() {
Ok(files) => files,
Err(err) => {
eprintln!("unable to read dir {}: {}", path.display(), err);
continue;
}
};
for (i, file) in files.enumerate() {
let file = match file {
Ok(file) => file,
Err(err) => {
eprintln!(
"unable to read dir entry {} in {}: {}",
i,
path.display(),
err
);
continue;
}
};
let path = file.path();
let Some(stem) = path.file_stem() else {
continue;
};
let Some(stem) = stem.to_str() else { continue };
if stem.starts_with("libLLVM") {
match unsafe { Library::new(&path) } {
Ok(library) => return library,
Err(error) => {
eprintln!(
"unable to open LLVM shared lib {}: {}",
path.display(),
error
);
continue;
}
}
}
}
}
}
panic!("unable to find LLVM shared lib")
});
/// LLVM C-API symbols with dynamic resolving.
pub mod proxy {
use super::SHARED_LIB;
include!(concat!(env!("OUT_DIR"), "/llvm_gen.rs"));
}