Compiling and developing with graph-tool
Authors: Tiago P. Peixoto1, Max Falkenberg1, Martina Contisciani1,2
Affiliations: 1Inverse Complexity Lab, 2Central European University
License: CC-BY
This document describes how to setup a Docker container to compile and develop graph-tool, independent of the operating system — it should work on GNU/Linux, Windows, or MacOS.
The first step is to install Docker itself, which is not covered here. Just follow the instructions on the website.
Building an image¶
With docker installed, we proceed with building an image which contains a fully functional Arch GNU/Linux OS, which you can use to run and install programs, completely independently from your host OS.
The image specification is defined in a Dockerfile that you should download (also available in the repo), then build with the following command run the same directory where the file resides:
docker build --platform linux/amd64 -t gt-workbench --build-arg USER=${USER} --build-arg UID=${UID} .
Creating and running from a container¶
Before we can run anything with our image, we need to create a container,
which is a persistent writable layer on top of the image — which is read-only
after it’s created — that will allow us to have an interactive workspace. We
create a container named gt-workbench
[1] with the command:
docker create --platform linux/amd64 -p 3000-5000:3000-5000 -i -t -v .:/work --name gt-workbench gt-workbench
Port forwarding is required so that myst running inside docker can be accessed from your browser. The range of ports can be specified via
-p HOSTPORT(START)-(END):CONTAINERPORT(START)-(END)
The container is in principle isolated from the host OS, but we usually want to
exchange files with it; so the above command also binds the current working
directory in the host OS with a directory /work
inside the container.
You can check which containers you have by running
docker container ls
Similar commands exist to stop, start, and remove containers, etc.
Once created, containers will persist, also across reboots. But before we can do anything useful with a container we need to start it:
docker start gt-workbench
The commands above can be put inside a Makefile, so that they can be called with
make build
or
make run
and so on, so you don’t have to remember every time exactly what to type.
And finally, we may wish to start an interactive shell inside the container with
docker exec -w /work --user=$USER -it gt-workbench bash
which will put us inside the /work
directory inside the container (which
points to the current working directory in the host).
Compiling graph-tool inside the container¶
From inside the container we can clone the git repository
git clone https://git.skewed.de/count0/graph-tool.git
We now setup the configure script (this usually needs to be done only once):
cd graph-tool
./autogen.sh
and finally we can setup the compilation as follows
The ccache
program is a wrapper aroung the compiler (g++
) that caches
its results, i.e. if we try to compile the same source for a second time, it
will only load the previous compilation from disk, which can speed up the
development at lot.
The compiler option -flto
enables “link time optimization”, which has the
effect of actually reducing the overall compilation time with GCC, and even
producing slightly better code.
Compiling graph-tool
from scratch takes a long time.
At the time of this writing, on my machine it finishes in around 20 mins with
-j 16
jobs (this requires a nontrivial amount of RAM, tread with care).
This is a good time to take a coffee or tea, and reflect about life.
In our lab, compiling graph-tool
counts as work.

./configure --prefix=/usr CXX="ccache g++" MOD_CXXFLAGS="-flto" LDFLAGS="-flto"
We can now actually start the compilation by evoking make
:
make -j 2
The option -j 2
sets the number of parallel jobs to two, which means that
two compilations units will be compiled in parallel. In principle, you should
choose a number as large as the number of cores in your system, to speed up the
compilation. However, the memory usage will increase linearly with that number
as well. Therefore, you should choose the highest number of jobs that will not
cause you to run out of memory, or to start to “swap”. The latter will actually
make your compilation significantly slower!
Note that when not running natively (e.g. in MacOS), Docker containers are
memory limited. This means that if you are compiling graph-tool
in a
container, the compilation may be terminated when the container runs out of
memory, even if there is sufficient memory available on your machine. Container
memory settings can be changed under the resources tab in the Docker Desktop app
or in the command line as detailed
here.
By default, the Docker Desktop app enables the option: Turns on Rosetta to accelerate x86_64/amd64 binary emulation on Apple Silicon.
However, on MacOS Sequoia Version 15.4 this appears to cause issues during compilation. Disabling this option under Settings > General
resolved the problem.
After compilation, we can install the library in the system with:
sudo make install
After that, we’re ready to use it:
$ ipython
Python 3.13.2 (main, Feb 5 2025, 08:05:21) [GCC 14.2.1 20250128]
Type 'copyright', 'credits' or 'license' for more information
IPython 9.0.2 -- An enhanced Interactive Python. Type '?' for help.
Tip: Put a ';' at the end of a line to suppress the printing of output.
In [1]: from graph_tool.all import *
And that’s it!
At this point, we can modify the source code and re-compile the library (which should go much faster, since only the differences need to be re-compiled).
graph-tool
within myst
In order to use the compiled graph-tool
version from inside the docker container with myst
you must activate port forwarding when creating the docker container (see above), and myst must be
installed inside the docker environment. This can be achieved by running
sudo pacman -S nodejs npm
sudo npm install -g mystmd
myst
can then be started by running the following within docker
myst start --execute
Updating graph-tool version¶
If you check the graph-tool
version using gt.__version__
,
you might notice that the commit ID doesn’t match the latest updates.
Don’t worry—this does not mean the update failed.
The commit ID reflects the time of configuration, not compilation.
To confirm that your update was successful, simply verify that the graph-tool folder is up to date (git pull
).
To update the graph-tool
version, we can run the following steps from inside the graph-tool folder:
git pull
make -j 2
sudo make install
And that’s it!
The container name chosen is the same name as the image, but it does not have to be like this, as you can have many containers based on the same image.