diff --git a/.github/workflows/publish-cvcpkg.yml b/.github/workflows/publish-cvcpkg.yml index 96ba207a..90f8a0d1 100644 --- a/.github/workflows/publish-cvcpkg.yml +++ b/.github/workflows/publish-cvcpkg.yml @@ -350,15 +350,17 @@ jobs: # same root cause as ci.yml's package-windows failures after the # image flip). Revisit when the v180 toolset stabilizes. - { os: windows-2022, platform: windows, arch: x86_64 } - exclude: - # Windows debug is unsound to publish here: the catalog has no - # windows-debug dep bundles, so a Debug libcvc would link against - # Release MSVC deps — a debug/release CRT mismatch producing a - # broken artifact. Restore once debug Windows dep bundles exist - # (via the remote-builder fleet). Linux/macOS have no such issue: - # a Debug libcvc links the Release (shared, ABI-stable) deps fine. - - config: debug - target: { os: windows-2022, platform: windows, arch: x86_64 } + # No windows-debug exclusion any more. It used to be unsound because + # the catalog had no windows-debug dep bundles, so a Debug libcvc + # would have linked Release MSVC deps — a debug/release CRT mismatch + # producing a broken artifact. The gap was measured across libcvc's + # 34 runtime deps and closed by publishing the ten that were missing: + # gmp, mpfr, gsl, tiff, libiimod, assimp, levmar, grpc, cgal and + # imagemagick. (fontconfig is scoped linux/macos, so it never + # applied.) A windows-debug libcvc bundle is what lets downstream + # consumers run a Debug matrix lane at all — transfix/F2Dock builds + # Debug and Release on all three platforms and now takes libcvc from + # the catalog rather than compiling it. include: # Extra pycvc-column jobs (linux x86_64, release only): each builds # libcvc + cvcgl locally to link against, then packs+publishes ONLY diff --git a/cvcpkg/recipes/libcvc/recipe.yaml b/cvcpkg/recipes/libcvc/recipe.yaml index 25fd4bbe..c68154ec 100644 --- a/cvcpkg/recipes/libcvc/recipe.yaml +++ b/cvcpkg/recipes/libcvc/recipe.yaml @@ -43,7 +43,27 @@ recipe: # spelling. Verified against the published bundle: 0 occurrences of # cvc::xmlrpc in cvcTargets.cmake and no archive, while include/xmlrpc/ # headers shipped. - cvc_revision: 2 + # Bumped 2 -> 4 (not 3: the catalog already has 3.3.0+cvc.3, and a revision + # at or below the published max is a silent no-op / 409). The +cvc.3 bundle + # STILL ships include/xmlrpc/ headers with no lib/libxmlrpc* archive and no + # cvc::xmlrpc in cvcTargets.cmake -- verified by installing it: + # cvcpkg install libcvc --prefix p --config release --link shared + # grep -c cvc::xmlrpc p/lib/cmake/cvc/cvcTargets.cmake -> 0 + # ls p/lib | grep -i xmlrpc -> (nothing) + # publish-cvcpkg.yml now passes -DCVC_USING_XMLRPC=ON on every lane AND hard- + # fails when the archive or the exported target is missing, but +cvc.3 was + # published before those guards landed, so the artifact never picked them up. + # This bump is what actually carries the fix to consumers. + # + # It is load-bearing downstream: transfix/F2Dock hard-requires cvc::xmlrpc + # (src/CMakeLists.txt FATAL_ERRORs without it, and its _libcvc_check_usable + # rejects any libcvc package lacking it). That rejection is why F2Dock has + # always fallen through to building libcvc FROM SOURCE -- which is the only + # reason CGAL and the platform toolchains enter its build at all, and hence + # why CGAL 6.2 (macOS/Windows) and the VS18 v180 CL.exe crash (Windows) break + # it. A bundle that actually exports cvc::xmlrpc removes the source build, + # and those failures with it. + cvc_revision: 4 maintainer: "cvcpkg group" maintainer_email: "info@cvcpkg.org" maintainer_url: "https://cvcpkg.org" diff --git a/src/cvc/CMakeLists.txt b/src/cvc/CMakeLists.txt index f9fd0ad5..347f50c9 100644 --- a/src/cvc/CMakeLists.txt +++ b/src/cvc/CMakeLists.txt @@ -251,10 +251,22 @@ if(NOT CVC_STATE_MEMORY_MANAGER) list(REMOVE_ITEM SOURCE_FILES core/state_memory_manager.cpp core/state_eviction_store.cpp) endif() -# The libcvc version number -set(CVC_VERSION_MAJOR 3) -set(CVC_VERSION_MINOR 0) -set(CVC_VERSION ${CVC_VERSION_MAJOR}.${CVC_VERSION_MINOR}) +# The libcvc version number, derived from project(libcvc VERSION ...) in the +# top-level CMakeLists so the two cannot drift apart. +# +# They had: this was hardcoded 3.0 while the project said 3.3.0, so every +# published bundle exported a cvcConfigVersion.cmake reading +# PACKAGE_VERSION "3.0" with COMPATIBILITY SameMajorVersion. Any downstream +# find_package(cvc 3.x.y) with y > 0 therefore failed the version check no +# matter which bundle was installed -- e.g. transfix/F2Dock asked for 3.2.0, +# never matched, and silently fell back to building libcvc from source. +# +# SOVERSION stays CVC_VERSION_MAJOR, so the runtime link name (libcvc.so.3) +# is unchanged and no consumer relinks. Only the full VERSION suffix +# (libcvc.so.3.0 -> libcvc.so.3.3.0) and the exported package version move. +set(CVC_VERSION ${PROJECT_VERSION}) +set(CVC_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) +set(CVC_VERSION_MINOR ${PROJECT_VERSION_MINOR}) message(STATUS "libcvc version: ${CVC_VERSION}") set(CVC_LINK_LIBS "") diff --git a/src/cvc/geometry/SDF/SignDistanceFunction_v2/DistanceTransform.cpp b/src/cvc/geometry/SDF/SignDistanceFunction_v2/DistanceTransform.cpp index 6d0051a2..878f7548 100644 --- a/src/cvc/geometry/SDF/SignDistanceFunction_v2/DistanceTransform.cpp +++ b/src/cvc/geometry/SDF/SignDistanceFunction_v2/DistanceTransform.cpp @@ -36,8 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -// Include app.h BEFORE DistanceTransform.h to avoid macro conflicts -// (reg3data.h defines error() as a macro which conflicts with cvc::app) #include #include "DistanceTransform.h" diff --git a/src/cvc/geometry/SDF/SignDistanceFunction_v2/RawivParser.cpp b/src/cvc/geometry/SDF/SignDistanceFunction_v2/RawivParser.cpp index d90ea76c..d90544c6 100644 --- a/src/cvc/geometry/SDF/SignDistanceFunction_v2/RawivParser.cpp +++ b/src/cvc/geometry/SDF/SignDistanceFunction_v2/RawivParser.cpp @@ -12,6 +12,22 @@ #include "reg3data.h" #include "bio.h" +namespace { + +// Was a function-like macro named `error(x)` in reg3data.h. A macro by that +// name escaping a header collides with any later declaration that uses the +// identifier -- CGAL 6's Static_filter_error::error(), boost.parameter's +// error(), cvc::app -- which is why three separate call sites carried +// include-ordering workarounds. Kept as a file-local function so the name +// cannot leave this translation unit. +void reg3_fatal(const char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(1); +} + +} // namespace + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -45,7 +61,7 @@ bool RawivParser::parse(Reg3Data* data, const char* fname) DiskIO *pio = new BufferedIO(fname); if(!pio->open()) { - error("Data File Open Failed"); + reg3_fatal("Data File Open Failed"); } pio->get(minext, 3); @@ -78,7 +94,7 @@ bool RawivParser::write(const Reg3Data& data, const char* fname) { DiskIO *pio = new BufferedIO(fname, DiskIO::WRITE); if(!pio->open()) { - error("Cannot Open Data File to write"); + reg3_fatal("Cannot Open Data File to write"); return false; } float maxext[3]; diff --git a/src/cvc/geometry/SDF/SignDistanceFunction_v2/reg3data.h b/src/cvc/geometry/SDF/SignDistanceFunction_v2/reg3data.h index 8bc9491c..fbfe19e9 100644 --- a/src/cvc/geometry/SDF/SignDistanceFunction_v2/reg3data.h +++ b/src/cvc/geometry/SDF/SignDistanceFunction_v2/reg3data.h @@ -9,8 +9,6 @@ #include "cubes.h" -#define error(x) {fprintf(stderr, "%s\n", x); exit(1);} - /** * Reg3Data: A class representing a scalar field on a regular 3D grid. * diff --git a/src/cvc/tests/mtxlib_test.cpp b/src/cvc/tests/mtxlib_test.cpp index 2d177cbf..19486e6b 100644 --- a/src/cvc/tests/mtxlib_test.cpp +++ b/src/cvc/tests/mtxlib_test.cpp @@ -2,19 +2,11 @@ // mtxlib (vector2/3/4, matrix33/44), FaceVertSet3D, BufferedIO, the parsers // (Geom3DParser, RawivParser) and DistanceTransform construction + geometric // predicates. -// -// Include order matters here, and is enforced against clang-format. reg3data.h -// (pulled in by DistanceTransform.h) defines a function-like macro `error(x)`. -// boost/parameter/parameters.hpp — reached transitively through cvc/core/app.h -// and gtest via boost.signals2 — contains a bare `error();` call, which that -// macro clobbers into a syntax error. So the boost-pulling headers must be -// parsed BEFORE the SDF v2 headers define the macro. -// -// The repo .clang-format is IncludeBlocks:Regroup with quoted includes sorted -// ahead of angle-bracket ones, so it would hoist the SDF headers above the -// cvc/boost includes and re-break the build — unless a non-include line splits -// them into separate, individually-sorted blocks. The #undef barriers below do -// exactly that (and are correct on their own merits). Do not merge these blocks. +#include "DistanceTransform.h" // pulls in FaceVertSet3D.h, reg3data.h, RawivParser.h +#include "Geom3DParser.h" +#include "bufferedio.h" +#include "mtxlib.h" + #include #include #include @@ -23,21 +15,21 @@ #include #include -#ifdef error -#undef error // no-op here; keeps this block separate from the SDF block below -#endif - -#include "DistanceTransform.h" // pulls in FaceVertSet3D.h, reg3data.h, RawivParser.h -#include "Geom3DParser.h" -#include "bufferedio.h" -#include "mtxlib.h" - -#ifdef error -#undef error // reg3data.h's error(x) macro must not leak into the test body -#endif - namespace { +// Regression guard for the `error(x)` macro that reg3data.h used to define. +// A function-like macro with that name escaping a header rewrites any later +// declaration that uses the identifier. CGAL 6 is the case that broke the +// build: CGAL/AABB_traits.h forwards to AABB_traits_3.h, which pulls in +// Static_filter_error with a `double error() const` member, and `error()` +// matches the one-parameter macro with an empty argument. boost.parameter and +// cvc::app hit the same thing. This struct mirrors the CGAL declaration, so +// reintroducing the macro anywhere reg3data.h can reach makes this file fail +// to compile. +struct StaticFilterErrorLookalike { + double error() const { return 1.0; } +}; + const float kEps = 1e-5f; // Mirror of DistanceTransform::MAX_FLOAT (== 1.0e12f, DistanceTransform.cpp:52), @@ -101,6 +93,20 @@ void expectMat44Near(const matrix44 &a, const matrix44 &b, float tol) { } // namespace +// =========================================================================== +// header hygiene +// =========================================================================== + +// Compiles only while no reachable header defines `error` as a macro; see +// StaticFilterErrorLookalike above. +TEST(Reg3DataHeaderHygiene, ErrorIsNotAMacro) { +#ifdef error + FAIL() << "a reachable header defines `error` as a macro again"; +#endif + const StaticFilterErrorLookalike probe; + EXPECT_DOUBLE_EQ(1.0, probe.error()); +} + // =========================================================================== // vector2 // =========================================================================== diff --git a/src/cvc/utility/algorithm.cpp b/src/cvc/utility/algorithm.cpp index 283a6ea3..b74be33e 100644 --- a/src/cvc/utility/algorithm.cpp +++ b/src/cvc/utility/algorithm.cpp @@ -24,7 +24,6 @@ #include #include -// CGAL headers must come before SDF headers due to macro conflicts #ifndef DISABLE_CGAL #include #include