2016年10月4日火曜日

マルチプラットフォーム対応のNuGetパッケージの作り方

まず、2016/10/4 現在、NuGet Docs サイトはリニューアルされ、かなり見やすくなってますので、ぜひそちらも参照ください。
昔のサイトもそれほど読みにくくはありませんでしたが、色々と情報が増えてどこを見ればいいのかわからない感じだったのも事実です。なので、個人的にはかなり良くなったと思います。 全文検索もできますし。
たとえば、docs.nuget.org のトップページにある「Guides」には目的別のガイドラインがありますし、クイックスタート的な記事もあります。このあたりを見れば結構何とかなるはずですし、リファレンスもメニューからたどることができます。
さて、その公式ドキュメントを見ればマルチプラットフォーム対応のやり方もわかると思います。色々書いてありますが(<file src> とか初めて知った)、ようは以下のようにすれば OK です。
  • .nupkg ファイル生成のソースとなるディレクトリツリー内の lib の下に、ターゲットプラットフォームを表す名前(TPM:Target Platform Moniker)のディレクトリを切り、そこに .dll と、IntelliSense 用の XML ドキュメントコメントファイルを入れます(XML 入れなくてもかまいません)
  • 依存先のパッケージがある場合、.nuspec/package/dependencies 要素の下に、TPM ごとに <group targetFramework="{TPM}"> 要素を対象の TPM ごとに記述します。この子要素として、依存先のパッケージを <dependency id="{パッケージの名前}" version="{バージョン}" /> といった具合に書いていきます。
  • .NET Standard 用の TPM を含む場合、サポートしていない古いバージョンの NuGet でよくわからないエラーが出ることがないように、/package/metadata 要素に minClientVersion="2.12" と記述します(これ、docs.nuget.org に書いてませんね……)
参考までに、MsgPack for CLI の .nuspec ファイルはこちら
ちょっと文字ばかりでわかりづらいでしょうか。実際に展開した .nupkgtree /F した結果はこんな感じです。
C:.
│  MsgPack.Cli.nuspec
│  [Content_Types].xml
│
├─lib
│  ├─MonoAndroid10
│  │      MsgPack.dll
│  │      MsgPack.xml
│  │
│  ├─net35-client
│  │      MsgPack.dll
│  │      MsgPack.XML
│  │
│  ├─net45
│  │      MsgPack.dll
│  │      MsgPack.XML
│  │
│  ├─net46
│  │      MsgPack.dll
│  │      MsgPack.XML
│  │
│  ├─sl5
│  │      MsgPack.dll
│  │      MsgPack.XML
│  │
│  ├─windowsphone8
│  │      MsgPack.dll
│  │      MsgPack.XML
│  │
│  └─Xamarin.iOS10
│          MsgPack.dll
│          MsgPack.XML
│
├─package
│  └─services
│      └─metadata
│          └─core-properties
│                  d502c190230a45328393d9c274cf792e.psmdcp
│
└─_rels
        .rels
ターゲットモニカについては、公式ドキュメント を参照してください。
Xamarin についてはちょっとわかりづらいですが、上記の例の記述で動くはずです。なお、monotouch が旧形式の Xamarin iOS、Xamarin.iOS が Unified app 版になります(Xamarin のドキュメント)。なお、旧形式については、Xamarin iOS の 10.0 からサポートされていません
さて、実際に作る際には、以下のようにするといいでしょう。
  • 実際に対応している OSS パッケージのディレクトリ構造や .nuspec ファイルを参考にする。私は JSON.NET や CoreFX のパッケージを参考にしました。
  • ローカルのディレクトリに配置して、動作を確認する。なお、v3 の場合、配置先のディレクトリを nuget init しておき、nuget add でパッケージを追加する必要があります。また、前に試した時、ローカルディレクトリは Windows でしかうまく動作しませんでしたが、最近は変わったかもしれません。
それでは、happy hacking!

.NET Fringe Japan 2016でしゃべりました

少し間が空いてしまいましたが、先週末、.NET Fringe Japanというイベントで(珍しく)しゃべってきました。当日のスライドはこちら

内容としては、まずは準備運動よろしく F# の話から始まり、C# の言語機能への提案方法まさかの .NET じゃない話Xamarin ソースの見方の Deep DiveOSS 開発のためになる話 と続いていき、日が沈むとともに IL を追加する方法の話 に行ったときにはどうなるかと思いましたが、最後は地に足の着いた deep dive でうまく終わりました。いや、松井さん最高です。正直あまり運営のお手伝いはできなかったのですが、色々な人の助けもあり、成功に終わったのかなと思います。いやー、みなさんコンテンツもしゃべりも上手で、そちらの方でも勉強になりました。

セッションスケジュール的には、ちょっと詰め込みすぎでしたかね。ただ、初回ということで、こんなマニアックな会で本当に人が集まるのか、という懸念もあり、1 トラックでまずはやってみようという話になったのでした。雨で、かつ色々と楽しそうな裏番組があった中で 100 人近い来場者があったので、次回は 2 トラックくらいにできるのかもしれません。

さて、私も好き勝手しゃべったわけですが、荒井さんのセッションの質問とか、懇親会での話とかを考えると、そもそもマルチプラットフォーム対応の NuGet パッケージの作り方を普通に説明すればよかったのでは、と気づいたので、一筆書こうと思います。そんなの日本語で話しても需要がないだろうと思っていたのですが、あそこはそういうことをする人たちの集まりなのでした :)

あと、あのメンツはどう見ても亜流とかいう生易しいものじゃなくて過激派グループだと思います