Saturday, January 9, 2016

続・Visual StudioからAndroid開発を実践してみた

Visual Studio 2015からAndroidの開発をしてみましたが、思わぬエラーに遭遇して悩みました。そんな経験を書き連ねてみます。


Clangで内部エラー


Visual Studio 2015でのデフォルトのコンパイラがClangなのですが、特定のソースファイルをコンパイルする時に以下のような内部エラーを発生させるようです。
1>  This application has requested the Runtime to terminate it in an unusual way.
1>  Please contact the application's support team for more information.
1>  Assertion failed!
1>
1>  Program: C:\ProgramData\Microsoft\AndroidNDK\android-ndk-r10e\toolchains\llvm-3.6\prebuilt\windows\bin\clang.exe
1>  File: /s/ndk-toolchain/src/llvm-3.6/llvm/tools/clang/lib/AST/DeclBase.cpp, Line 1299
1>
1>  Expression: DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"
1>clang.exe : error : clang frontend command failed with exit code 3 (use -v to see invocation)
1>  clang version 3.6
1>  Target: armv7-none-linux-androideabi
1>  Thread model: posix
1>  clang.exe: note: diagnostic msg: PLEASE submit a bug report to http://source.android.com/source/report-bugs.html and include the crash backtrace, preprocessed source, and associated run script.
1>  clang.exe: note: diagnostic msg:
1>  ********************
1>
1>  PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
1>  Preprocessed source(s) and associated run script(s) are located at:
1>  clang.exe: note: diagnostic msg: C:\Users\Jin0103\AppData\Local\Temp\bvh-1eb1f7.cpp
1>  clang.exe: note: diagnostic msg: C:\Users\Jin0103\AppData\Local\Temp\bvh-1eb1f7.sh
1>  clang.exe: note: diagnostic msg:
1>
1>  ********************

回避方法が無さそうなので、やむを得ずGCCに切り替えました。プロジェクトのプロパティのPlatform Toolsetで変更可能です。



libmのリンク


Visual Studioではsin, cos等の数学ライブラリは明示的にリンクしなければ以下のようなリンクエラーを出すようです。

1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(51): error : undefined reference to 'sin'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(56): error : undefined reference to 'cos'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(61): error : undefined reference to 'tan'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(66): error : undefined reference to 'asin'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(71): error : undefined reference to 'acos'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(78): error : undefined reference to 'atan2'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(109): error : undefined reference to 'floor'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(120): error : undefined reference to 'ceil'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(138): error : undefined reference to 'fmod'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(157): error : undefined reference to 'ceil'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(157): error : undefined reference to 'floor'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(167): error : undefined reference to 'sqrt'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(183): error : undefined reference to 'log'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(186): error : undefined reference to 'log10'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(187): error : undefined reference to 'log'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(187): error : undefined reference to 'log'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lmathlib.c(194): error : undefined reference to 'exp'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lobject.c(103): error : undefined reference to 'pow'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lobject.c(104): error : undefined reference to 'floor'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lobject.c(108): error : undefined reference to 'fmod'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/ltable.c(92): error : undefined reference to 'floor'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/ltable.c(103): error : undefined reference to 'frexp'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lvm.c(858): error : undefined reference to 'fmod'
1>D:\github\AdamasF\VisualStudio\..\submodules\lua\src/lvm.c(883): error : undefined reference to 'pow'

Androidのライブラリはファイル名が全てlibGLESv3, libOpenSLESのようにlibで始まるのですが、libを省略してGLESv3, OpenSLESのように指定する習慣があるようです。数学ライブラリはlibmなので、mとだけ指定するとリンクできます。


Precompiled Headerは切ってみる


なぜ発生するかわからないコンパイルエラーが出るときは、Precompiled Headerを切ってみます。(デフォルトで使うようになっている)


GCCのプリコンパイル済みヘッダはWindows+Visual Studioのものと仕組みが違います。

Windows+Visual Studioでは、例えばstdafx.hを各ソースの最上位でincludeすることを強制して重複する作業を省略しようとします。

GCCでは、各ソースの最上位で強制的にpch.hをincludeしたことにしてしまうようです。

個人的な経験なので参考にならないかもしれませんが、なぜかCであるLuaのソースコードで__cplusplusが定義されたり、Luaのソースコードで最上位で定義されなければならないLUA_COREやLUA_LIB等のマクロ定義に先駆けてlua.hがincludeされたことになっていました。

ぱっと見で分かり難いエラーの原因がプリコンパイル済みヘッダの間違った使い方であったというのはありがちなシチュエーションなので、仕組みを理解したうえで適用するか決めるのがよさそうです。

No comments:

Post a Comment