アンカンファレンスやろう

Xamrin Evolveが再来週に迫ってきましたね。

https://evolve.xamarin.com/

参加される皆さんどうぞよろしくお願いします。

 

まあそんな人はほぼ皆無だと思うわけですが、日本ではde:codeの前夜祭のようなものがあって、de:code参加者でなくても参加できるそうなので*1、前回書いたようなゲリラ(非公認)ミートアップのようなものをここでやりましょう。*2

connpass.com

アンカンファレンスって何?

アンカンファレンスというのは、セッションのように誰かが1人だけ発表して他の人はそれを聞くだけ、みたいな退屈な時間ではなくて、誰かがトピックを持ち込んで、それについてみんなが会話に参加するかたちで作っていく、単なる雑談の場よりはもう少しオーガナイズされたミートアップのようなものです。

プロジェクターがあるのでスライドを見せながらしゃべることもできますが、1人でしゃべっているだけだと単なる短いセッションで終わってしまうので、それは用意しても手短に、あるいは画面を共有するに留めるのが良いでしょう。わたしは基本的にスライドみたいなものを用意するつもりはありません。(Webページをみんなで眺めることはあるかもしれませんが。) 質疑応答が活発であれば、それで終わるかもしれませんね。

まあ先着順のようなので、そもそもその場でアンカンファレンスにエントリーできるかどうかは当日にならないとわからないのですが、わたしがいることには変わりないので、何かしらの場が作れるだろうと思います。15分で終わらなかった話をテーブルの外で続けてもいいですしね。

*1:かく言うわたしもde:codeには参加登録していませんし

*2:すぐに人数がいっぱいになったらどうしようと思ってちょっと待っていたのですが、その懸念は必要なかったようですしね。

Xamarin is going to be open to Everyone

Microsoft Build 2016 2日目のキーノートで、MonoランタイムがMITライセンスに変更され、Xamarin Runtimeと称されるXamarinプラットフォームの部分がオープンソース化されることが発表されました。

blog.xamarin.com

今後数ヶ月、おそらくは来月のXamarin Evolveまでに、何かしらの成果が公開されるのでしょう。Buildから1ヶ月もしないうちにXamarinオンリーイベントとか、まあまさかもう動かせないしやるしかないって感じですね。ちなみに参加が危ぶまれていたわたしですが、何とか行けることになったので、現地に赴かれる酔狂な皆様もある意味ご安心下さい。(?)

(XamarinがVSに…云々は、ここではどうでもいい話なので、そういう話はそういう方面のコミュニティを眺めて下さい。)

monoランタイムがMITライセンスになると、Unity(3D)のような製品が、ライセンスを気にすること無く、既に組み込みLinux環境に最適化されたmonoを、改変ソースを公開せずに使用できるようになります。(ただし、Unityで使用されているmonoランタイムは、本家monoにかなり手を加えたものであり、かつかなり昔のバージョンをもとにしているはずなので、最新版のmonoにすんなりアップデートするということはないだろうと思います。) .NET Coreも既にクロスプラットフォームで動作しますし、.NET MicroFxという選択肢もありますが、いま.NET Coreを選ぶのは、長期的な計画でもなければかなりチャレンジャーであることは否めませんし、minimized runtimeやstable embedded APIを期待している人は、まだmonoを選んだほうが良いかもしれません。この辺は、それぞれの特性や自分の計画を踏まえて選ぶのが良いでしょう。

ランタイムがMITライセンスに変更になったのは、もちろんMonoチームがもはや組み込みライセンスビジネスで生きていく必要がなくなった(Microsoftエコシステムの一部として開発していく)ことから実現したものです。

そしてXamarinプラットフォームのOSS化。ついにこの日が来てくれた、という感じです(まだですけど)。

いずれはLinux環境でも利用可能になり、全てとは言わないまでもコア部分だけでもオープンソースの環境として公開し、アプリケーションが開発できるようになってほしい、と思っていましたが、とうとう実現しそうです。

公式ブログには、アプリケーションをビルドするために必要となるツールとライブラリ一式がOSS化される、とあります。もちろんMicrosoftは全てをオープンソースに捧げているわけではなく、Visual StudioなどのIDEに統合する部分を、引き続き製品の一部として(のみ)提供していくわけで(ちなみにXamarin Studio for Windowsは無くなります。もちろんMonoDevelopは引き続きOSSです)、その部分はクローズドソースで収益源になるようです(その辺はFAQを見てもらえればと思います)。

ソースを書いてアプリケーションをビルドするための、最小限の環境は提供するから、IDEに頼りきらない開発者は我が道を切り開いて歩いてくれ、ということです。面白い。受けて立とうじゃないか。われわれは.NET Framework SDK Toolsしか無いような環境でも生き延びてきたんだぜ。(って自分が中の人だったことを忘れるところだった…)

個人的にも、自作のライブラリなどをiOS/Androidで展開する時に、商用製品を買ってもらわないとcontributeしてもらえない事態には、忸怩たる思いがあったので、これで誇りをもって開発していくことができます。

オープンソースで.NET開発を推進してきたMonoが、Xamarinになってクローズドソースの製品を売り続けてきたのを、Microsoftが買収してオープンソースにして公開するというのは、歴史の皮肉とも言えますが、実に面白い展開になってきましたね。

面白いといえば、JetBrainsとUnity3DとRedHatが.NET Foundationにjoinするというニュースもなかなかのインパクトだと思います。Riderもプレビュー版が公開されたばかりなので、JetBrainsが、Javaで書かれたIDEに.NETをどう組み込んで統合していくか、見ものですね。わたしが彼らに大いに期待しているのは、.NET Core統合の実現です。RedHatLinux環境で.NET Coreの普及を促進していくための協業をどう展開していくかですね。Unityは、まあ言うまでもないでしょうけど、最適なランタイムを実現するための選択肢が広がって、近くない将来の見通しは良くなったのではないかと思います。

Build1日目のUbuntu組み込みの件も含めて、今回のBuildには面白いネタがたくさんありましたね。日本でも5月下旬のde:codeでいろいろ紹介されると期待しています。わたしは今のところ参加する予定はないのですが(どういう身分になっているのかすら何も決まっていないし!)、この辺に関心のある人が集まる日々になるので、何かしら集まって話せる機会を設けたいところですね。

長かったこれまでと、分からないけど楽しみなこれから

今回は振り返り無駄話です。

もう遡ること13年以上前、初めてmonoにパッチを送った時のことを、今でも覚えています。実のところ、monoのML(当時はmono-listしかありませんでした)には当時のアーカイブがあるので、今でも見ることが出来るんですね。 http://lists.ximian.com/pipermail/mono-list/2002-October/008988.html

.NETは、2002年当時のわたしにとっては、オープンソース開発の世界における脅威でした。

.NET Frameworkを知ったのは、仕事でWindowsアプリケーション開発に初めて関わってほどなくのことでした。当時はJavaのコードを書き始めて半年くらいだったと思います。C++VBじゃない、Java並に簡単な言語でGUIアプリまで作れてしまう、その大きな可能性に魅了されましたが、同時にこれがWindowsでしか動作しない、プロプラエタリな開発環境であることは、わたしの目には大きな脅威として映りました。

わたしが職業エンジニアになったのは、ついうっかりのようなものです。当時のわたしは、大学で知財法制に無駄に詳しくなった後、その非論理的な制度設計に嫌気が差して*1、自由なソフトウェア(まあ正確にはオープンソースですが)の世界に魅入られており、この.NET Frameworkのような開発環境がオープンソースで存在すればいいのに、と思っていたのでした。.NETはECMAで標準化を図っていましたが、それはもう完全にJavaの標準化プロセスに対抗しているように見えました。だいたい技術標準だというのなら、実装が2つあるべきじゃないか。他に実装もないのに、何が標準化だ、と。

…そして、monoを「発見」したのです。

当時、monoは始まってから既に1年弱が経過していたと思います。その時点で、既にmcsでコンパイルしたコンソール アプリケーションをmonoランタイムで実行できるようになっていました。mcsはC#で書かれていて、セルフホストしておらず(mcsでmcsをビルドできるほど完成しておらず)、Windows上でcscを使ってビルドしなければなりませんでした。

そんな状態のmonoでしたが、さまざまなドキュメントが既に存在していたので、とりあえずそれらを日本語訳するところから始めました。MLにも登録して、眺めるようになりました。MLを眺めているうちに、Miguel de IcazaがXML DOMのAPIが足りないから実装してくれ〜、みたいなメッセージを投げたのを見て、えっ、そんなのも無いの?…と思って、ソースに手を入れはじめたのが、最初の一歩でした。(ちなみに書いたコードはいい加減で、間違って彼だけに送ってしまったら「すばらしい! ちなみにテストを書いてくれ!」みたいな返事が来て、初めてテストなるものを書いてみたら、全く期待通りに動かなかったのでした…)

当時、monoチームには日本語を話せるDuncanというハカーがいて(というか今でもXamarinにいるのですが)、彼といろいろ日本語で会話しながら、いつの間にかmonoの開発チャットに出入りして、カタコトの英語でやりとりできるようになったのでした。誰が誰だかは当初全然わかりませんでしたが、あのmonoを毎日作っている連中です。すげー!と思いながら、同時にとても追いつけない量の会話を流し見しながら、参加していたものでした。

1年ほど経って、わたしが転職を考えていた時、その話をそのDuncanにしたら「じゃあうちで働きなよ!」みたいなことになって、翌日Miguelから「何ドルで働く?」(うはhドルかよ!) 「Novellに統合されたら人を雇えるから来いよ」みたいな話が来て…それでmonoチームに入ることになったのでした。

そんなわけで、会社に入ったのはNovellになってからなのですが、Ximianは近くでずっと見ていましたし、完全にNovellとは別の指針で動いているXimianの一員として仕事していました。MiguelとNatの2人が始めたベンチャー企業が、Novellという大企業に買収されて、それでも(エンジニアの目に見える範囲では)あまり変わらない体制でGNOMEとMonoを開発していくのを、9年近く見てきました。

MonoとNovellの話は(今日は)どうでもいいのでした。今日は.NETの話を書きたい。

.NET Frameworkが猛威を振るっていた(ようにわたしに見えていた)のは、Microsoftが.NET 2.0をリリースして、並行して次世代.NETでWinFXと呼ばれる「全てがマネージド」の世界を構築しようとしていた頃でした。大量のマネージドコードのプロプラエタリなフレームワークが、うっすらとしたECMA CLIの上に悪夢のように覆いかぶさって、せっかくASP.NETが動くようになったLinuxが、また.NET開発の一線から遠ざかってしまう。何とかして対抗しなければならない。そう思いながらMonoの機能を拡張していたのでした。(まあそれはわたしの話であって、他のメンバーには当然ながら各々の思想があります。)

結果的にWinFXはだいぶ縮小した存在になり、WPFもWFもしばらくは大規模に使われず、WCFは出来るとみて着手することになったので、そういった懸念は概ね杞憂に終わったのでした。

その頃から、Microsoftの開発の潮流に変化が見え始めます。(WinFXの反省だったのかな、とわたしは勘ぐるのですが、)新しい.NET 3.5の開発からは宣伝的な文句は消え、Linqなど質実剛健な機能拡張が行われるようになりました。オープンな技術標準を目指したIdentity Metasystemのコンセプトとともに、Infocardが登場しました。ASP.NETの中核となるMVCオープンソースで公開され、ほどなくいくつかのコンポーネントオープンソースで公開されるようになっていったのでした。その後も、IronLanguages、Reactive Extensions、Roslyn、そして.NET Coreと、NET Framework (referencesource)、VSCodeと、オープンソース指向で開発していくMicrosoftの姿勢は、もはや揺るがないものになりました。

このオープンカルチャーの契機となったASP.NET MVCをリードしていたのが、今回の買収の結果、Xamarinチームを配下におさめることになった、Scott Guthrieです(今はAzureチームのトップですね)。彼はMiguel、Natの2人とは長く交友関係にあって、XimianのMonoチームがNovellレイオフされた時も、いろいろ出来る範囲で手助けしようとしてくれたそうです。今回の統合は、ごく自然に成り立ったと言えるでしょう。"married" と表現している人も少なからずいました。

今回の買収は、MiguelとNatの2人にとっては、2度目の大成功ということになります。Xamarinの立ち上げは容易なものではありませんでしたが(その辺はXamarinの2年半を振り返るを見てもらえればと思います)、今回このゴールのひとつに到達できて、わたしは、期待されていた、あるべき結末を見た思いになりました。

MiguelがECMA標準をもとにMonoを始めてから約15年。MonoはXamarin製品の中核であり、まだまだ使われていきますが、大きな節目を迎えたとは言えるでしょう。Nadellaの新生Microsoftの傘下に加わったXamarinが、これからMicrosoftと一緒に、Monoが築いてきたエコシステムをどう発展させていくのか。おそらくは中の人として、今後も見続けていきたいと思います。

*1:その辺は http://d.hatena.ne.jp/atsushieno/20070813/p1 にあります

DroidKaigi2016セッションと資料にまつわるあれやこれや

2/18-19のDroidKaigiで、Android Studio 2.0のInstant Runについて話してきたので、少しその補足というか背景とかを書いておこうと思うます。

(DroidKaigi自体はいろんな人といろんな話ができてちょう面白かったのだけど、これじゃただの小並感なのでその辺は他の人にお任せです。)

 

speakerdeck.com

DroidKaigiは、2015には一応CFPにXamarinネタを投げてみたけど採用されず(CFPにも「とりあえず使い方から.NETっぽいリアクティブなコードとか書くよー」とか適当なことしか書いてなかった)、参加申込も寝て起きたら瞬殺で終わっていて、結果的にノータッチだったのでした。

今年も当初は参加予定すら無かったのだけど、CFPがそれほど集まっていなくて、たまたまInstant Runの調べ物をしていて、これくらいなら軽くしゃべれて、新しいモノ好きにはウケる話かなーと思って、投げてみたら通ったという感じでした。(最終的にはえらい数のCFPが届いていましたが。)

今回はまずそれなりのストーリーラインがほしいなと思い、まずスライドの下地となる話をちゃんと書こうと決めました。それが最終的にはコレです。

qiita.com

多分それなりに長期的に役に立つ読み物になるんではないかと思います(自己評価)。

実のところ大半は3ヶ月くらい前にgistでまとめてあったのだけど、とりあえずDroidKaigiまで待ってから出すことにしました。インスタント実行の部分 (Part III)をどうするか決めていなかったためです。

この部分は、実のところちゃんと調べないと分からなかったので(今でもだいぶうっすらとした情報量のはず)、話に入れるかどうかも決めていませんでした。30分しかなかったし。割と直前まで迷いました。ただ、ビルドの話だけにするとどうしてもオチが弱かったので、それならInstant実行のあるべき姿をプッシュする方が面白いかなと思って、滑りこませることにしました。Xamarin関係の言及が多くなってしまったのは、完全に副作用です。仕事でもないのにわざわざ宣伝なんてうんざりだし。Continuousがオープンソースでなければ完全にカットするところでした。

DroidKaigiではInstant Runおじさんとか言われたりしてたけどw、あれ自体にはあんまし思い入れはない、というか普段はXamarin Studioで日々fast deploymentしているわけで、自分にとっては新しくないわけです。ついでに言えば、YAPF(横浜Androidプラットフォーム部, 当時)で Xamarin.Androidの話をした時にその基本的な仕組みをちょっとだけしたこともあるので、実はInstant Runの基本的な仕組みは、ごく一部の(?)Androidersにとっては、完全に新しい話ではなかったりします。Android SDKが追い付いてきて、お、やったね?という感じです。

(ちなみに、従来の Xamarin.Androidのfast deploymentでは、dllの変更はすぐに反映されるけど、生成されるACW(java interop部分)に変更が生じると、Javaビルドタスクが実行される→APKが生成される→再インストール、となってfast deployment効かないじゃん!ってことになっていたので、最近はその辺を改善する仕事をやっていたのでした。*1

まあ仕事中に得られた知見は発表のごく一 部にしか活かせず*2、基本的には仕事と無関係なJavaとGradleの調べ物の産物です。

セッション全体的には、しゃべりがちょっと早すぎたかな?とは思ったものの、まあ内容がやや詰め込み気味だったのでいたしかたなく(だいぶ削ったのでした)、伝えるべきことは伝えられたかと思います。

…次回、DroidKaigiかは分かりませんが、似たような機会があったら、また.NETやXamarinとは全く無関係な調べ物と話をしたいですね。

*1:2/20に初登場したアルファ版 では、アプリケーションのcsproj に<FastDeploymentType>Assemblies:Dexes</FastDeploymentType> というプロパティを追加してやると、その辺が機能するわけですが(今こっそり隠し機能を暴露した!)、くだらない政治的な紛争の結果、この辺はまだ リリースノートにも載っていません(!)。秘密ってほどのことではないけど

*2:Bazelに似たようなコードがあることを教えてもらった程度。Instant Runの発表直後にそんなの見つけてくるmonodevelopハカーこわい

お知らせ.bat

まだあったのか!という感じのこのhatenablogですが、今年もよろしくお願いします。

今回は(も)ざっくりお知らせです。

.NET Platform Standard日本語訳

まず、githubdotnet/corefxのリポジトリに、.NET Platform Standardというドキュメントがあって、これが.NET Coreの目指すプラットフォームの標準化について説明しています。これは将来の.NETの標準化の動向に大きく影響する内容で重要だと思うので、日本語訳を作ってみました。

https://gist.github.com/atsushieno/7056f56ce4cfd01e0239

ちなみに内容の80%くらいは、以下の岩永さんのスライドで分かりやすくまとめられているので、先にこっちを見て概要を掴んだほうがいいかもしれません。(というか、ここで言及されていないのはBait and switchの詳細とかガードレールの存在くらいかも。)

docs.com

JXUG #10 XamarinでのNuGetとCIを極めよう

次。ひさしぶりにJXUGでXamarinネタをしゃべります。

jxug.connpass.com

今回はトピック指定で来ましたので、NuGetを使う話です。まあ、NuGet自体の話はあんまり語ることがない(と思う)ので、PCLを絡めて、Xamarinで使うようなパッケージってどう使う / ビルドするといいの?みたいな話をしようと思います。(NuGetの使い方だけ何十分もひたすら聞きたい人なんて居ないよね…?)

で、PCLでライブラリを作る話ですが、最後に2014年5月にこの記事を書いてからもう2年経とうとしているわけでして*1

www.buildinsider.net

この間にいろいろアップデートがあったので(とは言ってもPCLの基礎はほとんど変わっていないという認識ですが)、その辺を反映しつつ、モダンなクロスプラットフォーム開発はどうなっている・どうなっていくのか、という方向性で話をしたいと思います。(上記の日本語訳は、そのためのものだと思ってもらえればと思います!) まあスライドはまだ1枚も書いていませんけど。

Instant Runを実現する仕組み at DroidKaigi2016

もうひとつ、セッションが確定したら書こうと思っているうちに参加人数がいっぱいになって告知する意味が全然なくなっちゃったDroidKaigi2016の1日目(2/18)に、Android Studio 2.0 Previewの新機能Instant Runについての話をします。Xamarinは無関係です。基本的には()

droidkaigi.github.io

Instant Runはパッと見では「何でそんなこと出来ちゃうの?」って思えるような不思議な機能ですが、この辺の黒魔術がどのように実現されているのか、掘り下げて解明していく話をしたいと思います。詳しくはまた事前にリークするかも。しないかも。

CFPには書いたのですが、Instant Runのソースは公開されていないので、おそらく推測で話すことになるでしょう。まあ、それなりの傍証がある、確からしい話をするつもりではあります。既にDroidKaigiに登録しているラッキーな人で、もし興味が湧いてきたら、ぜひ聞きに来て下さい。

*1:これ、公開されたのは5月なんですが、大部分はその前の冬休みに書き上げていたんですよね…

2015年の終わりに感謝する作品集

今年こそクリスマスの朝に間に合わせようと思い、しばしば年末まで引っ張っていた「今年出会ったすげー作品に感謝」の2015年版をon timeに書き上げました。例によって「今年出た」作品には限りません。わたしが今年発見した作品が対象です。

2014 2013 2012

watoさんのピアノ作品

まずは理屈抜きでハマった2曲から。最初はVocaloid曲をピアノアレンジした作品。この種の作品が原曲を超えて響いてくることはなかなかないと思うのですが、そういう懸念(?)とは完全に無縁の1曲でした(まあ原曲は全然知らなかったのですが)。

次は、アレンジ/作曲の立場が代わり、「歌ってみた」の元ネタがピアノ曲、です。「歌ってみた」を色々漁るようになったのは一昨年あたりからだったと思いますが、今年最も多く聴いていたのはコレです。コンテンツツリーを辿って、50曲を超える「歌ってみた」の大半を聴いたと思いますが、これが一番自分の好みに合っていたと思います。(わたしの場合、ボカロ自体には思い入れがほぼ皆無なので、気になったボカロ曲があると、まずコンテンツツリーを見て、好みに合う「歌ってみた」動画を探します。)

純粋に感覚的な好みでしかなく、あれこれ書けることはないのですが、どちらも、発見してからほぼ毎日聴いていて、わたしの穏和な日常の源泉でもあったと言えるでしょう。

暗鳴ニュイ

実のところつい一昨日発掘したばかりなのですが、こちらは音楽というよりUTAU音源として衝撃を受けたものでした。とりあえずこちらから:


《Anna Nyui candyVCV》FREELY TOMORROW《New VoiceBank》

曲自体は、2011年に初音ミクの神調教で話題になったやつ、のカバーですが、何がすごいかって、UTAUの特性を活かして、独自の「特殊音素」をいくつも録音した音源を作成・公開していて、この曲自体は、それ自体デモのひとつに過ぎない(!?)ところです。 動画の中で説明されていますが、喉切り母音連続音、長音母音、長子音CVVC、語尾息、特殊語尾息、喉きり語尾、舌きり語尾、といった、人間の歌唱において自然に出る(とされる)特徴のバリエーションをもつ原音を録音しているわけで、それだけでもかなりの作業量になりそうな気がします。(わたしは自分ではやったことないから本当のところは分からないわけですが、周りには録音作業をやっているグループもあるので、そこから類推するとやはり大変そう…) 詳しくは動画の中で解説されているので、ぜひ見てみていただきたいと思います。他の曲の調教解説も面白いです。

今のは連続音の音源を使った例ですが、次のCVVCのサンプルはもっとすごい。


《Anna Nyui》文学者の恋文 The Writer's Love Letter《UTAU cover》

典型的な「神調教」動画で感じるような「人間が歌っているみたい」とは性質が違う。まるで人間が感情を込めて歌っているように聞こえる。「ボカロ曲なんて『歌ってみた』で人間が情感を込めて歌ったものの魅力には絶対かなわん」というわたしの固定観念をあっさり飛び越えていった1曲です。そうか、情感はプログラムできるのか。ETMLを使わなくても。人間たるわれわれにはクオリアしか残されていないのか…

戯言はどうでもいいとして、音源を自力で作りこんでプログラマブルに表現力を広めていくというこのプロジェクトは、エンジニア的に大変魅力的です。音源ドライバやコンパイラを自作していた20世紀のコンピューター作曲家たちを見ているかのような気持ちになりました。

(まあ、あとこの1曲については、原曲の完成度が高いのも、繰り返し聴ける大きな要因だと思います。)

あと、音源だけでもすごいのに、このキャラクターコンテンツを全部1人で作られているっぽいの、本当にすごい。ルネサンス期万能主義の芸術家かよ!みたいな。

東京ザナドゥ

毎度Falcomのゲームなので、まあいつも通り遊ぼう、程度のつもりで始めたのですが…かなりしてやられた作品でした。このゲームの根幹にあるのは「立川の町おこし」なんですね。falcomはずっと本社を立川に構えている会社なので、思い入れがあるのでしょう。作中には、冒頭の立川駅の風景に始まり、「地元を知っていれば分かる」感じのシーンがたくさん登場します。作中のvenue紹介も(それぞれはほぼ現実には正確には存在しないものなのですが)いちいちそれぞれの魅力を伝えてくるようなテキストになっているんですね。エンディング画面に、全然本編で登場しなかった花火の絵まで出してくる辺り(リアルでは毎年昭和記念公園でやっているやつですね)、本当はもっと出したいものがあったのかもな、と思わせてくれます。(まあシネマシティは出てきませんでしたがw)

それでわたし自身も、あの近辺の学校に通っていたので、立川にはけっこう思い入れがあるのです。覚えている場所が出てくるたびに、ぉぉ、と思いながら進めていたものでした。間が悪いことに、その時は台湾で暮らしていた頃だったので、「もう早く東京に帰って立川を見に行きたい」と思う一方でした。それで結局台湾の居場所を引き払って東京に戻ってきてしまったわけで、たいへん罪作りな作品だったと思います(!) まあその、"立川は東京に含まれるのか問題"が無くもないですが

あと音楽もいいものが多かったと思います(曲数が抑えられていて = 粗製濫造になっていなくて良かった)し、それらの使われ方が上手かったですね。2015年にもなって未だにOPN由来っぽい音色をBGMに使っている辺り、変わらんなあと思いました。

また来年

今年は紹介数が控え目になりましたが、歌モノの動画はニコ動のマイリストだけでも30本くらい新しく追加されていて、それにyoutubeとかのものも加えて全部書いていたらキリがないので、これくらいにしておきたいと思います。

また来年も血沸き肉踊る楽しい作品に出会えることを楽しみにしています。

dotnetはどのように作られているのか

2017/03/21追記: この情報も大分古くなったので、現時点での最新情報は藤原さんによるこちらのエントリを参照すると良いでしょう。

Windows & Microsoft技術基礎Advent Calendar、25日目のエントリーです。最終日に相応しく、壮大な釣りタイトルを用意しましたが、ここでいう dotnet とは、.NET Coreにおけるコマンドラインツール dotnet のことです。

dnxに代わって最終的な.NET Coreの中心的な機能をコマンドラインで実現する予定であるこのコマンドは、.NET Coreの基礎を担う存在となるはずです。

そしてこれはオープンソースで公開されているのですから、自分でビルドすることもできるはずです。また、オープンソースディストリビューションオープンソースコンポーネントとして含まれるためには、その構成要素が本当に全てオープンソースで実現できているのか、確認する必要があります。

そういうわけで、今回は dotnet/cli リポジトリをチェックアウトしてビルドし、その内容を調べてみました。 https://github.com/dotnet/cli

はじめにお断りしておきますが、今回言及する一連のモジュールのビルドには、相応のリソース(ディスクスペース、ネットワーク)がかかります。実験するなら、家に引きこもって試す、大容量ストレージを用意する(札束で殴ってSSDを入手するか、HDDのI/Oでも良しとする忍耐心を身に付ける)等のノウハウを身につけてからが良いでしょう。

にわかの調べ物なので、適宜ツッコミ等お待ちしています。

dotnet/cli - dotnetのパッケージをビルドするツール

cli のREADME.mdの最初にはこう書いてあります:

This repo contains the source code for cross-platform .NET Core command line toolchain. It contains the implementation of each command, the native packages for various supported platforms as well as documentation.

このリポジトリには、コマンドラインツールチェインのソースコードが含まれている、と書いてあります。実際の役割は、(昔の).NET Framework SDK Tools、のサブセットのような感じです。実際のツールはほぼdotnetのみです。もっとも、この中には、C#/VBコンパイラーの呼び出しのためのdotnet-compileにはじまって、.NET Native化(dotnet-compile-native)、リソースのコンパイルdotnet-resgen)、配布パッケージ作成のためのdotnet-publishなど、さまざまな機能が実装されています。dotnetコマンドラインヘルプにresgenコマンド等は出てきませんが、dotnet resgenを実行すると、dotnet-resgenが呼び出されます。(実質的に単なるシェルスクリプトエイリアスっぽく見えますが、形式的には.NET Native化された別々のバイナリです)

実は、dotnet/cliリポジトリには、ツールの実体ソースはそれほど含まれていません。このリポジトリでビルドできるのは、インストールできるパッケージです。たとえば筆者の環境では、Ubuntu用の.debパッケージが出来上がります。WindowsならWixによるインストーラー パッケージが、OSXならproductbuildによる .pkg 形式のパッケージが、それぞれ出来るはずです。rpm系のパッケージビルダーはまだ無いようです。最近Microsoftと提携したRed Hatとか、コミュニティの誰かがcontributeすれば出来るのではないでしょうか。

では、dotnetパッケージの内容となる各種ツールはどのようにビルドしているかというと、実は重要な部分の多くは、ソースからのビルドを行っていません。代わりに、プライベートのnugetパッケージ リポジトリなどから、ビルド済みのバイナリをダウンロードしてきて、それをパッケージしています。実のところ、ビルドに必要なものを落としてくる方式は、.NET Core関係のリポジトリ群における標準的なものです。

dotnet/cliをチェックアウトして、build.shあるいはbuild.cmdを実行してみましょう。最後まで上手くいくと、パッケージがartifacts/packages/以下に作成されるはずです。

dotnetパッケージの内容

ではdotnetパッケージには何が含まれているのでしょうか。build.shを実行するとsudoパスワードを要求されて.debのパッケージまでインストールされますが(こわい!)、ここでインストールされたdotnetパッケージの内容を dpkg -L dotnet で見るとこうなります。 https://gist.github.com/atsushieno/78c2f5aef6477c3337a9

500行くらいあるのでgistにしましたが、内容はほぼ /usr/bin/dotnet*/usr/share/dotnet/* のみです。binの内容はこの通りただの /usr/share/dotnet/bin 以下へのシンボリックリンクなので、実質的に全てshare/dotnet以下に入っています。

ではこのディレクトリの中には何が入っているのでしょうか。少しずつグループに分けて見て行きたいと思います…が、無駄に長いので、次の節に進む前の「まとめ」だけ見ると良いと思います。

(1) /usr/share/dotnet/runtime/coreclr

ここには、coreclrの内容が含まれているようです。coreclrのソースは dotnet/coreclr にあります。

(2) /usr/share/dotnet/bin/corehost

以下、いくつかのファイルは、dotnet/cli 直下でビルドされ、dotnetの各コマンドの実装で使われています。このcorehostは、.NET Coreのホスティング環境で、配布パッケージに埋め込まれるものです。続くdotnet-run.dllは、dotnet runコマンドの実装です。

(3) /usr/share/dotnet/bin/Microsoft.Extensions.FileSystemGlobbing.dll

以下、いくつかのファイルは、dotnet/cli に含まれるツールの依存関係です。このdll自体は、githubのaspnet/FileSystem以下にあるモジュールで、dotnet-run.dllのソースで依存関係としてproject.jsonで指定されています。

(「いくつかのファイル」と書きましたが、FileSystemはdnxの唯一のsubmoduleでもあるので、もしかしたらこれだけが特別かもしれません。)

(4) /usr/share/dotnet/bin/dnx

このディレクトリには、ビルドスクリプトで直接ダウンロードされたdnxのパッケージが展開されます(ビルドスクリプトOSX/Linux用のshellとWindows用のpowershellで別々ですが、だいたい同じ処理内容になっていると思います)。dnxのソースはaspnet/dnxにあります。

(5) /usr/share/dotnet/bin/csi

csi。roslynに入っているC# interactiveです。dotnet-repl-csiを実装するために使われているのでしょう。roslynのソースはdotnet/roslynにあります。

(6) /usr/share/dotnet/bin/crossgen

crossgenは、ネイティブイメージの生成に使用されるクロスコンパイラーです。これは、.NET Nativeの実装…ではなく、従来のngenの実装(あるいはその一部)で、coreclrに含まれるツールです。

(7) /usr/share/dotnet/bin/libPortableRuntime.a

今度は(今度こそ).NET Nativeの一部です。.NET Nativeのソースはdotnet/corertにあります。他にもilc.exeなどcorert由来のものがしばらく続きます。

(8) /usr/share/dotnet/bin/dotnet-resgen.dll

この辺はdotnet/cliの一部で、dotnet-resgenを実装しています。

(9) /usr/share/dotnet/bin/csc.dll

ここからはだいたいroslynの一部です(たまにcliのバイナリも見られますが)。

(10) /usr/share/dotnet/bin/appdep

appdepというのは、実際にはdotnet-compile-nativeコマンドの機能のひとつである .NET Nativeコンパイラーの依存関係で、これ自体はnugetパッケージになっています。ソースとしてはcorertということになります。

パッケージ内容のまとめ

… 以上を総括すると、dotnet/cli の内容は、概ね次の各パッケージの内容を引っ張ってきていると言えます:

  • dotnet/coreclr
  • dotnet/corert
  • dotnet/roslyn
  • aspnet/dnx
  • aspnet/その他各種依存ライブラリ

dotnetのビルド

dotnetのビルドは、dotnet/cli/build.shを追いかければ分かると思いますが、3ステージに分かれています。 - stage0: stage 1 dotnetをビルドするためのツールをダウンロードします。主にscripts/compile.sh - stage1: dotnetをstage 0の(ダウンロードした)dotnetでビルドします。主にscripts/build/build-stage.sh - stage2: dotnetをstage 1のdotnetでビルドします。その後roslynにcrossgenをかけたり、.NET Nativeの依存関係(appdeps)をかけ、dotnet publishで最終的なパッケージ内容を構築します。

stage 1 buildを実行するbuild-stage.shの中で、各.NET Coreプロジェクトをビルドしているのが、このパッケージのビルドの主要な部分と言えるでしょう。

dotnetの依存関係

さて、繰り返しになりますが、dotnetのビルドでは、以下のモジュールが(直接 or 間接的に)バイナリダウンロードされているらしいことが、前述の通り明らかになりました。

  • dotnet/coreclr
  • dotnet/corert
  • dotnet/roslyn
  • aspnet/dnx
  • aspnet/その他各種依存ライブラリ

実際には、これらのモジュールが連鎖的に他のモジュールを取り込んでいる部分があります。わかりやすい例としては、dnxが参照するcorefxが挙げられるでしょう。

また、各依存モジュールが、再帰的に自分自身を参照している場合があります。たとえば、corertのビルド時には、cliが生成するパッケージ(dotnet)がダウンロードされて使用されます。

というわけで、他のモジュールがどうやってビルドされているのかも多少追いかけないと、dotnetがどのようにビルドされてその世界を構築しているのか、わからないはずです。

それぞれの分析については今後の課題としたいところですが、このcliモジュールのビルドと各モジュールのビルドの間で齟齬がないか、確認する目的で、一応それぞれをビルドしてみました。以下に、各関連リポジトリのビルド出力のファイルリストを列挙しておきます。

ここまでの考察、と補足的な分析

(1) dotnetはdnxを置き換えるために導入されたのではなかったの? 何でdnxが使われるどころかパッケージにまで含まれているの? という疑問が生じてきますが、わたしは、現状ではdotnet runコマンドの実装はdotnetコマンドでまだ(?)実現できず、最終的にdnvmに相当する機能などが整備されたらdotnetに置き換え可能になるのではないか、と想像しています。.NET Coreは現在RCですが、これは機能的にフリーズということであって、パッケージングの調整などはこれから行われるのではないか、最終バージョンに含まれるようになるかは分からないだろう、という感じで理解しています。

(2) パッケージの中にいくつかファイルの重複が見られますが(libcoreclr.soはいくつあるの?)、これは、それぞれのプログラムをdotnet publishで生成した結果であろうと思います。その意味では.debの内容を細かく分けて分析する意義はあまりなかったかもしれません(!)

同じことが、この cli 以外の各モジュールについても言えます。roslynのパッケージにはcoreclrやcorefxのファイルが含まれていますが、おそらく大半はdotnet publishでバンドルされたものであって、roslyn自身の実体は、csc, csi, vbc, Microsoft.CodeAnalysis.*.dllくらいでしょう。

(3) バイナリパッケージをダウンロードしてきてビルドするというのは、ビルドに無駄な時間がかからない、依存関係で破綻する可能性が少し低くなる、といったメリットはありますが、同時に、どこまで本当にオープンソースでビルドできるのか分からない、という問題もあります。たとえば、上記のリストからはroslynのUbuntuビルドにcsi.exeは含まれていない、ということが分かります(roslynのビルドは、WindowsではRoslyn.slnを、それ以外の環境ではCrossPlatform.slnを使用するので、その辺りで齟齬があるのでしょう)。これはWindowsでビルドされたものが巡り巡ってバイナリとしてUbuntuに含まれている、ということでしょう。この辺りは解明・解決しておかないと、Linuxディストリビューションオープンソースのパッケージとして含まれることができなくなってしまう可能性があります。

dotnetはそのビルドの性質から、既存のdotnetバイナリ パッケージを前提としていますが、それはC#コンパイラとmscorlib.dllがC#で書かれているmonoなんかもそうですし、現在ならコンパイラツールチェイン全般に言えることだと思います。オープンソースのツールチェインによってビルドできるようなソースが存在することが自明であれば十分であり、卵と鶏問題を厳密に追及するのは、ライセンスの観点からは意味がなく、実質的には非生産的です。)

(4) coreclrのビルド出力を見ると分かりますが、この中にはcorefxのアセンブリは含まれていません。一方、cliのパッケージの内容としては、dotnet/runtime/coreclrディレクトリ以下にmscorlib以外のcorefxアセンブリ含まれています。これらはどこから来ているのでしょうか?

その答えはscripts以下で “runtime/coreclr” をgrepしたら、scripts/build/build-stage.shのみが引っかかったことを契機に分かりました。このスクリプトの中で、明示的にsrc/Microsoft.DotNet.Runtimeをビルドしているのですが、ここにはREADME.mdがあって、内容にはこうあります:

This is a utility project that brings the CoreCLR down and lets us publish it as though it were an app. Do NOT add any C# code to it! It is not designed to actually be compiled as an assembly, it's just used for its dependencies.

このプロジェクトがruntime/coreclrディレクトリを出力パスとしてビルドされると、ここにproject.jsonで記述された依存関係が展開されることになります。実のところ、dependenciesは次の1行のみです。

"dependencies": {
  "NETStandard.Library" : "1.0.0-rc2-23616"
},

この"NETStandard.Library"のパッケージ、実体はcorefxのstandard platformに対応する"netstandard"のことだろうと思うのですが、どのモジュールから生成されているのか、今回は発見できませんでした。corefx(少なくともmaster)には無さそうです(nuspecが見当たらない)…ここにあるべきだとは思うのですが。

(5) corefx自体は膨大なアセンブリの集積であり、dotnetでは全てをパッケージすることはありません。各アプリケーションに必要なものは、project.jsonなどに記述すれば、dotnetコマンドがnuget経由でダウンロードしてくることになるでしょう。

dotnet/coreclr and co.

さて、今回、先ほど言及した、ダウンロードされてくる.NET Coreモジュールの全てについて、厳密にビルドを追いかけるのは、ちょっと現実的ではありませんし(何しろ書こうと思い立って調べ始めたのが3日前くらいですし!)、今回はあとdnxについて軽く言及する程度にしておいて、他のモジュールについてはざっくりと書いておこうと思います。

coreclrは、Cで書かれたランタイムであり、元来このモジュールだけで全て完結していました。mscorlibのビルドは(cscを使って)全ての実装がビルドされていました。これが、昨今ではそのソースをcorefxに移転しているようです。mscorlibの実装はやや特殊であり、ランタイムと密結合している部分が多いので、coreclrの一部となっていたわけですが、いずれにしろcoreclrとcorefxは切り離せない関係にあると言えるでしょう。

corefxのリポジトリには、coreclrをターゲットとする(けどdotnetで必須というわけではない)大量のアセンブリがあり、それらはnugetパッケージとしてビルドされます。実は、おそらくビルドの最終生成物はbinとpackagesの両方のディレクトリにあると思うのですが、今回はbinの内容だけを出して、packagesの内容は含めませんでした。ここにはcorefxのビルドに必要な依存関係もダウンロードされているようなので(たとえばdnx-monoやMSBuild.exeなど)、何がビルド出力なのか自明ではなかったためです。気になる人は一度ビルドしてみて下さい(ビルド作業は長大なものですが…)

corertは、ビルドに際してこのdotnetモジュールに依存していたりと、内容を精査してみないと分からない部分がありますが、ネイティブコンパイル機能自体は、ランタイムに必須の機能というほどでもないので、今回は調査対象外としました。個別に後で追いかける価値は、あるでしょう。

aspnet/dnx

dnxはgithub上ではdotnetではなくaspnet配下にあります(歴史的な事情によるものでしょうか)。

dnxのビルドにはKoreBuildとSakeというビルドシステムが使われます。これらはnugetパッケージとして取得されます。KoreBuildにはdnxが含まれており、つまりこのモジュールも鶏と卵の関係にあります。ちなみにnuget.exeもバイナリダウンロードされます。

KoreBuildは、おそらくSakeの応用として作られた、.NET Coreに特化したビルド構成ファイル群なのでしょう。KoreBuildのソースは、源流がどこにあるのかわたしには確認できませんでしたが、aspnet/Universe/KoreBuild-dotnetに一連のソースがあるようです(devブランチであり、masterにはありません)。

dnxに限らず、dnxを使うモジュールをビルドする際に気をつけておきたいのが、使用するdnvmのランタイムとバージョンです。Ubuntu環境であれば、現状coreclrではまだビルドできません。実のところ古いdnx-monoでも、dnxのビルドは失敗します。わたしは1.0.0-rc2-16348を使って何とかビルドできました。

ちなみに、dnxのビルドにはdnxが必要です。おそらくSakeがdnxで動作するのでしょう。dnxがビルドするプロジェクトは、その実行に必要なファイルを、dnx自身からコピーすることになります。ではdnxでビルドしたプロジェクトでは、どういうファイルが必要になるのでしょうか? それらは生成あるいはコピーされるのでしょうか? ここは未調査ですが、おそらくdotnetコマンドがMicrosoft.DotNet.Runtimeというダミープロジェクトをビルドすることで「ランタイム アセンブリ」のようなものを構築したのと、同じことが行われているのではないかと思います(つまり、project.jsonの内容に照らして、無いものはnugetからダウンロードしてくる、ということでしょう)。

いずれにしても、わたしの理解としては、dnxの使用は、ある程度過渡的なものであり、役割としても、ビルドの性格としても、概ねdotnetと重複するものであって、コレを別途追求する意義はあまりないのではないか、といったところです。

(Sake/KoreBuildが過渡的なものなのかどうかは、今は判断保留としておきます。)

総括など

ここまでざっと見てきたことで、dotnetツールが、全てをソースからフルビルドしているのではなく、関連モジュールの既成バイナリをnugetからダウンロードしてきて、それを展開するかたちで構成されていることが、そして、それぞれのビルドについて、適切にオープンなソースからビルドされたものが最終的に含まれているのかを調べる道筋が、何となく理解してもらえたのではないでしょうか。

今回調べたようなことを、CoreCLR読書会というグループで勉強会のようなかたちで共有しています。CoreCLR Book of the Runtimeの翻訳などもそこで行っています。興味のあるマニヤックな皆さんの参加をお待ちしています。そのうちまた開催すると思うので、twitterにアンテナでも張っていてください。