├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | .idea 5 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cdylib-link-lines" 3 | version = "0.1.5" 4 | description = "Collection of link-lines useful to build correct cdylibs on targets" 5 | authors = ["Luca Barbato "] 6 | repository = "https://github.com/lu-zero/cdylib-link-lines" 7 | edition = "2018" 8 | license = "MIT" 9 | readme = "README.md" 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Luca Barbato 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # link-line helper to build correct cdylibs 2 | 3 | [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) 4 | 5 | ## Supported targets 6 | 7 | - Linux and Android 8 | - macOS and iOS 9 | - Windows (gnu) 10 | 11 | ## Usage 12 | 13 | ### build.rs 14 | 15 | Add the crate to your [build-dependencies](https://doc.rust-lang.org/cargo/reference/manifest.html#dependency-sections), in your `build.rs`, call `metabuild()`. 16 | 17 | ``` toml 18 | [build-dependencies] 19 | cdylib-link-lines = "0.1" 20 | ``` 21 | 22 | ``` rust 23 | fn main() { 24 | cdylib_link_lines::metabuild(); 25 | } 26 | ``` 27 | ### metabuild 28 | 29 | If you are using the `metabuild` [unstable feature](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#metabuild) 30 | 31 | ``` toml 32 | cargo-features = ["metabuild"] 33 | 34 | [package] 35 | name = "mypackage" 36 | ... 37 | metabuild = ["cdylib-link-lines"] 38 | 39 | [build-dependencies] 40 | cdylib-link-lines = "0.1" 41 | ``` 42 | 43 | ## Credits 44 | 45 | Helper spun off [crav1e](https://github.com/lu-zero/crav1e), contains code written by Luca Barbato and Derek Buitenhuis. 46 | Synchronized with the [cargo-c](https://github.com/lu-zero/cargo-c) 0.9 logic thanks to Ivan Enderlin. 47 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::path::PathBuf; 3 | 4 | pub 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. 42 | pub 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 { 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 | } 92 | --------------------------------------------------------------------------------