xeus-cling is a Jupyter kernel for C++ based on the C++ interpreter cling and the native implementation of the Jupyter protocol xeus.
Introduction¶
Licensing¶
We use a shared copyright model that enables all contributors to maintain the copyright on their contributions.
This software is licensed under the BSD-3-Clause license. See the LICENSE file for details.
Installation¶
Using the conda-forge package¶
A package for xeus-cling is available for the mamba (or conda) package manager.
mamba install -c conda-forge xeus-cling
From source with cmake¶
You can also install xeus-cling
from source with cmake. This requires that you have all the dependencies installed in the same prefix.
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/path/to/prefix ..
make install
On Windows platforms, from the source directory:
mkdir build
cd build
cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=/path/to/prefix ..
nmake
nmake install
Installing the Kernel Spec¶
When installing xeus-cling in a given installation prefix, the corresponding Jupyter kernelspecs are installed in the same environment and are automatically picked up by Jupyter if it is installed in the same prefix.
However, if Jupyter is installed in a different location, it will not pick up the new kernels. The xeus-cling kernels (for C++11, C++14 and C++17 respectively) can be registered with the following commands:
jupyter kernelspec install PREFIX/share/jupyter/xcpp11 --sys-prefix
jupyter kernelspec install PREFIX/share/jupyter/xcpp14 --sys-prefix
jupyter kernelspec install PREFIX/share/jupyter/xcpp17 --sys-prefix
For more information on the jupyter kernelspec
command, please consult the jupyter_client
documentation.
Build options¶
Build flags¶
You can specify additional build flags that will be used by xeus-cling
to compile the code in the notebook. To do so, you need to edit the kernelspec
file (usually share/jupyter/kernels/xcppSTD/kernel.json
, where STD
is the
version of the cpp standard) and add the build flags in the argv
array.
For instance, if you want to pass the -pthread -lpthread
flags to xeus-cling
and compile C++17 code, the C++17 kernelpec file becomes:
{
"display_name": "C++17",
"argv": [
"/home/yoyo/miniconda3/envs/xwidgets/bin/xcpp",
"-f",
"{connection_file}",
"-std=c++17",
"-pthread",
"lpthread"
],
"language": "C++17"
}
Using third-party libraries¶
When building a binary, you usually specify the include directories and the library path of third-party libraries in the build tool. The library will be loaded upon binary execution.
xeus-cling
is slightly different, it allows you to specify both include directories and
library path, however you need to load the library explicitly. This is done with special
pragma commands that you can use in a code cell in a Jupyter Notebook:
#pragma cling add_include_path("inc_directory")
#pragma cling add_library_path("lib_directory")
#pragma cling load("libname")
Magic commands¶
Magics are special commands for the kernel that are not part of the C++ programming language.
There are defined with the symbol %
for a line magic and %%
for a cell
magic.
A few magics are available in xeus-cling. In the future, user-defined magics will also be enabled.
%%executable¶
Dump the code from all entered cells into an executable binary. The content of the cell is used for the body of the main function.
%%executable filename [-- linker options]
Example

Optional arguments:
You can use the following options which will be passed to the linker and will influence code generation:
-fsanitize |
enable instrumentation with ThreadSanitizer |
-g |
enable debug information in the executable |
%%file¶
This magic command copies the content of the cell in a file named filename.
%%file [-a] filename
Example

Optional argument:
-a |
append the content to the file. |
%timeit¶
Measure the execution time execution for a line statement (%timeit) or for a block of statements (%%timeit)
Usage in line mode
%timeit [-n<N> -r<R> -p<P>] statement
Usage in cell mode
%%timeit [-n<N> -r<R> -p<P>]
statements
Example

Optional arguments:
-n |
execute the given statement <N> times in a loop. If this value is not given, a fitting value is chosen. |
-r |
repeat the loop iteration <R> times and take the best result. Default: 7 |
-p |
use a precision of <P> digits to display the timing result. Default: 3 |
Displaying rich content¶
The Jupyter rich display system allows displaying rich content in the Jupyter notebook and other frontend.
This is achieved by sending mime bundles to the front-end containing various representations of the data that the frontend may use.
A mime bundle may contain multiple alternative representations of the same object for example
a
text/html
representation for the notebook and other web frontends.a
text/plain
representation for the console.
Besides plain text and html, other mime type can be used such as image/png
or even custom mime type for which a renderer is available in the front-end.
Default plain text representation¶
By default, xeus-cling provides a plain text representation for any object.
In the case of a basic type such as double
or int
, the value will be
displayed.
For sequences (exposing an iterator pair begin
/ end
), the content of
the sequence is also displayed.
Finally, for more conplex types, the address of the object is displayed.
Providing custom mime representations for user-defined types¶
For a user-defined class myns::foo
, you can easily provide a mime
representation taylored to your needs such as a styled html
table including
the values of various attributes.
This can be achieved by simply overloading the function
nl::json mime_bundle_repr(const foo&);
in the same namespace myns
as foo
.
The rich display mechanism of xeus-cling
will pick up this function through
argument-dependent-lookup (ADL) and make use of it upon display.
Example: image/png
representation of an image class¶
In this example, the im::image
class holds a buffer read from a file. The
mime_bundle_repr
overload defined in the same namespace simply forwards the
buffer to the frontend.
#include <string>
#include <fstream>
#include "xtl/xbase64.hpp"
#include "nlohmann/json.hpp"
namespace nl = nlohmann;
namespace im
{
struct image
{
inline image(const std::string& filename)
{
std::ifstream fin(filename, std::ios::binary);
m_buffer << fin.rdbuf();
}
std::stringstream m_buffer;
};
nl::json mime_bundle_repr(const image& i)
{
auto bundle = nl::json::object();
bundle["image/png"] = xtl::base64encode(i.m_buffer.str());
return bundle;
}
}

Displaying content in the frontend¶
The first way to display an object in the front-end is to omit the last semicolon of a code cell. When doing so, the last expression will be displayed.
Another way of achieving this, is to include the xcpp::display
function
and passing the object to display. xcpp::display
is defined in the
<xcpp/xdisplay.hpp>
header.

Note
A subtle distinction between using xcpp::display
and omitting the last
semicolon is that the latter results in a cell output including a prompt
number, while the former will only show the rich front-end representation.
This behavior is consistent to the Python kernel implementation where 1
results in an output while print(1)
result in a display message.
Inline documentation¶
The standard library¶
The xeus-cling
kernel allows users to access help on functions and classes
of the standard library.
In a code cell, typing ?std::vector
will simply display the help page on
vector from the cppreference website.

Enabling the quick-help feature for third-party libraries¶
The quick help feature can be enabled for other libraries. To do so, a doxygen
tag file for your library must be placed under the xeus-cling
“data”
directory of the installation prefix, namely
PREFIX/share/xeus-cling/tagfiles
For xeus-cling
to be able to make use of that information, a JSON
configuration file must be placed under the xeus-cling
configuration
directory of the installation prefix, namely
PREFIX/etc/xeus-cling/tags.d
Note
For more information on how to generate tag files for a doxygen documentation, check the relevant section of the doxygen documentation.
The format for the JSON configuration file is the following
{
"url": "Base URL for the documentation",
"tagfile": "Name of the doxygen tagfile"
}
For example the JSON configuration file for the documentation of the standard library is
{
"url": "https://en.cppreference.com/w/",
"tagfile": "cppreference-doxygen-web.tag.xml"
}
Note
We recommend that you only use the https
protocol for the URL. Indeed,
when the notebook is served over https
, content from unsecure sources
will not be rendered.
The case of breathe and sphinx documentation¶
Another popular documentation system is the combination of doxygen and sphinx, thanks for the breathe package, which generates sphinx documentation using the XML output of doxygen.
The xhale Python package can be used to convert the sphinx inventory files produced breathe into doxygen tag files.
