ラベル エラー の投稿を表示しています。 すべての投稿を表示
ラベル エラー の投稿を表示しています。 すべての投稿を表示

2011年11月23日水曜日

静的ライブラリ中のシグネチャが衝突してビルドできないときに再ビルドしないでシグネチャを書き換える

皆さんも以下のようなビルドエラーを見たことが一度はあると思います。

これはビルド時に同一プロジェクト内に同じ名前のシグネチャの関数やクラスが存在するためリンクができなくて失敗しているというエラーです。特に以下のようなケースでよく発生します。
  • 自分が作ったクラスや関数の名前と、外部から持ってきたライブラリが使っているクラスや関数の名前が衝突している
  • 外部から持ってきたライブラリ同士でクラスや関数の名前が衝突している
  • 外部ライブラリをインストールする際に、-all_loadしたり-ObjCしたりている
そういうわけで、外部からライブラリをたくさん導入すると、base64やMD5など、プログラム上でよく使われるのに標準で用意されていないライブラリがよく衝突してしまうわけです。大抵の場合はぶつかっているシグネチャの名前をソースコード上でちょっと書き換えて再度ビルドすることで回避ができるのですが、極稀にソースコードを書き換えることができないケースが存在します。以下にそんな場合の対処方法をまとめます。


■具体例
AdMobのSDK(libGoogleAdMob.a)とopenssl(libcrypto.a)を同時に一つのプロジェクトにインストールした時、冒頭の画像のようにMD5というシグネチャがビルド時に衝突してしまうのです。AdMobのはプロプロエタリなので当然書き換えられませんし、opensslのように巨大で複雑なコードに手を入れて再ビルドするのも非常に危険です。そもそもopensslはビルド自体が難しいのです。

このような場合は、ソースコード自体を書き換えるのではなくビルド済みの静的ライブラリ側のオブジェクトファイルを書き換えることで対処を行うことが可能です。
コンパイル時のリンカの設定を変更すれば対処できそうな気もするんですが、GNU ldにはそのようなオプションが見当たりませんでした。なんかSun Solarisのldだと対処できるみたいです。
参考: http://stackoverflow.com/questions/6940384/how-to-deal-with-symbol-collisions-between-statically-linked-libraries
参考: http://stackoverflow.com/questions/393980/restricting-symbols-in-a-linux-static-library

注意: 以下の手順は失敗すると静的ライブラリ自体が完全に破損したり、実行時に深刻な問題が発生する可能性があります!! 以下の解説を見てもちんぷんかんぷんな人は適用しないことを強くおすすめいたします。この手順を適用したことによって発生したいかなる損害についても私は責任をとりかねます。


■静的ライブラリ内部のシグネチャを書き換える方法
静的ライブラリ内部のシグネチャを書き換えるには、以下のようなツールを使用します。

lipo
以前にもご紹介した、Apple純正のユニバーサルバイナリ/ユニバーサルライブラリ(fat binaryともいいます)を作ったりバラしたりするツールです。iOSのライブラリはほぼすべてがi386, armv6, armv7の三種類に対応するfat binaryになっており、基本的にApple純正でないツールはそういったfat binaryに対して歯が立たないので、まずこのツールを使って普通のライブラリに戻した上で、以下のツールを使うわけです。

nm
こいつもApple純正です。バイナリの中に入っているシグネチャの名前を一覧表示することができます。Apple純正なのでfat binaryに対しても使えて超便利です。

objdump
GNU objdumpというツールがありまして、こいつを使うとバイナリの詳細な中身を覗き見ることができます。nmよりも表示される情報が詳細です。Apple純正ではないので、以下で紹介されているようにしてMacPorts経由でインストールするのをお勧めします。
http://d.hatena.ne.jp/amachang/20080401/1207027290

objcopy
GNU objcopyです。ライブラリ内部のシグネチャを書き換える事ができるツールで、objdumpとセットでついてくるのですが、残念ながらiOS向けのバイナリに対しては全く使えません。話すと長くなるのですがバージョンを変えようがarm向けのセットをインストールしようがarでライブラリからオブジェクトファイルを取り出して試みてみようが何やっても一切無駄です。使えませんので諦めてください。
参考: http://www.mail-archive.com/bug-binutils@gnu.org/msg02829.html
参考: http://stackoverflow.com/questions/2231698/how-can-i-easily-install-arm-elf-gcc-on-os-x

objconv
で、使えないobjcopyに代わって、今回の英雄です。こいつを使って実際にライブラリ内部のシグネチャを自由自在に書き換えることができます。メンテもしっかり行われているようで動作も安定しています。以下のサイトからダウンロードできます。
サイト: http://www.agner.org/optimize/#objconv
マニュアル: http://www.agner.org/optimize/objconv-instructions.pdf
残念ながらsource配布のみしか無いため、自分でビルドしてやる必要があります。と言ってもそこそこ簡単で、以下のようにするだけです。
  • ソースコードをダウンロードする
  • zipを解凍する
  • source.zipを解凍する
  • build.shを実行する。ただしこのシェルスクリプトは1行目だけがひどくバグってるので、自分で中を見てビルドコマンドを叩いてやるようにしてください。ね?簡単でしょう?
さて、これで実際にシグネチャの書き換えを行う準備が整いました。


■実践:全く同一のライブラリのシグネチャだった場合
base64なんかでよく発生します。この場合は片方をweakシンボルにします。
weakシンボルとは: http://d.hatena.ne.jp/syohex/20100610/1276180481 がわかりやすいです。

早速やってみましょう。以下の例ではlibTest.a中のbase64_encodeシグネチャを書き換えます。
まずは以下のコマンドで対象のライブラリのfat binaryを通常のバイナリに戻して:
lipo -thin armv6 libTest.a -output libTest_armv6.a
lipo -thin armv7 libTest.a -output libTest_armv7.a
lipo -thin i386 libTest.a -output libTest_i386.a
objconvを実行:
objconv -fmacho -nw:base64_encode libTest_armv6.a
objconv -fmacho -nw:base64_encode libTest_armv7.a
objconv -fmacho -nw:base64_encode libTest_i386.a
lipoで元通りに戻します:
lipo -create libTest_i386.a libTest_armv6.a libTest_armv7.a -output libTest.a
これでビルドが通るはずです。


■実践:同じ名前の違うライブラリのシグネチャだった場合
冒頭のMD5のケースがこれです。名前が同じなのに実装がまるで違うので、weakシンボルにすると深刻なバグが発生します。こういう時は慎重に見定めた上で、使われていないと思われる方のシグネチャをhiddenシンボル(ローカルシンボル)にして、外部ファイルからリンクできないようにしてしまいます。これなら実装は存在しますがリンクされないようになるだけなので、対象のシンボルが外部から使われていないのであればこれだけでいけます。

今度はlibcrypto.a中の_MD5シグネチャを書き換えてみましょう。
こちらもまずはlipoを使って通常のバイナリに戻して:
lipo -thin armv6 libcrypto.a -output libcrypto_armv6.a
lipo -thin armv7 libcrypto.a -output libcrypto_armv7.a
lipo -thin i386 libcrypto.a -output libcrypto_i386.a
objconvを実行:
objconv -fmacho -nl:_MD5 libcrypto_armv6.a
objconv -fmacho -nl:_MD5 libcrypto_armv7.a
objconv -fmacho -nl:_MD5 libcrypto_i386.a
lipoで元通りにして完成:
lipo -create libcrypto_i386.a libcrypto_armv6.a libcrypto_armv7.a -output libcrypto.a
これで無事ビルドが通りました。


■実践:同じ名前の違うライブラリのシグネチャで、かつ外からバリバリ呼ばれていた場合

2011年2月2日水曜日

"Failed to launch simulated application: Unknown error." が発生したときの対処法



iPhone シミュレーター起動時に表題のエラーが発生したときの対処法です。


表題のエラーは文字通り原因不明の問題が発生したときに表示されるのですが、問題のうちの一つに「バンドルリソース内にMac OSが使用する予約されたリソース名が含まれていると発生する」というものがあります。

たとえば
Contents
Resources
などの名前のディレクトリやファイルをバンドルリソース内に作成してしまうと、ビルドは通るのですがシミュレーター実行時にエラーが発生するようです。これらの予約された名前は使わないようにすると良いです。

2010年12月29日水曜日

アプリのビルド時に CSSMERR_TP_NOT_TRUSTED エラーが発生したときの対処法

http://d.hatena.ne.jp/drill256/20090820/1250752178
http://discussions.apple.com/thread.jspa?threadID=1630090

このエラーは、以下の証明書がすべて存在しないか、または Keychain Access 内でのステータスが、「この証明書は信頼されています。」ではないときに発生するようです。
  • Apple Worldwide Developer Relations Certification Authority
  • iPhone Developer または iPhone Distribution


上記の画像のように、「この証明書は信頼されています。」と緑色のチェックマーク付きで表示されている必要があります。そうでない場合は何らかの問題があります。

対処法は、
  1. まず何はなくともこれらの証明書がすべて存在するか確認する。 Apple Worldwide Developer Relations Certification Authority を忘れているケースが良くあります。
  2. 「この証明書は信頼されています。」になっていない場合には、証明書を選択して、「情報を見る」 -> 「信頼」 -> 「システムデフォルトを使う」 を選択する。「常に信頼する」ではダメです、エラーになります。
証明書をどのキーチェイン項目に入れていても問題はなさそうです。私の場合は WWDR をシステムに、 iPhone Developer をログインに入れていますが正常に動作しています。

2010年5月30日日曜日

iPad 3G を Xcode につないだら対応していない OS と言われてしまった件



昨日の勉強会でさっそく買ったばかりのiPad 3GをXcodeにつないでみたら、ご覧のように対応していないOSであるとエラーが出てしまいました。

再度iPhone Developer CenterからSDKをダウンロードしてインストールし直したら問題なく動作するようになりました。おそらく単にSDKが古かっただけなのだとは思いますが、一応。

2010年2月15日月曜日

Flash の SWC は使ってはいけない

タイトルからしてなかなかひどいですが、調査結果もなかなかひどいです。

■結論:fl.controls(最初からFlashに付属しているコンポーネント)を含むSWCを作ると正しく読み込まれない
まずはこちらに検証用のプロジェクトを用意しましたので、ご覧になってみてください。
package {
import flash.display.MovieClip;

public dynamic class Abesi extends MovieClip
{
public function Abesi() {
trace("abesi");
trace(this.button, this.textArea);
}
}
}
package {
import flash.display.MovieClip;

public dynamic class Hidebu extends MovieClip
{
public function Hidebu() {
trace("hidebu");
trace(this.button, this.textArea);
}
}
}
とまぁ、なんの変哲もないタダのFlashコードをswcとして出力し、TestMainの中でnewして出力しているだけなのですが、なんとswcに書き出すタイミングに応じて確実にエラーになって落ちるというひどい問題があるようなのです。


■検証結果
以下のスプレッドシートにまとめてみました。
http://spreadsheets.google.com/ccc?key=0AoXhhCSOuqOtdE5rNy1wc2N2Z2JuV1NPUFBjdlRNeHc



たぶん私の書き出し方に何か問題があるのだろうとは思っているのですが、何処を見てもそれに関する情報が見あたらなかったので解決できず、結局swcの使用はあきらめることにしました><

2009年9月8日火曜日

Mac OS X 10.6 Snow Leopardのeasy_installでPILをビルドするときに気をつけることなど

Snow LeopardにPIL(Python Imaging Library)をインストールしようとして見事にハマりましたので、後学のために事の顛末を記しておきます。


■まず最初に、調べて分かった結論
  • Snow LeopardでPythonを使うときは、デフォルトで付属しているPython 2.6.1を使用すること。
  • Snow LeopardにはPython 2.5.4も付属しているが、こちらは使用するべきではない。
  • Snow LeopardのPython 2.5.4のdistutilには不具合?があり、UnixCCompilerクラスがC言語のモジュールを64bitでビルドしてくれないため、Snow Leopardでは動作しなくなる
  • したがって、C言語のモジュールを使用しているPILはSnow LeopardのPython 2.5.4を使うとビルド出来ない
  • どうしても2.5.4を使いたいときには、環境変数にARCHFLAGS "-arch x86_64"を追加してからPILをビルドするとうまくいくかもしれない(未確認)
  • MacPortやMacPythonからのインストールは実験していないため未確認

※ あくまで2009年9月8日現在での断片的な情報です。皆様がごらんになっている時点では既にMacPort上のPythonやMacPythonも対応を完了しているかもしれませんので、参考程度にご覧ください。でもSnow Leopard上のPython 2.5.4はほんとお勧めしません。


■ことのはじまり
Leopardのころはきちんと動いていたGoogle App Engine SDKが、Snow Leopardにアップグレードしたとたん突然PILモジュールがないと警告を出すようになってしまいました。確認してみると/Library/Python/Python2.5/site-packages/以下に確かにインストールされているのですが、何度試しても警告が消えません。Pythonのバージョンも以前から使っているPython 2.5のままです。これは何かがおかしい、再インストールした方がいいだろうと判断し、http://www.pythonware.com/products/pil/から1.1.6のソースコードを落としてきていざビルド。
sudo python setup.py install
python selftest.py
・・・が、動きません。なにやらImagingMathが見つからないだのなんだのとエラーが出てしまいます。これだけではよく分からないので、直接PILのモジュールをPythonからimportしてみることにしました。
akisute PIL$ python2.5
Python 2.5.4 (r254:67916, Jul 7 2009, 23:51:24)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import Imaging
>>> # 問題なくインポートできました
>>> import _imaging
Traceback (most recent call last):
File "", line 1, in
ImportError: dlopen(./_imaging.so, 2): Symbol not found: _jpeg_resync_to_restart
Referenced from: /Library/Python/2.5/site-packages/PIL/_imaging.so
Expected in: flat namespace
in /Library/Python/2.5/site-packages/PIL/_imaging.so
>>>
ふむふむ、どうやらこの_imaging.soというのがなにやら悪さをしているようです。@tokibito先生にお尋ねしたところ、このsoファイルというのはC言語のソースをコンパイルしたライブラリで、Pythonから動的にインポートできるようにpython.hというヘッダをインクルードしてつくられているらしいということが分かりました。なるほど、それでPythonから直接C言語で書かれてビルドされたライブラリをimportできるんですね。凄いなPython。

となると怪しいのはPILのビルド工程。先ほどのエラーを見ると_jpeg_resync_to_restartというシンボルが見つからないと表示されていたため、インストールに使ったlibjpeg(MacPortよりインストール)に何か問題があったのではないかと推測したのですが、特に問題は見つからず。

次にPILのビルドログを調査。細かいwarningが出まくるのはいつものことなので無視して調べてみますが、一見何もエラーは出ていません。するとあることに気づきました。
gcc-4.2 -Wl,-F. -bundle -undefined dynamic_lookup -arch i386 -arch ppc build/temp.macosx-10.6-i386-2.5/_imaging.o build/
temp.macosx-10.6-i386-2.5/decode.o build/temp.macosx-10.6-i386-2.5/encode.o build/temp.macosx-10.6-i386-2.5/map.o build/
----
中略
----
-L/o
pt/local/lib -L/System/Library/Frameworks/Python.framework/Versions/2.5/lib -L/usr/lib -ljpeg -lz -o build/lib.macosx-10
.6-i386-2.5/_imaging.so
うん、なるほど、原因が分かりました。-arch i386と -arch ppcでしかビルドされていないのがまずそうですね。Snow Leopardは64bitですから、-arch x86_64を追加してビルドしなければならないはずです。

ためしにPython 2.6.1でこの_imaging.soを読み込もうとしてみた結果がこちら。
akisute PIL$ python
Python 2.6.1 (r261:67515, Jul 7 2009, 23:51:51)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import _imaging
Traceback (most recent call last):
File "", line 1, in
ImportError: ./_imaging.so: no appropriate 64-bit architecture (see "man python" for running in 32-bit mode)
>>>
ビンゴ!間違いなさそうです!あとは、どうすれば64bitでビルド出来るかを調べるだけです。


■distutilとの戦い
とは言ってみたものの、そもそも一体全体どういうカラクリでpython setup.py installコマンドがgccビルドを実行しているのかが分かりません。まずはsetup.pyのソースを読んでみることにしました。するとdistutils.command.build_extなるモジュールをimportして使っていることが判明。怪しい。Python2.5のシステムライブラリをあさってみると、ありましたありました。


さっそくコードを読んでみると・・・
475         objects = self.compiler.compile(sources,
476 output_dir=self.build_temp,
477 macros=macros,
478 include_dirs=ext.include_dirs,
479 debug=self.debug,
480 extra_postargs=extra_args,
481 depends=ext.depends)
おおっといきなり発見、self.compiler.compileとか怪しさ抜群です。こいつはどこからやってきたのかとソースをたどると、なにやらunixccompiler.pyというモジュールを発見。いかにも私がコンパイラだと言わんばかり。犯人はこいつに違いない。さっそくコードを開いて-archとかで検索をかけてみましたが、i386とかppcとか直接指定している箇所は見あたりませんでした。その代わり別の収穫を発見。
def _darwin_compiler_fixup(compiler_so, cc_args):
"""
This function will strip '-isysroot PATH' and '-arch ARCH' from the
compile flags if the user has specified one them in extra_compile_flags.

This is needed because '-arch ARCH' adds another architecture to the
build, without a way to remove an architecture. Furthermore GCC will
barf if multiple '-isysroot' arguments are present.
"""
----
中略
----
if stripArch or 'ARCHFLAGS' in os.environ:
while 1:
try:
index = compiler_so.index('-arch')
# Strip this argument and the next one:
del compiler_so[index:index+2]
except ValueError:
break

if 'ARCHFLAGS' in os.environ and not stripArch:
# User specified different -arch flags in the environ,
# see also distutils.sysconfig
compiler_so = compiler_so + os.environ['ARCHFLAGS'].split()
----
後略
----
環境変数ARCHFLAGSとかいうのを見てるみたいです。なるほど、じゃこいつに"-arch x86_64"とか追加すればきちんと64bitビルドしてくれるのでしょうか?


■そしてあっけない幕切れ
ここまでなんとか一人で調査していたものの、たまりかねた隣の席の皆さんからアドバイス。

「Python 2.6じゃないのがまずいんじゃね?」

え、何、そういうこと?まぁ念のために試してみるか、ということでPythonを2.6に切り替えて再度PILをビルド。

あ、-arch x86_64がビルドオプションについてる。

あ、python selftest.py一発で通った。

あ、Google App Engine SDKがPILの警告吐かなくなった。

終了。

なにそれ。俺の苦労、何よ。


■あれ?
・・・おかしいな、今日作るはずだったGoogle App Engineのアプリ、まだ10行ぐらいしか書いてないよ><

2009年6月26日金曜日

Keychain Accessから秘密鍵を書き出すときに、「エラーが発生しました。項目を読み込めません。」と表示されたときの対処法

iPhone開発にはAppleが発行する証明書が必要になるため、なにかとKeychain Accessのお世話になることが多いです。特に、複数台のMacで開発を行っている場合は、証明書を認証するための秘密鍵を複数台のMacにインストールする必要があります。
このとき、最初のMacから別のMacに秘密鍵を移すために、Keychain Accessから秘密鍵を書き出しする必要があるのですが、書き出した秘密鍵を取り込もうとすると「エラーが発生しました。項目を読み込めません。」とエラーが出て取り込みが出来ないケースがあります。


こんなダイアログです。

このダイアログが出てしまったときの対処法をまとめてみました。


■結論から言うと
このダイアログが出てしまったときは、秘密鍵の書き出し方を間違っています。


この「すべての項目」画面から鍵を書き出してしまうと、書き出しには成功しますが読み込むときに100%失敗してしまいます。


こちらの「証明書」画面から証明書の階層を開き、鍵を書き出すと、正常に読み込むことが出来ます。

2009年5月2日土曜日

Google App Engineで、index.yamlに記述したインデックスが正しく生成されないときの対処法



Google App EngineでDatastoreのindexを利用したアプリケーションを作成していたのですが、運悪くindexの生成がいつまで経っても終わらない現象に見舞われてしまいました。データ量はたかだか1000件程度しかないのですが、3日経ってもindexの状態が"Building"のまま。Googleグループの書き込みを見ると(http://groups.google.co.jp/group/google-appengine/search?group=google-appengine&q=index)、indexの生成に失敗するというケースがたびたび発生しているようです。
  • index対象となるモデルの数は全く関係がない。数件しか保存されていないモデルに対してindexを生成しても発生する。
  • Googleの中の人曰く、indexはアプリ開発者全体で共有のindex作成クローラーによって行われているため、全体的に一度に利用する人が増えると不安定になる。

■まずはappcfg.pyを利用して、indexを消して再生成してみる
まずはindexをいったん消して再作成することにより、自分の手で解決できないかどうか試してみます。こちらの記事(http://osima.jp/blog/gae-index-in-trouble.html)を参考にさせていただきました。

まずは、index.yaml中のトラブルを起こしているindexをコメントアウトして削除し、
# Get a list of articles for "all" news page.
#- kind: Article
# properties:
# - name: is_duplicated
# - name: date_update
# direction: desc

ターミナルから以下のコマンドを実行。
appcfg.py --force vacuum_indexes /path/to/my/application

うまくいけば、管理者コンソールのIndexesメニューを開くと、対象のindexが"Deleting"という状態になっているはずですので、しばらく待って完全にindexが消えてからindex.yaml中で再度コメントアウトした記述を復活して、
appcfg.py update_indexes /path/to/my/application

を実行すれば、無事にindexが再作成されます。


■それでもだめなら、GoogleグループからGoogleの中の人にお願いして消してもらう
これでうまくいけば万事解決なのですが、ときどきこの方法ではうまくいかない場合があります。たとえば私の場合は、下記のようなエラーが出て上手くindexの削除が出来ませんでした。
akisute $ appcfg.py --force vacuum_indexes .
Fetching index definitions diff.
Deleting selected index definitions.
2009-05-02 12:48:33,476 WARNING appcfg.py:670 An index was not deleted. Most likely this is because it no longer exists.

kind: Article
properties:
- name: is_duplicated
- direction: desc
name: date_update

このような場合は、2009/05/02現在、米国本家のGoogle App Engineグループ(http://groups.google.co.jp/group/google-appengine)に直接お願いしてGoogleの中の人によってindexを削除してもらうしかないようです。以下の点に気をつけて新規ディスカッションを投稿すれば、スムーズにindexを削除してもらえると思います。
  • indexの生成がBuildingのまま進まない、24時間以上経っているのにうんともすんとも言わないことを明記する
  • appcfg.py vacuum_indexを試したけれどもうまくいかなかったことを明記する
  • 自分のアプリのApp IDを載せる
  • どのindexを削除してもらいたいかを載せる
参考までに、Google App Engineグループをindexで検索したときの結果(http://groups.google.co.jp/group/google-appengine/search?group=google-appengine&q=index)を載せてみました。同様の症状例がたくさん報告されていますので、それらの文面を適当にパクって参考にして投稿するのをおすすめします。
ただし、
Before posting, please read our Charter. Please note that due to recent spam activity, a member's first post will be moderated by one of the group's managers.
と注意書きがあるとおり、現在Spam対策として、最初の1回目の投稿はモデレータによってチェックされてしまい、すぐに投稿が反映されないみたいです。投稿されたとしても、いつindexの削除をしてくれるかはGoogleの中の人の気まぐれになってしまうので、解決には少々時間がかかります。


■英語が苦手なら、日本のコミュニティに助けてもらおう!
どうしても英語が苦手なら、日本のGoogle App Engineコミュニティ(http://groups.google.co.jp/group/google-app-engine-japan)に相談してみるとよいかもしれません。たとえば、こちらの投稿(http://groups.google.co.jp/group/google-app-engine-japan/browse_thread/thread/289b87a344715ea1/c9b5f8e394ac6a47)が参考になります。


■でも本当は
早くこんなトラブルが起こらないようなシステムになってほしいです><

2009年3月19日木曜日

Your mobile device has encountered an unexpected error (0xE800003A)

いつになってもこのエラーの対処法が覚えられなくてGoogle先生にお尋ねすることになっているので、ここに備忘録を記しておきます。

1.info.plistのBundle identifierとProvisioning ProfileのApp Identifierを一致させる


これはネットのどこを見ても書いてある情報なので大丈夫だと思いますが一応。
面倒ならば、裏技的手法として、Provisioning ProfileのApp Identifierを*だけにするという手段があります。こんな風に。
ABCDEFGHIJK123.*
この方法だとオープンソースのプロジェクトを拾ってきたときでもすぐに実機インストールすることができるので、いちばんお勧めかもしれません。


2.クリーニングする(Shift+Command+K)

で、1.は毎回試すのですが、それでもうまくいかないので次はこれ。クリーニングを行います。
もしくはプロジェクトフォルダ以下のbuildディレクトリの中身をすべて消してしまっても同様の効果が得られます。


今のところこの二つを試したら毎回うまくビルド出来ているので、とりあえずはこれで大丈夫かと思います。