-
Notifications
You must be signed in to change notification settings - Fork 0
Customize the Configuration
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]]
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=ReleaseNote: 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 . # WindowsThis is handy to toggle the BUILD_* module flags (see below) and to point external libraries to custom locations without re-typing long command lines.
The build type controls the optimization/debug flags passed to the compiler. Set it with CMAKE_BUILD_TYPE:
cmake <source-tree> -DCMAKE_BUILD_TYPE=DebugThe 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.
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=OFFor, 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=ONTip: you can also simply comment out the modules you don't need directly in the umbrella
CMakeLists.txt, or toggle the flags interactively withccmake/cmake-gui.
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_MMCFBlock→BUILD_MCFBlock,BUILD_BinaryKnapsackBlock -
BUILD_InvestmentBlock→BUILD_SDDPBlock,BUILD_UCBlock -
BUILD_TwoStageStochasticBlock→BUILD_StochasticBlock -
BUILD_SDDPBlock→BUILD_StochasticBlock -
BUILD_StochasticBlock→BUILD_CapacitatedFacilityLocationBlock -
BUILD_CapacitatedFacilityLocationBlock→BUILD_MCFBlock,BUILD_BinaryKnapsackBlock -
BUILD_BundleSolver→BUILD_MILPSolver -
BUILD_MCFClassSolver→BUILD_MCFBlock -
BUILD_MCFLemonSolver→BUILD_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_MILPSolverbuilds whichever of the four interchangeable solver back-ends are found on your system —HiGHSMILPSolver(HiGHS),SCIPMILPSolver(SCIP),CPXMILPSolver(CPLEX) andGRBMILPSolver(Gurobi). At least one of them must be installed; see the installation guide for how to install them.
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=ONand 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 patternThe 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 # sharedOn Windows, when building shared libraries the umbrella automatically sets CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON so that all symbols are exported from the DLLs.
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:
extlib/makefile-default-paths-linuxextlib/makefile-default-paths-macosextlib/makefile-default-paths-win
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).
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"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-pathsextlib/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/torchThe 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.jsonmanifest (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*_ROOTdefaults inmakefile-default-paths-winthen point insideC:/vcpkg/installed/x64-windows. See the installation guide for the full Windows setup.
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=ONOnce 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_REGISTRYis set toONby default (inCMakeSettings.txt), so all the modules build against one another out of the build tree, with no install required.
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)- Installation guide — install SMS++ and its dependencies.
- Getting started — your first SMS++ program.
- Troubleshooting — solutions to common build and configuration problems.