Repository navigation
Using SMS++ with vcpkg
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]]
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-projectis 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 (seeports/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.
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]".
-
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.) -
Manifest mode. This guide uses vcpkg's manifest mode, in which your project ships a
vcpkg.jsonand vcpkg installs the listed dependencies automatically at CMake configure time. You do not runvcpkg install smsppby hand; the dependencies are resolved from the manifest. -
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.
In the root of your project, create a vcpkg.json that:
- lists
smsppindependencies, and - routes both
smsppandstoptto the SMS++ registry underconfiguration.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 listsmspp. Its transitive dependencies (includingstopt) 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— thegitregistry entry tells vcpkg that the namedpackagesmust be resolved from the SMS++ registry instead of the default vcpkg registry.stopt,cadicalanddaqpmust appear in thispackageslist alongsidesmspp, because they are not in the default registry; if you omit them, vcpkg will fail to find them when resolvingsmspp'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
baselinefields are different things. Thebaselineinside theconfiguration.registriesentry pins the SMS++ registry repository; the top-levelbuiltin-baselinepins the default vcpkg registry (your local vcpkg checkout).
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 HEADCopy 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.
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 thefind_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 sameSMS++::namespace by their respective CMake configs (e.g.find_package(MILPSolver)→SMS++::MILPSolver).
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 buildOn 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.
Run the resulting executable to confirm the dependency is wired up correctly:
./build/my-appWith 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.
There are two independent baselines to keep current:
-
The SMS++ registry baseline (the
baselineinside theconfiguration.registriesentry). Re-run thegit ls-remotefrom 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 agit pullin 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.ps1provides an-updatevcpkgflag that rewrites the"builtin-baseline"field in the umbrella's ownvcpkg.jsonto the currentgit rev-parse HEADofC:\vcpkg. That flag operates on the SMS++ umbrella's manifest, not on your consumer project; for your own project, updatebuiltin-baselineby hand as shown above. See the Installation guide for details on-updatevcpkg.
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.
- Installation guide — building and installing SMS++ from source.
- Getting started — your first program with SMS++.
- SMS++ vcpkg registry — the registry repository and its README.