cdylib_link_lines/
lib.rs

1use std::env;
2use std::path::PathBuf;
3
4pub fn metabuild() {
5    let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
6    let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
7    let env = env::var("CARGO_CFG_TARGET_ENV").unwrap();
8
9    // We do not care about `_pre` and such.
10    let major = env::var("CARGO_PKG_VERSION_MAJOR").unwrap();
11    let minor = env::var("CARGO_PKG_VERSION_MINOR").unwrap();
12    let patch = env::var("CARGO_PKG_VERSION_PATCH").unwrap();
13
14    // Give the priority to [`cargo-c`](https://github.com/lu-zero/cargo-c) in case of.
15    let prefix = PathBuf::from(env::var_os("CARGO_C_PREFIX").unwrap_or("/usr/local".into()));
16    let libdir = env::var_os("CARGO_C_LIBDIR").map_or(prefix.join("lib"), Into::into);
17
18    let target_dir = env::var_os("CARGO_TARGET_DIR").map_or(
19        {
20            let manifest_dir = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap());
21            manifest_dir
22                .join("target")
23                .join(std::env::var("PROFILE").unwrap())
24        },
25        Into::into,
26    );
27
28    let name = env::var_os("CARGO_PKG_NAME").unwrap();
29    let name = name.to_str().expect("pkg name is not valid UTF-8");
30
31    let lines = shared_object_link_args(
32        &name, &major, &minor, &patch, &arch, &os, &env, libdir, target_dir,
33    );
34
35    for line in lines {
36        println!("cargo:rustc-cdylib-link-arg={}", line);
37    }
38}
39
40/// Return a list of linker arguments useful to produce a
41/// platform-correct dynamic library.
42pub fn shared_object_link_args(
43    name: &str,
44    major: &str,
45    minor: &str,
46    patch: &str,
47    _arch: &str,
48    os: &str,
49    env: &str,
50    libdir: PathBuf,
51    target_dir: PathBuf,
52) -> Vec<String> {
53    let mut lines = Vec::new();
54
55    match (os, env) {
56        ("android", _) => {
57            lines.push(format!("-Wl,-soname,lib{}.so", name));
58        }
59
60        ("linux", _) | ("freebsd", _) | ("dragonfly", _) | ("netbsd", _) => {
61            lines.push(format!("-Wl,-soname,lib{}.so.{}", name, major));
62        }
63
64        ("macos", _) | ("ios", _) => {
65            lines.push(format!(
66                "-Wl,-install_name,{1}/lib{0}.{2}.{3}.{4}.dylib,-current_version,{2}.{3}.{4},-compatibility_version,{2}",
67                name,
68                libdir.display(),
69                major,
70                minor,
71                patch,
72            ));
73        }
74
75        ("windows", "gnu") => {
76            // This is only set up to work on GNU toolchain versions of Rust
77            lines.push(format!(
78                "-Wl,--out-implib,{}",
79                target_dir.join(format!("{}.dll.a", name)).display()
80            ));
81            lines.push(format!(
82                "-Wl,--output-def,{}",
83                target_dir.join(format!("{}.def", name)).display()
84            ));
85        }
86
87        _ => {}
88    }
89
90    lines
91}