Currently only a subset of CP-SAT is supported.
Pull requests providing the missing features are welcome, but please pay attention to documentation and tests.
This project provides two packages:
-
ortoolsis an OCaml interface for building CP-SAT models. It does not require an installation of OR-Tools as it simply works with the protocol buffer format. Seeutils/sat_solve_pb.{c,py}for examples of interfacing with the CP-SAT solver. -
ortools_solversbuilds onortoolsto provide a simple OCaml interface for calling CP-SAT. Building and installing it requires an OR-Tools installation (see below).
Online docs: https://inria.github.io/ocaml-ortools/
wget https://github.com/google/or-tools/releases/download/v9.15/Google.OrTools.runtime.linux-x64.9.15.6755.nupkg
unzip Google.OrTools.runtime.linux-x64.9.15.6755.nupkg \
'runtimes/linux-x64/native/*' \
-d 'ortools'
export ORTOOLS_LIBS=$(realpath ./ortools/runtimes/linux-x64/native)
LIBRARY_PATH="$ORTOOLS_LIBS:$LIBRARY_PATH"
LD_LIBRARY_PATH="$ORTOOLS_LIBS:$LD_LIBRARY_PATH"
wget https://github.com/google/or-tools/releases/download/v9.15/Google.OrTools.runtime.osx-arm64.9.15.6755.nupkg
unzip Google.OrTools.runtime.osx-arm64.9.15.6755.nupkg \
'runtimes/osx-arm64/native/*' \
-d 'ortools'
export ORTOOLS_LIBS=$(realpath ./ortools/runtimes/osx-arm64/native)
LIBRARY_PATH="$ORTOOLS_LIBS:$LIBRARY_PATH"
DYLD_LIBRARY_PATH="$ORTOOLS_LIBS:$DYLD_LIBRARY_PATH"
Obtain the runtime libraries:
-
Option 1: From the or-tools releases on github, download
Google.OrTools.runtime.<os>-<arch>.9.<minor>.<patch>.nupkgwhere os ∈ { linux, osx, win } and arch ∈ { arm64, x64 } andunzipit. The required files are inruntimes/*/native. -
Option 2 (more difficult than it may seem): Download or build from source following the official instructions (see the C++ section). See also the notes below.
-
Option 3 (involves Python): Install the Python libraires with
pip. The OR-Tools runtime can be found insite-packages/ortools/.libs.
Ensure that libortools.9.dylib (macOS) or libortools.so.9 (Linux), and
the other runtime libraries, are accessible by your compiler and loader.
For example, on macOS, set LIBRARY_PATH (for compilation) and
DYLD_LIBRARY_PATH (for execution) environment variables.
On Linux, set LIBRARY_PATH (for compilation) and LD_LIBRARY_PATH (for
execution) environment variables.
I would have liked all this to be automatic, but:
-
There do not seem to be suitable brew/linux packages that could be linked from opam;
-
Vendoring the source in the opam package and building it on install is error-prone and resource-intensive (see notes below and also an attempt in the
vendoringbranch); -
Including several binary versions in the opam package is tedious to maintain and wasteful to download; and
-
Dynamically downloading the library on build is prevented by opam sandboxing (see the
downloadbranch for a prototype).
On macOS, install the required libraries:
brew install abseil protobuf protobuf-c re2 zlib bzip2 eigen@3
I tested against the following versions:
abseil 20260107.0
protobuf 33.4
protobuf-c 1.5.2
re2 2025-11-05
zlib 1.3.1
bzip2 1.0.8
eigen@3 3.4.1
Download the OR-Tools source:
git clone --depth 1 --branch v9.15 https://github.com/google/or-tools.git
Then, in the OR-Tools source directory:
cmake -DBUILD_SAMPLES=OFF -DBUILD_EXAMPLES=OFF -DBUILD_FLATZINC=OFF \
-DBUILD_TESTING=OFF \
-DUSE_COINOR=OFF -DUSE_CPLEX=OFF -DUSE_GLPK=OFF -DUSE_HIGHS=OFF \
-DUSE_PDLP=OFF -DUSE_SCIP=OFF -DUSE_XPRESS=OFF \
-DUSE_GLOP=ON -DUSE_GUROBI=ON \
-S . -B build
cmake --build build --config Release -j -v
The USE_GUROBI and USE_GLOP options are needed to avoid missing symbols
errors during linking.
For the Abseil library, Debian packages provides libabsl-dev version
20240722, but OR-Tools v9.15 requires version 20250814.
For Protocol Buffers, Debian packages provides protobuf-compiler and
libprotobuf-c-dev v3.21.12, but OR-Tools v9.15 requires version v33.1.
Protocol Buffers requires RE2, which Debian provides as a package
libre2-dev, but this library also depends on Abseil, so if Abseil is
rebuilt, then RE2 must also be rebuilt.
Otherwise the packages libz-dev, libbz2-dev, and libeigen3-dev are
required.
Download the OR-Tools and Abseil source:
git clone --depth 1 --branch v9.15 https://github.com/google/or-tools.git
cd or-tools
git clone --depth 1 --branch 20250814.1 https://github.com/abseil/abseil-cpp.git
Add the following lines at the top of abseil-cpp/CMakeLists.txt:
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
Edit cmake/dependencies/CMakeLists.txt by replacing
FetchContent_Declare(
absl
GIT_REPOSITORY "https://github.com/abseil/abseil-cpp.git"
GIT_TAG "20250814.1"
GIT_SHALLOW TRUE
UPDATE_COMMAND git reset --hard
PATCH_COMMAND git apply --ignore-whitespace
"${CMAKE_CURRENT_LIST_DIR}/../../patches/abseil-cpp-20250814.1.patch"
OVERRIDE_FIND_PACKAGE
SYSTEM
)
with
FetchContent_Declare(
absl
SOURCE_DIR "${CMAKE_SOURCE_DIR}/abseil-cpp"
)
Build with the following commands:
cmake -DCMAKE_CXX_STANDARD=20 \
-DBUILD_absl=ON -DBUILD_Protobuf=ON -DBUILD_re2=ON \
-DBUILD_SAMPLES=OFF -DBUILD_EXAMPLES=OFF -DBUILD_FLATZINC=OFF \
-DBUILD_TESTING=OFF -DBUILD_MATH_OPT=ON \
-DUSE_COINOR=OFF -DUSE_CPLEX=OFF -DUSE_GLPK=OFF -DUSE_HIGHS=OFF \
-DUSE_PDLP=OFF -DUSE_SCIP=OFF -DUSE_XPRESS=OFF \
-DUSE_GLOP=ON -DUSE_GUROBI=ON \
-S . -B build
cmake --build build --config Release -j 16 -v
The options USE_GLOP and USE_GUROBI must be set to avoid linking errors.
Compiling with USE_GUROBI requires that USE_MATHOPT be set.
(I needed -j 16 to stop my build machine from freezing on errors.)
All of this is quite horrible. What's more, in terms of packaging the
binaries with opam, in addition to libortools.so, one would have to
include a subset of the 180 libabsl_*.so files, libre2.so, and one or
all of libprotobuf-lite.so, libprotobuf.so, libprotoc.so. This could
lead to conflicts with other current or future OCaml packages that
dynamically load, directly or indirectly, the Abseil, RE2, or Protocol
Buffer libraries.
The Protocol Buffers interfaces have been generated with ocaml-protc (with pull/263).
If required, they can be regenerated as follows.
git clone git@github.com:google/or-tools.git
cd or-tools
git checkout v9.15 % TODO: update with required version
opam install ocaml-protoc
ocaml-protoc --binary --pp --make --ml_out src/model \
<path-to-or-tools>/ortools/sat/cp_model.proto
ocaml-protoc --binary --pp --make --ml_out src/model \
<path-to-or-tools>/ortools/sat/sat_parameters.proto
Cheat sheets
- git tag -a -m '...release notes...' --sign
- dune-release bistro
- in ocaml-ortools: build the docs
dune build @doc - check out the
gh-pagesbranch to ocaml-ortools-gh-pages - in ocaml_ortools-gh-pages:
rm -r index.html odoc.support ortools ortools_solvers - in ocaml_ortools-gh-pages:
cp -r ../ocaml-ortools/_build/default/_doc/_html/* . git add,commit,push`, etc.
-
More sophisticated
Ortools_solversinterface: write in C++, require OR-Tools headers.- Support FeasibleSolutionObserver interface with callbacks into OCaml.
- Eliminate the redundant copy in
ocaml_ortools_sat_solve.
-
Finish migrating OR-Tools
sat/samples -
Use
alcotestto test the interface. -
CP-SAT: Support
Intervalconstraints -
CP-SAT: Support
NoOverlapconstraints -
CP-SAT: Support
NoOverlap2Dconstraints -
CP-SAT: Support
Elementconstraints -
CP-SAT: Support
Circuitconstraints -
CP-SAT: Support
Routesconstraints -
CP-SAT: Support
Tableconstraints -
CP-SAT: Support
Automatonconstraints -
CP-SAT: Support
Inverseconstraints -
CP-SAT: Support
Reservoirconstraints -
CP-SAT: Support
Cumulativeconstraints -
CP-SAT: Support
Dummyconstraints -
Support other solvers