Gecode 6.3.0 and 6.4.0 are releasedDRAFT
After a long pause, Gecode has two new releases. Gecode 6.3.0 is dated 7 July 2026, and Gecode 6.4.0 followed on 15 July.
The two versions have different purposes. Version 6.3.0 collects the changes that accumulated on its release branch during the seven years since Gecode 6.2.0. Version 6.4.0 moves development to the main branch, makes CMake the intended build system, and switches releases to source-only.
If you are starting a project or upgrading an existing one, use 6.4.0. I have grouped the changes below by what they mean for users and developers, rather than following the commit history.
Building and using Gecode is more conventional
The most visible change in Gecode 6.4.0 is the build and installation flow. CMake was available before, but it now covers the native build properly and is the intended way to build Gecode. A normal source build looks like this:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Releasecmake --build build --parallelcmake --build build --target checkcmake --install build --prefix /path/to/installThe install step creates a CMake package. A separate CMake project can therefore consume Gecode without maintaining its own FindGecode.cmake file or manually assembling include paths and libraries:
find_package(Gecode CONFIG REQUIRED)
add_executable(my-model main.cpp)target_link_libraries(my-model PRIVATE Gecode::gecode)The aggregate Gecode::gecode target is the simple default. Projects that want a narrower dependency can request and link individual components, such as driver, flatzinc, or gist.
The package also exports Gecode_VERSION, so downstream version checks no longer need to inspect generated headers.
The packages carry transitive dependencies and record which optional components were built. This is particularly useful for installations involving MPFR, Qt, or Gist. Qt 6 is now preferred, while Qt 5.15 and later remains supported.
The minimum CMake version is 3.21, and the build expects a C++17-capable compiler. The Autotools build remains supported in 6.4.0, but is planned for removal in a later release.
The maintenance generators have moved from Perl to Python scripts run through uv, making their environment easier to reproduce. Ordinary CMake builds use the generated files included in the source release and do not need these scripts.
MiniZinc and FlatZinc have caught up
Much of Gecode 6.3.0 brings its MiniZinc integration up to date. The accumulated changes include:
- support for the standard
sliding_amongandregular_setconstraints; - the full
cumulativesscheduling constraint, including optional activities forcumulativeanddisjunctive; - solver configuration and library files installed in the locations expected by MiniZinc;
- value, domain, and bounds propagation annotations;
- better FlatZinc errors, including MiniZinc constraint names when they are available; and
- the experimental
on_restartinterface for expressing restart-based meta-search.1
Several individually small fixes bring the FlatZinc behavior closer to the intended MiniZinc semantics. Array arguments are correctly unshared for constraints such as inverse, division, modulo, arg_min, arg_max, and tables. Element constraints can preserve index offsets rather than introducing transformed arrays.
Zero-duration tasks, empty sets, integer powers, and Boolean tables now follow their intended MiniZinc semantics.
Gecode 6.4.0 adds support for the experimental MiniZinc black-box propagator interface.2 A FlatZinc model can connect a custom value or bounds propagator implemented in either a shared library or a persistent subprocess. The propagator returns both its result and the dependencies that determine when it must run again. A model can therefore use specialized propagation without first adding a native propagator to the solver itself.
The black-box interface is experimental rather than a frozen long-term API. It does, however, provide a practical way to test propagator ideas from MiniZinc.
New propagation choices
Gecode 6.4.0 adds selectable support representations for extensional integer constraints.3
A TupleSet can use dense, sparse, or compressed-dense supports, or let Gecode choose automatically.
The selected representation is then used by the corresponding table propagator.
FlatZinc tables and examples that materialize larger tuple sets use automatic selection.
Tuple sets for table constraints can have very different shapes. A representation suited to a small dense table may waste memory on a large sparse one. Library users can choose the representation explicitly, while the automatic mode lets Gecode make the same choice for FlatZinc tables.
Bin-packing propagation also has lower bounds based on dual-feasible functions.4 They can detect infeasible packing states earlier than the previous propagation alone, and the advanced propagation level is now the default.
Correctness and stability work
The less visible part of 6.4.0 is also the part I value most in a solver release: a broad round of correctness and stability fixes.
Two integer propagator fixes address serious corner cases. Domain-level global cardinality propagation could lose solutions by counting assigned variables twice and retaining stale conflict information. The sorted constraint could fail to terminate when a matching component had no compatible interval. Both have regression tests.
Floating-point propagation received a similar pass. Interval medians no longer overflow near large bounds, which could otherwise prevent search from making progress.5 Multiplication, power, and nth-root propagation now contract intervals directly and avoid several tight-bound and even-root corner cases.
Search and cloning were tested under sanitizers and deterministic fault injection. This uncovered races and lifetime issues in parallel search, undefined behaviour during branch-and-bound recomputation, and incomplete cleanup when allocation fails while cloning a space or constructing MiniModel expressions. Failed cloning is now transactional. The source space is restored and the partial clone is released instead of leaving forwarding links or actor lists in an inconsistent state.6
Ordinary examples rarely exercise these paths. Allocation failures and timing-dependent search races are hard to reproduce without dedicated fault-injection and sanitizer configurations, which make them repeatable enough to catch regressions.
Version 6.3.0 already did preparatory work in the same direction. Platform-specific thread implementations were replaced by standard C++ threads, statistics counters were widened for long-running searches, the test suite gained parallel execution, and a leak in parallel search was fixed.7 Version 6.4.0 builds on that foundation with current Windows, macOS, and Linux CI coverage.
Compatibility changes to check
There are three changes worth checking before updating an existing build:
- Releases are source-only. There are no Gecode-provided Windows installers or macOS disk images for 6.4.0.
- The old
qecodeandquacodecontrib modules are no longer part of the repository or release archive. Projects that still depend on them must keep an older release or maintain the modules separately. - The public
GECODE_FLATZINC_VERSIONmacro has been removed. It described a fixed FlatZinc language revision, while current MiniZinc integration is capability-based. UseGECODE_VERSIONfor the Gecode release, and the installed MiniZinc solver metadata for FlatZinc capabilities.
Static Windows clients using the older GIST_STATIC_LIBS spelling continue to work, although GECODE_STATIC_LIBS remains the preferred macro.
Getting the release
Gecode 6.4.0 can be downloaded from the Gecode download page or from the GitHub release. The source is also available directly from the release-6.4.0 tag.
For all individual changes, see the 6.4.0 and 6.3.0 changelog. The reference documentation and Modeling and Programming with Gecode have also been rebuilt for the release.
These releases clear a substantial backlog. For future work, the larger change is simpler: Gecode has one active development branch and a build that fits current C++ projects.
Footnotes
-
The Gecode implementation of
on_restartwas contributed by Jip J. Dekker. The interface builds on Solver-Independent Large Neighbourhood Search. ↩ -
The Gecode implementation was contributed by Jip J. Dekker. The interface is described in Defining Propagators in MiniZinc, by Jip J. Dekker, Peter J. Stuckey, Guido Tack, Huu Quang Tran, and Markus Wagner. ↩
-
Thanks to Helmut Simonis for discovering the problem with sparse domains while working on Modeling the Inglenook Shunting Puzzle, co-authored with Luis Quesada. The Inglenook model prompted the sparse
TupleSetrepresentation and automatic representation selection described here. ↩ -
The dual-feasible-function propagation was contributed by Fabio Tardivo. It is based on the lower-bound portfolio described in CP for Bin Packing with Multi-Core and GPUs, by Fabio Tardivo, Laurent Michel, and Enrico Pontelli. ↩
-
Pierre Talbot reported the unbounded-float case in issue #164 that exposed the overflow in the interval-median calculation. ↩
-
Kris Coester and Alexander Shepil from SAP contributed the original exception-safety and allocation-failure work in PR #211. SAP has described how it uses Gecode for advanced variant configuration. ↩
-
Alexis LG contributed the fix for the parallel-search solution-queue leak reported in issue #156. ↩