cocos2d-x v3.17がAndroidでビルドできない時の対策

※2018/11/18更新

NDK Build

従来cocos2d-xのプロジェクトに自前のクラスを追加したら、iOSの場合はXcodeにファイルを追加すれば良いし、Androidの場合はproj.android/app/jni/Android.mkに相応のファイルを追加すれば良かったのですが、v3.17ではそう行かなくなったようです。

実験として、新規プロジェクトを作成:

cocos new Test1 -l cpp

そして、デフォルトのHelloWorldシーンをMainシーンに変えてみました。
iOSで動作確認の上、上記Android.mkにMainScene.cppを追加して以下にすれば良いはずです。

LOCAL_SRC_FILES := $(LOCAL_PATH)/hellocpp/main.cpp \
                   $(LOCAL_PATH)/../../../Classes/AppDelegate.cpp \
                   $(LOCAL_PATH)/../../../Classes/HelloWorldScene.cpp \
                   $(LOCAL_PATH)/../../../Classes/MainScene.cpp

ところが、実行すると以下のようなエラーが出ました。

$ cocos run -p android
...
  /Users/poo/test/Test1/Classes/AppDelegate.cpp:121: error: undefined reference to 'MainScene::createScene()'
  clang++: error: linker command failed with exit code 1 (use -v to see invocation)
  ninja: build stopped: subcommand failed.

Mainシーンのクラスファイルが見つからないようですね。

ログをよく見ると、最初に実行されたコマンドは以下でした。

running: '"/Users/poo/test/Test1/proj.android/gradlew" --parallel --info assembleDebug -PPROP_BUILD_TYPE=cmake'

最後のビルドタイプはcmakeになっていることが分かります。

調べたところ(参考1)、proj.android/gradle.propertiesの中でデフォルトPROP_BUILD_TYPE設定がcmakeになっているので、それをndk-buildに変えればAndroid.mkが参照されるようになっているとのことでした。

しかし実際いくら変えても、実行されるコマンドは”-PPROP_BUILD_TYPE=cmake”のままで、もちろんビルドも失敗で終わります。

そこまで言うならcmakeを使うよとすっかり負けてしまいました。Orz
※2018/11/18追記:


proj.android/gradle.propertiesの設定はAndroid Studioに有効であり、コマンドラインでは–build-typeの指定で解決できることが分かりました。
つまりndk-buildでビルドしたいなら、コマンドは以下になります。

$ cocos run -p android --build-type ndk-build

今回はこれが回答になるかと思います。
以下のCMake部分では新たに追加した参考3によると、Google NDKのガイドではCMakeをネイティブライブラリをビルドするデフォルトツールとされているため、今後はndk-buildが徐々に減り、CMakeが徐々に増える傾向となるでしょう。
なので、早いうち慣れとくといいと思います。

しかしSDKBOXを使うなら、現段階v1.0.2.0ではCMakeに関してはノータッチのようですので、インポートするとCMakeではコンパイルエラーになります。
設定に関する情報も探してみましたが、見つかったのが参考5ぐらいで、まだまだ情報が少ないです。
ちなみに、参考5の情報は既に古いようで、そのままやってもうまくいきませんでしたので、今のところSDKBOXを使うなら、やっぱりndk-buildに切り替えたほうが一番手っ取り早いだと思います。


CMake

CMakeのクラスファイルリストはプロジェクトルートにある「CMakeLists.txt」で設定できます。
デフォルトはこうなっているはずです。

list(APPEND GAME_SOURCE
     Classes/AppDelegate.cpp
     Classes/HelloWorldScene.cpp
     )
list(APPEND GAME_HEADER
     Classes/AppDelegate.h
     Classes/HelloWorldScene.h
     )

ここに追加したcppファイルとヘッダーをそれぞれ追加すれば良いはずです。

また、Classesディレクトリーの下にサブディレクトリーを作り、それらを追加したい場合、もうひと手間かかります。
例えば今回のMainSceneはClasses/mainのところに置くとします。
構造はこうなるはずです。

Classes/
├── AppDelegate.cpp
├── AppDelegate.h
├── HelloWorldScene.cpp
├── HelloWorldScene.h
└── main
    ├── MainScene.cpp
    └── MainScene.h

この場合、上記のcppとヘッダーファイル追加するだけでは足りません。
このようなエラーになるはずです。

  /Users/poo/test/Test1/Classes/AppDelegate.cpp:26:10: fatal error: 'MainScene.h' file not found
  #include "MainScene.h"
           ^~~~~~~~~~~~~
  1 error generated.

サブディレクトリーを作った場合、CMakeLists.txtの128行あたりにある「PRIVATE Classes」のあとにサブディレクトリーを追加する必要があります。

target_include_directories(${APP_NAME}
        PRIVATE Classes
        PRIVATE Classes/main #<=ここらへんに追加
        PRIVATE ${COCOS2DX_ROOT_PATH}/cocos/audio/include/
)

まとめ

新しいクラスファイル追加した場合、Android版ではCMakeLists.txtに以下の3箇所に追加する必要になります。

  1. list(APPEND GAME_SOURCE ブロックにCPPファイルを追加
  2. list(APPEND GAME_HEADER ブロックにヘッダーファイルを追加
  3. Classesの下にサブディレクトリーがあれば、target_include_directories(${APP_NAME} ブロックにそのディレクトリーを追加

ファイルがたくさんあるときは、以下のコマンドでリストアップしてからコピペするといいでしょう。

#cpp
find Classes -name *.cpp -type f

#header
find Classes -name *.h -type f
参考
  1. CMake Guide
  2. How to properly add include directories with CMake
  3. Android template project doesn’t build on `PROP_BUILD_TYPE=ndk-build`
  4. Can’t use cmake build for android when using cocos console
  5. SDKBOX CMake integration

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください