CoreRTで外部ライブラリを使用する際に詰まった件
(新年)初投稿です。
相当期間が開いてしまいましたが…
.NetNativeがどこまで使用できるかをリサートしている時に、外部ライブラリの参照で詰まったのでメモ程度に書き残しておきます。
昔のバージョンのdotnet cliではそのまま --native をつけることによりネイティブでビルド出来ていたようですが、今は分離されているようです。
github.com
この記事ではVisual Studio 2017をビルドツールとして使用しています。
また、CoreRTをクローンしてきてCドライブ直下に展開しています(書きやすくするため)
まずは結論から。
CoreRTのビルドがReleaseだろうが、アプリケーションのビルドがReleaseだろうが、外部ライブラリはDebugである必要があるみたい。おそらく方法はあると思うのでわかり次第記事にします
どうやらReleaseビルドでかつ、awaitを外部ライブラリで使用しているとこの問題が起きる模様。サンプル作成しました
github.com
PS C:\corert> .\build.cmd vs2017
このようにvs2017をつけることによりVisual Studio 2017 RCを使用してデバッグビルドでビルドさせることを*1明示しています。尚この記載が無く、Visual Studio 2015がインストールされていない場合はビルドが行われません。
ビルドが終わるまで結構時間がかかるので待ちましょう。日本語環境だとUnicodeの関係でテストに失敗するのが現れますが気にしない方針で行きます。
まずはここのテンプレートを見ながらcsprojを生成していじってみます。
安易な考えで
<Project ToolsVersion="15.0"> <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\Sdk\Sdk.props" /> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="<社内ライブラリ>.Context"> <Version>0.1.0-alpha-000022</Version> <PrivateAssets>All</PrivateAssets> </PackageReference> </ItemGroup> <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\Sdk\Sdk.targets" /> <Import Project="$(IlcPath)\Microsoft.NETCore.Native.targets" /> </Project>
のようにして、Program.csでテストコードでも書いてビルドを行ってみます。
ここで行うビルドは、Visual Studio についてる開発者コマンドプロンプトを使いましょう。x64でビルドしたらx64の開発者コマンドプロンプトを使用してください。
C:\Users\azuta\Downloads\dtnt\corerttest>dotnet restore /p:IlcPath=C:\corert\bin\Product\Windows_NT.x64.Debug\packaging\publish1 dotnet build /t:LinkNative /p:IlcPath=C:\corert\bin\Product\Windows_NT.x64.Debug\packaging\publish1
これでビルドは通るはずです(執筆時点)
Microsoft (R) Build Engine version 15.1.545.13942 Copyright (C) Microsoft Corporation. All rights reserved. corerttest -> C:\Users\azuta\Downloads\dtnt\corerttest\bin\x64\Debug\netcoreapp1.1\corerttest.dll Build succeeded. 0 Warning(s) 0 Error(s) Time Elapsed 00:00:24.11
結果の表示で.dllとなっているのは気にせず、そのまま bin\x64\Debug\netcoreapp1.1\native\ を見てみるとexeとpdbだけの2つが存在します。
試しにこのまま実行しようとしてみると例外が発生しました。
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly '<社内ライブラリ>.Context'. The system cannot find the file specified. File name: '<社内ライブラリ>.Context' at corerttest!<BaseAddress>+0x2e291806 at corerttest!<BaseAddress>+0x2e29010f at corerttest!<BaseAddress>+0x2e27216a at corerttest!<BaseAddress>+0x2e271cce at corerttest!<BaseAddress>+0x2e261064 -------------------------------------------------- Debug Assertion Violation Message: FailFast Expression: 'ASSERT_UNCONDITIONALLY' File: C:\corert\src\Native\Runtime\EHHelpers.cpp, Line: 498 --------------------------------------------------
どうやらこのライブラリに存在するメソッドを呼ぼうとしている時に、このライブラリファイルが無いというエラーが発生している模様。PackageReferenceを指定しているのになぜ発生しているのかと気になって調べた所、イッシューに上がってました。
どうやらIlcReferenceも一緒に書いてライブラリを指定してやる必要があるんだそうな。
そこで.nugetディレクトリ内にあるdllファイルを指定して再度restore、ビルド*2を行ってみた。
-------------------------------------------------- Debug Assertion Violation Message: Hardware exception raised inside the runtime. Expression: 'ASSERT_UNCONDITIONALLY' File: C:\corert\src\Native\Runtime\EHHelpers.cpp, Line: 486 --------------------------------------------------
( ^ω^)・・・
意味不明なので調べてみたが、特にそれっぽい記事は無い。
仕方がないので試行錯誤してみた所、外部ライブラリが「Release」でビルドされていることに関係しているようだ。
外部ライブラリをDebugに変えてビルドしなおし、参照すると正しく動作する。
てっきりCoreRT側がReleaseビルドでないことが問題かと思い、
PS C:\corert> .\build.cmd vs2017 Release
のようにしてReleaseビルドでビルドして、再度アプリケーションのビルドを行っても変わらず*3
現在はローカルでビルドしたDebugビルドを使用していますが、出来ればnugetから取得したReleaseビルドのライブラリを使用したい所。
P.S. Releaseビルドでかつ、外部ライブラリ内でawaitを使用していると そこでエラー落ちしているようです。
また何か分かったら続きの記事書こうと思います。