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
use std::env;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use serde_derive::Deserialize;
use toml;
#[derive(Deserialize)]
pub struct Manifest {
pub package: Package,
}
#[derive(Deserialize)]
pub struct Package {
pub name: String,
}
fn get_name() -> String {
let mut s = String::new();
let manifest_dir: PathBuf = env::var_os("CARGO_MANIFEST_DIR").unwrap().into();
let path = manifest_dir.join("Cargo.toml");
File::open(path).unwrap().read_to_string(&mut s).unwrap();
let manifest: Manifest = toml::from_str(&s).unwrap();
manifest.package.name
}
pub fn metabuild() {
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
let major = env::var("CARGO_PKG_VERSION_MAJOR").unwrap();
let minor = env::var("CARGO_PKG_VERSION_MINOR").unwrap();
let micro = env::var("CARGO_PKG_VERSION_PATCH").unwrap();
let prefix: PathBuf = env::var_os("CARGO_C_PREFIX")
.unwrap_or("/usr/local".into())
.into();
let libdir = env::var_os("CARGO_C_LIBDIR").map_or(prefix.join("lib"), |v| v.into());
let target_dir = env::var_os("CARGO_TARGET_DIR").map_or(
{
let manifest_dir: PathBuf = env::var_os("CARGO_MANIFEST_DIR").unwrap().into();
manifest_dir
.join("target")
.join(std::env::var("PROFILE").unwrap())
},
|v| v.into(),
);
let name = get_name();
let lines = shared_object_link_args(
&name, &major, &minor, µ, &arch, &os, &env, libdir, target_dir,
);
let link = "cargo:rustc-cdylib-link-arg=";
for line in lines {
println!("{}{}", link, line);
}
}
pub fn shared_object_link_args(
name: &str,
major: &str,
minor: &str,
micro: &str,
_arch: &str,
os: &str,
env: &str,
libdir: PathBuf,
target_dir: PathBuf,
) -> Vec<String> {
let mut lines = Vec::new();
if os == "linux" {
lines.push(format!("-Wl,-soname,lib{}.so.{}", name, major));
} else if os == "macos" {
let line = format!("-Wl,-install_name,{1}/lib{0}.{2}.{3}.{4}.dylib,-current_version,{2}.{3}.{4},-compatibility_version,{2}",
name, libdir.display(), major, minor, micro);
lines.push(line)
} else if os == "windows" && env == "gnu" {
lines.push(format!(
"-Wl,--out-implib,{}",
target_dir.join(format!("{}.dll.a", name)).display()
));
lines.push(format!(
"-Wl,--output-def,{}",
target_dir.join(format!("{}.def", name)).display()
));
}
lines
}