Skip to content

Add CLIPPER2_NO_IOSTREAM build-time option#1094

Open
zmerlynn wants to merge 1 commit intoAngusJohnson:mainfrom
zmerlynn:add-no-iostream-guard
Open

Add CLIPPER2_NO_IOSTREAM build-time option#1094
zmerlynn wants to merge 1 commit intoAngusJohnson:mainfrom
zmerlynn:add-no-iostream-guard

Conversation

@zmerlynn
Copy link
Copy Markdown

@zmerlynn zmerlynn commented May 3, 2026

Adds option(CLIPPER2_NO_IOSTREAM) (default OFF) + matching #ifndef guards in clipper.core.h / clipper.h. When set, propagates the macro as a PUBLIC compile definition so consumers' own includes of Clipper2's headers also strip the iostream-using overloads — load-bearing for the freestanding use case.

Includes a <Lib>_no_iostream_check OBJECT target per built library variant that compiles a tiny TU with the macro defined; always-on, fails the build if iostream usage creeps into the public headers outside the macro guards.

Motivation + broader consumer cocktail: elalish/manifold#1046 (comment)

Wraps iostream-using overloads in clipper.core.h and clipper.h with
`#ifndef CLIPPER2_NO_IOSTREAM`. Adds an `option(CLIPPER2_NO_IOSTREAM)`
that propagates the macro as a PUBLIC compile definition; default
behavior unchanged when off. Adds a `<Lib>_no_iostream_check` OBJECT
target per built library variant that fails the build if iostream
usage creeps into the public headers outside the macro guards.

For the broader consumer cocktail this enables:
elalish/manifold#1046 (comment)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/manifold that referenced this pull request May 3, 2026
Wraps iostream-using overloads in the public headers (manifold.h,
manifoldc.h) and their impls (src/impl.cpp, bindings/c/manifoldc.cpp)
with `#ifndef MANIFOLD_NO_IOSTREAM`. Adds an
`option(MANIFOLD_NO_IOSTREAM)` (default OFF) that propagates the macro
as a PUBLIC compile definition on the manifold target so consumers'
own includes of manifold's headers also strip the iostream-using
overloads. Default behavior unchanged when off.

The bundled Clipper2 (when MANIFOLD_USE_BUILTIN_CLIPPER2=ON) carries
a corresponding patch that adds `CLIPPER2_NO_IOSTREAM` macro guards
to its public headers — tracking AngusJohnson/Clipper2#1094, drops
once that PR lands and the SHA pin moves past it. When
MANIFOLD_NO_IOSTREAM=ON, manifold sets CLIPPER2_NO_IOSTREAM=ON for
the bundled Clipper2 build.

CMake-level conflict guards: MANIFOLD_NO_IOSTREAM=ON is incompatible
with MANIFOLD_DEBUG / MANIFOLD_TIMING (those use std::cout for
diagnostic output), and currently requires MANIFOLD_TEST=OFF (test
fixtures use <filesystem>/<fstream>; restriction will be lifted by a
follow-up MANIFOLD_NO_FILESYSTEM option).

Build-time check: src/no_iostream_check.cpp + a manifold_no_iostream_check
OBJECT target compile manifold/manifold.h with MANIFOLD_NO_IOSTREAM
defined. Always-on; fails the build if iostream usage creeps into
the public header outside the macro guards.

CI: new build_no_iostream cell on Ubuntu/clang exercising
MANIFOLD_NO_IOSTREAM=ON + MANIFOLD_USE_BUILTIN_CLIPPER2=ON (the
patch-application path).

Motivation + the broader consumer cocktail this enables:
elalish#1046 (comment)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/manifold that referenced this pull request May 3, 2026
Wraps iostream-using overloads in the public headers (manifold.h,
manifoldc.h) and their impls (src/impl.cpp, bindings/c/manifoldc.cpp)
with `#ifndef MANIFOLD_NO_IOSTREAM`. Adds an
`option(MANIFOLD_NO_IOSTREAM)` (default OFF) that propagates the macro
as a PUBLIC compile definition on the manifold target so consumers'
own includes of manifold's headers also strip the iostream-using
overloads. Default behavior unchanged when off.

The bundled Clipper2 (when MANIFOLD_USE_BUILTIN_CLIPPER2=ON) carries
a corresponding patch that adds `CLIPPER2_NO_IOSTREAM` macro guards
to its public headers — tracking AngusJohnson/Clipper2#1094, drops
once that PR lands and the SHA pin moves past it. When
MANIFOLD_NO_IOSTREAM=ON, manifold sets CLIPPER2_NO_IOSTREAM=ON for
the bundled Clipper2 build.

CMake-level conflict guards: MANIFOLD_NO_IOSTREAM=ON is incompatible
with MANIFOLD_DEBUG / MANIFOLD_TIMING (those use std::cout for
diagnostic output), and currently requires MANIFOLD_TEST=OFF (test
fixtures use <filesystem>/<fstream>; restriction will be lifted by a
follow-up MANIFOLD_NO_FILESYSTEM option).

Build-time check: src/no_iostream_check.cpp + a manifold_no_iostream_check
OBJECT target compile manifold/manifold.h with MANIFOLD_NO_IOSTREAM
defined. Always-on; fails the build if iostream usage creeps into
the public header outside the macro guards.

CI: new build_no_iostream cell on Ubuntu/clang exercising
MANIFOLD_NO_IOSTREAM=ON + MANIFOLD_USE_BUILTIN_CLIPPER2=ON (the
patch-application path).

Motivation + the broader consumer cocktail this enables:
elalish#1046 (comment)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/manifold that referenced this pull request May 3, 2026
Wraps iostream- and filesystem-using bits of the public API and tests
under `#ifndef MANIFOLD_NO_IOSTREAM` / `#ifndef MANIFOLD_NO_FILESYSTEM`.
Adds an `option(MANIFOLD_NO_IOSTREAM)` (default OFF) that propagates
both macros as PUBLIC compile definitions on the manifold target;
consumers' own includes of manifold's headers also see the stripped
API. The two macros stay semantically distinct in the source
(NO_IOSTREAM gates the iostream-using public API; NO_FILESYSTEM
gates `<filesystem>`/`<fstream>` use in test fixtures), but the
single user-facing option flips both — `<filesystem>` paths are only
useful if you can `<fstream>` them, so they go together in practice.

Wraps land in:
  * include/manifold/manifold.h, bindings/c/include/manifold/manifoldc.h
    (header decls of ReadOBJ/WriteOBJ + manifold_*_obj C-API)
  * src/impl.cpp, bindings/c/manifoldc.cpp (impls + sstream/iomanip
    includes)
  * test/test_main.cpp (filesystem includes + file-I/O fixture
    helpers, with stub-alternates so call sites keep linking)
  * test/manifold_test.cpp, test/polygon_test.cpp,
    test/manifoldc_test.cpp (per-test/per-block gates for the
    iostream-using TESTs; polygon corpus tests are skipped via a
    no-op stub for RegisterPolygonTests)

The bundled Clipper2 (when MANIFOLD_USE_BUILTIN_CLIPPER2=ON) gets
a corresponding patch (cmake/patches/0001-clipper2-no-iostream.patch)
that adds `CLIPPER2_NO_IOSTREAM` macro guards to its public headers —
tracking AngusJohnson/Clipper2#1094, drops once that PR lands and
the SHA pin moves past it. When MANIFOLD_NO_IOSTREAM=ON, manifold
sets CLIPPER2_NO_IOSTREAM=ON for the bundled Clipper2 build.

CMake-level guard: MANIFOLD_NO_IOSTREAM=ON is incompatible with
MANIFOLD_DEBUG / MANIFOLD_TIMING (those use std::cout for diagnostic
output), enforced by FATAL_ERROR.

Build-time checks (always-on, regardless of the option's value):
  * src/no_iostream_check.cpp + manifold_no_iostream_check OBJECT
    target compiles manifold/manifold.h with the macro defined.
  * bindings/c/no_iostream_check.cpp + manifoldc_no_iostream_check
    does the same for the C-API header.

CI: new build_no_iostream cell on Ubuntu/clang with
MANIFOLD_NO_IOSTREAM=ON + MANIFOLD_USE_BUILTIN_CLIPPER2=ON +
MANIFOLD_STRICT=ON. Builds + runs manifold_test (271/272 tests pass —
iostream-using TESTs are gated out). Plus a step that verifies the
DEBUG conflict guard fires.

Discussion + the broader consumer cocktail:
elalish#1046 (comment)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/manifold that referenced this pull request May 3, 2026
Strips iostream- and filesystem-using bits from the public API and
tests, for freestanding/embedded consumers (e.g.,
wasm32-unknown-unknown via wasm-cxx-shim). Default OFF.

When ON, defines MANIFOLD_NO_IOSTREAM and MANIFOLD_NO_FILESYSTEM as
PUBLIC compile defs on manifold, gates iostream-using TESTs at
compile time, and triggers CLIPPER2_NO_IOSTREAM=ON for the bundled
Clipper2 via a carry-patch tracking AngusJohnson/Clipper2#1094
(drops once that lands and the SHA pin moves past it). Incompatible
with MANIFOLD_DEBUG / MANIFOLD_TIMING (FATAL_ERROR).

Always-on manifold_no_iostream_check and manifoldc_no_iostream_check
compile the public headers with the macro defined to catch creep.

Discussion: elalish#1046

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/manifold that referenced this pull request May 3, 2026
Strips iostream- and filesystem-using bits from the public API and
tests, for freestanding/embedded consumers (e.g.,
wasm32-unknown-unknown via wasm-cxx-shim). Default OFF.

When ON, defines MANIFOLD_NO_IOSTREAM and MANIFOLD_NO_FILESYSTEM as
PUBLIC compile defs on manifold, gates iostream-using TESTs at
compile time, and triggers CLIPPER2_NO_IOSTREAM=ON for the bundled
Clipper2 via a carry-patch tracking AngusJohnson/Clipper2#1094
(drops once that lands and the SHA pin moves past it). Incompatible
with MANIFOLD_DEBUG / MANIFOLD_TIMING (FATAL_ERROR).

Always-on manifold_no_iostream_check and manifoldc_no_iostream_check
compile the public headers with the macro defined to catch creep.

Discussion: elalish#1046

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/manifold that referenced this pull request May 4, 2026
Strips iostream- and filesystem-using bits from the public API and
tests, for freestanding/embedded consumers (e.g.,
wasm32-unknown-unknown via wasm-cxx-shim). Default OFF.

When ON, defines MANIFOLD_NO_IOSTREAM and MANIFOLD_NO_FILESYSTEM as
PUBLIC compile defs on manifold, gates iostream-using TESTs at
compile time, and triggers CLIPPER2_NO_IOSTREAM=ON for the bundled
Clipper2 via a carry-patch tracking AngusJohnson/Clipper2#1094
(drops once that lands and the SHA pin moves past it). Incompatible
with MANIFOLD_DEBUG / MANIFOLD_TIMING (FATAL_ERROR).

Always-on manifold_no_iostream_check and manifoldc_no_iostream_check
compile the public headers with the macro defined to catch creep.

Discussion: elalish#1046

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/manifold that referenced this pull request May 4, 2026
Strips iostream- and filesystem-using bits from the public API and
tests, for freestanding/embedded consumers (e.g.,
wasm32-unknown-unknown via wasm-cxx-shim). Default OFF.

When ON, defines MANIFOLD_NO_IOSTREAM and MANIFOLD_NO_FILESYSTEM as
PUBLIC compile defs on manifold, gates iostream-using TESTs at
compile time, and triggers CLIPPER2_NO_IOSTREAM=ON for the bundled
Clipper2 via a carry-patch tracking AngusJohnson/Clipper2#1094
(drops once that lands and the SHA pin moves past it). Incompatible
with MANIFOLD_DEBUG / MANIFOLD_TIMING (FATAL_ERROR).

Discussion: elalish#1046

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pca006132 pushed a commit to elalish/manifold that referenced this pull request May 4, 2026
Strips iostream- and filesystem-using bits from the public API and
tests, for freestanding/embedded consumers (e.g.,
wasm32-unknown-unknown via wasm-cxx-shim). Default OFF.

When ON, defines MANIFOLD_NO_IOSTREAM and MANIFOLD_NO_FILESYSTEM as
PUBLIC compile defs on manifold, gates iostream-using TESTs at
compile time, and triggers CLIPPER2_NO_IOSTREAM=ON for the bundled
Clipper2 via a carry-patch tracking AngusJohnson/Clipper2#1094
(drops once that lands and the SHA pin moves past it). Incompatible
with MANIFOLD_DEBUG / MANIFOLD_TIMING (FATAL_ERROR).

Discussion: #1046

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/wasm-cxx-shim that referenced this pull request May 4, 2026
Manifold's `MANIFOLD_NO_IOSTREAM` build option is now upstream
(merged in elalish/manifold#1690 on 2026-05-04). The single
vendored carry-patch shipped at v0.4.0-alpha.1 is no longer
needed — manifold owns the option, and its `manifoldDeps.cmake`
carries a Clipper2 tracking patch for AngusJohnson/Clipper2#1094
internally.

The shim drops the carry-patch entirely:
  * `cmake/manifold-patches/0001-manifold-no-iostream.patch` deleted
    (and the now-empty directory removed).
  * `wasm_cxx_shim_add_manifold()`'s SKIP_BUILTIN_PATCHES argument
    removed (no builtin patches to skip). MANIFOLD_GIT_TAG and
    EXTRA_MANIFOLD_PATCHES continue to work.
  * `install(DIRECTORY .../manifold-patches ...)` rule dropped.
  * Helper smoke test updated for the new file layout.

Manifold pin bumped from `5f95a3ac` (master pre-#1690) to
`3ce9622b` (master at release time, includes #1690 + one
downstream commit). Build + test verified end-to-end on the new
pin: 18/18 ctest, 121/121 inner manifold tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
zmerlynn added a commit to zmerlynn/wasm-cxx-shim that referenced this pull request May 4, 2026
Manifold's `MANIFOLD_NO_IOSTREAM` build option is now upstream
(merged in elalish/manifold#1690 on 2026-05-04). The single
vendored carry-patch shipped at v0.4.0-alpha.1 is no longer
needed — manifold owns the option, and its `manifoldDeps.cmake`
carries a Clipper2 tracking patch for AngusJohnson/Clipper2#1094
internally.

The shim drops the carry-patch entirely:
  * `cmake/manifold-patches/0001-manifold-no-iostream.patch` deleted
    (and the now-empty directory removed).
  * `wasm_cxx_shim_add_manifold()`'s SKIP_BUILTIN_PATCHES argument
    removed (no builtin patches to skip). MANIFOLD_GIT_TAG and
    EXTRA_MANIFOLD_PATCHES continue to work.
  * `install(DIRECTORY .../manifold-patches ...)` rule dropped.
  * Helper smoke test updated for the new file layout.

Manifold pin bumped from `5f95a3ac` (master pre-#1690) to
`3ce9622b` (master at release time, includes #1690 + one
downstream commit). Build + test verified end-to-end on the new
pin: 18/18 ctest, 121/121 inner manifold tests pass.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant