前置き
- Utf8Json とは、私が尊敬して止まない @neuecc さん *1 が作った C# で動作する高速な JSON シリアライザのコトです。
- 私の頭脳で理解出来た範囲で仕組みを掻い摘まむと、以下のような特徴があります。
- 何で速いのか?とかは README を読むと良いんじゃないかな?
- で、この Utf8Json のルール定義コードを生成するジェネレータが .NET Core 2.1 な macOS 上で動作しない *2 コトが判明したので、その辺どうにかするために格闘した記録をここに綴ります。
.NET Core is 何?
- .NET のオープンソース実装の一つです。
- .NET Standard を使用した .NET 実装であり、Windows, macOS, Linux の何れの環境でも動作するコンソールアプリケーションを作れます。
- 詳しいことは この記事 を参照すると良いんじゃないでしょうか。
- まぁ、凄く雑に言えば macOS でも動く .NET です。
- 私は、.NET 界隈に明るくないので、ググって調べた範囲だとこんな感じっぽいです。
なんで動作しないの?
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Runtime.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
- README に従って releases ページに添付してある
Utf8Json.UniversalCodeGenerator
というコードジェネレータのコマンドを叩くと、上記のようなエラーを吐いて落ちてしまいます。dotnet Utf8Json.UniversalCodeGenerator.dll
とかやっても同じでした。Utf8Json.UniversalCodeGenerator.runtimeconfig.json
の書き換えも試しましたがダメでした。
- 原因は深追いしてないので不明です。
- まぁ、エラーを見るに
System.Runtime.Extensions.dll
的なモノを参照出来てないんだと思います。 - 同一ディレクトリに存在してるんですが、それでも読めないのが謎です。.NET のバージョン問題とか?
- まぁ、エラーを見るに
どうやって解消したの?
- ローカルの環境でビルドし直しました。
- 幸いにも、コードジェネレータのソースコードも GitHub に上がっているので、そのプロジェクトを JetBrains Rider 上でビルドしました。
- Xamarin Studio とか Visual Studio for Mac とか Visual Studio Code とかでもビルド出来るかも知れませんが、やり方分からんのでパス。
- 手順としては以下の通り。
- GitHub から clone したソースの中にあるソリューションファイル
Utf8Json.sln
を Rider で開く -
src
以下にある唯一エラーが出ていないUtf8Json.UniversalCodeGenerator
というプロジェクトを選択 - メニューなりコンテキストメニューなりからビルド
-
src/Utf8Json.UniversalCodeGenerator/bin/Debug/netcoreapp2.0
以下にUtf8Json.UniversalCodeGenerator.dll
が出来る
- GitHub から clone したソースの中にあるソリューションファイル
- このできあがった dll を
dotnet
コマンド経由で実行したら以下のようにちゃんとコマンドヘルプが出るようになりました!
$ dotnet src/Utf8Json.UniversalCodeGenerator/bin/Debug/netcoreapp2.0/Utf8Json.UniversalCodeGenerator.dll arguments help: -i, --inputFiles=VALUE [optional]Input path of cs files(',' separated) -d, --inputDirs=VALUE [optional]Input path of dirs(',' separated) -o, --output=VALUE [required]Output file path -f, --allowInternal [optional, default=false]Allow generate internal( friend) -c, --conditionalsymbol=VALUE [optional, default=empty]conditional compiler symbol -r, --resolvername=VALUE [optional, default=GeneratedResolver]Set resolver name -n, --namespace=VALUE [optional, default=MessagePack]Set namespace root name
それ欲しいんだけど!
- 元の Utf8Json が MIT ライセンスなんで多分大丈夫だとは思いますが、ビルド成果物を再配布して良いモノか分からんかったので、一先ず公開とかはしないでおきます。
- 要望が多ければ @neuecc さんに許可とって、Fork したリポジトリの releases ページにでも添付するかも。
所感
- 触ったコトない環境でビルドやら何やらやるのは結構骨が折れますね…。
- アーキテクチャとかの概念がある程度分かっていないとエラーの意味が分からないし、分かっても対処の仕方が思いつかないなぁとか感じました。
- まぁ、とりあえずやりたいことは達成できたので満足!
*1:@neuecc さんは、かの有名な UniRx の作者さんです。
*2:ちなみに、同じく @neuecc さんが作った MessagePack for C# や ZeroFormatter なんかも同じくシリアライザなんですが、こちらはほぼ確実に macOS では動かないっぽい(未検証だけど)ので完全に見送っています。