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

Autodetect CPU target features from Cargo #32

Merged
merged 2 commits into from
Sep 10, 2024
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ cc = "1"
glob = "0.3"

[features]
default = ["std", "parallel", "neon"]
default = ["std", "parallel"]
std = []
parallel = ["cc/parallel"]
neon = [] # ARM NEON SIMD (will crash on ARM CPUs without it)
Expand Down
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

libwebp is built with the [`cc`](//lib.rs/cc) crate. It needs a C compiler, but `cmake` is not used.

Set `TARGET_CPU` env var to `native` or your desired CPU architecture to optimize the C code for it.
Set `RUSTFLAGS="-Ctarget-cpu=native"` or your desired CPU architecture to optimize the C code for it.

## Usage

Expand All @@ -15,19 +15,16 @@ Add the following to the `Cargo.toml` in your project:
libwebp-sys = "0.9"
```

or to require newer CPUs with SIMD support:

```toml
[dependencies]
libwebp-sys = { version = "0.9", features = ["avx2", "sse41", "neon"] }
```

or to require `no_std` support:

```toml
libwebp-sys = { version = "0.9", default-features = false, features = ["parallel", "neon"] }
libwebp-sys = { version = "0.9", default-features = false, features = ["parallel"] }
```

The `neon`, `sse41` and `avx2` feature flags can be set to force support for Neon, SSE 4.1 and AVX2
respectively, but this is usually unnecessary as it can be set through
`-Ctarget-feature` (e.g. `RUSTFLAGS="-Ctarget-feature=avx2"`) as well.

## Examples

### Encode
Expand Down
25 changes: 13 additions & 12 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ fn main() {
cc.file(manifest_dir.join(f));
}

for f in glob::glob("vendor/sharpyuv/**/*.c")
.expect("glob vender/src failed")
.flatten()
{
for f in glob::glob("vendor/sharpyuv/**/*.c").expect("glob vendor/src failed") {
let f = f.expect("glob iteration vendor/src failed");
sharpyuv_build.file(manifest_dir.join(f));
}
sharpyuv_build.compile("sharpyuv");
Expand All @@ -48,25 +46,28 @@ fn setup_build(build: &mut cc::Build, include_dir: &PathBuf) {
build.flag("-D_CRT_SECURE_NO_WARNINGS");
}

if let Ok(target_cpu) = env::var("TARGET_CPU") {
build.flag_if_supported(&format!("-march={}", target_cpu));
}
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH");
let target_features = env::var("CARGO_CFG_TARGET_FEATURE").expect("CARGO_CFG_TARGET_FEATURE");
let has_feature = |f: &str| target_features.split(',').any(|feature| feature == f);

let target_cpu = env::var("TARGET_CPU").ok();
let target_cpu = target_cpu.as_deref().unwrap_or(&*target_arch);
build.flag_if_supported(format!("-march={}", target_cpu));

let target = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH");
match target.as_str() {
match target_arch.as_str() {
"x86_64" | "i686" => {
build.define("WEBP_HAVE_SSE2", Some("1"));
if cfg!(feature = "sse41") {
if cfg!(feature = "sse41") || has_feature("sse4.1") {
build.define("WEBP_HAVE_SSE41", Some("1"));
build.flag_if_supported("-msse4.1");
}
if cfg!(feature = "avx2") {
if cfg!(feature = "avx2") || has_feature("avx2") {
build.define("WEBP_HAVE_AVX2", Some("1"));
build.flag_if_supported("-mavx2");
}
}
"aarch64" => {
if cfg!(feature = "neon") {
if cfg!(feature = "neon") || has_feature("neon") {
build.define("WEBP_HAVE_NEON", Some("1"));
}

Expand Down
Loading