アズタケの開発日誌

備忘録を兼ねて作ってしまいました。さて、今回は何日坊主になるか・・・

CoreRTでnugetのパッケージ参照を自動的にIlcReferenceさせる話

昨日に続いて.NetNative(CoreRT)に関するものです。

現在の最新版(master)ではパッケージ参照を追加したとしてもIlcReferenceを行わないため、仮にパッケージ参照を行い、Program.csで該当メソッドを使用したとしても以下のようにFileNotFoundExceptionが発生してしまいます。

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
--------------------------------------------------

これを解決するために探した結果、昨日も記載してあるこ↑こ↓に行きつくわけですが、nugetパッケージ参照は手動でIlcReferenceを記載しなくてはなりません。
イッシューでメンバーの方が「そんなに難しくないからtargetsリバースエンジニアリングしてみ!」と言っている*1し、今までMSBuildファイル等はいじったことがない*2ので、どうせなのでやってみようってことでやってみました。

Targetの構文が変わっているのか、Stackoverflowなど参考にしても中々うまくいかなかったのが印象的でしたが、MSBuildファイルは操作できることが多く、結構複雑なことまで*3出来ることに驚きました。まるで簡単なスクリプトエンジンみたい。

さて本題に戻すと、以下のような記載をcsproj内に追加すれば出来ました。

  <Target Name="SetReferences" BeforeTargets="IlcCompile">
    <ItemGroup>
      <IlcReference Include="%(ReferencePath.Identity)" />
    </ItemGroup>
  </Target>

サンプルとして全体としてはこうなります。

<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" />
  </ItemGroup>
  <Target Name="SetReferences" BeforeTargets="IlcCompile">
    <ItemGroup>
      <IlcReference Include="%(ReferencePath.Identity)" />
    </ItemGroup>
  </Target>
  <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\Sdk\Sdk.targets" />
  <Import Project="$(IlcPath)\Microsoft.NETCore.Native.targets" />
</Project>

出来れば最新のdotnet cliで生成されたものをベースにしたい所ではありますが、最新のdotnet cliベースで作成して.NETCore.Nativeをインポートしてビルドするとこうなります。

IlcCompile:
  ディレクトリ "native\" を作成しています。
  "C:\corert\bin\Product\Windows_NT.x64.Release\packaging\publish1\CoreRun.exe" "C:\corert\bin\Product\Windows_NT.x64.
  Release\packaging\publish1\ilc.dll" @"native\dotnetnewtest.ilc.rsp"
LinkNative:
  link  @"native\link.rsp"
LINK : fatal error LNK1181: 入力ファイル 'native\.obj' を開けません。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.cs
proj]
C:\corert\bin\Product\Windows_NT.x64.Release\packaging\publish1\Microsoft.NETCore.Native.targets(151,5): error MSB3073
: コマンド "link  @"native\link.rsp"" はコード 1181 で終了しました。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.csproj
]
プロジェクト "C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.csproj" (LinkNative ターゲット) のビルドが終了 しました -- 失敗。


ビルドに失敗しました。

"C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.csproj" (LinkNative ターゲット) (1) ->
(LinkNative ターゲット) ->
  LINK : fatal error LNK1181: 入力ファイル 'native\.obj' を開けません。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.
csproj]
  C:\corert\bin\Product\Windows_NT.x64.Release\packaging\publish1\Microsoft.NETCore.Native.targets(151,5): error MSB30
73: コマンド "link  @"native\link.rsp"" はコード 1181 で終了しました。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.cspr
oj]

    0 個の警告
    2 エラー

経過時間 00:00:17.14

まだプレビュー版なので致し方無いでしょうが、構文などが結構シンプルになっているので、早めに対応してほしいですね。

*1:英語力ガバガバなので信用してはいけない

*2:編集させる系は今まで全部外部ツールに投げたりPowershell実行させたり

*3:一定の水準超えたらタスクとしてdllファイル作った方が早いかもしれませんが