Development Guide¶
Ready to contribute to the project? Here is how to set up a local development environment.
Initial Setup¶
Fork the cda-tum/mqt-qmap repository on GitHub (see https://docs.github.com/en/get-started/quickstart/fork-a-repo).
Clone your fork locally
$ git clone git@github.com:your_name_here/mqt-qmap --recursive
Warning
The
--recursive
flag is required to also clone all the required submodules. If you happen to forget passing the flag on your initial clone, you can initialize all the submodules by executinggit submodule update --init --recursive
in the main project directory.Change into the project directory
$ cd mqt-qmap
Create a branch for local development
$ git checkout -b name-of-your-bugfix-or-feature
Now you can make your changes locally.
(Optional, highly recommended) Set up a virtual environment
$ python3 -m venv venv $ source venv/bin/activate
Note
If you are using Windows, you can use the following command instead:
$ python3 -m venv venv $ venv\Scripts\activate.bat
Ensure that pip, setuptools, and wheel are up to date:
(venv) $ pip install --upgrade pip setuptools wheel
(Optional, highly recommended) Setup nox to conveniently run many development tasks.
(venv) $ pipx install nox
If you use macOS, then nox is in brew, use
brew install nox
.Note
If you do not have pipx (pip for applications) installed, you can install it with:
(venv) $ pip install pipx (venv) $ pipx ensurepath
If you use macOS, then pipx is in brew, use
brew install pipx
.(Optional) Install pre-commit to automatically run a set of checks before each commit.
(venv) $ pipx install pre-commit (venv) $ pre-commit install
If you use macOS, then pre-commit is in brew, use
brew install pre-commit
.Make sure to have the SMT Solver Z3 >= 4.8.15 installed. This can be accomplished in a multitude of ways:
Under Ubuntu 20.04 and newer:
sudo apt-get install libz3-dev
Under macOS:
brew install z3
Alternatively:
pip install z3-solver
in the virtual environmentDownload pre-built binaries from https://github.com/Z3Prover/z3/releases and copy the files to the respective system directories
Build Z3 from source and install it to the system
Working on the core C++ library¶
Building the project requires a C++ compiler supporting C++17 and CMake with a minimum version of 3.19.
Note
We noticed some issues when compiling with Microsoft’s MSCV compiler toolchain. If you want to start development on this project under Windows, consider using the clang compiler toolchain. A detailed description of how to set this up can be found here.
Configure and Build¶
Our projects use CMake as the main build configuration tool. Building a project using CMake is a two-stage process. First, CMake needs to be configured by calling
$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_QMAP_TESTS=ON -DBINDINGS=ON
This tells CMake to
search the current directory
.
(passed via-S
) for aCMakeLists.txt
file.process it into a directory
build
(passed via-B
).the flag
-DCMAKE_BUILD_TYPE=Release
tells CMake to configure a Release build (as opposed to, e.g., a Debug build).the flag
-DBUILD_QMAP_TESTS=ON
tells CMake to also build the C++ tests.the flag
-DBINDINGS=ON
tells CMake to also build the Python bindings.
After configuring with CMake, the project can be built by calling
$ cmake --build build --config Release
This tries to build the project in the build
directory (passed via --build
).
Some operating systems and development environments explicitly require a configuration to be set, which is why the --config
flag is also passed to the build command. The flag --parallel <NUMBER_OF_THREADS>
may be added to trigger a parallel build.
Building the project this way generates
the main libraries
libqmap_*_lib.a
(Unix) /qmap_*_lib.lib
(Windows) in thebuild/src
directorytest executables
qmap_test_*
containing unit tests in thebuild/test
directorythe Python bindings library
pyqmap.<...>
in thebuild/mqt/qmap
directory
Running C++ Tests¶
We use the GoogleTest framework for unit testing of the C++ library.
All tests are contained in the test
directory.
After building the project (as described above), the C++ unit tests can be run by executing the test executables in the build/test
directory.
[.../build/test] $ ./qmap_heuristic_test [.../build/test] $ ./qmap_exact_test
C++ Code Formatting and Linting¶
This project mostly follows the LLVM Coding Standard, which is a set of guidelines for writing C++ code. To ensure the quality of the code and that it conforms to these guidelines, we use
clang-tidy – a static analysis tool that checks for common mistakes in C++ code, and
clang-format – a tool that automatically formats C++ code according to a given style guide.
Common IDEs like Visual Studio Code or CLion have plugins that can automatically run clang-tidy on the code and automatically format it with clang-format.
If you are using Visual Studio Code, you can install the clangd extension.
If you are using CLion, you can configure the project to use the
.clang-tidy
and.clang-format
files in the project root directory.
They will automatically execute clang-tidy on your code and highlight any issues. In many cases, they also provide quick-fixes for these issues. Furthermore, they provide a command to automatically format your code according to the given style.
Note
If you want to use clang-tidy from the command line, you first have to configure CMake with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
to generate a compilation database.
It needs this information to correctly analyze the code.
After configuring CMake, you can run clang-tidy on a file by calling
$ clang-tidy <FILE> -- -I <PATH_TO_INCLUDE_DIRECTORY>
where <FILE>
is the file you want to analyze and <PATH_TO_INCLUDE_DIRECTORY>
is the path to the include
directory of the project.
Working on the Python module¶
Pybind11 is used for providing bindings of the C++ core library to Python.
This allows to keep the performance critical parts of the code in C++ while providing a convenient interface for Python users.
All of the bindings code is contained in the src/python
directory.
The Python package itself lives in the src/mqt/qmap
directory.
Building the Python module¶
It is usually most efficient to install the build dependencies in your environment once and use the following command that avoids a costly creation of a new virtual environment at every compilation:
(venv) $ pip install 'scikit-build-core[pyproject]' setuptools_scm pybind11 (venv) $ pip install --no-build-isolation -ve ".[dev]"
You may optionally add -Ceditable.rebuild=true
to auto-rebuild when the package is imported.
Otherwise, you need to re-run the above after editing C++ files.
Running Python Tests¶
The Python part of the code base is tested by unit tests using the pytest framework.
The corresponding test files can be found in the test/python
directory.
A nox
session is provided to conveniently run the Python tests.
(venv) $ nox -s tests
This installs all dependencies for running the tests in an isolated environment, builds the Python package, and then runs the tests.
Note
If you don’t want to use nox
, you can also run the tests directly using pytest
.
(venv) $ pytest test/python
Python Code Formatting and Linting¶
The Python code is formatted and linted using a collection of pre-commit hooks. This collection includes:
ruff – an extremely fast Python linter and formatter, written in Rust.
mypy – a static type checker for Python code
There are two ways of using these hooks:
You can install the hooks manually by running
(venv) $ pre-commit install
in the project root directory. This will install the hooks in the
.git/hooks
directory of the repository. The hooks will then be executed automatically when committing changes.You can use the
nox
sessionlint
to run the hooks manually.(venv) $ nox -s lint
Note
If you don’t want to use
nox
, you can also run the hooks directly usingpre-commit
.(venv) $ pre-commit run --all-files
Working on the Documentation¶
The documentation is written in reStructuredText and built using Sphinx.
The documentation source files can be found in the docs/source
directory.
You can build the documentation using the nox
session docs
.
(venv) $ nox -s docs
Note
In order to properly build the jupyter notebooks in the documentation, you need to have pandoc
installed. See the pandoc documentation for installation instructions.
This will install all dependencies for building the documentation in an isolated environment, build the Python package, and then build the documentation. Additionally, the session will automatically serve the docs on a local web server.
Note
If you don’t want to use
nox
, you can also build the documentation directly usingsphinx-build
.(venv) $ sphinx-build -b html docs/ docs/_buildThe docs can then be found in the
docs/_build
directory.