diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75ed45d..31d00df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy + targets: x86_64-unknown-none - uses: Swatinem/rust-cache@v2 - run: cargo fmt --all -- --check - run: cargo clippy --all-targets --no-default-features -- -D warnings @@ -21,6 +22,19 @@ jobs: - run: cargo test --all-targets --features arctic - run: cargo clippy --all-targets --all-features -- -D warnings - run: cargo test --all-targets --all-features + # A crate that says `#![no_std]` and is only ever built on a host with one + # proves nothing. This target has no `std` to find. + - run: cargo build --target x86_64-unknown-none --no-default-features + - run: cargo build --target x86_64-unknown-none --no-default-features --features hydrate + # The arctic backend needs an OS for its thread-local storage, so it + # cannot be built for a bare target - but it must still not pull `std` in. + - name: The arctic backend does not enable std + run: | + graph=$(cargo tree --no-default-features --features arctic -f '{p} [{f}]') + echo "$graph" | grep -E 'arctic-wt|ps-reclaim' + if echo "$graph" | grep -E '(arctic-wt|ps-reclaim) v[^[]*\[[^]]*std'; then + echo "std leaked into the arctic backend"; exit 1 + fi package: name: Release dry run diff --git a/Cargo.toml b/Cargo.toml index f09e8cb..74c088c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "worktable-vec" -version = "0.1.4" +version = "0.1.5" edition = "2024" rust-version = "1.85" license = "MIT OR Apache-2.0" @@ -12,12 +12,16 @@ categories = ["data-structures"] [features] default = [] +# On by default for nobody: this crate is `#![no_std]` and the core never needed +# `std`. The feature exists so a backend that does need one can say so, and so a +# bare-metal caller can prove it is not getting one. +std = ["arctic?/std"] # Load and unload rows as pages. Optional because it is the only thing here # that needs a serializer. hydrate = ["dep:rkyv", "dep:embedded-io"] arctic = ["dep:arctic"] -congee = ["dep:congee"] -wti = ["dep:wti"] +congee = ["dep:congee", "std"] +wti = ["dep:wti", "std"] [dependencies] rkyv = { version = "0.8.17", default-features = false, features = ["alloc", "bytecheck"], optional = true } @@ -26,7 +30,10 @@ rkyv = { version = "0.8.17", default-features = false, features = ["alloc", "byt # a caller with an OS gets real files and a caller without one plugs in whatever # it has. Nothing here needs `std` either way. embedded-io = { version = "0.7", default-features = false, features = ["alloc"], optional = true } -arctic = { package = "arctic-wt", version = "^0.1, >=0.1.9", optional = true } +# `default-features = false` and an explicit SMR backend, so enabling `arctic` +# does not silently enable `std`. 0.1.11 is the first release where that is +# possible: before it, `smr-ps-reclaim` forced `std` on. +arctic = { package = "arctic-wt", version = "^0.1, >=0.1.11", optional = true, default-features = false, features = ["smr-ps-reclaim"] } congee = { package = "congee-wt", version = "^0.4, >=0.4.4", optional = true } wti = { package = "WorkTablesIndex", version = "^0.0, >=0.0.11", optional = true, default-features = false, features = ["concurrent"] }