Skip to content

build: replace c-blosc git submodule with meson wrap subprojects - #865

Open
d-v-b wants to merge 4 commits into
zarr-developers:mainfrom
d-v-b:build/meson-wraps
Open

d-v-b wants to merge 4 commits into
zarr-developers:mainfrom
d-v-b:build/meson-wraps

Conversation

@d-v-b

@d-v-b d-v-b commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

🤖 AI text below 🤖

Note

Stacked on #864 (NEON shuffle). The first commit here is #864's; review the last three commits. Draft until #864 lands and the c-blosc tarball is hosted in this repo (see Before merging).

Summary

This replaces the c-blosc git submodule, and the ~170 lines of hand-listed internal-complibs sources in src/numcodecs/meson.build, with meson subprojects:

  • zstd, lz4 and zlib come from WrapDB (subprojects/{zstd,lz4,zlib}.wrap). Previously their versions were whatever c-blosc bundled; now they can be bumped independently with meson wrap update. This PR moves zstd 1.5.6 → 1.5.7 and zlib 1.3.1 → 1.3.2; lz4 stays at 1.10.0.
  • c-blosc 1.x is not in WrapDB, so subprojects/c-blosc.wrap pins the same commit the submodule pointed to (04c06fb). subprojects/packagefiles/c-blosc/ holds its meson.build (upstream only ships CMake) and numcodecs' patches, currently the NEON shuffle from perf(blosc): use NEON SIMD for byte-shuffle on aarch64 #864. Patching c-blosc no longer requires forking the submodule.
  • Trimmed c-blosc tarball. The upstream archive carries its own zstd/lz4/zlib/snappy copies, tests and compat fixtures (~2.4 MB of sdist). tools/make_c_blosc_tarball.py extracts only blosc/, the license files and the README into a reproducible 60 KB tarball, which the wrap points at.
  • The system_* options keep their meaning. When a library isn't taken from the system, its subproject is configured first, so every dependency() lookup, including c-blosc's, resolves to the same static build. The build log shows c-blosc reusing the zstd subproject (found: YES 1.5.7 (cached)).
  • Packaging. In pyproject.toml, meson-python now skips installing subproject artifacts (--skip-subprojects) and includes their sources in the sdist (--include-subprojects), so the sdist builds offline.
  • Licenses. License texts for all bundled C code now live in LICENSES/ and are listed in license-files. This adds zstd's license, which the wheels were missing before.
  • CI and docs. The submodules: checkout settings and Read the Docs config are removed, and the contributing guide is updated.

Trade-offs

  • A C++ compiler is now required to build from source. zstd's WrapDB meson project declares C++, although libzstd itself is C. Standard CI images and Alpine's build-base include one. Alternatives: a numcodecs-maintained zstd overlay, or an upstream WrapDB change.
  • The sdist grows from 6.3 MB (0.17.0) to 8.3 MB. WrapDB's zstd (2.5 MB), zlib (1.6 MB) and lz4 (0.4 MB) are full upstream release archives, where the old sdist only had their lib/ sources via c-blosc. These could be trimmed the same way as c-blosc, at the cost of losing plain meson wrap update bumps.
  • Builds from a git checkout, including cibuildwheel, download sources on first build. Offline builders can run meson subprojects download beforehand or build from the sdist.

Before merging

  • Merge perf(blosc): use NEON SIMD for byte-shuffle on aarch64 #864 and rebase.
  • Host the c-blosc tarball in this repository. source_url in subprojects/c-blosc.wrap currently points at a release asset on the PR author's fork (vendor/c-blosc-04c06fb7339d). To verify it, run python tools/make_c_blosc_tarball.py 04c06fb7339d3df3600b1862077b8699b30a0e1d; the tarball sha256 should be ebadbf11…a7f7a81 and the uncompressed tar sha256 6b7381ba…42b28f4. Then re-upload it here and update the URL.

Testing

Locally on macOS arm64 (Python 3.14):

  • The full test suite passes (1,007 passed, 31 skipped).
  • A sha256 over Blosc output from 1,452 (typesize × length × blocksize × shuffle × codec) combinations matches the pre-migration build.
  • The sdist contains all subproject sources, and a wheel built from it with --wrap-mode=nodownload succeeds.
  • The wheel contains only numcodecs' extension modules plus license files; the extensions link only libSystem.

Linux, Windows and cibuildwheel runs are not yet verified locally; this PR's CI covers them.

🤖 Generated with Claude Code

c-blosc 1.x only provides SSE2/AVX2 shuffle kernels. On aarch64 its
dispatcher always selects blosc_internal_(un)shuffle_generic, a scalar
byte-by-byte loop that dominates Blosc runtime on ARM.

On aarch64, compile a drop-in replacement for c-blosc's shuffle-generic.c
that implements those two symbols with NEON kernels (copied from c-blosc2)
for type sizes 2, 4, 8 and 16, falling back to the scalar loop otherwise.
The c-blosc submodule is left untouched and the output is byte-identical.

Controlled by a new `neon` meson option (default: auto).

Assisted-by: ClaudeCode:claude-opus-5-5
Replace the c-blosc submodule and the hand-maintained source lists for its
internal-complibs with meson subprojects:

- zstd, lz4 and zlib come from WrapDB (subprojects/*.wrap), so their
  versions are no longer tied to c-blosc's bundled copies.
- c-blosc 1.x is not in WrapDB, so subprojects/c-blosc.wrap pins the same
  commit as the old submodule, and subprojects/packagefiles/c-blosc/
  provides its meson.build plus numcodecs patches (the NEON shuffle).
- The system_* options keep their meaning; when a library is not taken
  from the system, the subproject is configured first so every lookup,
  including c-blosc's, resolves to the same static build.
- meson-python skips installing subproject artifacts and includes the
  subproject sources in the sdist, so the sdist builds offline.
- License texts for the bundled libraries now live in LICENSES/, adding
  the previously missing zstd license.

Assisted-by: ClaudeCode:claude-opus-5-5
The upstream c-blosc archive bundles zstd, lz4, zlib and snappy sources plus
tests and compat fixtures, none of which the meson build uses (the codec
libraries come from their own subprojects).

Add tools/make_c_blosc_tarball.py, which extracts blosc/, the license files
and the README into a deterministic tarball, and point c-blosc.wrap at that
tarball. c-blosc now takes 0.07 MB of the sdist, which shrinks from 10.7 MB
to 8.3 MB.

Assisted-by: ClaudeCode:claude-opus-5-5
Drop the submodules settings from the GitHub Actions checkouts and the
Read the Docs config now that c-blosc is a meson subproject, and add a
release note for the migration.

Assisted-by: ClaudeCode:claude-opus-5-5
@codecov

codecov Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (1f83681) to head (1879207).

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #865   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           27        27           
  Lines          905       905           
=========================================
  Hits           905       905           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@d-v-b
d-v-b requested a review from mkitti September 27, 2026 12:04
@d-v-b
d-v-b marked this pull request as ready for review September 27, 2026 12:04
@mkitti

mkitti commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

How much conda-forge breakage is involved here?

https://github.com/conda-forge/numcodecs-feedstock/blob/main/recipe%2Fmeta.yaml

@d-v-b

d-v-b commented Sep 28, 2026

Copy link
Copy Markdown
Contributor Author

Not much I think

@mkitti

mkitti commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

I think we should just wrap cmake here with https://mesonbuild.com/CMake-module.html

@mkitti

mkitti commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

This might be relevant: Blosc/c-blosc2#690

We should move to blosc2 as soon as possible.

@d-v-b

d-v-b commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

This might be relevant: Blosc/c-blosc2#690

We should move to blosc2 as soon as possible.

blosc2 cannot write data that blosc1 reads. so we have to keep blosc1 around.

@mkitti

mkitti commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

@d-v-b

d-v-b commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author

it would be a breaking change to blosc1 readers

buffers generated with C-Blosc2 are not format-compatible with C-Blosc1 (i.e. forward compatibility is not supported)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants