Skip to content

Using SMS++ with vcpkg

Donato Meoli edited this page Oct 16, 2026 · 9 revisions

If you want to consume SMS++ as a dependency in another project, the easiest way is through the SMS++ vcpkg registry. It packages SMS++ (and its otherwise-unavailable dependency StOpt) as vcpkg ports, so any project can pull smspp like any other library, with vcpkg taking care of building it and all of its transitive dependencies.

This guide explains how to set up a project that depends on SMS++ via the registry. If you instead want to build and install SMS++ itself from source, see the Installation guide; for a first program against an already-installed SMS++, see Getting started.

[[TOC]]

What the registry provides

The registry lives at https://gitlab.com/smspp/vcpkg-registry.git. It is a vcpkg git registry that exposes these ports:

Port Version Upstream
smspp 0.6.0 https://gitlab.com/smspp/smspp-project
stopt 6.3 https://gitlab.com/stochastic-control/StOpt
cadical 3.0.1 https://github.com/arminbiere/cadical
daqp 0.10.3 https://github.com/darnstrom/daqp

stopt (StOpt), cadical (CaDiCaL, the SAT solver of the sat feature) and daqp (DAQP, the QP solver of the milp feature next to HiGHS) are dependencies of smspp that are not available in the default vcpkg registry, so they are hosted here too. This means a project depending on smspp routes these packages to this single registry and needs no other custom registry for SMS++. cadical is built as a static library, and not on Windows, where CaDiCaL does not build: there SATBlock has no SAT solver.

The registry has the standard vcpkg layout:

ports/
  smspp/
    portfile.cmake      # downloads the smspp-project release and builds it
    vcpkg.json          # port manifest + dependencies
  stopt/
    portfile.cmake      # fetches StOpt v6.3 and builds it
    vcpkg.json          # port manifest + dependencies
versions/
  baseline.json         # default versions served by the registry
  s-/
    smspp.json          # version -> git-tree map
    stopt.json          # version -> git-tree map

The complete dependency set that vcpkg pulls in for smspp is declared in ports/smspp/vcpkg.json: Boost (including boost-mpi), bzip2, eigen3, getopt, highs, liblemon, msmpi (on Windows), netcdf-cxx4, pthreads, stopt and zlib. You do not need to list any of these yourself.

Note: smspp-project is an umbrella of git submodules, so the archive GitLab generates for a tag would carry none of their content. The release pipeline therefore publishes a tarball of the whole tree, submodules included, in the package registry of the project, and that is what the port downloads (see ports/smspp/portfile.cmake). Each new tag of the umbrella updates the port by itself: the release pipeline triggers the one of the registry, which sets the version, its SHA512 and the version database.

One feature per module

The port has a feature per module, named after its acronym, so a project builds only the modules it uses:

Feature Module Feature Module
ucblock UCBlock milp MILPSolver
mcf MCFBlock bundle BundleSolver
bkb BinaryKnapsackBlock lds LagrangianDualSolver
mmcf MMCFBlock frankwolfe FrankWolfeSolver
cflb CapacitatedFacilityLocationBlock bnx BranchAndXSolver
lukfi LukFiBlock bds BendersDecompositionSolver
stochastic StochasticBlock mcfclass MCFClassSolver
tssb TwoStageStochasticBlock mcflemon MCFLemonSolver
mssb MultiStageStochasticBlock srs ScenarioReductionSolver
sddp SDDPBlock svm SVMBlock
investment InvestmentBlock sfdcr SingleFlowDCRBlock
sat SATBlock satellites SatellitesBlock
mkab MultiKnapsackAssignBlock subgrad SubGradSolver

A feature brings in the features of the modules it needs, e.g. investment those of sddp, tssb and ucblock. The extra feature tools builds the command-line tools of the modules that are enabled (ucblock_solver, sddp_solver, mcfblock_solver, …) under tools/smspp in the vcpkg tree, together with their configuration files and example instances.

Every feature is a default one, so "smspp" alone builds the whole project. To pick a few, turn the default features off:

{
  "name": "smspp",
  "default-features": false,
  "features": [ "ucblock", "milp" ]
}

or, in classic mode, vcpkg install "smspp[core,ucblock,milp,tools]".

Prerequisites

  1. A vcpkg checkout. Clone vcpkg and bootstrap it:

    git clone https://github.com/microsoft/vcpkg.git
    ./vcpkg/bootstrap-vcpkg.sh        # Linux/macOS
    # .\vcpkg\bootstrap-vcpkg.bat     # Windows

    Note the path to your vcpkg checkout; you will pass its toolchain file to CMake. (On Windows, the SMS++ install scripts use C:\vcpkg.)

  2. Manifest mode. This guide uses vcpkg's manifest mode, in which your project ships a vcpkg.json and vcpkg installs the listed dependencies automatically at CMake configure time. You do not run vcpkg install smspp by hand; the dependencies are resolved from the manifest.

  3. A C++ toolchain and CMake (CMake >= 3.21, the minimum required by the SMS++ core). SMS++ is a C++17 framework, so a reasonably recent compiler is needed.

Step 1 — Create the project vcpkg.json

In the root of your project, create a vcpkg.json that:

  • lists smspp in dependencies, and
  • routes both smspp and stopt to the SMS++ registry under configuration.registries.
{
  "name": "my-project",
  "version": "1.0.0",
  "dependencies": [
    "smspp"
  ],
  "builtin-baseline": "f8be6942c0c5abd48bb325726d57af9ac39e251d",
  "configuration": {
    "registries": [
      {
        "kind": "git",
        "repository": "https://gitlab.com/smspp/vcpkg-registry.git",
        "baseline": "<commit-SHA-of-the-registry>",
        "packages": [
          "smspp",
          "stopt",
          "cadical",
          "daqp"
        ]
      }
    ]
  }
}

Key points:

  • dependencies — you only need to list smspp. Its transitive dependencies (including stopt) are declared by the port itself. To build only some of the modules, replace the "smspp" string with the object form above, which turns the default features off and lists the ones you want.
  • configuration.registries — the git registry entry tells vcpkg that the named packages must be resolved from the SMS++ registry instead of the default vcpkg registry. stopt, cadical and daqp must appear in this packages list alongside smspp, because they are not in the default registry; if you omit them, vcpkg will fail to find them when resolving smspp's dependencies.
  • baseline (inside the registry entry) — the full commit SHA of the SMS++ registry repository to pin to (see Step 2).
  • builtin-baseline — the commit SHA of your vcpkg checkout used to pin all packages that come from the default vcpkg registry (Boost, Eigen, etc.). See Updating baselines.

Note: The two baseline fields are different things. The baseline inside the configuration.registries entry pins the SMS++ registry repository; the top-level builtin-baseline pins the default vcpkg registry (your local vcpkg checkout).

Step 2 — Pick the registry baseline

vcpkg requires a baseline for a git registry: it must be the full commit SHA of the SMS++ registry repository (normally the latest commit on its default branch). Get it with:

git ls-remote https://gitlab.com/smspp/vcpkg-registry.git HEAD

Copy the SHA into the baseline field of the registry entry. vcpkg then resolves the requested versions through the registry's versions/baseline.json and versions/s-/*.json maps and builds each port from ports/<port>/.

Note: A short SHA or a branch name is not accepted by vcpkg for a git registry baseline — use the full 40-character commit SHA.

Step 3 — Write a minimal CMakeLists.txt

SMS++ exports its core library as the imported target SMS++::SMS++, found via find_package(SMS++). Link against it exactly as you would for a system-installed SMS++:

cmake_minimum_required(VERSION 3.21)
project(my-project CXX)

# provided by the smspp vcpkg port
find_package(SMS++ CONFIG REQUIRED)

add_executable(my-app main.cpp)
target_link_libraries(my-app PRIVATE SMS++::SMS++)

A minimal main.cpp to verify the link works:

#include <iostream>

#include <SMS++/AbstractBlock.h>

using namespace SMSpp_di_unipi_it;

int main()
{
 AbstractBlock b;
 std::cout << b;
 return 0;
}

Note: The exported target name SMS++::SMS++ and the find_package(SMS++) call are the same ones used in Getting started; nothing about how you reference SMS++ in CMake changes when it comes from vcpkg. Other SMS++ modules are exported under the same SMS++:: namespace by their respective CMake configs (e.g. find_package(MILPSolver) → SMS++::MILPSolver).

Step 4 — Configure with the vcpkg toolchain

Point CMake at vcpkg's toolchain file. With it on the command line and a vcpkg.json present, vcpkg builds and installs the dependencies (the first configure builds SMS++ and all of its dependencies, which can take a while) before configuring your project:

cmake -S . -B build \
      -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake \
      -DCMAKE_BUILD_TYPE=Release

cmake --build build

On Windows the toolchain path is typically C:/vcpkg/scripts/buildsystems/vcpkg.cmake.

Note: The first configure compiles SMS++ and its full dependency tree from source; this can take a long time and a fair amount of disk space. Subsequent configures reuse the vcpkg binary cache.

Step 5 — Run it

Run the resulting executable to confirm the dependency is wired up correctly:

./build/my-app

With the main.cpp above it prints an empty Block, which tells you SMS++ was found, linked and is usable from your project:

AbstractBlock with:
0 types of static Variables, 0 types of dynamic Variables,
0 types of static Constraints, 0 types of dynamic Constraints,
0 inner Blocks

From here, populate the Block and attach a Solver as in Getting started: everything you build against an installed SMS++ works unchanged when SMS++ comes from the vcpkg registry. To pull in a solver too, add its module to find_package / target_link_libraries (e.g. find_package(MILPSolver) and SMS++::MILPSolver); the smspp port already builds the modules, so no extra dependencies entry is needed.

Updating baselines

There are two independent baselines to keep current:

  • The SMS++ registry baseline (the baseline inside the configuration.registries entry). Re-run the git ls-remote from Step 2 and update the SHA whenever you want to pick up a new SMS++/StOpt port version published by the registry.

  • The vcpkg builtin baseline (builtin-baseline). This pins the versions of the packages that come from the default vcpkg registry. After a git pull in your vcpkg checkout, set it to the new revision so your manifest resolves against the updated package versions:

    git -C /path/to/vcpkg rev-parse HEAD

    On Windows, the SMS++ install script INSTALL.ps1 provides an -updatevcpkg flag that rewrites the "builtin-baseline" field in the umbrella's own vcpkg.json to the current git rev-parse HEAD of C:\vcpkg. That flag operates on the SMS++ umbrella's manifest, not on your consumer project; for your own project, update builtin-baseline by hand as shown above. See the Installation guide for details on -updatevcpkg.

Reference: the umbrella's own manifest

For comparison, the SMS++ umbrella consumes its own dependencies through vcpkg with the manifest at the repository root (vcpkg.json). Note that the umbrella's manifest lists every dependency explicitly (Boost, HiGHS, LEMON, netCDF, stopt, …) because it builds SMS++ rather than consuming the smspp port; when you consume the smspp port instead, listing smspp alone is enough. The umbrella routes only stopt to a registry (a StOpt-specific one), whereas a consumer of the smspp port routes both smspp and stopt to the SMS++ registry described above.

See also

Clone this wiki locally