はじめに
make menuconfigで見てみると、NuttXでもlibc++
やuClibc++
などが使えるようになっているらしい。
ただ、ライブラリのソースはカーネルやアプリからは分離されているようで、別途取得する必要がある。
具体的なやり方はAlan C. Assis
さんが紹介してくれているのでなぞってみる。
コミットログを見るにこの人はコアなコントリビュータっぽい。
ソースの取得
NuttX
$ git clone https://bitbucket.org/nuttx/nuttx
Apps
$ git clone https://bitbucket.org/nuttx/apps
libc++
$ git clone https://bitbucket.org/acassis/libcxx
libc++のインストール
libc++のソースをNuttXのソースツリーにインストールする。
$ cd libcxx $ ./install.sh ../nuttx Installing LLVM/libcxx in the NuttX source tree Installation suceeded
./install.shの中身
基本的にはNuttXのソースツリーの構造をチェックして、ファイルをコピーしているだけっぽい。 ここではチェック部分を省略したが、実際はかなり細かくチェックしている。
#!/bin/bash usage="USAGE: $0 <full path to the NuttX directory>" # Get the single, required command line argument nuttx_path=$1 if [ -z "${nuttx_path}" ]; then echo "ERROR: Missing path to the NuttX directory" echo $usage exit 1 fi # Lots of sanity checking so that we do not do anything too stupid if [ ! -d src ]; then echo "ERROR: Directory src/ does not exist in this directory" echo " Please CD into the libcxx directory and try again" echo $usage exit 1 fi ...(snip)... libxx_srcdir=${nuttx_path}/libs/libxx if [ ! -d "${libxx_srcdir}" ]; then echo "ERROR: Directory ${libxx_srcdir} does not exist" echo $usage exit 1 fi ...(snip)... libcxx_incdir=${nuttx_incdir}/libcxx if [ -d "${libcxx_incdir}" ]; then echo "ERROR: Directory ${libcxx_incdir} already exists" echo " Please remove the ${libcxx_incdir} directory and try again" echo $usage exit 1 fi ...(snip)... # Installation echo "Installing LLVM/libcxx in the NuttX source tree" filelist=`find src -type f` for file in $filelist; do if [ "${file##*.}" = "cpp" ]; then endfile="`basename ${file} .cpp`.cxx" else endfile=${file} fi install -D ${file} ${libxx_srcdir}/libcxx/${endfile#src/} done mkdir -p ${libcxx_incdir} filelist=`find include -type f` for file in $filelist; do install -D ${file} ${nuttx_path}/include/libcxx/${file#include/} done filelist=`find machine -type f` for file in $filelist; do install -D ${file} ${nuttx_path}/include/${file} done echo "Installation suceeded" echo ""
拡張子cpp
をすべてcxx
に変換し、NuttXのlibs/libxx/libcxx
にコピー。
include
以下のファイルはそのままNuttXのinclude/libcxx
にコピー。
machine
以下のファイルもそのままで、NuttXのinclude
にコピーしている。
コンフィグレーションとビルド
今回はstm32f4discovery/testlibcxx
を使用する。
元記事ではこの前にいくつかパッチを適用しているが、今回の手順で試す場合は必要なさそうだった。
$ ./tools/configure.sh ./configs/stm32f4discovery/testlibcxx $ make -j4
動作確認
出来上がったnuttx.bin
を書き込む。
$ st-flash write nuttx.bin 0x8000000
ボードをリセットするとnshが起動する。
helpコマンドを実行するとhelloxx
が見つかるので実行する。
nsh>helloxx helloxx_main: Saying hello from the dynamically constructed instance CHelloWorld::HelloWorld: Hello, World!! helloxx_main: Saying hello from the instance constructed on the stack CHelloWorld::HelloWorld: Hello, World!! helloxx_main: Saying hello from the statically constructed instance CHelloWorld::HelloWorld: Hello, World!!
ちゃんと動いている。
C++11
例えば、ラムダ式や一様初期化 (uniform initialization)とかは動くのか。
helloxxのソースを変更して試してみる。
diff --git a/examples/helloxx/helloxx_main.cxx b/examples/helloxx/helloxx_main.cxx index 4be4bf6b..3bc4865b 100644 --- a/examples/helloxx/helloxx_main.cxx +++ b/examples/helloxx/helloxx_main.cxx @@ -43,6 +43,9 @@ #include <debug.h> #include <nuttx/init.h> +#include <iostream> +#include <vector> +#include <algorithm> #include "platform/cxxinitialize.h" @@ -161,6 +164,8 @@ extern "C" printf("helloxx_main: Saying hello from the statically constructed instance\n"); g_HelloWorld.HelloWorld(); #endif + std::vector<char> vec{'h','e','l','l','o',' ','w','o','r','l', 'd', '\n'}; + std::for_each(vec.begin(), vec.end(), [](char c){std::cout << c;}); delete pHelloWorld; return 0;
再度makeコマンドでnuttx.binを作り、helloxx
を実行する。
nsh>helloxx helloxx_main: Saying hello from the dynamically constructed instance CHelloWorld::HelloWorld: Hello, World!! helloxx_main: Saying hello from the instance constructed on the stack CHelloWorld::HelloWorld: Hello, World!! helloxx_main: Saying hello from the statically constructed instance CHelloWorld::HelloWorld: Hello, World!! hello world nsh>
最後にhello world
が追加されている。
ちゃんと動くようだ。