C++
C++11
Cling
Jupyter
C++17

C++11/14/17インタプリタ環境 Jupyter-Cling

More than 1 year has passed since last update.

Jupyter-Cling

以前C++インタプリタClingについて、「C++11インタプリタ Clingのビルド」という記事を書きました。

C++のインタプリタなんだからインタプリタ環境のJupyterから呼び出せるんじゃないかとJupyter kernelsのページを確認したところ、案の定ありました。

Clingインストール

CERNのサイトでバイナリも配布されていますので通常はこちらを使うのが良いでしょう

バイナリ版を使用する場合は次に進んで下さい。

Cling Packaging Tool

Clingのビルドに何やらよさげなスクリプトが用意されているので次の手順でClingをビルドします。
なお、Clingのビルドの際にClangをビルドするため、非常に時間がかかります。

wget https://raw.githubusercontent.com/root-project/cling/master/tools/packaging/cpt.py
chmod +x cpt.py
./cpt.py --check-requirements && ./cpt.py --create-dev-env Debug --with-workdir=./cling-build/

なお、./cpt.py --check-requirementsのところでCMakeが既に入っていないとコケます。
CMakeさえ入っていれば後は自動でaptを呼んで必要なライブラリを取得してくれるようです。

cling-build/ling-Ubuntu-16.04-x86_64-0.5~dev-4681e80といったフォルダができるので、任意の場所(/opt/cling等)にシンボリックリンクを張るなどします。

Jupyter

/share/cling/Jupyter/kernel/にJupyterのkernelが用意されています。

pip install -e .
jupyter-kernelspec install --user cling-cpp17
jupyter-kernelspec install --user cling-cpp14
jupyter-kernelspec install --user cling-cpp11

jupyterを起動する際、clingにパスを通す必要がありますので注意して下さい。

run.sh
#!/usr/bin/env bash
PATH=/opt/cling/bin:$PATH jupyter notebook

Hello World

image.png

気になったところ

c++17が起動しない

c++17を選択すると次のようなエラーを吐いてkernelが起動しません。

エラーを見た感じc++1zしか対応していないようです。(Ubuntu 16.04由来?)

error: invalid value 'c++17' in '-std=c++17'
note: use 'c++98' or 'c++03' for 'ISO C++ 1998 with amendments' standard
note: use 'gnu++98' or 'gnu++03' for 'ISO C++ 1998 with amendments and GNU extensions' standard
note: use 'c++11' for 'ISO C++ 2011 with amendments' standard
note: use 'gnu++11' for 'ISO C++ 2011 with amendments and GNU extensions' standard
note: use 'c++14' for 'ISO C++ 2014 with amendments' standard
note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard
note: use 'c++1z' for 'Working draft for ISO C++ 2017' standard
note: use 'gnu++1z' for 'Working draft for ISO C++ 2017 with GNU extensions' standard
In file included from input_line_2:1:
/opt/cling/include/cling/Interpreter/RuntimeUniverse.h:162:26: warning: default template arguments for a function template are a C++11 extension [-Wc++11-extensions]
      template <class T, class = T (*)() /*disable for arrays*/>
                         ^       ~~~~~~~
input_line_2:3:62: error: expected function body after function declarator
extern "C" int __cxa_atexit(void (*f)(void*), void*, void*)  noexcept;
                                                             ^
input_line_2:5:55: error: use of undeclared identifier '__cxa_atexit'
extern "C" int atexit(void(*f)())  throw ()  { return __cxa_atexit((void(*)(void*))f, 0, __dso_handle); }
                                                      ^
python3: cling-build/cling-src/tools/clang/lib/AST/DeclBase.cpp:1334: void clang::DeclContext::removeDecl(clang::Decl*): Assertion `(DC->hasExternalVisibleStorage() || Pos != Map->end()) && "no lookup entry for decl"' failed.

応急処置として次のような修正を加えます。

/share/cling/Jupyter/kernel/cling-cpp17/kernel.patch
diff -u a/cling-cpp17/kernel.json b/cling-cpp17/kernel.json
--- a/cling-cpp17/kernel.json   2017-09-06 04:46:58.764971000 +0900
+++ b/cling-cpp17/kernel.json   2017-09-06 07:16:59.802765356 +0900
@@ -4,6 +4,6 @@
       "jupyter-cling-kernel",
       "-f",
       "{connection_file}",
-      "--std=c++17"
+      "--std=c++1z"
   ]
 }

/share/cling/Jupyter/kernel/clingkernel.patch
diff -u a/clingkernel.py b/clingkernel.py
--- a/clingkernel.py    2017-09-06 04:46:58.744971000 +0900
+++ b/clingkernel.py    2017-09-06 07:14:08.954707308 +0900
@@ -92,7 +92,7 @@
     flush_interval = Float(0.25, config=True)

     std = CaselessStrEnum(default_value='c++11',
-            values = ['c++11', 'c++14', 'c++17'],
+            values = ['c++11', 'c++14', 'c++17', 'c++1z'],
             help="C++ standard to use, either c++17, c++14 or c++11").tag(config=True);

     def __init__(self, **kwargs):

もう一度インストールを行えばc++17のkernelが起動します。

pip install -e .
jupyter-kernelspec install --user cling-cpp17

clingが落ちれば容赦なく死ぬ

clingが落ちるコードを実行すると容赦なくkernelが落ちます。

ログを一切出さずに再起動するため、どこが悪いのか判別できず、ある程度の勘所と根気が必要です。
しかし、コンソールでclingが落ちると全ての入力が失われる一方で、Jupyterでは入力履歴がセルで残るため、やり直しが非常に簡単です。

C++の学習などの用途でJupyterを使わない手は無いのではないでしょうか。