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にパスを通す必要がありますので注意して下さい。
#!/usr/bin/env bash
PATH=/opt/cling/bin:$PATH jupyter notebook
Hello World
気になったところ
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.
応急処置として次のような修正を加えます。
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"
]
}
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を使わない手は無いのではないでしょうか。