diff --git a/.gitignore b/.gitignore index be4ca70..af4eccc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.pdb .idea/ .vscode/ +Cargo.lock codecov* debug/ target/ @@ -9,5 +10,4 @@ temp/ tmp/ venv/ -# This is a library, no lock -Cargo.lock +!codecov.yml diff --git a/README.md b/README.md index 390aff4..c767a44 100644 --- a/README.md +++ b/README.md @@ -88,20 +88,24 @@ 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" ``` diff --git a/build.rs b/build.rs index e57fe1d..dcde498 100644 --- a/build.rs +++ b/build.rs @@ -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(), @@ -12,20 +12,42 @@ 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 compile definition, plus an + // include path if CMake fetched SIMDe into the build tree. + if env::var("CARGO_CFG_TARGET_ARCH").is_ok_and(|arch| arch == "aarch64") { + // 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, regardless of + // where the SIMDe headers are provided from. + bridge.define("SIMDE_ENABLE_NATIVE_ALIASES", None); + + let simde_include = cmake_out.join("build").join("_deps").join("simde-src"); + if simde_include.exists() { + bridge.include(simde_include); + } else { + println!( + "cargo:warning=SIMDe headers were not found in CMake build output; \ + ensure SIMDe is available on the include path if bridge compilation fails." + ); + } + } + + bridge.compile("fastpfor_bridge"); // Link the FastPFOR library - must be done after the bridge is compiled println!("cargo:rustc-link-search=native={lib_path}"); diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..b41c205 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,6 @@ +codecov: + require_ci_to_pass: false + +coverage: + status: + patch: off