はじめに
本記事には、以下の内容が含まれています。
- C++実行環境の構築
- nanobindを用いたPythonからのC++の関数の実行環境構築
対象環境はWindowsで、下記が私の環境です。
- Windows 11 Home
- VS Code (拡張機能: C/C++, CMake, CMake Toolsをインストール済)
事前準備(CMake, make, gccのインストールとC++の実行確認)
自分は普段Pythonしか書いていなくて、C++のビルド環境を構築するのにも手間取ったので、ここで合わせてまとめておきます。このあたりが詳しい方は、nanobindの設定の方に進んでください。
こちらに記載の通り下記の準備をしていきます。
- CMake
- Build Tools for Visual Studio 2022(MSVC)
CMakeのインストール
こちらから、Windows x64 Installer: cmake-3.28.0-rc5-windows-x86_64.msi をクリックして進めていきます。
手順は、こちらを参考にしました。
Build Tools for Visual Studio 2022(MSVC) のインストール
こちらからインストーラーをダウンロードできます。
手順は、こちらを参考にしました。
C++の実行確認
ここまででC++のビルドに必要なツールはインストールし終えました。ここからは、一旦C++だけで実行ができる状態になっているかを確認していきます。
実行確認の前に、VSCodeのCMake Tools拡張機能の設定について、下記の3つの設定をしておきましょう。自動Configureする部分をfalseにしてます。後の方で拡張機能でConfigureすると、Pythonのパスがうまく取れなかったので全てfalseにしています。
"cmake.configureOnOpen": false, // CMakeプロジェクトディレクトリを開いたときに自動でConfigure
"cmake.configureOnEdit": false, // CMakeLists.txtの保存時に自動でConfigure
"cmake.automaticReconfigure": false // 構成が変わったときに自動でConfigure
できたら、まずはプロジェクトディレクトリを作成し、カレントディレクトリを移動します。(今回はcmake-trialとします。)
下記のようにCMakeLists.txtを作成します。
cmake_minimum_required(VERSION 3.15)
project(cmake-trial LANGUAGES CXX)
add_executable(cmake-trial main.cpp)
また、main.cppも作成します。
#include <iostream>
int main(int, char**){
std::cout << "Hello, from cmake-trial!\n";
}
ディレクトリ構成は下記のようになります。
cmake-trial
| CMakeLists.txt
| main.cpp
下記を順に実行していき、同じような出力が得られたらOKです。
> cmake -G "Visual Studio 17 2022" -S . -B build
-- The CXX compiler identification is MSVC 19.38.33130.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.38.33130/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (2.7s)
-- Generating done (0.0s)
-- Build files have been written to: <path-to-project>/cmake-trial/build
> cmake --build build --config Debug
MSBuild version 17.8.3+195e7f5a3 for .NET Framework
1>Checking Build System
Building Custom Rule <path-to-project>/cmake-trial/CMakeLists.txt
main.cpp
cmake-trial.vcxproj -> <path-to-project>\cmake-trial\build\Debug\
cmake-trial.exe
Building Custom Rule <path-to-project>/cmake-trial/CMakeLists.txt
> ./build/Debug/cmake-trial.exe
Hello, from cmake-trial!
ちなみに、少しだけコマンドの説明を書いておきます。(あまりわかっていない部分もあるので、間違いあれば随時修正します)
- cmake -G “Visual Studio 17 2022” -S . -B build
- -G: コンパイラの指定
- -S: Sourceディレクトリ
- -B: buildディレクトリ
- cmake –build build –config Debug
- –build: buildディレクトリ
- –config: コンフィグモードの指定(Debug/Release/RelWithDebInfo/MinSizeRel?)
お疲れ様です。ここまでできたら、C++の実行環境は作れていると思います!
nanobindを使ってみる
nanobind とは
nanobind は、Python で C++ 型を公開したり、その逆を行う小さなバインディング ライブラリです。これはBoost.Pythonとpybind11を彷彿とさせ、ほぼ同じ構文を使用します。これらの既存のツールとは対照的に、nanobind はより効率的です。バインディングはより短い時間でコンパイルされ、より小さなバイナリを生成し、実行時のパフォーマンスが向上します。
より具体的には、ベンチマークでは、pybind11 と比較して コンパイル時間が最大 4 倍速く、バイナリが最大 5 倍小さく、実行時のオーバーヘッドが最大10 倍低いことが示されています。nanobind は、重要な指標でも Cython よりも優れています (バイナリ サイズの3 ~ 12 倍の削減、コンパイル時間の1.6 ~ 4 倍の削減、同様のランタイム パフォーマンス)。
https://nanobind.readthedocs.io/en/latest/index.html
実際にnanobindを使ってみましょう!
下記を見ながら進めていきます。
まずは、プロジェクトディレクトリを作成します。今回は、 nanobind-test
とします。poetryを使っている方は、 poetry new nanobind-test
で、 nanobind-test
プロジェクトを作成した後からスタートします。
nanobindのインストール
Installing the library を参考にします。推奨されているのはpipでのインストールですが、私はpoetryでパッケージ管理を行っているので、 poetry add
でインストールしていきます。もし、venvなどで管理している方はpipでインストールして問題ないです。
poetry add nanobind
poetryの場合、下記のような出力が返ってきたらOKです。
Using version ^1.8.0 for nanobind
Updating dependencies
Resolving dependencies... (0.4s)
Package operations: 1 install, 0 updates, 0 removals
• Installing nanobind (1.8.0)
Writing lock file
もし、poetry(Windows上)の環境構築も行いたい方はこちらを参照してください。
CMakeLists.txtの作成
Setting up a build system を参考にします。
まずは、下記のようなCMakeLists.txtを作成します。それぞれの説明は、リンク先等を参照してください。
cmake_minimum_required(VERSION 3.15)
project(nanobind-test LANGUAGES CXX) # Replace 'my_project' with the name of your project
find_package(Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
# Detect the installed nanobind package and import it into CMake
execute_process(
COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE NB_DIR)
list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}")
find_package(nanobind CONFIG REQUIRED)
nanobind_add_module(my_ext my_ext.cpp)
ビルドしてPythonから実行してみる
Creating your first extension を参考にします。
下記のようなmy_ext.cppを作成します。
#include <nanobind/nanobind.h>
int add(int a, int b) { return a + b; }
NB_MODULE(my_ext, m) {
m.def("add", &add);
}
この時点でのディレクトリ構成は下記です。poetryで管理している方は他にもファイルがあるかもしれないですが、最低限はこちらのようになっていればOKです。
nanobind-test
| CMakeLists.txt
| my_ext.cpp
|
+---.venv
| +---Lib
| | \---site-packages
| | +---nanobind
| | .
| |
| \---Scripts
では、buildしてみましょう。下記のような出力が出ればOKです。
> cmake -G "Visual Studio 17 2022" -S="." -B="./build" -DPython_EXECUTABLE="./venv/Scripts/python.exe"
-- The CXX compiler identification is MSVC 19.38.33130.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.38.33130/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Python: <path-to-project>/nanobind-test/.venv/Scripts/python.exe (found suitable version "3.10.11", minimum required is "3.8") found components: Interpreter Development.Module
-- Configuring done (7.7s)
-- Generating done (0.1s)
-- Build files have been written to: <path-to-project>/nanobind-test/build
> cmake --build build --config Release
MSBuild version 17.8.3+195e7f5a3 for .NET Framework
1>Checking Build System
Building Custom Rule <path-to-project>/nanobind-test/CMakeLists.txt
nb_internals.cpp
nb_func.cpp
nb_type.cpp
nb_enum.cpp
nb_ndarray.cpp
nb_static_property.cpp
common.cpp
error.cpp
trampoline.cpp
implicit.cpp
コードを生成中...
nanobind-static.vcxproj -> <path-to-project>\nanobind-test\build\Release\nanobind-static.lib
Building Custom Rule <path-to-project>/nanobind-test/CMakeLists.txt
my_ext.cpp
ライブラリ <path-to-project>/nanobind-test/build/Release/my_ext.lib とオブジェクト <path-to-project>/nanobind-test/build/Release/my_e
xt.exp を作成中
my_ext.vcxproj -> <path-to-project>\nanobind-test\build\Release\my_ext.cp310-win_amd64.pyd
Building Custom Rule <path-to-project>/nanobind-test/CMakeLists.txt
ここで、仮想環境を使っている場合、下記の引数が必要です。
# ".venv\Scripts\python.exe"は各自のPythonへのパス
-DPython_EXECUTABLE=".venv\Scripts\python.exe"
build/Releaseディレクトリができているはずです。
buildディレクトリに移動し、下記のようにmy_ext.add関数が使えればOKです!
> cd build
> python
Python 3.10.11 (tags/v3.10.11:7d4cc5a, Apr 5 2023, 00:38:17) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import Release.my_ext as my_ext
>>> my_ext.add(1,2)
3
おわりに
今回は、公式ドキュメントに沿って、nanobindを動かすところまで記載しました。
今後は、実際に使っていく過程で便利な機能を書いていきたいと思っています。
Note(今後更新予定の内容やメモ)
GCCとMinGW
最初、MSVCではなく、GCC・MinGWで行おうとしていましたが、エラー(後述)でハマってしまい、MSVCにしました。
GCCのインストール
こちらに記載の通りの手順を踏むと、インストールできます。
最終的にgcc 13.1.0をインストールできました。(2023/11/18時点)
> gcc --version
gcc (Rev6, Built by MSYS2 project) 13.1.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
エラー内容
下記でcmakeまで行った後に、
cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER:FILEPATH=C:\msys64\ucrt64\bin\gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:\msys64\ucrt64\bin\g++.exe -S . -B .\build -DPython_EXECUTABLE=".venv\Scripts\python.exe"
buildコマンドを打つと、下記のようなエラーが発生する。
(nanobind-test-py3.10) <path-to-project>\nanobind-test>cmake --build build
[ 7%] Building CXX object CMakeFiles/nanobind-static.dir/.venv/Lib/site-packages/nanobind/src/nb_internals.cpp.obj
In file included from <path-to-project>/nanobind-test/.venv/Lib/site-packages/nanobind/include/nanobind/nanobind.h:47,
from <path-to-project>\nanobind-test\.venv\Lib\site-packages\nanobind\src\nb_internals.cpp:10:
<path-to-project>/nanobind-test/.venv/Lib/site-packages/nanobind/include/nanobind/nb_error.h:30:17
error: 'dllexport' implies default visibility, but 'class nanobind::python_error' has already been declared with a different visibility
30 | class NB_EXPORT python_error : public std::exception {
| ^~~~~~~~~~~~
<path-to-project>/nanobind-test/.venv/Lib/site-packages/nanobind/include/nanobind/nb_error.h:98:17
error: 'dllexport' implies default visibility, but 'class nanobind::builtin_exception' has already been declared with a different visibility
98 | class NB_EXPORT builtin_exception : public std::runtime_error {
| ^~~~~~~~~~~~~~~~~
mingw32-make[2]: *** [CMakeFiles\nanobind-static.dir\build.make:76: CMakeFiles/nanobind-static.dir/.venv/Lib/site-packages/nanobind/src/nb_internals.cpp.obj] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:109: CMakeFiles/nanobind-static.dir/all] Error 2
mingw32-make: *** [Makefile:90: all] Error 2
make
最初、cmakeにbuildコマンドがあることを知らなかったのでmakeをインストールしていました。( make
コマンドと cmake --build build
コマンドの違いがよくわかってない)
make のインストール
こちらからインストーラーをダウンロードできます。
手順は、こちらを参考にしました。
VSCode CMake ToolsでのConfigure時に仮想環境からPythonパスを取ってくれない問題
問題
CMake ToolsのConfigureを使うと、.venvからPythonを取ってきてくれない。
find_package(Python) でWindowsの環境変数に書いてあるPythonを拾ってきちゃう。
このとき、VSCodeのターミナルは poetry shell
で仮想環境をアクティベートしている。
おそらく、VSCodeの拡張機能では、poetryの環境下だと認識できていない(仮想環境をアクティベートできていない)ためだと思われる。解決方法があれば、追記する。
VS Code でCMakeLists.txtの保存時に自動でConfigureしないようにする設定。
"cmake.configureOnEdit": false
解決のためにこれまで見たCMakeの参考記事など
- C/C++プロジェクトをCMakeでビルドする
- [BUG] Embedding documentation is wrong #2855
- CMakeの使い方(その1)
- cmake(1)
- https://github.com/crownstone/bluenet/blob/master/CMakeLists.txt#L128
- https://cmake.org/cmake/help/latest/module/FindPython.html#:~:text=used%2C%20if%20any.-,Python_FIND_VIRTUALENV,-New%20in%20version
- https://runebook.dev/ja/docs/cmake/module/findpython#:~:text=%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%A7%E3%81%99%E3%80%82-,Python_FIND_REGISTRY,-%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%203.13%20%E3%81%AE
- CMake で msvc と mingw-w64 向けにビルドをする
コメント