[geos-commits] [SCM] GEOS branch 3.14 updated. d18db3a1108a504938e7da4f7818c7195cc021c4

git at osgeo.org git at osgeo.org
Sun Dec 7 14:08:32 PST 2025


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, 3.14 has been updated
       via  d18db3a1108a504938e7da4f7818c7195cc021c4 (commit)
      from  beb52e94b100efc12a8f764d896586adc10420c8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d18db3a1108a504938e7da4f7818c7195cc021c4
Author: Mike Taves <mwtoews at gmail.com>
Date:   Mon Dec 8 10:53:37 2025 +1300

    Refactor FE_ macro checks for Emscripten; add CI job (#1333)
    
    * Refactor FE_ macro checks for Emscripten; add CI job
    * Re-introduce HAVE_FENV via opt-in MISSING_FENV define
    * Check for cfenv C++ header instead of fenv.h C header
    * Add NEWS entry

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 113f55e61..c1741a25f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -481,6 +481,49 @@ jobs:
       working-directory: ./build
       run: ctest -V --output-on-failure -C ${{ matrix.build_type }}
 
+  emscripten:
+    name: Emscripten WASM build
+    runs-on: ubuntu-latest
+    steps:
+    - name: Install
+      run: |
+        set -e
+        sudo -E apt-get update
+        sudo -E apt-get autopurge -y needrestart
+        sudo -E apt-get -yq --no-install-suggests --no-install-recommends install make cmake emscripten ccache
+
+    - uses: actions/checkout at v5
+
+    - name: Retrieve build cache
+      uses: actions/cache/restore at v4
+      id: restore-cache
+      with:
+        path: .ccache
+        key: emscripten-${{ github.ref_name }}-${{ github.run_id }}
+        restore-keys: emscripten
+
+    - name: Build
+      run: |
+        set -e
+        mkdir build
+        cd build
+        cmake --version
+        emcmake cmake \
+          -D BUILD_SHARED_LIBS=OFF \
+          -D USE_CCACHE=ON \
+          ..
+        cmake --build . -j $(nproc)
+        ccache --show-stats
+
+    - name: Save build cache
+      uses: actions/cache/save at v4
+      with:
+        path: .ccache
+        key: ${{ steps.restore-cache.outputs.cache-primary-key }}
+
+#    - name: Test
+#      working-directory: ./build
+#      run: ctest --output-on-failure
 
   code-quality:
     name: Code quality checks
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a1e2f0c6e..8f63318f4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -317,6 +317,12 @@ set(CMAKE_CXX_FLAGS_COVERAGE "-fprofile-arcs -ftest-coverage")
 include(CheckLibraryExists)
 check_library_exists(m pow "" HAVE_LIBM)
 
+#-----------------------------------------------------------------------------
+# Extra include
+#-----------------------------------------------------------------------------
+include(CheckIncludeFileCXX)
+check_include_file_cxx(cfenv HAVE_FENV_H)
+
 #-----------------------------------------------------------------------------
 # Target geos: C++ API library
 #-----------------------------------------------------------------------------
@@ -558,10 +564,3 @@ if(PROJECT_IS_TOP_LEVEL)
 
   unset(_is_multi_config_generator)
 endif()  # PROJECT_IS_TOP_LEVEL
-
-include(CheckIncludeFile)
-check_include_file(fenv.h HAVE_FENV_H)
-
-if(HAVE_FENV_H)
-    target_compile_definitions(geos_cxx_flags INTERFACE HAVE_FENV)
-endif()
diff --git a/NEWS.md b/NEWS.md
index d31f941e0..cf736c28d 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,4 +1,10 @@
 
+## Changes in 3.14.2
+2025-xx-xx
+
+- Fixes/Improvements:
+  - Relax other floating-point exception handling with other compilers (GH-1333, Mike Taves)
+
 ## Changes in 3.14.1
 2025-10-27
 
@@ -8,7 +14,6 @@
   - GridIntersection: Fix crash for certain polygons outside grid extent (Dan Baston)
   - Fix incorrect envelope calculation for arcs (GH-1314, Dan Baston)
 
-
 ## Changes in 3.14.0
 2025-08-21
 
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index 063c408ff..ecaa63d2f 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -63,6 +63,11 @@ foreach(_testfile ${_testfiles})
     set_tests_properties(unit-${_cmake_testname} PROPERTIES TIMEOUT 30)
 endforeach()
 
+if(NOT HAVE_FENV_H)
+  # Used to set HAVE_FENV in test files
+  add_compile_definitions(MISSING_FENV)
+endif()
+
 # Run all the unit tests in one go, for faster memory checking
 # under valgrind. Restrict to one configuration so it is only
 # run with 'ctest -C Valgrind'
diff --git a/tests/unit/algorithm/distance/DiscreteHausdorffDistanceTest.cpp b/tests/unit/algorithm/distance/DiscreteHausdorffDistanceTest.cpp
index f50b58680..8e85bf0a4 100644
--- a/tests/unit/algorithm/distance/DiscreteHausdorffDistanceTest.cpp
+++ b/tests/unit/algorithm/distance/DiscreteHausdorffDistanceTest.cpp
@@ -16,7 +16,10 @@
 #include <cmath>
 #include <string>
 #include <memory>
+#if !defined(MISSING_FENV)
+#define HAVE_FENV
 #include <cfenv>
+#endif
 
 namespace geos {
 namespace geom {
@@ -191,13 +194,17 @@ template<>
 void object::test<6>
 ()
 {
+#ifdef HAVE_FENV
     std::feclearexcept(FE_ALL_EXCEPT);
+#endif
 
     runTest(
         "LINESTRING (0 0, 100 0, 10 100, 10 100)",
         "LINESTRING (0 100, 0 10, 80 10)", 0.001, 47.89);
 
+#ifdef FE_INVALID
     ensure("FE_INVALID raised", !std::fetestexcept(FE_INVALID));
+#endif
 }
 
 // Crash on collection with empty components
diff --git a/tests/unit/capi/GEOSDistanceTest.cpp b/tests/unit/capi/GEOSDistanceTest.cpp
index f5f5e1471..152aade8b 100644
--- a/tests/unit/capi/GEOSDistanceTest.cpp
+++ b/tests/unit/capi/GEOSDistanceTest.cpp
@@ -9,7 +9,10 @@
 #include <algorithm>
 #include <cstdio>
 #include <cstdlib>
+#if !defined(MISSING_FENV)
+#define HAVE_FENV
 #include <fenv.h>
+#endif
 #include <cmath>
 
 #include "capi_test_utils.h"
@@ -119,8 +122,10 @@ void object::test<4>
     geom1_ = fromWKT("POINT (0 0)");
     geom2_ = fromWKT("POINT (1 1)");
 
+#ifdef HAVE_FENV
     // clear all floating point exceptions
     feclearexcept (FE_ALL_EXCEPT);
+#endif
 
     double d;
     int status = GEOSDistance(geom1_, geom2_, &d);
@@ -128,9 +133,11 @@ void object::test<4>
     ensure_equals(status, 1);
     ensure_equals(d, std::sqrt(2));
 
+#ifdef FE_OVERFLOW
     // check for floating point overflow exceptions
     int raised = fetestexcept(FE_OVERFLOW);
     ensure_equals(raised & FE_OVERFLOW, 0);
+#endif
 }
 
 // same distance between boundables should not raise floating point exception
@@ -142,8 +149,10 @@ void object::test<5>
     geom1_ = fromWKT("LINESTRING (0 0, 1 1)");
     geom2_ = fromWKT("LINESTRING (2 1, 1 2)");
 
+#ifdef HAVE_FENV
     // clear all floating point exceptions
     feclearexcept (FE_ALL_EXCEPT);
+#endif
 
     double d;
     int status = GEOSDistance(geom1_, geom2_, &d);
@@ -151,9 +160,11 @@ void object::test<5>
     ensure_equals(status, 1);
     // ensure_equals(d, std::sqrt(2));
 
+#ifdef FE_OVERFLOW
     // check for floating point overflow exceptions
     int raised = fetestexcept(FE_OVERFLOW);
     ensure_equals(raised & FE_OVERFLOW, 0);
+#endif
 }
 
 template<>
diff --git a/tests/unit/capi/GEOSIntersectionTest.cpp b/tests/unit/capi/GEOSIntersectionTest.cpp
index c94b056a7..4a03845df 100644
--- a/tests/unit/capi/GEOSIntersectionTest.cpp
+++ b/tests/unit/capi/GEOSIntersectionTest.cpp
@@ -140,7 +140,9 @@ void object::test<7>
 
     result_ = GEOSIntersection(geom1_, geom2_);
 
+#ifdef FE_INVALID
     ensure(!std::fetestexcept(FE_INVALID));
+#endif
 }
 
 template<>
diff --git a/tests/unit/capi/GEOSProjectTest.cpp b/tests/unit/capi/GEOSProjectTest.cpp
index af8640f8b..d2556a897 100644
--- a/tests/unit/capi/GEOSProjectTest.cpp
+++ b/tests/unit/capi/GEOSProjectTest.cpp
@@ -100,14 +100,22 @@ void object::test<5>
     geom1_ = GEOSGeomFromWKT("LINESTRING (0 0, 1 1, 1 1, 2 2)");
     geom2_ = GEOSGeomFromWKT("POINT (0 1)");
 
+#ifdef HAVE_FENV
     std::feclearexcept(FE_ALL_EXCEPT);
+#endif
     double dist = GEOSProject(geom1_, geom2_);
+#ifdef FE_INVALID
     ensure("FE_INVALID raised", !std::fetestexcept(FE_INVALID));
+#endif
     ensure_equals("GEOSProject", dist, 0.7071, 0.0001);
 
+#ifdef HAVE_FENV
     std::feclearexcept(FE_ALL_EXCEPT);
+#endif
     double dist_norm = GEOSProjectNormalized(geom1_, geom2_);
+#ifdef FE_INVALID
     ensure("FE_INVALID raised", !std::fetestexcept(FE_INVALID));
+#endif
     ensure_equals("GEOSProjectNormalized", dist_norm, 0.25);
 }
 
diff --git a/tests/unit/capi/GEOSVoronoiDiagramTest.cpp b/tests/unit/capi/GEOSVoronoiDiagramTest.cpp
index 7c5b05bcd..d79181351 100644
--- a/tests/unit/capi/GEOSVoronoiDiagramTest.cpp
+++ b/tests/unit/capi/GEOSVoronoiDiagramTest.cpp
@@ -5,7 +5,10 @@
 // geos
 #include <geos_c.h>
 // std
+#if !defined(MISSING_FENV)
+#define HAVE_FENV
 #include <cfenv>
+#endif
 
 #include "capi_test_utils.h"
 
@@ -57,7 +60,9 @@ template<>
 void object::test<1>
 ()
 {
+#ifdef HAVE_FENV
     std::feclearexcept(FE_ALL_EXCEPT);
+#endif
 
     geom1_ = GEOSGeomFromWKT("POINT(10 20)");
 
@@ -69,7 +74,9 @@ void object::test<1>
     geom2_ = GEOSVoronoiDiagram(geom1_, nullptr, 0, 1);
     ensure_geometry_equals(geom2_, "MULTILINESTRING EMPTY");
 
+#ifdef FE_INVALID
     ensure("FE_INVALID raised", !std::fetestexcept(FE_INVALID));
+#endif
 }
 
 //More points:
diff --git a/tests/unit/capi/capi_test_utils.h b/tests/unit/capi/capi_test_utils.h
index 67818d6a1..0b8d03284 100644
--- a/tests/unit/capi/capi_test_utils.h
+++ b/tests/unit/capi/capi_test_utils.h
@@ -7,7 +7,10 @@
 
 #include <cstdarg>
 #include <cstdio>
+#if !defined(MISSING_FENV)
+#define HAVE_FENV
 #include <cfenv>
+#endif
 
 
 namespace capitest {
@@ -29,7 +32,9 @@ namespace capitest {
             wktw_ = GEOSWKTWriter_create();
             GEOSWKTWriter_setRoundingPrecision(wktw_, 10);
 
+#ifdef HAVE_FENV
             std::feclearexcept(FE_ALL_EXCEPT);
+#endif
         }
 
         ~utility()
diff --git a/tests/unit/geom/EnvelopeTest.cpp b/tests/unit/geom/EnvelopeTest.cpp
index b1250a63e..5974f84e0 100644
--- a/tests/unit/geom/EnvelopeTest.cpp
+++ b/tests/unit/geom/EnvelopeTest.cpp
@@ -8,7 +8,10 @@
 #include <geos/geom/Coordinate.h>
 
 #include <array>
+#if !defined(MISSING_FENV)
+#define HAVE_FENV
 #include <cfenv>
+#endif
 #include <unordered_set>
 
 namespace tut {
@@ -23,7 +26,9 @@ using geos::geom::Envelope;
 struct test_envelope_data {
     test_envelope_data()
     {
+#ifdef HAVE_FENV
         std::feclearexcept(FE_ALL_EXCEPT);
+#endif
     }
 
     static std::size_t
@@ -91,11 +96,21 @@ struct test_envelope_data {
     static void
     ensure_no_fp_except()
     {
+#ifdef FE_DIVBYZERO
         ensure("FE_DIVBYZERO raised", !std::fetestexcept(FE_DIVBYZERO));
+#endif
+//#ifdef FE_INEXACT
         //ensure("FE_INEXACT raised", !std::fetestexcept(FE_INEXACT));
+//#endif
+#ifdef FE_INVALID
         ensure("FE_INVALID raised", !std::fetestexcept(FE_INVALID));
+#endif
+#ifdef FE_OVERFLOW
         ensure("FE_OVERFLOW raised", !std::fetestexcept(FE_OVERFLOW));
+#endif
+#ifdef FE_UNDERFLOW
         ensure("FE_UNDERFLOW raised", !std::fetestexcept(FE_UNDERFLOW));
+#endif
     }
 };
 
diff --git a/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp b/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp
index 27279708e..66865b349 100644
--- a/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp
+++ b/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp
@@ -9,7 +9,10 @@
 #include <geos/util.h>
 
 // std
+#if !defined(MISSING_FENV)
+#define HAVE_FENV
 #include <cfenv>
+#endif
 #include <memory>
 
 using namespace geos::geom;
@@ -33,9 +36,13 @@ struct test_coverageunionng_data {
     {
         std::unique_ptr<Geometry> geom = r.read(wkt);
         std::unique_ptr<Geometry> expected = r.read(wktExpected);
+#ifdef HAVE_FENV
         std::feclearexcept(FE_ALL_EXCEPT);
+#endif
         std::unique_ptr<Geometry> result = CoverageUnion::geomunion(geom.get());
+#ifdef FE_INVALID
         ensure("FE_INVALID raised", !std::fetestexcept(FE_INVALID));
+#endif
 
         try {
             ensure_equals_geometry_xyzm(result.get(), expected.get());
diff --git a/util/geosop/CMakeLists.txt b/util/geosop/CMakeLists.txt
index 165727460..2351fc6ff 100644
--- a/util/geosop/CMakeLists.txt
+++ b/util/geosop/CMakeLists.txt
@@ -16,6 +16,10 @@ add_executable(geosop
 
 target_link_libraries(geosop PRIVATE geos geos_c)
 
+if(NOT HAVE_FENV_H)
+  target_compile_definitions(geosop PRIVATE MISSING_FENV)
+endif()
+
 install(TARGETS geosop
   DESTINATION ${CMAKE_INSTALL_BINDIR}
 )
diff --git a/util/geosop/GeosOp.cpp b/util/geosop/GeosOp.cpp
index 05307cf30..bee8b75a9 100644
--- a/util/geosop/GeosOp.cpp
+++ b/util/geosop/GeosOp.cpp
@@ -26,7 +26,8 @@
 #include <geos/io/WKBStreamReader.h>
 #include <geos/io/WKBWriter.h>
 
-#if defined(HAVE_FENV)
+#if !defined(MISSING_FENV)
+#define HAVE_FENV
 #include <cfenv>
 #endif
 #include <fstream>
@@ -396,30 +397,44 @@ void GeosOp::run(OpArguments& opArgs) {
     //------------------------
 
     try {
-#if defined(HAVE_FENV)
+#ifdef HAVE_FENV
         std::feclearexcept(FE_ALL_EXCEPT); // clear floating-point status flags
-#endif
 
         execute(op, opArgs);
 
-#if defined(HAVE_FENV)
+#ifdef FE_INEXACT
         // Catch everything except for FE_INEXACT, which is usually harmless
         const int fpexp = std::fetestexcept(FE_ALL_EXCEPT ^ FE_INEXACT);
+#else
+        const int fpexp = std::fetestexcept(FE_ALL_EXCEPT);
+#endif
         if (args.isVerbose && (fpexp != 0)) {
             std::cerr << "Operation raised floating-point environment flag(s):";
+#ifdef FE_DIVBYZERO
             if (fpexp & FE_DIVBYZERO)
                 std::cerr << " FE_DIVBYZERO";
+#endif
+#ifdef FE_INEXACT
             if (fpexp & FE_INEXACT)
                 std::cerr << " FE_INEXACT";
+#endif
+#ifdef FE_INVALID
             if (fpexp & FE_INVALID)
                 std::cerr << " FE_INVALID";
+#endif
+#ifdef FE_OVERFLOW
             if (fpexp & FE_OVERFLOW)
                 std::cerr << " FE_OVERFLOW";
+#endif
+#ifdef FE_UNDERFLOW
             if (fpexp & FE_UNDERFLOW)
                 std::cerr << " FE_UNDERFLOW";
+#endif
             std::cerr << std::endl;
         }
-#endif
+#else  // MISSING_FENV
+        execute(op, opArgs);
+#endif  // HAVE_FENV
     }
     catch (std::exception &e) {
         std::cerr << "Run-time exception: " << e.what() << std::endl;

-----------------------------------------------------------------------

Summary of changes:
 .github/workflows/ci.yml                           | 43 ++++++++++++++++++++++
 CMakeLists.txt                                     | 13 +++----
 NEWS.md                                            |  7 +++-
 tests/unit/CMakeLists.txt                          |  5 +++
 .../distance/DiscreteHausdorffDistanceTest.cpp     |  7 ++++
 tests/unit/capi/GEOSDistanceTest.cpp               | 11 ++++++
 tests/unit/capi/GEOSIntersectionTest.cpp           |  2 +
 tests/unit/capi/GEOSProjectTest.cpp                |  8 ++++
 tests/unit/capi/GEOSVoronoiDiagramTest.cpp         |  7 ++++
 tests/unit/capi/capi_test_utils.h                  |  5 +++
 tests/unit/geom/EnvelopeTest.cpp                   | 15 ++++++++
 .../operation/overlayng/CoverageUnionNGTest.cpp    |  7 ++++
 util/geosop/CMakeLists.txt                         |  4 ++
 util/geosop/GeosOp.cpp                             | 25 ++++++++++---
 14 files changed, 146 insertions(+), 13 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list