Spresense SDK 環境で LLVM libc++ 標準ライブラリを使う方法(newlib math 編)
最新の NuttX バージョンでは LLVM "libc++" C++ Standard Library を Configuration により選択できるようになっていますが、Spresense SDK 環境で使用している NuttX バージョンにはそれがまだ取り込まれていないのでマニュアルで組み込む必要があります。
math ライブラリとして、NuttX math ライブラリを使う場合はこちら に書きましたが、
本記事は libc++ を使いつつ、math ライブラリはコンパイラ付属の newlib を使用する方法です。
TensorFlow Lite を使うときに newlib math にしないとまともに動作しなかったので別記事にしました。
インストール
インストール方法は、<Your spresense/nuttx directory>
に Spresense SDK 環境の nuttx ディレクトリを指定して install.sh
を実行します。
$ git clone https://github.com/baggio63446333/libcxx
$ cd libcxx
$ ./install.sh <Your spresense/nuttx directory>
インストールといっても nuttx 以下のディレクトリにソースやヘッダファイルをコピーするだけです。
- nuttx/libs/libxx/libcxx
- nuttx/include/libcxx
- nuttx/include/machine
これらコピー先のディレクトリは、.gitignore
ファイルにより構成管理対象外に設定されているので、git status
コマンドを実行しても表示されません。
アンインストール(ファイル削除)するときは、uninstall.sh
を実行します。
$ cd libcxx
$ ./uninstall.sh <Your spresense/nuttx directory>
コンフィグレーション
LLVM C++ Library を有効にするには、以下のように Configuration を設定します。
menuconfig
を開きます。
$ cd spresense/sdk
$ ./tools/config.py default -m
Library Routines ->
から Build LLVM libcxx
にチェックを入れます。
menuconfig
の設定を完了し、configs/feature/libcxx/defconfig
ファイルとして設定を保存しておきます。
$ ./tools/mkdefconfig.py feature/libcxx
ファイルの中身はこのようになります。
$ cat configs/feature/libcxx/defconfig
-CLOCK_MONOTONIC=y
+LIBCXX=y
+LIBCXX_EXCEPTION=n
この設定だけだとコンパイルエラーが発生してしまうので、コンパイラ付属の <cmath>
をインクルードさせるために nuttx/include/cxx/cmath
に #include_next 行を追加します。
CONFIG_ARCH_MATH_H
が定義されているかどうかで処理を分けています。
$ diff -u nuttx/include/cxx/cmath{.org,}
--- nuttx/include/cxx/cmath.org
+++ nuttx/include/cxx/cmath
@@ -43,6 +43,10 @@
#include <nuttx/config.h>
#include <nuttx/compiler.h>
+#ifdef CONFIG_ARCH_MATH_H
+# include_next <cmath>
+#else
+
#include <math.h>
//***************************************************************************
@@ -136,4 +140,5 @@
}
+#endif // CONFIG_ARCH_MATH_H
#endif // __INCLUDE_CXX_CMATH
arm-none-eabi-gcc のバージョンに依存しますが、コンパイラ付属の std_abs.h
が標準の<stdlib.h>
をインクルードしており、多重定義で怒られてしまうので、常に NuttX 側のヘッダファイルを参照するように変更します。
$ diff -u /Users/xxx/spresenseenv/usr/arm-none-eabi/include/c++/7.3.1/bits/std_abs.h{.org,}
--- /Users/xxx/spresenseenv/usr/arm-none-eabi/include/c++/7.3.1/bits/std_abs.h.org
+++ /Users/xxx/spresenseenv/usr/arm-none-eabi/include/c++/7.3.1/bits/std_abs.h
@@ -35,7 +35,7 @@
#include <bits/c++config.h>
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
-#include_next <stdlib.h>
+#include <stdlib.h>
#ifdef __CORRECT_ISO_CPP_MATH_H_PROTO
# include_next <math.h>
#endif
コンパイルオプションを変更するために、Makefile を変更します。
- -Inuttx/include/libcxx へのインクルードパスの追加
- -stdc=c++98 から -std=c++11 への変更
- -D_NuttX_ 定義の追加
参考:https://github.com/baggio63446333/spresense/commit/06802864c6026ce1caac66da3aca99ea93220810
$ diff --git a/sdk/tools/scripts/Make.defs b/sdk/tools/scripts/Make.defs
index 4eb5ddaab5..9f54a50af3 100644
--- a/sdk/tools/scripts/Make.defs
+++ b/sdk/tools/scripts/Make.defs
@@ -49,7 +49,10 @@ ifeq ($(WINTOOL),y)
DIRUNLINK = $(TOPDIR)/tools/unlink.sh
MKDEP = $(TOPDIR)/tools/mkwindeps.sh
ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(SDKDIR)/include}"
- ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" -isystem "${shell cygpath -w $(SDKDIR)/include}
+ ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" -isystem "${shell cygpath -w $(SDKDIR)/include}"
+ifeq ($(CONFIG_LIBCXX),y)
+ ARCHXXINCLUDES += -isystem "${shell cygpath -w $(TOPDIR)/include/libcxx}"
+endif
ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
HOSTEXEEXT = .exe
else
@@ -57,6 +60,9 @@ else
MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(SDKDIR)/include
ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx -isystem $(SDKDIR)/include
+ifeq ($(CONFIG_LIBCXX),y)
+ ARCHXXINCLUDES += -isystem $(TOPDIR)/include/libcxx
+endif
ARCHSCRIPT = -T$(TOPDIR)/boards/$(CONFIG_ARCH)/$(CONFIG_ARCH_CHIP)/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
HOSTEXEEXT =
endif
@@ -86,10 +92,10 @@ ifneq ($(CONFIG_DEBUG_NOOPT),y)
endif
ARCHCFLAGS = -fno-builtin -mabi=aapcs -ffunction-sections -fdata-sections
-ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fno-rtti -std=c++98
+ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fno-rtti -std=c++11
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
-ARCHDEFINES =
+ARCHDEFINES = -D__NuttX__
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
ビルド
tools/config.py
の引数に feature/libcxx
を入れることで LLVM C++ Library が有効になります。
$ cd spresense/sdk
$ ./tools/config.py feature/libcxx <その他のconfig...>
$ make
Author And Source
この問題について(Spresense SDK 環境で LLVM libc++ 標準ライブラリを使う方法(newlib math 編)), 我々は、より多くの情報をここで見つけました https://qiita.com/baggio/items/1944157e0ff3474a962e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .