Skip to content

Customize the Configuration

Donato Meoli edited this page Jun 18, 2026 · 3 revisions

This guide covers how to customize the configuration of SMS++ when building it with CMake. It applies both to the umbrella SMS++ Project — which fetches, configures and builds all the modules at once — and to the individual modules, which can be fetched, configured and built one by one. Some modules expose additional configuration options of their own, documented in their README.

If you just want to get SMS++ up and running with sane defaults, follow the installation guide and the INSTALL scripts instead — in most cases you don't need to touch any of the settings below.

[[TOC]]

How to pass settings to CMake

You can add or change a setting by passing a custom variable to CMake on the command line with the -D option (note the D):

cmake <source-tree> -D<VAR_NAME>=<var-value>

For example:

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release

Note: for a primer on how CMake works, see the official CMake tutorial.

If you are building through the umbrella SMS++ Project, you can also set the same variables once and for all in the CMakeSettings.txt file at the root of the project, using the set command:

set(<VAR_NAME> <var-value>)

CMakeSettings.txt is included at the very top of the umbrella CMakeLists.txt, so anything you set there is picked up automatically at configure time. It ships with a few settings already active (BUILD_SHARED_LIBS, CMAKE_EXPORT_PACKAGE_REGISTRY, Boost_NO_WARN_NEW_VERSIONS) and many more commented out, ready to be uncommented.

Finally, if you prefer an interactive interface over the command line, configure once and then edit the cached variables with ccmake (Linux/macOS) or cmake-gui (Windows):

cd build
ccmake ..        # Linux/macOS, needs cmake-curses-gui
cmake-gui .      # Windows

This is handy to toggle the BUILD_* module flags (see below) and to point external libraries to custom locations without re-typing long command lines.

Build type

The build type controls the optimization/debug flags passed to the compiler. Set it with CMAKE_BUILD_TYPE:

cmake <source-tree> -DCMAKE_BUILD_TYPE=Debug

The available build types, and the flags CMake adds for each, are:

Value Compiler flags
Debug -g
MinSizeRel -Os -DNDEBUG
Release -O3 -DNDEBUG
RelWithDebInfo -O2 -g -DNDEBUG

By default, CMAKE_BUILD_TYPE is empty, so none of these flags are applied. For day-to-day use we recommend Release; in Debug builds the umbrella also disables inlining (-fno-inline) to make stepping through the code easier.

Enabling and disabling modules

The umbrella project is a collection of Blocks, Solvers, tools and tests, each guarded by its own BUILD_<Module> option. By default a module is built only if its submodule has already been initialized (i.e. its CMakeLists.txt is on disk); otherwise the option defaults to OFF. When a BUILD_* flag is turned ON but the submodule is missing, the umbrella initializes it for you with git submodule update --init --recursive.

The available flags are:

Blocks

Flag Module
BUILD_BinaryKnapsackBlock DP-based binary knapsack
BUILD_UCBlock Unit Commitment (power systems)
BUILD_MCFBlock Min-Cost Flow Block
BUILD_MMCFBlock Multicommodity MCF
BUILD_LukFiBlock Test functions for nonsmooth optimization
BUILD_StochasticBlock Stochastic wrapper
BUILD_SDDPBlock SDDP algorithm
BUILD_CapacitatedFacilityLocationBlock Capacitated Facility Location
BUILD_InvestmentBlock Investment problem
BUILD_TwoStageStochasticBlock Two-stage stochastic wrapper

Solvers

Flag Module
BUILD_MILPSolver MILP/MIQP via HiGHS, SCIP, CPLEX, Gurobi
BUILD_BranchAndXSolver Branch-and-X solver
BUILD_BundleSolver Bundle / nondifferentiable optimization
BUILD_LagrangianDualSolver Lagrangian dual
BUILD_MCFClassSolver MCFSolver, wraps MCFClass
BUILD_MCFLemonSolver MCF via LEMON

Tools and tests

Flag What it builds
BUILD_tools Command-line tools
BUILD_tests System / integration test suites

To build only a subset of modules, turn the others off explicitly, for example:

cmake -S . -B build -DBUILD_SDDPBlock=OFF -DBUILD_BundleSolver=OFF

or, the other way around, enable just what you need on top of a minimal configuration:

cmake -S . -B build -DBUILD_UCBlock=ON -DBUILD_MILPSolver=ON -DBUILD_tests=ON

Tip: you can also simply comment out the modules you don't need directly in the umbrella CMakeLists.txt, or toggle the flags interactively with ccmake / cmake-gui.

Automatic dependency resolution

Each module flag automatically pulls in the modules it depends on, so you never have to enable a dependency by hand. The umbrella resolves the following chains before adding any subdirectory:

  • BUILD_MMCFBlockBUILD_MCFBlock, BUILD_BinaryKnapsackBlock
  • BUILD_InvestmentBlockBUILD_SDDPBlock, BUILD_UCBlock
  • BUILD_TwoStageStochasticBlockBUILD_StochasticBlock
  • BUILD_SDDPBlockBUILD_StochasticBlock
  • BUILD_StochasticBlockBUILD_CapacitatedFacilityLocationBlock
  • BUILD_CapacitatedFacilityLocationBlockBUILD_MCFBlock, BUILD_BinaryKnapsackBlock
  • BUILD_BundleSolverBUILD_MILPSolver
  • BUILD_MCFClassSolverBUILD_MCFBlock
  • BUILD_MCFLemonSolverBUILD_MCFBlock

Whenever any module is enabled, the SMS++ core library is built as well, since every module depends on it.

MILP back-ends: enabling BUILD_MILPSolver builds whichever of the four interchangeable solver back-ends are found on your system — HiGHSMILPSolver (HiGHS), SCIPMILPSolver (SCIP), CPXMILPSolver (CPLEX) and GRBMILPSolver (Gurobi). At least one of them must be installed; see the installation guide for how to install them.

Build the system tests

Unlike the older BUILD_TESTING toggle, the integration/system test suites in the umbrella are controlled by the BUILD_tests flag described above. Enable them with:

cmake <source-tree> -DBUILD_tests=ON

and disable them (the default, unless the tests submodule is already initialized) with -DBUILD_tests=OFF. Once configured, run them with:

ctest -V -C Release            # run all tests
ctest -V -R <test-name>        # run a single test by name pattern

Shared or static libraries

The vanilla CMake default is to build static libraries. The umbrella, however, sets BUILD_SHARED_LIBS to ON in CMakeSettings.txt, so by default it builds shared libraries. To override this, pass:

cmake <source-tree> -DBUILD_SHARED_LIBS=OFF   # static
cmake <source-tree> -DBUILD_SHARED_LIBS=ON    # shared

On Windows, when building shared libraries the umbrella automatically sets CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON so that all symbols are exported from the DLLs.

Location of external libraries

CMake automatically finds the required libraries when they are installed in standard system locations (e.g. via apt on Debian-based systems, homebrew on macOS, or vcpkg on Windows). If you installed them with our installation guide or the INSTALL scripts, they should be picked up out of the box.

The default search locations are defined, per operating system, in:

These files are shared between the CMake build and the hand-written makefiles: the umbrella CMakeLists.txt parses the <Lib>_ROOT = <path> entries and turns them into the corresponding CMake variables (skipping the generic /usr and /usr/local defaults, which CMake already searches).

Overriding paths individually

If a library is installed somewhere non-standard, point CMake at it with the matching *_ROOT variable:

Variable Path
Boost_ROOT Boost root directory
Eigen3_ROOT Eigen3 root directory
netCDF_ROOT netCDF-C root directory
netCDFCxx_ROOT netCDF-C++ root directory
LEMON_ROOT LEMON root directory
CPLEX_ROOT CPLEX root directory
GUROBI_ROOT Gurobi root directory
SCIP_ROOT SCIP root directory
HiGHS_ROOT HiGHS root directory
StOpt_ROOT StOpt root directory
CoinUtils_ROOT COIN-OR CoinUtils root directory
Osi_ROOT COIN-OR Osi root directory
Clp_ROOT COIN-OR Clp root directory
FastFlow_ROOT FastFlow root directory
Torch_ROOT Torch (PyTorch C++ API) root directory

For example, if you extracted Boost in /my/custom/path:

cmake <source-tree> -DBoost_ROOT="/my/custom/path"

Overriding paths in bulk (makefile-paths)

If several libraries need to be relocated, editing the command line every time gets tedious. Instead, copy the default file for your OS into extlib/makefile-paths and edit the paths there:

cp extlib/makefile-default-paths-linux extlib/makefile-paths
# then edit extlib/makefile-paths

extlib/makefile-paths, if present, is read first by both the CMake build and the makefiles, and the values it defines take precedence over the OS defaults. Because this file is .gitignore-d, your local paths are never committed and survive a git pull without conflicts. A typical Linux override looks like:

CPLEX_ROOT     = /opt/ibm/ILOG/CPLEX_Studio
GUROBI_ROOT    = /opt/gurobi
SCIP_ROOT      = /opt/scip
HiGHS_ROOT     = /opt/HiGHS
StOpt_ROOT     = /opt/StOpt
CoinUtils_ROOT = /opt/coin-or
Osi_ROOT       = /opt/coin-or
Clp_ROOT       = /opt/coin-or
Torch_ROOT     = /opt/torch

The same override mechanism applies to the makefile-only sub-projects shipped inside some modules, namely BundleSolver/NdoFiOracle/extlib/makefile-paths and MCFClassSolver/MCFClass/extlib/makefile-paths. The INSTALL scripts generate all of these automatically when run with a non-default --install-root.

Windows / vcpkg: on Windows the dependencies listed in the vcpkg.json manifest (Boost, HiGHS, StOpt, LEMON, the COIN-OR libraries, netCDF-C++, MS-MPI, …) are resolved by vcpkg in manifest mode at configure time. Point CMake at the vcpkg toolchain with -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake; the *_ROOT defaults in makefile-default-paths-win then point inside C:/vcpkg/installed/x64-windows. See the installation guide for the full Windows setup.

Using the User Package Registry

When building modules individually, other modules locate the SMS++ core library (and each other) through CMake's find_package, which normally requires the library to be installed. You can skip the install step by exporting each build tree into CMake's User Package Registry with CMAKE_EXPORT_PACKAGE_REGISTRY:

cmake <source-tree> -DCMAKE_EXPORT_PACKAGE_REGISTRY=ON

Once a package is exported in the registry, CMake finds it even if it is not installed system-wide. This is particularly convenient when building SMS++ submodules without installing the core library first.

Note: in the umbrella SMS++ Project, CMAKE_EXPORT_PACKAGE_REGISTRY is set to ON by default (in CMakeSettings.txt), so all the modules build against one another out of the build tree, with no install required.

Custom output directories

By default, CMake writes the build artifacts under the build directory. To collect all libraries and executables under predictable lib/ and bin/ folders, uncomment the corresponding lines in CMakeSettings.txt (or pass them with -D):

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

See also

Clone this wiki locally