質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Q&A

解決済

1回答

2940閲覧

Xamarin.AndroidのBeforeBuildの実行タイミングについて

退会済みユーザー

退会済みユーザー

総合スコア0

Xamarin

Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

1グッド

0クリップ

投稿2016/12/05 04:37

Xamarin.Android用のプロジェクトを自動生成して使っています。

Nativeライブラリを含むプロジェクトは、以下URLを参考にして

http://qiita.com/hIDDEN_xv/items/177ac7ba756afde6ddfe#%EF%BC%94%E3%83%93%E3%83%AB%E3%83%89%E3%82%BF%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B

XML

1<Target Name="BeforeBuild"> 2 <Exec WorkingDirectory="jni" Command="$(AndroidNdkDirectory)\ndk-build" /> 3</Target>

を追加しています。

プロジェクトファイルではNativeライブラリはパス及びファイル名は記述されていますが、実体(libs\arm64-v8a\libopenjpeg-dotnet.soなど)が存在しない状態です。

この時に、Xamarin Studioからすべてビルドを実行すると以下のようなエラーが出てビルドできません。
BeforeBuildによってNativeライブラリがコンパイルされ、所定の位置にインストールされ、ビルドが通ることを期待しています。

エラー抜粋

ターゲット _CreateNativeLibraryArchive: C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: "CreateNativeLibraryArchive" タスクが予期せずに失敗しました。\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: System.IO.DirectoryNotFoundException: パス 'libs\arm64-v8a\libopenjpeg-dotnet.so' の一部が見つかりませんでした。\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: 場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: 場所 System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: 場所 System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: 場所 Xamarin.Android.Tools.Files.CopyIfChanged(String source, String destination)\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: 場所 Xamarin.Android.Tasks.CreateNativeLibraryArchive.Execute()\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: 場所 Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()\r C:\Program Files (x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1149,5): error MSB4018: 場所 Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() プロジェクト "OpenMetaverse.Android.csproj" 内のターゲット "_CreateNativeLibraryArchive" のビルドが終了しました -- 失敗。 プロジェクト "OpenMetaverse.Android.csproj" のビルドが終了しました -- 失敗。

実体が存在しない事によるエラーと考え、
回避策として、ビルドする前に一度ndk-buildをすると、実体が存在するため、以下のように

ターゲット _SetupApplicationJavaClass: Application Java class: android.app.Application ターゲット BeforeBuild: C:\ProgramData\Microsoft\AndroidNDK64\android-ndk-r11c\ndk-build [armeabi] Install : libopenjpeg-dotnet.so => libs/armeabi/libopenjpeg-dotnet.so [armeabi-v7a] Install : libopenjpeg-dotnet.so => libs/armeabi-v7a/libopenjpeg-dotnet.so [arm64-v8a] Install : libopenjpeg-dotnet.so => libs/arm64-v8a/libopenjpeg-dotnet.so [x86] Install : libopenjpeg-dotnet.so => libs/x86/libopenjpeg-dotnet.so [x86_64 Install : libopenjpeg-dotnet.so => libs/x86_64/libopenjpeg-dotnet.so ターゲット ResolveProjectReferences:

インストールされ、ビルドも完了します。


質問:
BeforeBuildより前に、_CreateNativeLibraryArchiveがあり、Nativeライブラリが何かされている(zipとしてアーカイブされるところまではわかりました。)ということは、BeforeBuildにおいて、コンパイルされ、所定の位置にインストールされたものは、そのビルド時の生成物に含まれないということなのでしょうか?

もし、そうなら<Target Name="BeforeBuild">を追加せずに運用しようと思っておりますが、挙動がよくわからないので質問させていただきました。

よろしくお願いします。

ikuwow👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

MSBuildの一般的な知識として読んでいただければと思いますが、BeforeBuild/AfterBuildは実行順序を保証しない、外部からのターゲット実行の追加方法として利用できる機能なので、BeforeBuildで自分の手元で指定したターゲットよりXamarinのビルドタスクが先に実行される可能性があることは、否定できません。詳しくはコチラ:
http://sedodream.com/2013/02/12/MSBuildDependsOnTargetsVersusBeforeTargetsAfterTargets.aspx

ビルドターゲットの実行順序を保証できるやり方としては、BuildDependsOnなどの既定のMSBuildプロパティ(変数)を拡張して、自分のタスクを滑りこませるやり方です:

<PropertyGroup> <BuildDependsOn>MyTargets;$(BuildDependsOn)</BuildDependsOn> </PropertyGroup>

BuildDependsOnはだいぶ粒度の粗いレベルでの実行順序指定プロパティなので、場合によってはもっと細かいプロパティを探す必要があるかもしれません。基本的に、Xamarin.Android.Common.targets では、プロパティ名が '_' で始まっているものは第三者がタスク追加可能なものとみなしても良いので(Xamarin.Android.Binding.targetsはそうでもない)、どんなプロパティが拡張可能かはtargetsファイルを追っかけてもらえればと思います。

投稿2016/12/05 07:40

atsushieno

総合スコア121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/05 08:05

回答ありがとうございます! 期待しない結果が得られる理由がわかりました。 MSBuildについて詳しく見ていきながら、Xamarin.Android.Common.targetsの中身をのぞき、どのように対処するのか考えたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問