Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SHADERC_STATIC="./here/" #2

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@ code that happens to be owned by Google.
Usage
-----

This library uses [`build.rs`](build/build.rs) to automatically check out
and compile a copy of native C++ shaderc and link to the generated artifacts,
which requires `git`, `cmake`, and `python` existing in the `PATH`.

To turn off this feature, specify `--no-default-features` when building.
But then you will need to place a copy of the `shaderc_combined` static library
to the location (printed out in the warning message) that is scanned by the
linker.
The included shaderc-sys crate uses [`build.rs`](shaderc-sys/build/build.rs) to discover or build a copy of libshaderc. See Setup section.

First add to your `Cargo.toml`:

Expand Down Expand Up @@ -80,7 +73,19 @@ assert!(text_result.as_text().starts_with("; SPIR-V\n"));
Setup
-----

To build the shaderc-rs crate, the following tools must be installed and available on `PATH`:
Building the underlying libshaderc from source takes a while. You can provide it or use system libraries by setting the `SHADERC_STATIC` path. On Linux, the build script also checks for independent libglslang and libSPIRV and includes them only if found.

`--no-default-features` still works on shaderc-rs, but shaderc-sys implements this behavior in a deprecated manner. Prefer `SHADERC_STATIC="../path/to/libshaderc/and/glsang/etc/"`. This method only works with a monolithic **libshaderc_combined.a**.

If you need to prefer building libshaderc from source to override system libraries etc, explicitly enable the build-from-source feature:
```
cargo build --features=build-from-source
```

The shaderc-sys [`build.rs`](shaderc-sys/build/build.rs) will automatically check out and compile a copy of native C++ shaderc and link to the generated artifacts,
which requires `git`, `cmake`, and `python` existing in the `PATH`.

To build your own libshaderc for the shaderc-sys crate, the following tools must be installed and available on `PATH`:
- [CMake](https://cmake.org/)
- [Git](https://git-scm.com/)
- [Python](https://www.python.org/) (works with both Python 2.x and 3.x, on windows the executable must be named `python.exe`)
Expand Down Expand Up @@ -132,6 +137,8 @@ For example on ubuntu:
sudo apt-get install build-essential git python cmake
```

On Arch linux, the [shaderc package](https://www.archlinux.org/packages/extra/x86_64/shaderc/) will include glsang and SPIRV libs in a detectable location.

### macOS Example Setup

Assuming Homebrew:
Expand Down
1 change: 1 addition & 0 deletions shaderc-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ name = "shaderc_sys"
[features]
check-passthrough = []
dont-use-deprecated = []
build-from-source = []

[dependencies]
libc = "0.2"
Expand Down
101 changes: 97 additions & 4 deletions shaderc-sys/build/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,13 @@
mod cmd_finder;

use std::env;
use std::env::consts;
use std::path::{Path, PathBuf};

static COMBINED_LIB: &str = "shaderc_combined";
static COMBINED_LIB_FILE: &str = "libshaderc_combined.a";
static SPIRV_LIB: &str = "libSPIRV.a";

fn build_shaderc(shaderc_dir: &PathBuf, use_ninja: bool) -> PathBuf {
let mut config = cmake::Config::new(shaderc_dir);
config
Expand Down Expand Up @@ -55,6 +60,7 @@ fn build_shaderc_msvc(shaderc_dir: &PathBuf, use_ninja: bool) -> PathBuf {
}

fn main() {
// Deprecated --no-defaults path inhereted from before shaderc-rs & shaderc-sys split
if env::var("CARGO_FEATURE_CHECK_PASSTHROUGH").is_ok()
&& env::var("CARGO_FEATURE_DONT_USE_DEPRECATED").is_err()
{
Expand All @@ -67,9 +73,93 @@ fn main() {
);
println!("cargo:rustc-link-search=native={}", out_dir);
println!("cargo:rustc-link-lib=static=shaderc_combined");
emit_stdc_link();
return;
}

// Explicit overrides first
let mut search_dir = if let Ok(lib_dir) = env::var("SHADERC_LIB_DIR") {
println!("cargo:warning=Using specified pre-built libshaderc");
Some(lib_dir)
} else if let Ok(lib_path) = env::var("SHADERC_LIB_PATH") {
println!("cargo:warning=Using specified pre-built libshaderc");
Some(lib_path)
} else if let Ok(lib_path) = env::var("SHADERC_STATIC") {
println!("cargo:warning=Using specified pre-built libshaderc");
Some(lib_path)
} else {
None
};

let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

// Guess linux path for system library unless requested to do source build
if search_dir.is_none()
&& target_os == "linux"
&& env::var("CARGO_FEATURE_BUILD_FROM_SOURCE").is_err()
{
println!("cargo:warning=Checking for system installed libraries");
search_dir = Some("/usr/lib/".to_owned());
}

// Try to build with the static lib if a path was received or chosen
if let Some(search_dir) = search_dir {
let search_path = Path::new(&search_dir);
let combined_lib_path = search_path.join(COMBINED_LIB_FILE);
let dylib_name = format!("{}shaderc{}", consts::DLL_PREFIX, consts::DLL_SUFFIX);
let dylib_path = search_path.join(dylib_name.clone());

if let Some((lib_dir, lib_name)) = {
if combined_lib_path.exists() {
Some((search_dir.clone(), COMBINED_LIB.to_owned()))
} else if dylib_path.exists() {
Some((search_dir.clone(), dylib_name))
} else {
None
}
} {
match (target_os.as_str(), target_env.as_str()) {
("linux", _) => {
println!("cargo:rustc-link-search=native={}", lib_dir);
let spirv_path = search_path.join(SPIRV_LIB);
if spirv_path.exists() {
println!("cargo:warning=Found SPIRV. Linking SPIRV & glslang");
println!("cargo:rustc-link-lib=static=SPIRV");
println!("cargo:rustc-link-lib=static=SPIRV-Tools-opt");
println!("cargo:rustc-link-lib=static=SPIRV-Tools");
println!("cargo:rustc-link-lib=static=glslang");
} else {
println!("cargo:warning=Only libshaderc library found. Assuming SPIRV & glslang included.");
}
println!("cargo:rustc-link-lib=static={}", lib_name);
println!("cargo:rustc-link-lib=dylib=stdc++");
return;
}
("windows", "gnu") => {
println!("cargo:warning=Windows MinGW static builds experimental");
println!("cargo:rustc-link-search=native={}", lib_dir);
println!("cargo:rustc-link-lib=static={}", lib_name);
println!("cargo:rustc-link-lib=dylib=stdc++");
return;
}
("macos", _) => {
println!("cargo:warning=MacOS static builds experimental");
println!("cargo:rustc-link-search=native={}", lib_dir);
println!("cargo:rustc-link-lib=static={}", lib_name);
println!("cargo:rustc-link-lib=dylib=c++");
return;
}
(_, _) => {
println!("cargo:warning=Platform unsupported for pre-built libshaderc");
}
}
} else {
println!("cargo:warning=pre-built library not found");
}
}

println!("cargo:warning=Falling back to from-source build");
let mut finder = cmd_finder::CommandFinder::new();

finder.must_have("cmake");
Expand All @@ -78,9 +168,6 @@ fn main() {

let has_ninja = finder.maybe_have("ninja").is_some();

let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let shaderc_dir = Path::new(&manifest_dir).join("build");

Expand All @@ -91,10 +178,16 @@ fn main() {
};

lib_path.push("lib");

println!("cargo:rustc-link-search=native={}", lib_path.display());
println!("cargo:rustc-link-lib=static=shaderc_combined");

emit_stdc_link();
}

fn emit_stdc_link() {
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

match (target_os.as_str(), target_env.as_str()) {
("linux", _) | ("windows", "gnu") => println!("cargo:rustc-link-lib=dylib=stdc++"),
("macos", _) => println!("cargo:rustc-link-lib=dylib=c++"),
Expand Down