Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,20 +88,26 @@ For local development, you may need to install the following packages:

```bash
# This list may be incomplete
sudo apt-get install build-essential libsimde-dev
sudo apt-get install build-essential
```

`libsimde-dev` is optional. On ARM/aarch64, the C++ build fetches SIMDe via CMake,
and the Rust CXX bridge now reuses that fetched include path automatically.
Install `libsimde-dev` only if you prefer a system package fallback.

### macOS
To build `FastPFor` on macOS, you'll need to install `SIMDe`.
Since Homebrew installs packages in `/opt/homebrew` (for Apple Silicon), you'll also need to explicitly set the include paths.
On Apple Silicon, manual SIMDe installation is usually not required.
The C++ build fetches SIMDe via CMake, and the Rust CXX bridge reuses that path.

If you prefer a system package fallback, install SIMDe with Homebrew and set include flags.

```bash
# install SIMDe via Homebrew
# optional: install SIMDe via Homebrew
brew install simde
```

```bash
# Ensure the compiler can find the required headers before building
# optional fallback: ensure the compiler can find Homebrew headers
export CXXFLAGS="-I/opt/homebrew/include"
export CFLAGS="-I/opt/homebrew/include"
```
Expand Down
36 changes: 28 additions & 8 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// Builds the C++ `FastPFOR` library and bridge when the `cpp` feature is enabled.
#[cfg(feature = "cpp")]
fn build_fastpfor() {
use std::path::Path;
use std::{env, path::Path};

assert!(
Path::new("cpp/CMakeLists.txt").exists(),
Expand All @@ -12,20 +12,40 @@ fn build_fastpfor() {

// Compile FastPFOR using CMake
println!("cargo:rerun-if-changed=cpp");
let lib_path = cmake::Config::new("cpp")
.define("WITH_TEST", "OFF")
.build()
.join("lib");
let cmake_out = cmake::Config::new("cpp").define("WITH_TEST", "OFF").build();
let lib_path = cmake_out.join("lib");
let lib_path = lib_path.to_str().unwrap();

// Compile the bridge
println!("cargo:rerun-if-changed=src/cpp/fastpfor_bridge.h");
println!("cargo:rerun-if-changed=src/cpp/mod.rs");
cxx_build::bridge("src/cpp/mod.rs")
let mut bridge = cxx_build::bridge("src/cpp/mod.rs");
bridge
.include("cpp/headers")
.include("src/cpp")
.std("c++14")
.compile("fastpfor_bridge");
.std("c++14");

// On ARM/aarch64, FastPFOR headers include SIMDe shims for SSE intrinsics.
// CMake fetches SIMDe to build FastPFOR itself, but the Rust/CXX bridge is a
// separate compilation unit and needs the same include path + define.
if env::var("CARGO_CFG_TARGET_ARCH").is_ok_and(|arch| arch == "aarch64") {
let simde_include = cmake_out.join("build").join("_deps").join("simde-src");
if simde_include.exists() {
bridge
.include(simde_include)
// Mirror `cpp/cmake_modules/simde.cmake` for the bridge TU:
// FastPFOR headers use SSE names directly (e.g. __m128i, _mm_*),
// so we need SIMDe's native aliases enabled here as well.
.define("SIMDE_ENABLE_NATIVE_ALIASES", None);
} else {
println!(
"cargo:warning=SIMDe headers were not found in CMake build output; \
install SIMDe (e.g. `brew install simde`) if bridge compilation fails."
Comment thread
yutannihilation marked this conversation as resolved.
Outdated
);
}
}

bridge.compile("fastpfor_bridge");

// Link the FastPFOR library - must be done after the bridge is compiled
println!("cargo:rustc-link-search=native={lib_path}");
Expand Down
Loading