2. Compiling from Source

2.1. Quick Start

These are simplified instructions for Ubuntu, Fedora, Arch, and macOS. If a step doesn’t work or fit your case, please consult the sections below.

First, get MØD and install the easy dependencies:

git clone --recursive https://github.com/jakobandersen/mod.git
cd mod
./bootstrap.sh
pip3 install -r requirements.txt  # may need --user to install in home folder instead of system folders
# Ubuntu:
sudo apt install $(bindep -b | tr '\n' ' ')
# Fedora:
sudo dnf install $(bindep -b | tr '\n' ' ')
# Arch:
sudo pacman -Suy $(bindep -b | tr '\n' ' ')
# macOS:
brew tap Homebrew/bundle  # may not be needed
brew bundle

Then:

  1. (Ubuntu and Fedora < 33) Install Boost from source, see Boost and Boost.Python with Python 3. Remember the installation path.

  2. (Optional) Install CPLEX. Remember the installation path.

  3. (Ubuntu) Install Graphviz from source:

    sudo apt install librsvg2-dev libpango1.0-dev
    wget http://graphviz.gitlab.io/pub/graphviz/stable/SOURCES/graphviz.tar.gz
    tar -xf graphviz.tar.gz --one-top-level=graphviz --strip-components=1
    cd graphviz
    ./configure
    make
    sudo make install
    

Finally, compile and install MØD:

mkdir build
cd build
# Without CPLEX:
cmake ../ -DCMAKE_PREFIX_PATH=path/to/boost
# With CPLEX:
cmake ../ -DCMAKE_PREFIX_PATH=path/to/boost -DCPLEX_DIR=path/to/cplex
make
sudo make install

2.2. From a Git Repository

After a checkout of the desired version, do:

git submodule update --init --recursive
./bootstrap.sh

This is needed to first fetch certain dependencies and second to generate build files, extract the API documentation, and create the file VERSION based on the current commit.

See From a Source Archive on how to then build the package.

2.3. As Dependency of Another CMake Project

MØD supports use via add_subdirectory in CMake. The target mod::libmod is exported, which can be used with target_link_libraries to link against libMØD. The version is in the variable mod_VERSION. Note that running ./bootstrap.sh is still needed if the source is a repository clone (e.g., a Git submodule).

2.4. From a Source Archive

The package is build and installed from source as a CMake project. Generally that means something like:

mkdir build
cd build
cmake ../ <options>
make -j <n>
make install

A source archive can also be created with make dist.

The following is a list of commonly used options for cmake. Additional options specific for MØD along with their default valule are also listed. See also Dependencies for elaboration on some of them.

  • -DCMAKE_INSTALL_PREFIX=<prefix>, set a non-standard installation directory. Note also that the GNUInstallDirs module is used.

  • -DCMAKE_BUILD_TYPE=<build type>, set a non-standard build type. The default is RelWithDebInfo. An additional build type OptDebug is available which adds the compilation flags -g -O3.

  • -DCMAKE_PREFIX_PATH=<paths>, set a ;-separated list of paths used for finding most dependencies. The paths should generally be the prefixes specified when the dependency was installed. See also https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html#variable:CMAKE_PREFIX_PATH.

  • -DBUILD_DOC=on, whether to build documentation or not. This is forced to off when used via add_subdirectory.

  • -DBUILD_POST_MOD=on, whether to build the post-processor or not.

  • -DBUILD_POST_MOD_FMT=on, whether to build the Latex format files used by the post-processor or not. Format files may need to be updated when the Latex compiler is updated, so when making a binary distribution of MØD that does not include the Latex compiler, it is probably a good idea to set this to off. If the format files are not installed they will be compiled dynamically by the post-processor when needed, i.e., making each post-processor run slightly slower. Alternatively, the format file can be (re)installed by the post-processor using the mod_post --install-format/mod_post --install-format-sudo options.

  • -DBUILD_PY_MOD=on, whether to build the Python bindings or not.

  • -DBUILD_PY_MOD_PIP=on, whether to install the Python bindings via pip or not. The bindings are always installed in the <prefix>/lib folder, so a normal import in Python will probably not find the module. Having this setting on will enable a build of a fake Python package to be installed via pip in the default system folder. This fake package will redirect the import to the real location. This package can be uninstalled with pip uninstall mod-jakobandersen.

  • -DBUILD_TESTING=off, whether to allow test building or not. This is forced to off when used via add_subdirectory. When on the tests can be build with make tests and run with ctest.

  • -DBUILD_TESTING_SANITIZERS=on, whether to compile libraries and tests with sanitizers or not. This is forced to off when BUILD_COVERAGE=on.

  • -DBUILD_EXAMPLES=off, whether to build and allow running of examples as tests or not. This is forced to off when used via add_subdirectory. This is forced to off when BUILD_TESTING is off.

  • -DBUILD_COVERAGE=off, whether to compile code and run tests with GCov. When on the sanitizers on tests will be disabled. After building the tests, execute make coverage_collect without parallel jobs to run tests. Afterwards, execute make coverage_build to compile the code coverage report.

  • -DENABLE_SYMBOL_HIDING=on, whether symbols internal to the library are hidden or not. Disabling this option may degrade performance, and should only be done while developing extensions to the C++ library.

  • -DENABLE_DEP_SYMBOL_HIDING=on, whether symbols from library dependencies are hidden or not. Disabling this option may make it slower to load the library at runtime.

  • -DENABLE_IPO=on, whether to use link-time optimization or not. Disabling this option may degrade performance, but speed up linking time. As default the link-time optimizer will only use 1 thread. To use more threads, e.g., 7, use the following options for configuration -DCMAKE_MODULE_LINKER_FLAGS="-flto=7" -DCMAKE_SHARED_LINKER_FLAGS="-flto=7", when using GCC as the compiler.

  • -DUSE_NESTED_GRAPH_CANON=on, whether to use the dependency GraphCanon from the Git submodule or not.

  • -DUSE_NESTED_NLOHMANN_JSON=on, whether to use the dependency nlohmann/json from the Git submodule or not.

  • -DWITH_LOLA=on, whether to enable/disable features depending on LoLA.

  • -DWITH_OPENBABEL=on, whether to enable/disable features depending on Open Babel.

  • -DWITH_CPLEX=on, whether to enable/disable features depending on CPLEX.

  • -DWITH_CLP=on, whether to enable/disable features depending on CLP.

2.5. Dependencies

Python dependencies are listed in requirements.txt (which includes requirements_nodoc.txt).

Dependencies that can be satisfied via the system package manager are listed in bindep.txt. Any missing package can be listed using the Bindep program (which can be installed via requirements.txt).

The following is a detailed list of all dependencies and the CMake switches related to them.

  • This documentation requires (-DBUILD_DOC=on):

    • A supported version of Sphinx.

    • The Python package sphinx-autoapi (module name: autoapi).

  • libMØD:

    • A C++ compiler with reasonable C++17 support is needed.

    • Boost dev >= 1.73 (use -DBOOST_ROOT=<path> for non-standard locations).

    • GraphCanon >= 0.5. This is fulfilled via a Git submodule (make sure to do git submodule update --init --recursive), but if another source is needed, set -DUSE_NESTED_GRAPH_CANON=off.

    • nlohmann/json >= 3.7.3. This is fulfilled via a Git submodule (make sure to do git submodule update --init --recursive), but if another source is needed, set -DUSE_NESTED_NLOHMANN_JSON=off.

    • (optional) LoLA, Low-level petri-net analyser (-DWITH_LOLA=on).

    • (optional) Open Babel dev, >= 2.3.2 (-DWITH_OPENBABEL=on).

    • (optional) An ILP solver from the following list. At run-time, use the function getAvailableILPSolvers()/getAvailableILPSolvers() to see which have been enabled.

      • CPLEX dev (-DWITH_CPLEX=on, use -DCPLEX_DIR=<path> to specify the installation path). Depending on the CPLEX version it may require a license file to be accessible. See the documentation of CPLEX for this. Newer versions of CPLEX do not have this requirement.

      • CBC dev (-DWITH_CBC=on) from the COIN-OR package, along with a compatible LP solver:

        • CLP from the COIN-OR package, and included in CBC.

  • PyMØD (-DBUILD_PY_MOD=on):

    • Python 3 dev

    • Boost.Python built with Python 3

    • (Optional) IPython 3

  • PostMØD (-DBUILD_POST_MOD=on):

    • pdflatex available in the PATH or in CMAKE_PROGRAM_PATH, with not too old packages (Tex Live 2012 or newer should work).

    • pdf2svg available in the PATH or in CMAKE_PROGRAM_PATH.

    • dot and neato from Graphviz available in the PATH or in CMAKE_PROGRAM_PATH. They must additionally be able to load SVG files and output as both SVG and PDF files (all via cairo). That is, in the output of dot -P the following edges must exist:

      • cairo_device_svg -> output_svg

      • cairo_device_pdf -> output_pdf

      • rsvg_loadimage_svg -> render_cairo

    • If you install Graphviz from source, you can check if the status output in the end of configure includes the following two lines:

      pangocairo:    Yes
      rsvg:          Yes
      

2.6. Boost and Boost.Python with Python 3

A package with the sources of Boost can be downloaded from http://boost.org.

2.6.1. Basic Installation

Boost uses a custom build system which may be difficult to use. A procedure for compiling and installing Boost with Python 3 for Boost.Python is the following.

  1. ./bootstrap.sh --with-python=python3 (optionally give --prefix=some/path to specify a non-standard installation path.

  2. ./b2 (optionally give -j N (similar to GNU Make) to compile with multiple threads)

  3. ./b2 install (optionally give --prefix=some/path to specify a non-standard installation path (if not done earlier).

After bootstrap.sh has been run, the file project-config.jam has been created, which can be edited to customise installation path and a lot of other things. All edits should be done before running b2.

2.6.2. Non-standard Python Installation

Passing --with-python=python3 to bootstrap.sh should work. This adds a line similar to “using python : 3.3 ;” to project-config.jam. After compilation (running b2) the file stage/lib/libboost_python3.so should exist. If not, it did not detect Python 3 properly.

If Python is installed in a non-standard location, add the a line similar to “using python : 3.3 : python3 : /path/to/python/3/installtion/include ;” to project-config.jam, where the last path is the path to the include-folder of the Python-installation.

2.6.3. Custom GCC Version

Before running b2 create the file user-config.jam in the root of the home dir (see here for the full documentation). Put a line similar to “using gcc : : /path/to/g++-4.8” in the file.