【Android】CrystaX NDKでgcc5を使いC++14のコードをコンパイルする【Cocos2dx】

どうも、ぺーぺーの新人のりやさんです

ちょこっとCosos2dxのゲームのAIを作る上でコンパイル時計算を使っていたら

コンパイラにconstexpr関数でnot return statementを使っていると怒られてしまいました。

Android NDKのgccにおいてc++14の機能は使えるものと使えないものがあることがわかり、gccのバージョンを調べてみると

なんと4.9! 最新のAndroid NDKでもこれは変わらず!

Relaxing requirements on constexpr functions:(constexpr関数の制限緩和)

に対応しているのはgcc5からなんですよね…

この機能によってconstexpr関数は

  • globally-visible side-effects, such as modification of an object of static storage duration (other than the object being constructed, if any);

  • expressions which cannot be evaluated during translation, such as dynamic memory allocation, comparisons with unspecified results and lvalue-to-rvalue conversions on objects which are neither constant nor created during the evaluation;

  • non-portable constructs, such as an attempt to violate type-safety or to inspect the underlying storage of the abstract machine (for instance, through a reinterpret_cast), or use of inline asm;

  • invocation of a function which is not constexpr; or

  • undefined behavior.

<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3597.htmlより引用>

(グローバル、スタティックオブジェクトへのアクセス/動的割り当て/型安全性に違反する行為(reinterpret_cast等)、インラインアセンブラの利用/非constexpr関数の呼び出し/未定義動作)
以上に該当しない場合はコンパイル時に評価されます。

つまり副作用がなければ何でもあり。

逆にC++11仕様の場合、関数内にはreturn statement以外かけません。forやwhileは使えないので再帰を駆使、コンテナは独自のイテレータを使う、参照を取れないので複数の値はタプルで返す等、地獄の実装になります。

絶対Cocos2dxでC++14コードをAndroid向けビルドしたい! そんな時は

Android NDKを消しとばしてCrystaX NDKを使いましょう! CrystaX NDK ならgcc5.3に対応しています! しかもgcc6への対応も意欲的!

ただし、推奨環境ではないので色々弄る必要があります。

 

MacOSX 環境でのCocos2dx向けCrystaX構築方法

1. まずbrewを用いてCrystaXをインストールします。

ターミナルを開きます。brewは適宜インストールしてください。

2. ~/.bash_profileを弄ります。

このプロファイルには、皆さんがcocos2dxのsetup.pyを実行した時に入力したNDK_ROOTなるものがexportされているはずです。

AndroidNDKからCrystaXに変えましょう。

 

この辺は環境依存なので自分のbrewのパッケージ保管場所を入力してください。

 

3. android-studioの設定をいじります。(既存のプロジェクトがある場合)

現在のcocos2dxプロジェクトを開いて、タブのFile->Project Structure->SDK Locatinに飛び、Android NDK locationに先ほどと同じパスを入力します。

 

4. コンパイラのバージョンを指定します。
cocos2dxはAndroidNDKを想定しているので、toolchainを4.9に指定しています。

cocos2d-x-3.11.1/tools/cocos2d-console/plugins/plugin_compile/build_android.py

を開き、206行目あたりにある

を4.9から5に書き換えます。

環境によってはまずい感じの変更ですが、慈悲はなし。C++14道は険しいのだ。

 

5. cocos2dxのフレームワークでなぜかビルドエラーが出るので修正します。

YOUR_PROJECT_ROOT/cocos/uiUIWebViewImpl-android.h/cppにおいて

uint32_tがビルドで死ぬので、全部intに書き変えましょう。これもまずそうな変更ですが、おそらく今時32bit環境のAndroidなんてないと思います! きっとintは4byteですよ…

 

さて、ここまでやれば

cocos run -p android –android-studio

で実行です!ビルドが通れば勝ち!

もしerrorが出てきても大丈夫。環境が変わりシンボルリンクがかなり厳しくなります。今errorを吐いているSTLは本当に必要なヘッダをincludeしていますか? functional, type_traits, utility等、使ったSTLの所属するヘッダはしっかりincludeしましょう。

 

return statement以外を持つconstexpr関数を書いてみたり、変数テンプレートを使ってみたり(gcc 5から対応した機能)して、gccのメジャーバージョンが5になってるか確認してみてくださいね。

(ちなみにCrystaX NDKにおけるconstexpr関数の挙動がおかしい感じ…誰か調査してください)

今回はこの辺で!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です