GitHubの買収とオープンソースコミュニティについて

6月2日にmicrosoftgithubを買収する噂が流れて、3日には確定情報として流れて、4日には正式発表があった。これに対しては歓迎する声から悲しむ声、非難する声などさまざまな反応があった。この反応の一部が、どちらの方向についてもあまり良くないと思っているので、可能な限り問題のある反応を潰しておこうという意図でこれを書くことにした。

ちなみに、笑える反応としては、githubにアクセスするとClipperやカイル君が出てくるようになるみたいなジョーク画像の類があるけど、これを集めているとキリがないし今回はきちんと論じたいことがあるので、その辺は他所に任せたい。

それはさておき、これは長い文章(になる予定)なので、最初にふたことで要約しておきたい:

  • 新CEOのNatは割と信用できるやつで、きっとGitHubを上手くやっていってくれるので、もしMSというだけで疑っているだけならちょっと人柄を知ってほしい
  • OSSにはさまざまな立ち位置で関わってくる人がいるのだから、それぞれの立ち位置にきちんと思いを巡らせてから発言するべきであって、買収に否定的な向きを「アンチMicrosoft」などと単純化して物事を見誤ってはならないし、それに基づいてOSSコミュニティを攻撃するようなことは決してするべきではない。

新しいCEOについて

今回はポジショントークになる部分があるのでハッキリ書いておきたい。わたしにとっては基本的に他人事だけど、他人事気分でいられない事情として、新しいCEOとしてXamarinのCEOだったNat Friedmanが就任する。NatはもうXamarinを率いておらず組織上も関係ないのだけど、当然ながら彼がCEOとして手腕を発揮しているところをこの目で見てきたので、完全に身内の主観的な立場にしかならないので、彼が優れたCEOであることを喧伝するし、読者にはわたしがそういう目線で書いていることを意識して一歩引いて評価してもらいたい。彼の功績の例については5年前に詳しく書いている。

NatはもともとMiguelと一緒にLinuxデスクトップの会社であるところのHelix Codeを立ち上げてNovellに買収されるところまで成長させたfounderであり、彼自身もdashboardというデスクトップ検索のプロジェクトを立ち上げたりしていたし*1Novell時代にもOpenSUSE Build ServiceやSUSE Studioのようなビルドサービスを立ち上げてきた人間だ。VS AppCenterとやっている/やりたいことは近い。

Natはgithubを現状と同様にオープンな状態を維持していくと語っていて、これは抽象的な言い分だからどれくらい信じるか、何を信じるかはわたし自身も全面的に肯定することはないし*2、誰しも「他人がMSを信用しないこと」に対して文句を付ける筋合いは無いと思っている。Natもそう思っていて "I'm not asking for your trust" と言っている。言葉ではなく実績で信頼を維持していくというやっていきの姿勢だ。

Xamarinは商用製品で成功した会社だし、その成功モデルは別にOSSの成功モデルではないから、Xamarinで成功したからといって直ちにGithubの信頼を得られそうだということにはならない。コミュニティの信用の見込みの期待値を過剰に高めることについては、わたしは適切ではないと思っている。

githubに関するいろいろな前提の説明

gitの非独占

githubは、ソフトウェアの設計図ソースコードをgitリポジトリで公開したい人たちのためのコミュニティサイトであり、gitリポジトリで管理したい人たちのためのサービスである*3

gitはソースコードのいわゆるバージョン管理システムで、「リポジトリ」が開発開始時からの全てのソースコードの履歴を保持する。gitの大きな特徴は、リポジトリが簡単に複製でき、複数のリポジトリ上で分散管理できるということにある。gitというソフトウェアの立ち上げ人はLinuxを立ち上げたLinus Torvaldsであるが、彼がgitを作ることになったのは、Linuxソースコード管理ツールとして使われていたBitKeeperというソフトウェアがプロプラエタリで、さまざまな不利益をコントリビューターに強いていたからである(詳しくはWikipediaの説明などを参照されたい)。git以前にはSubversionというものがあったが、これはLinux開発に耐えるものではないとされていた。

gitはBitKeeper依存への反省をもとに、リポジトリのあらゆるクローンが単独で完結する仕組みとなっている。githubにあるリポジトリは、アクセスできるユーザーが全て複製してローカルで再現できる。githubリポジトリをいったんクローンして、githubの競合企業であるgitlabにpush(アップロード)のは、完全にgitが想定している使い方である。git自身もOSSとして公開されていて、Webサーバーさえあれば誰でもリポジトリをWebに公開することができる。

githubの"openness"

githubは、そこで管理されているソースコードを、本質的には独占できない。独占していると言えるのは、最新版の開発拠点になっているということと、他のソフトウェアへの依存関係(後述)があることと、変更修正依頼(pull request)や問題報告(issues)などgit以外の開発支援機能があるためである。githubはissueなどもエクスポート可能にしていて、実際gitlabはこれらを取り込むことが出来る。

githubで公開されるソフトウェアはいわゆるOSSである必要はない。ソースコードを公開することは、それが「オープンソース」の定義に準ずるライセンスで公開されていることを意味しない(Microsoftは、過去に「OSSではない」と指摘された"Shared Source" CLIを、githubで公開することができる)。しかし、公開されているソースコードは誰でもcloneしてコピーを個人的な範囲で自由にでき、あるいはgithubの登録ユーザーがforkして自分の管理下に置いて公開することが出来る(これは利用規約にそう書かれているので、たとえばソースを公開しつつ「転載禁止」とすることはできない。少なくともgithub上には転載されうる)。プライベートリポジトリを作成しておいて、そこへのアクセスを別途登録ユーザーに対してのみ開放するようなトリッキーなこともできる(たとえばEpicGamesのUnrealEngine)。もう少し補足すると、githubでは課金ユーザーがプライベートリポジトリを持つことが出来るし、無課金ユーザーでもorganizationを作って複数アカウントでグループを運用することも出来るが、organizationのプライベートリポジトリはEnterpriseなどの契約を結ばないと作成できない*4

githubはもとより営利企業であって、github.comはプロプラエタリなサーバーソフトウェアによって動作している。GitHubMicrosoftになるからといって、オープンであったものがプロプラエタリになったりするわけではない。GitHubはもともとOSSコミュニティに対してそれなりに積極的な支援の姿勢を見せてきたが、これはあくまで彼らの主観的な方向性であって、Natが指揮するGitHubも同様であると言われている(主観的な議論なので、客観的な成果は今後を見て評価するしかない)。Natが過去にOSS方面で一定の活動をしてきたことは考慮してもよいし、しなくてもよい。会社や立場が変われば事情も変わるはずだ。

オープンソースステークホルダーについて

developers, users, promoters, and co.

わたしがたまにセッションスピーカーとして参加していた台湾のカンファレンスにCOSCUPというものがある。正式名称を Conference for Open Source Coders, Users and Promoters というもので、長々しくて面食らうかもしれないが、オープンソースのコーダー(開発者)、ユーザー、広告屋(プロモーター)を参加者とするイベントである。まあ名前が幅広く「ユーザー」や「広告屋」(つまり非技術者)までカバーしていても、実質的には開発者向けイベントの側面が強い*5。しかし、ここで気付いてもらいたいのは、「オープンソースのコミュニティ」にはさまざまなステークホルダーが存在する、ということである。githubの運営会社が変わると、開発者が歓迎することであっても、そのユーザーにとっては面倒が発生するということがありうる。

OSSのソフトウェアは多数公開されているが、単独で完結していないものが多い。ソフトウェアには依存関係がある。ソフトウェアは割とソーシャルにできている。だから、自分がGitHub社やMicrosoft社と特に無関係であっても、自分のソフトウェアが依存しているソフトウェアの開発者や、あるいは逆に自分のソフトウェアに依存している開発者が、何かしらの利害関係を有していると、自分も無関係ではいられないことになる。

Are OSS people really opponent?

githubの買収に否定的なのはOSSコミュニティである、みたいな言説がよく流れていて、これが正しいかどうかはおそらく誰も検証していないと思うが、いくつか指摘しておくべきことがある。まず「オープンソース」は「フリーソフトウェア」とは違っていて(概念的にはフリーソフトウェアOSSに含まれる)、フリーソフトウェアの開発者や支持者のうち原理主義的なユーザーは、以前からプロプラエタリなGitHubも拒絶しているのである(たとえばRichard Stallmanはこうだ)。少なくとも利用していることがライセンス上矛盾しているとまでは言えないので、そこまで求めない関係者も多い。AGPLの思想とは相容れないとは言えそうだ。

フリーソフトウェア原理主義的であるかは別として、OSSコミュニティでgithubのようなサービスを使って「いない」ところも実はかなり多い。gitサーバーは自前で立てることもそれなりに簡単にできる。過去にはsourceforge.netがOSSのハブとして機能していたこともあって、今でもsf.netを使っているプロジェクトもまれにある。もっともsourceforgeマルウェア組み込み事件など多数の問題を起こして、だいぶ信用を失っていった。他には、GNU Projectではsavannahというサービスを提供している。githubの競合相手でもあるgitlabは、自分たちのソースコードを公開していて、これはgithubよりはフリーソフトウェア支持者の思想と相性がよい。GNOME ProjectはLinuxデスクトップの大手だが、github買収騒動のほんの数日前に(記憶が正しければ、自前ホスティングから)gitlabに移行した。

githubそのものは、特に技術的な「色を付ける」ことをしていないが、実際には「githubリポジトリがある」エコシステムとそうでないエコシステムがあって、githubだけを見ていても実際の技術トレンドが正確であるとは言い難い。ざっくりとした評価にしかならないが、旧くからあるUnix系のライブラリやツールはgithubを使っていないことが多い。Web系の技術ではよく使われている。githubに一番コミットしているのは今回の当事者であるMicrosoftらしいが、では.NETが開発の主流かというとそんなことは無い(MSはvscodeやTypeScriptも公開しているので、これらも大きな割合を占めている)。しかしいずれにしろ、GitHubMicrosoftのものになって、Microsoftが.NETのリポジトリを特にプロモートするようなことになったら、githubからある程度の技術トレンドをフェアに推測することすら出来なくなる。Microsoftには会社全体として統計を偏らせるインセンティブがあることは否めず、githubは不信感を持たれないように機能を実装していく必要があるだろう。

何度でも書くが、いくらNatが「信用してほしい」と言っても、その信頼性が高いと言っても、それを信じない人には信じない正当な理由がありうる。だからこそNatは「信用してほしい、とは言わない」と言っているのである。彼はこの点とても率直で誠実に事に当たろうとしている、とわたしは考えている(もちろん「だからGitHubの運用も信用してほしい/したほうがよい/しないのは不当に疑り深い」などと書くと彼の言葉選びが台無しになるので、わたしも書かないし、そういう主張をしている人にはNatの真意を汲み取ってもらいたいと思う)。

gitリポジトリは複数のサーバーに複製できるので、githubに「ミラー」を作られていることが多い。AndroidLLVMGNU各種プロジェクトなど、ポピュラーなOSSプロジェクトは、たいがいgithubにミラーが置かれている。これらはあくまでミラーであって本家ではないので、それらのソフトウェアの開発者自身がGitHubからMicrosoftへの体制変更で影響を受けるということにはならない。しかし前述の通り、OSSにはさまざまな立場で関わってくる人がいて、その中には「githubにあるミラーを依存リポジトリとして活用している」という人もいる。彼らが体制の変更について文句を言って聞いてもらえる立場であるかどうかは別途検討を要するが、利害関係があることに変わりはない。

しかし、「OSSコミュニティが文句を言っている」という字面から想像されるような構図は、こういった実態を踏まえて考えると、実のところ違和感しかない。

立場が逆であったらどうなっていたか考える

XamarinはMicrosoftに買収されるまではGoogleサービスを使っていた。メールはgmailでやり取りされ、Calendarも自然にGoogleが使われていた。Microsoftになったことで、Googleは使えなくなってしまった。社外秘のメッセージをこともあろうにGoogleに読まれるようなことになったらまずい、ということがあろう*6githubではプライベートリポジトリを使って非公開のソフトウェアを開発してソースを管理できる。GitHubが競合相手だった会社は多くないが、経営主体がMicrosoftとなれば話は変わる。

AppleGoogleなどは、元来github以外でソースを管理していて、直接的な影響を受けることはないかもしれないが、いずれにしろ、利害関係者の幅が格段にひろがるのは紛れもない事実である。githubからリポジトリを撤収しなければならないという判断を下す会社もあろう。Wiredの記事では、cycle.jsの作者はリポジトリをgitlabに移行したというし、JetBrainsは今後もgithubを使い続けるとしている。今回の動きについては、間違いなくMicrosoftのアクションによって引き起こされたものであって、OSSコミュニティの一部の反応にも理がある。これを「MS嫌いの」OSSコミュニティが文句を言っている、と評価するのは筋違いである。cycle.jsが移動するなら、cycle.jsにまつわるライブラリのリポジトリも移動するかもしれないだろう。

もしMicrosoftではなくたとえばGoogleGitHubを買っていたら、Microsoftリポジトリを撤収したかもしれない(わたしはdotnetグループに属していないので彼らのorganizationのリポジトリは見えないが、.NET Coreの開発はgithubで行われているようだし、プライベートリポジトリがあって何かを準備していたとしてもおかしくはない)。立場が逆だった時に「MSは未だにGoogleに反感をもっているのか」と言われたらどう思うか、考えてみるとよい。

多様性の尊重と哲学の相違

直接の利害関係が無いとしても、SCMビジネスの世界におけるパワーバランスが極端に変化するのを、健全な競争社会のあり方として懸念して、少しでも以前の状態に近いかたちに戻そうとする人もいることだろう。わたしもそのような行動を取ることがまれによくある。Twitterによる独占を懸念したMastodonユーザーもいたはずだ。こういう声に対しては、わたしは引き止めるために言えることは何も思いつかない。リポジトリだけなら独占することは出来ないんだし両方使っていても別にいいんじゃない、くらいのことは言うかもしれないが、開発者としては明らかに無駄だろう。ミラーを用意するのは誰でもいいはずだ。

これですら、別に「Microsoftが嫌い」だからそうしているわけではない。わたしは好んでFirefoxを使っているけど、Googleが嫌いだからChromeを使わないわけではない。

Microsoftが嫌いだ/信用できないから使わない

もちろん世の中にはMicrosoftが嫌いな人もいるだろう。わたしは個人的にNadellaはとてもよくやっていると思っているし、彼が指揮している部分のMicrosoftは積極的に支持しているが、ハラスメントやスキャンダルに満ちた会社や組織は決して支持しない。MSに親を殺された人間*7に「2018年にもなってまだMSが嫌いとか言ってるのか」みたいな無神経なことは言えないだろう(少なくとも真人間であるわたしには出来ない)。各々には各々の理由があって好き嫌いがあるのであって、それが無知によるものなら具体的に啓蒙すれば良いことだし、個人的なものであるなら(法規範などルールに牴触するものでもないかぎり)他人があれこれ口出しするほどのことでもない。そもそも他人に口出しする前に自分を省みるべきである。

diversity and inclusionを維持していくために

長々と書いてきたが、GitHubから他所へ移行しようという人たちも、おおよそMicrosoftが「嫌い」だからそうしているのではないし、Microsoftが「嫌い」であるという人たちにも相応の理由があってそうしているということをわれわれは尊重しなければならない、ということを書いた。

今回わたしが観測した中には、OSSコミュニティに対する侮辱意識をもって誹謗中傷しているようなのもあったのだけど、こういう、非マイクロソフト的な態度の人間には噛み付く「マイクロソフト騎士団*8」のような姿勢は歓迎できない。Nat Friedmanが6/7に行ったreddit AMA (ask me anything)のこの回答は、自分たちに否定的な立場をとる開発者たちについても、真摯な姿勢を見せている:

"Developers are independent thinkers and will always have a healthy degree of skepticism, but I admit I was sad to see that some felt compelled to move their code. I take the responsibility of earning their trust seriously. (...) I hope those who have tried out other Git hosts in the past few days will keep an open mind and consider moving back once we’ve demonstrated our commitment to openness and made GitHub even better. If they choose not to move back, that’s their prerogative and we celebrate developer choice even when developers don’t choose us."

(強調筆者)

Natは開発者(特にOSSコミュニティに近い開発者)というものがどういう人種であるのか、よくわかっている。こういう姿勢を見習ってほしい。

Microsoftの社是はempower everyoneであり、それをもう少し具体化した指針のひとつにrespect diversity & inclusionというものがある。さまざまな立場の人たちを受け容れ、サポートしていくことが、現在ではMicrosoftらしいやり方なのである。

最初から中立的な存在であったGitHubに、今さら新しいMicrosoftの良いところを取り込んでもらいたいと思うようなおこがましいことはないが、新しい組織体系になっても「旧」に腐食されること無く、より価値をたかめていってほしいと思っている。

*1:この辺はわたしは遠巻きに眺めていた程度にしか知らないのだけど、その後Beagleに繋がっている。Beagleハッカーはその後何人もGoogleにさらわれてしまったのだった…

*2:たとえば、わたしはacceptableだと思っているけど、ページのトップに早速合併を報告するバナーが出てきたことを取り沙汰する向きはtwitterではそれなりに観測された。これを「良くない」というユーザーもいることだろう。

*3:公開は無償で、管理はプライベートであれば有償で、それぞれ行えるものなので、ここでは区別した。

*4:これは関係者にしか意味がないけど、Xamaritansの技術書典用のリポジトリがわたしの個人リポジトリになっているのはそういった事情がある

*5:この辺は「技術カンファレンス」を標榜しているのに実際には非技術者向けイベントと化しつつある日本マイクロソフトのde:codeなんかとは真逆の感じになっている。

*6:そこまでは言わないかもしれない。Googleは決してそんなことはしないだろうという一般的な推測がはたらくが、リスク計算はされる

*7:間接的な理由を含意するネットジャーゴンとして読むこと

*8:マイクロソフトシンパと書いたら主語がでかすぎるとコメントをいただいたので表現を変えた

Xamarin最新情報2018 (de:code2018) の補足情報

de:code2018が何とか終わりました。イベント自体にいろいろ問題はありましたが、とりあえずそれはおいておいて、わたしのセッションに来ていただいた方はありがとうございました。

スライドはこちらで公開してあります(イベント事務局側でも録画とpptを公開するんだと思います)。当日に「期待していた内容と合っていない…!」みたいな事故を防ぐために数日前にプレビュー版を事前公開していましたが、そもそもtwitterで事前チェックの発言を発見した人がいたかどうかは不明…

speakerdeck.com

事前に軽くしゃべってみたら80分くらいかかってしまったので、いろいろ削って、でもストーリーラインは何とか残しておこうとなった結果こんな感じでしたが、いろいろ端折ってしまったので、ちまちま補足しようと思います。

Ooui.Wasm

デモの手順はほぼOouiのwikiに書いてあるとおりです。Webサーバはこれと同様にdotnet-serveをインストールして使いましたが、Webサーバであれば何でも良いので、たとえばWeb Server for Chromeなんかでもいけます。

中に入っているmono.wasmやらmono.jsやらは、Oouiがmonoのwasmサポートのビルド済みアーカイブをダウンロードして使っていて、その場でビルドしているわけではありません(monoランタイムはでかいのでかなり時間がかかるはず)。ちなみに.NET Coreコンソールアプリで、Linuxからでもビルドして実行できます(Workbooksを動かそうと思ったのでMacにしましたが、そうでなければUbuntuでセッションやるつもりでした)。

デモで使用したバージョンは0.10.222でしたが、この中で使われているXamarin.Formsは2.5です。せっかくWebなのでFlexLayoutを試そうかなあなどと思ったのですが、実装されているかを確認する以前の問題でした。

ちなみに、wasmを使うものではないのですが、HTML5ベースのCanvasを使ってブラウザ上にGUIレンダリングしようというプロジェクトは他にも、というか大昔から存在していました。gtk-broadwayというやつです。これはクライアント1つにつきWebアプリのセッションを1つ使うもので、あまり現実的に使えるものではなかったと思います。PoC (proof of concept)としては面白いというやつです。あとUnityのWebGL projectなんかは概念的には近いものになっているんじゃなかろうか。

あとOoui.Wasmがこれだけ動かせるんならControlGalleryくらい動かせるんじゃねーの…?と思って自分でプロジェクトを作って移植してみたりしたのですが、実行時に謎のエラーになり、冷静に考えたらFormsのmasterからとってきたサンプルであるところのControlGalleryが2.5のやつで動くわけねーな…!ということになりました。試すまでもなくlimitationsがどこかにまとまっていたのですがちと今すぐ見つからない…

Workbooks

Workbooks。2006年頃から存在していたC# interactive shellを中心としたツールの現在の姿であるといえます(当時はMono.CSharp.dllでしたが、現在ではRoslynです)。C# interactive shellがVSに載ったのが3,4年前くらいだと思うと、この方面のmonoのイノベーションはRoslynの7,8年くらい前には起こっていた感じです。

ASP.NET Coreで作られたWeb版ですが、Reactアプリです。まだ鋭意開発中のやつです。デモでも再現したのですが、いったんコードの文法ミスなどでREPL実行がエラー評価になるとどこかで非同期処理がバグっているらしくdotnet runを再実行しないといけなくなる状態です。ちなみにmasterブランチで出来ます。トップディレクトリでdotnet buildを実行した後、Clients/Xamarin.Interactive.Client.Web/ ディレクトリでdotnet runするだけです。

WorkbooksはC#オブジェクトを結果として表示するとき、デフォルトではプロパティリストのようなかたちで表示することになるのですが、これをカスタムレンダリングすることも可能です。この場合のレンダリングとはHTML文字列なのですが*1、この辺の仕様はドキュメント化されているものの、まだプレビュー状態で、しかも開発者と相談していたら「これからReactコンポーネントに書き換える予定だから今はやめとけ」と言われたので、この辺で遊ぶ予定だったのですがあきらめました。

デスクトップ側も動かそうとして失敗したわけですが、agent側のアプリも終了しないとクライアント側だけ切って再起動とかやってもそのクライアント セッションでは二度と立ち上がらなくなるようなので、この辺の接続状態の試験シナリオが足りていないのでしょう(まあ普段agentを落とす必要は無いのですが…)。

ちなみにデスクトップ版ではFormsも試せるのですが、これはバージョン2.5固定です。3.0のnugetパッケージなどに更新したら期待通りには動作しません。これはWorkbooks agentが固定バージョンを想定して作られているためです(そうしないと挙動をうまく制御できなかったらしい)。WorkbooksでFlexLayoutのデモをやろうと思っていたのですが、これもあきらめました。ただ開発チーム的には2.5でないと困る理由はなく3.0にしたいと言っていたので、そのうち上がるでしょう。

FlexCSS

ReactNativeでyogaが使われていて云々については、Cheap Dive into React Native (booth)に書かれていた話で、これがR/Nの中身を知るのにはよさみがあるので、興味がある人は読むといいでしょう。

CSSをサポートに対してXAML至上主義者がネガティブだという話、具体的にはこういうのを見てもらえればわかると思います。わたしは今後一切XAML至上主義者を助けまいという気持ちになりましたが、これはあくまでわたしの意見なので、壇上ではそこまでは言いませんでした。ちなみにBuildのForms 3.0のセッションでも「否定的な意見も出てくるのだが…」くらいのニュアンスでそういう話を紹介しています。

XAMLまわりもWPFもそうなんですけど、Windowsチームが作っているものって、.NETチームが作っているものと違って、2018年になっても何もオープンソース化されないんですよね。.NET Core 3.0に追加されるというWindows desktop packもバイナリ配布ですし。VS/VSMac d15.7におけるXAMLサポートの拡充も、そういう状況のもとで行われているんだ、ということは、もっと知られてもいいのかも。

XAMLに生き残らせる価値があるのか、よく考え直す時期に来ていると思います。

LiveReload

hot reloadの類型である、という話をして紹介したのですが、stateとviewの分離が重要である、という話をもっと強調しても良かったかもしれません。FlutterのHot Reloadのページにも、"sometimes described as stateful hot reload,"と書かれているように、実行中のstateを維持したままviewの変更を反映する、という意味合いの強い機能であり、だからXAMLのLive Reloadなのであり、MVVMに準ずるviewとstateの分離が重要なわけです。

現状XAMLのみのサポートですが、理想をいえば、Elmish.XamarinFormsのようなXAMLAPI呼び出しもコード分析して反映できるとうれしいでしょう。まだコードを読んでいませんが、flutterのhot reloadはそういうDartの実装が含まれているのだろうと理解しています。

Android StudioにはInstant Runという機能があり、これにはcold swap / warm swap / hot swapという3段階の機能レベルがあるのですが(最近の状況はわかりませんが、hot swapまで行くとだいぶ動作が怪しかったものでした)、レイアウトリソースの更新はwarm swapのレベルで実現しています。これがhot reloadに近い存在です。ちなみにhot swapは実行中のコードの差し替えも行うもので、これはVisual Studio使いにはedit and continueと言えばわかりやすいでしょう。XamarinにもLive Playerという機能があります(de:codeでは川合さんのセッションで紹介されていたもの)。

所属とか組織とか

最後におまけですが…Xamarinは合併直後はAzureというかGuthrieの下に雑に統合されていたものが、VS/mobileチームということになって、グループとしてはVSということになったみたいです。それに伴って、Test CloudやらApp Centerやらといったサーバー関係のチームはXamarinからサーバー製品のチームの下に再編成されたようです。もともとtest cloudはless painfulを買収して成立したチームですし、独立性は高かったので、あまり違和感はないですね。

そういうわけで、App Centerなどのサーバー製品はXamarinとは無関係になり、個別に発展していくことになるでしょう。われわれは本来のXamarinとしてMonoを中心としたフレームワークの開発に注力していくことになりそうです。

*1:ちなみにこれはWeb版だけでなくデスクトップ版クライアントでも同様です。表示しているのはInspectorと同じWeb UIなので

Xamarin最新情報 2018(仮) @ de:code 2018

技術書典4が終わって放心状態で過ごしているatsushienoです(参加してくださった皆さんありがとうございました)。MonoDevelop本がまあまあ売れて、MML本は完売した上に電子版も売れてくれて赤字にならずに済んだので喜んでおります。まあ次は日常のコーディング活動に支障を来さないようにしよう…

技術書典4でリリースした書籍はboothで電子版を販売しています。

xamaritans.booth.pm

xamaritans.booth.pm

MythBusters他既刊を何冊かComic ZINさんに現場でお渡ししてきたのですが、まだ入庫作業の連絡が何も来ていない状態です。そのうち秋葉原店に並ぶのではないかと思います。MML本は完売となったため電子版のみです。再販の予定はありません(ゴメンナサイ。採算がとれる気がしないので)。

Xamarin最新情報 2018(仮) @ de:code 2018

さて今回もお知らせです。今日まで「MSに出社しないで10ヶ月(たぶん)」を記録していたのですが、あんまし関係なく因果が巡り巡って(?)、de:code 2018でXamarinの最新情報を話すトラックを担当することになりました。

https://www.microsoft.com/ja-jp/events/decode/2018/sessions.aspx#AC09

MSのイベントに何度も参加している人にしか分からないかもしれませんが、de:codeのセッションにはレベルというものがあって、100/200/300/400/500の中から設定するのですが、わたしが自分で設定できるようになっていたので、300としました(昨年は500にしたので、monoのJITに踏み込んだ話をしましたね)。300のセッションならこれくらいの密度の話を用意しておくべきかなという意識に基づいた設定です。実のところ、わたしも雑な話しかしない予定です。そんなに難しい話にはならないと思います。最近あんまりニュースフラッシュ的な話はしていない(というか過去や未来の話をしても現在の話をあまりしていない)んですよね。昔はそこそこやっていたんですけど。

Test CloudやApp Centerといったサーバーまわりの製品がXamarinからサーバー製品のチームに移管された現在、Xamarinは原点に立ち返って(?)、フレームワークであるところのMonoを中心に、主にクライアントサイドで展開する各種プラットフォーム、そしてツールチェインとIDEを扱うことになるでしょう。

.NET Standard化の流れがクロスプラットフォーム側に押し寄せてくる中で、MSBuildを中心とするビルドシステムの混沌を、IDEサポートも含めて整然と解決していくことができるのか、というのが目下のわたしの注目するところで、当然ながらビルドサーバー製品でも問題になってくる箇所のはずですが、わたしはノータッチなので、関連製品のセッションを担当するスピーカーに質問してくるとよいでしょう。ヒントというほどでもないですが、マルチターゲットビルドの話についてMVP Summitで聞いてきた勢もいるはずですね。

クロスプラットフォームという観点でXamarinを語る向きには*1、ReactNativeの隆盛やKotlin/NativeやFlutterの登場、そしてそれらが明らかにしてきたニーズに、Xamarinがどう回答していくかも気になると思うので、その辺も話題にしたいなあとは思っています。

.NETエコシステムとしての包括的な話は別セッションであるのですが、秘密の噂によるとどうもこれがわたしのセッションの裏番組になりそうなので、そうなると多少話がかぶってでもBlazorの話とかもしないといけないのかなあみたいな気持ちになっています。monoランタイムが使われているという点以外は完全に無関係なのですが…。

まあどの話題も、時間との兼ね合いで、上手く盛り込めなかったら封印するかもしれません。わたしとしては、セッション後にはask the speaker的な場所でふらふらしているつもりですし、そもそもこの日以外でも健全なコミュニティにはいつでも出向いて話をするつもりでいるので、聞きたい話などがありましたらmastodontwitterなどで伝わるように書いておいておいてください。時間の許す範囲で何かしら話せることを用意していくと思います(間にGoogle I/O参加を挟むので割とタイトかもしれない…)。この話をすると諸方面から「いっそGoogle I/O報告会@de:codeにしてほしい」と言われるのですが、さすがにそれは客層が合わない()と思うので、セッション時間外にでも訊いてもらえればと思います。

*1:たまに勘違いされている気もしますが、Xamarinはむしろネイティブプラットフォーム指向のフレームワークなんですよね。BCLが一緒なだけで。

技術書典4新刊によせて

はいどーも! atsushienoです。今回は技術書典4の新刊のお知らせです。

Xamarin Mythbusters / MonoDevelop Masters Book

技術書典4におけるサークルXamaritansはき01、新刊はXamarin Mythbusters / MonoDevelop Masters Bookです。

techbookfest.org

見本ページなどもサークル用のgithub.ioページで公開しています。

今回のサークルの方針

今回はサークルの方針をどうするか、とても悩まされる回になりました。わたしとしては個人としてとにかく音楽技術系のネタを出せるようにしたいので、これは自分だけになりそうだな…というか音楽系で書ききるネタ無いな…でも売り子さんいないと自分が当日イベントスタッフで狩り出されるからサークルとしてアウトになる…*1という事情から、サークル申込がFIXしてサークル名が確定する頃には「やっぱXamaritansとしての新刊は出すべ…」というモードになりました。

(「出ない」という選択肢もありましたが、Xamaritansの本がまだ割とあるので、もう少し売り出しておきたいなあという気持ちです。5月末まではboothでも販売するつもりなのですが、在庫管理費が爆上がりする予定なので、今後はオンライン販売もしなくなる予定です。)

それで執筆者を募集し始めたわけですが、それまでずっと「今回は(音楽で)自分だけで出そうかな〜」みたいなモードでtwitterなどにも書いたりしていたので、執筆者が集まる感じにはならず、とりあえずスタッフは何とかなるやろ…という感じで3月から1人で1冊書いて体裁が整うであろうMonoDevelop本を書くことにしました。これが、本書の大半が"MonoDevelop Masters Book"となった経緯です。

第1章(Xamarin.iOS

3月も後半になってきて、いよいよ売り子がいなくてヤバいしどうにかしないと…となっていたところに、ひらのさん @ailen0ada がひとつiOSネタで書いて売り子もしてくださるというので、お願いすることにしました。それで上がってきたのが、第1章のXamarin.iOS に翻弄されないために ̶̶ その傾向と対策です。

技術書典の新刊の案内を出す時に、いつも各章の内容を広告過剰気味に(!?)まとめるのですが、この記事は掛け値なしに、ひらのさんレベルの開発者が開発中の問題に遭遇した時に、どうやってxamarin-maciosのソースコードまで踏み込んで問題を解決するか、というやり方が文字で読めるようになっている貴重なものです。

残り(MonoDevelop

そういうわけで、残りは全てMonoDevelopのコンセプト・アルバムのような内容です。MonoDevelopを素の状態で使っている人は多くないかもしれませんが、Xamarin StudioやVisual Studio for MacはUnityも含めて幅広く使われているはずなので、これらを使ったことがあって、何となくどんなものか分かるという開発者が第一の対象読者ということになります。

ただ、MonoDevelop本といっても、MonoDevelopの使い方みたいな誰でも書ける(?)話を書くつもりは無かったので、今回の内容はMonoDevelopは何で/どのようにIDEなのか?という観点で、機能と仕組みを解説しています。IDEはアドイン機構を使って自分の好きなように機能追加できるし、何ならC#テキストエディタデバッグサポートだってアドインなんだし、それらはこれこれこういう感じで実現しているんだ、といったことが分かるように解説するようにしています。あと、何より、MonoDevelopの開発スタート当時から観察しているわたしだけしか知らなそうな話をまとめたりもしているので、歴史記録係(?)としての役目をひとつ果たしたような気持ちになっています。

当初は「少なくとも30ページ、がんばって50ページくらいは書いて1冊の本としての体裁が整うようにしたい…」というローなテンションで書いていたのですが、最終的にはこの部分だけで100ページ弱になってしまいました。

本編は以前の執筆メンバーでもある中澤さん(@muo_jp)と杉田さん(@toshi0607)のおふたりから神レビューをいただいて、読み進め方に難のあった部分などを多々修正できています(本当にありがたいです)。

表紙

当初、今回も絵師に表紙をお願いしていたのですが、依頼して慢心していたら直前になって「本業が忙しくなって描けなそうだ」ということになってしまい、やべえ…と思いながら無理やりフリー素材*2をこねくり回して乗り切りました。

f:id:atsushieno:20180419085023p:plain

英霊召喚したつもりだったのですが、絵師に「猿が感電している」と言われてかなしい思いをしました() 絵師にはその後裏表紙をでっち上げてもらってpsdへのレイアウトもお願いできたので、この方面は助けていただきました。

MMLコンパイラmugeneによる音楽制作ガイ ド(あるいは、1週間で作るオンデマンド同人誌)

さて、実は今回もう1冊新刊があります(!?) 自作のMMLコンパイラのガイドブックです。

Xamaritansの入稿を終えた先週の後半から「もともと音楽技術系の本を出したいって言っていたのに、蓋を開けてみればXamarinサークルじゃん…これ自分が一番やりたかったことじゃないし何か間違ってる…!」という気持ちになり、それならせめてコピー本でもいいからなんか音楽ネタを出そう、と思ったのでした。とはいえ、いま着手しようと思っている方面はコードを書いてからでないと書く意味がなく、それならMML打ち込みまわりで現状をまとめたほうが良いだろうと、金曜の晩に腹づもりを決めて、土日の空いている時間で書くことにしました。

いざ書き始めてみると、土曜1日で20ページくらい上がって、しかし内容は予定の半分くらいしか出来ておらず、日曜も他の用事をこなしつつ集中して書いたら30ページくらいになってしまい、それでも7割方しか書けていなかったので、これはもう1日使おう、と決めて火曜に休みをとって、サンプルや画像を取り込んだら最終的に3日で48ページの本になってしまいました。

3日目は表紙をでっちあげる作業もしていました。こんな感じです。自分のUbuntu環境でCMYKなpsdを編集できるのはKritaしか知らないので慣れないKritaでやっています(しんどい)。表面はMIDIプレイヤーのスクショ、裏面はvscodeで開いたMMLのスクショというらくらく構成()です。まあでっち上げにしては悪くないのでは…(!?)

f:id:atsushieno:20180419082929p:plain

コピー本にするつもりだったのですが、こんなページ数ではホッチキスで止めるのも無理だし、電子版でいいか…とおもっていたのですが、中綴じのオンデマンド印刷で何とかなりました(印刷所に入稿できる本としてもギリギリのページ数)。間に合わないだろうと思っていたのですが、印刷所にも送れるタイミングで終えられたし、イベント4日前でも何とかなるもんですね。こんな短期間でできるとは。

いざとなったらこのペースで書けるのか…と思いましたが、これは単に「書ける」ネタで「やりたかったこと」だったからですね。人間、やっぱり一番やる気のある作業に着手させるのが一番生産性が高い、「仕事」なんかしているバヤイではないな、と改めて思った次第です(落合陽一っぽさある)。

内容は、MIDIMMLで作曲というびみょいジャンルの作業で拙作コンパイラをどう使えばいいのか、ギターとかベースとかドラムとかどうやって打ち込むの?という、ドキュメントとしてそのままgithubに放り込むのは妥当では無さそうな方向性で書いたガイドブックとなっています。2018年にMMLの本はさすがに売れねーだろ…!と思って、20冊だけ用意してありますが、まあ売れ残ると思うので(慢心)、ほしい方はのんびり来ていただければと思います。特にわたしがブースにいない時は誰にも説明できない内容の本ですので…

技術書典4での出展体制

今回は後半からわたしもイベントスタッフ業を離れることができることになったので、ブースに在籍することにしました。これまで自分が書いて回しているサークルなのに当日の内容説明なども全く出来ずに申し訳ない気持ちだったのですが、今回は(ちょっとですが)正常化されたかたちです。

理想としては、今後も出展するなら、当日スタッフ業は一切やらないというかたちで参加しようと思っています。準備期間も重なって、今なかなか厳しいものがあります*3。自分だけのサークルなら自分が売り子に立たないといけないし、自分がまとめるサークルでは無責任に回すわけにもいかないし…とか、そういう本筋ではないことで悩みたくはないですよね。

そんなわけで、今回までは流されっぱなしでしたが、今後はもう少し確たる方針でやっていこうと思います。

*1:イベントスタッフには他にも自分だけのサークルを持っているメンバーもいるのですが、TechBoosterのメンバーに売ってもらえるという恵まれた体制なので、事情が全く異なるんですよね

*2:Googleでlicensing filterかけた画像検索

*3:これも、必要だから書いているのに「遊んでいるのかな…」みたいな気持ちになってホントよくないんです

NuGetパッケージが不要なnetstandardパッケージをずるずると追加する問題

Xamarin.AndroidやXamarin.iOSでNuGetパッケージを追加していると、たまに膨大な.NET Standardのパッケージが追加されて「は?」ってなることがあると思います。具体的にはNewtonsoft.Jsonとか。

無駄に縦に長いNewtonsoft.Jsonの依存パッケージリスト

こいつら実のところゴミなんです。いらないんです。しかもゴミなのに消せないんです。Newtonsoft.Jsonが依存しているからちゃんと消せないようなかたちで追加してあげたのねん! ボンビー!

これが原因で、ビルド時になると、MSBuildがこんな警告を出してくるようになります(原典はxamarin-androidのgithub issue)。

2> "Microsoft.CSharp, Version=2.0.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was chosen because it was primary and "Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was not.
2> References which depend on "Microsoft.CSharp, Version=2.0.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0\Microsoft.CSharp.dll].
2> C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0\Microsoft.CSharp.dll
2> Project file item includes which caused reference "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\MonoAndroid\v1.0\Microsoft.CSharp.dll".
2> Microsoft.CSharp
2> References which depend on "Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [].
2> C:\Users\mml\Development\test_app\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll
2> Project file item includes which caused reference "C:\Users\mml\Development\test_app\packages\Newtonsoft.Json.10.0.3\lib\netstandard1.3\Newtonsoft.Json.dll".
2> C:\Users\mml\Development\test_app\tes_app\bin\Debug\netstandard1.6\test_app.dll
2> Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL

何だそりゃ、ってなりますよね。これは全てNuGetの出来が悪いせいです。NuGetがやっつけ仕様で出来ているためです。正確に言えば、NuGetの実装が悪いわけではなくて、NuGetで運用されるパッケージ管理システムがきちんと設計されていないことに起因します。

Newtonsoft.Jsonのnupkgには、さまざまなプロファイルのアセンブリが含まれています。

無駄に横に長いNewtonsoft.Jsonのプロファイルリスト

Xamarin.Androidのプロジェクトにこれが追加された時に、実際にプロジェクトで利用されるプロファイルはどれでしょうか? netstandard1.3? portable-net45+win8+wp8+wpa81 (Profile259) ?

これ、実際にパッケージ解決に使われているのは、netstandard1.3なんです。ちなみにここでProfile259に解決されていれば、この問題は生じなかったんですね。Profile259には依存関係の列挙が無いのです。

ところでこの「正解」はどうすれば選べるのでしょうか? NuGetパッケージの開発者には、Profile259のサポートとnetstandard1.3のサポートを両方含める理由があります。それぞれのTFM (target framework moniker)で示されるフレームワークのサポート対象が異なるからです。(netstandard1.3とPCL Profile 259の関係は包摂的かもしれない。その検証を全てのPCLプロファイルとnetstandardのバージョンについて実施できますか?)

そして、どちらのTFMがより「優先」されるかを判断することはできません。なぜならライブラリ開発者によっては、PCL側により多くの機能を実装しつつnetstandard側は限定的な機能のみを提供しているかもしれないし、逆かもしれないからです(たとえば、bait & switchなPCLあるいはnetstandardなライブラリの有無によって幅広い実装を一方でのみ実現している場合)。

いずれにしろ、netstandard1.3でTFMが解決されると、NuGetは次にそのgroupのdependenciesを取得しにかかります。

  <group targetFramework=".NETStandard1.3">
    <dependency id="NETStandard.Library" version="1.6.1" exclude="Build,Analyzers" />
    <dependency id="Microsoft.CSharp" version="4.3.0" exclude="Build,Analyzers" />
    <dependency id="System.ComponentModel.TypeConverter" version="4.3.0" exclude="Build,Analyzers" />
    <dependency id="System.Runtime.Serialization.Primitives" version="4.3.0" exclude="Build,Analyzers" />
    <dependency id="System.Runtime.Serialization.Formatters" version="4.3.0" exclude="Build,Analyzers" />
    <dependency id="System.Xml.XmlDocument" version="4.3.0" exclude="Build,Analyzers" />
  </group>

これらのパッケージが(a)NETStandard.Libraryの内容から、あるいは(b)Microsoft.CSharpの内容から、実際にダウンロードされてプロジェクトに追加されるのかはわかりませんが、追加された時には netstandard1.3の文脈で追加されているようです。Microsoft.CSharp(4.3.0)について具体的な挙動を見てみると、このパッケージにはMonoAndroidのダミーTFM(実装がないやつ)と、netstandard1.3の実装ありTFMが含まれており、Newtonsoft.Jsonを追加したXamarin.Androidのアプリケーションには(残念ながら)正しいダミー側ではなく間違った実装側が追加されます。

いずれにしろこれらのパッケージが順次解決されていき、.csprojには大量の無関係な参照が追加されていくのです。衝突するふたつのTFMを解決する定性的なやり方は存在しないので、解決策はありません

もっともNewtonsoft.JsonのNuGetパッケージングもいささか怪しいものです。Newtonsoft.Json.nuspecの一部を見てみましょう。

  <group targetFramework=".NETStandard1.3">
    <dependency id="NETStandard.Library" version="1.6.1" exclude="Build,Analyzers" />
    <dependency id="Microsoft.CSharp" version="4.3.0" exclude="Build,Analyzers" />
    ...
  </group>

targetFrameworkは1.3なのにNETStandard.Library 1.6.1を依存関係として引っ張ってきているのっておかしくないですかね? .NET Coreランタイムが古いと動かないような実装かもしれないのに。この辺Newtonsoft.Jsonのやり方は軽率だと思います。とはいえ、だからといってこれを解決しても衝突するふたつのTFMが解決できない問題が解決するわけではありませんし(とわたしは理解しています)、問題は開発者が軽率であることよりも、こういうパッケージングが出来てしまうことではないか、とも考えられます。

ちなみに、 https://docs.microsoft.com/en-us/nuget/reference/target-frameworks からリンクされている Get Nearest FrameworkツールでProject Frameworkにmonoandroid、Package Frameworksにnetstandard1.3 portable-profile259 を渡して診断させると netstandard1.3 が返ってきますが、その判断を支える正当な理由はどこにもありません。

.NET Standard Library 2.0とNuGetまわりでは、「仕様レベルでちゃんと解決できていない問題がある」みたいなmeta issueがあり、とりあえず長すぎて読む気もしないのですが、見切り発車だったなという感想を持たざるを得ない感じです。

そんなわけで現状では「これが仕様上想定される動作だ」ということになるのですが、わたしの予想では、Newtonsoft.Jsonのパッケージングを修正することで問題を解決することができるのではないかと思っています。具体的にはこんな感じです。

<dependencies>
  <group targetFramework="MonoAndroid1.0" />
  ...
</dependencies>

ただhttps://github.com/JamesNK/Newtonsoft.Jsonにはnuspecファイルが無いし、パッケージングはめんどくさいps1で実装しているっぽいんですよね。ちょっと追いかける気がしない。まあ気が向いたらコメントするかもしれません。ここで書いたことをひと通り英語でもう一回書くのは面倒だなあ…

DroidKaigi 2018 Embeddinator-4000セッションの事前資料

2/6追記: スライドも事前公開した。

speakerdeck.com

DroidKaigi 2018でEmbeddinator-4000のセッションをやることになったので、セッションスライドを書きながら、どんな話をして、どんな話をしないか、どのへんがまだ検討中なのか、といったことを、一般参加者のみなさんがセッションを聴講するかしないか判断できるように、事前公開しておこうとおもう。あくまで興味ある人が読んでおいてもいいかなーっていう内容であって、当日はもっと簡単な内容で済ませるかもしれない。なおセッション資料はまだ完成していないのでまだ公開できないのだけど、少なくとも直前には公開しておく予定だ。気が向いたら作りかけを週明けくらいに公開するかも。しないかも。

(コレは何なのかというと、セッションタイトルに「Embeddinator-4000でAndroid Studioから.NETのコードを利用する」とあるように、これはXamarinとは違ってAndroid Studioで作れるJava/Kotlinアプリケーションで.NETのライブラリを使いまわせるものだ。DLL群からaarを作ってついでにmonoランタイムもパッケージして、実行時はmonoでDLLのコードを実行するやつだ。)

セッションの内容の大まかな内容については、現時点でもざっくり書いておこう。

  • e4kとは? Xamarinとは違う?
  • Background: Mono, NDK, JNI
  • demo2つ(どちらもHello Worldレベルのシンプルなやつ)
  • e4kでできること: 完成度と課題
  • e4k以外のバインディング機構の評価軸。特に
    • ランタイムの堅牢性
    • 明確なバインディング仕様
    • IDEのサポート
    • ライブラリ エコシステムの構築

最後の項目はまだ煮詰まっていない。他のバインディング生態系として、Kotlin、Swift、RubyPythonJavaScript/TypeScriptあたりはちょっとでも言及しておきたいとは思っている(ただ、多分深く触れる時間は無い)。

逆に以下は今回は話さない方向性でまとめている:

  • e4kの使い方の説明
  • e4kのツールチェインを実現する仕組み(Clang, CppSharp, JNA)
  • Xamarin.Formsの埋め込み方のstep by step解説
  • .NETに由来するe4kの事情(正直自信ない。何が「出来ない」かをきちんと筋道立てて説明するためには、ここは省けない気もしている)
  • React Native(RNはそもそも今回議題にするバインディング機構ではなく、2日目にRNのアーキテクチャのセッションがあるのでそちらを見るべき。あと自分が詳しくない)

e4kの最新情報(?)

2017年夏期からの差分(ない)

Embeddinator-4000…と書くと長いのでスライドではe4kと書いている…については、実は昨年8月に行われたJXUG名古屋でも90分くらい(!?)しゃべっている。普段は同じ話題を扱うセッションを2回も行うことはしないのだけど、今回は地域から参加者がかぶらなそうなのと、オーディエンスがガチのXamarinユーザーと生粋のJava/Kotlin系のAndroid開発者で、根本的にターゲットを変えて内容も変えるべきなのと、e4kはまだかなりmoving targetだから半年もあればいろいろ変わって実装もいい感じに整理されてくるだろう…という楽観的な考えがあったためだ。

名古屋ではもともと50分程度だったものが、時間が余っているというので引き伸ばして話してしまったものだったので、今回はシュッとこなさなければならない。そういうわけで、前提知識としてe4kの基盤にあるもの(monoとか)について話す部分は、10分程度に圧縮することにした。大圧縮だ。ここをしっかり説明したところで、その後の内容と関わることは少なく、生粋のAndroiderに響くものもたぶん小さいと思って削った。

さらに、いつもなら事前に長大な資料をまとめてからスライドを書き始めるのだけど、e4kについては、既にExtensive Xamarinに30ページ近い文章をかいてしまっていて(この内容はJXUGの内容にそれなりに近い)、今さらまとめ直すことといったら最新情報と、もう少し踏み込んだ調査くらいだ。

「半年も経てばいろいろ変わる」という読みは完全にアテが外れた。新バージョンのリリースが無く、リリース版を前提として考えると、状況は全くと言っていいほど変わっていない。主に変化していたのはObjective-Cサポートまわりで、Android/Javaまわりは実のところ荒野といっていい状況だ。e4kは米国のMSのイベントのキーノートでも取り上げられる程度に本気度高めでコミットしているプロジェクトだけど、プレゼンテーションのためにXamarin.Formsのライブラリを組み込んだデモまで行ったところから、まるで満足したかのように動きがない…というと言い過ぎだが、コードはゆっくり進捗している。

Formsを動かそう→やめとこ

ともあれ、それならそれで現状に基づいてしゃべるしかない。

e4kでXamarin.Formsが動くなら(まあe4kを使いたいような状況でもXamarin.Formsを使うというのは、わたしは筋悪だと思うけど)、他もいろいろ何とかなって使い物になるだろう、と期待してみると痛い目にあう(あった)。e4kは.NETのライブラリをAndroidiOSのネイティブプロジェクトで「使える」ようにするためのものだ。「使う」ためにはライブラリで提供するAPIは使える状態になってくれないと困る。しかしXamarin.Formsのライブラリ…のうちのAndroidプラットフォーム固有のやつ…をバインドしようとすると失敗する。まだe4kはそこまで完成していないのだ(!)

おかしいじゃん、デモでは動いていたのにバインディングの生成に失敗するなんてありえなくない?…と当然思うわけだが、ここで悟らされた。「ライブラリのコードが動く」のと「ライブラリがバインド出来る」のは完全に別の問題なのだ。Formsを使ったアプリケーションとなるライブラリに「バインド」するのは、Formsの膨大なAPI全てを問題なく「バインド」するより、はるかに簡単なのだ。イベントのデモで動いていたe4kの実体はこれなのだ。

今Formsのようなbait & switchのライブラリをバインドして動かすためには、

という作業が必要になる。これをやる価値があるのは、e4kのデモを見せる時くらいだろう。日々の開発でやるようなことではない。

FormsはUIなので、動くものを見せると見栄えがする。だからFormsを見せたい、というのはわかる。ただ、わたしは、自分で使いたい用途で使えないようなものを無理やり動かしてデモで見せても、あまり意味がないと思っている。

ライブラリの異言語バインディングを問題なく生成するのは非常に難しい。Xamarinでも特に難しい作業のひとつだ。e4kでも難しいのだが、e4kの状況はさらに厳しく、Xamarin.Androidなら可能なAPIメタデータの操作が、e4kではサポートされていない。

再利用可能なエコシステムを構築する(あるいはそれなしでやっていく)ということ

ともあれ、バインド出来ないものがあるのは仕方ない。利用可能なAPIの口だけを用意したライブラリを作って、アプリケーション上ではそれを再利用して組み込めば良い…と思うと、そこにも罠がある。ひとつのAPKに含めることができるe4k由来のaarはひとつだけなのだ。アプリケーションに必要なDLLは全てひとつのe4k呼び出しで生成されるaarにまとめなければならない。この時点で、単独のaarとしての再利用性はほぼ無くなった。単独でMavenに上げて役に立つようなものは、まだ作れない。あくまで自分のアプリケーションの中で使うしかない。

逆に、そこまで割り切っても、ついFormsで実装してしまった複雑なUIを使いまわすことは可能そうなので、技術的にはやはり相応の価値はある。わたしのとりあえずの目的はmscorlib.dllをバインドできて、ろくにリンクしない状態でもaarに含められるようになることだが(と言っても実装は他のエンジニアが仕切っているので、わたしはせいぜいissueを報告したりたまにパッチを書く程度にとどめている)、そこまで出来るようになって、あとライブラリの依存関係と再利用性の問題が解消できれば、それなりにエコシステムを築く土台にはなると考えている。

あと、今回はそんなわけで応用ライブラリのバインディングには手を出さなかったのだけど、e4kで使えるようになってほしいライブラリ群として一連のXamarin Pluginsがある。Xamarinを知らない人向けにひとことで書くと、クロスプラットフォームAPIで、実装側ではプラットフォーム固有のAPIを使えるようにしてくれるという仕組みなので、同じコードがiOS向けのe4kでサポートされるようになれば、きっと楽になるはずだ。ただこれを実現するためには、きちんとbait & switchの仕組みをEmbeddinator-4000.exeが解決できなければならない。今はそこまで出来ていない(はず)。

…という話を本当は踏み込んでやりたいのだけど、多分これは生粋のAndroiderを置いてきぼりにするだけなので、この辺は軽く触れる程度にとどめておこうと思う。

e4kの外側

ここから先はe4k以外のエコシステムに敷衍して話せるような、一般化した話をしたいと思っているのだけど、正直現時点でもどういう議論の方向性にするかは決めていない。あと話の性質的に「オチ」がつかないので(e4k自体については↑の通りで十分にオチがついていると思っている)、最後がgdgdになる可能性がけっこうある。まあ、でも各論で終わるなら避けられないだろう…

隣の芝生は青く見える? 青臭く見える?

ここまでe4kについてだいぶ客観的に評価してきたつもりだけど、e4kはまだemerging technologyであり、ここから何をやっていく必要があるかは見通しておきたい。幸いわれわれはXamairnをゼロから構築してきたので、どういうものが必要になってくるかはだいたい分かっている。

そしてこれは似たような言語間のバインディング機構を構築しようとしている人々にとっても、きっと役に立つ話だ。

プラットフォームAPIへのアクセス: やりたい? やりたくない?

swiftを素材に話を始めよう。今、SwiftをAndroidに持ってきて動かそうとしている人は何人かいる(Swift for Android、SwiftJava、Silverなど、プロジェクトが複数ある)。SwiftをAndroidで動かす目的が、Swiftでアプリケーションを全部書くことだとしたら、今あるものでは全然足りない。AndroidのアプリケーションはJavaAPIを駆使しなければ書けない。SwiftはAppleLLVMエコシステムで発展してきた言語だから、同じLLVMに根差すことになったAndroid NDKとは親和性が高いけど、Xamarinが「全てをC#で」書くのと同じ意味で「全てをSwiftで」書こうと思ったら、Java APIとの相互運用は避けられない。逆にAndroid APIにアクセスしなくてもいい、Swiftの標準ライブラリだけ使えれば良い、というのであれば、現状で十分だろう。

プラットフォームAPIにアクセスしなくてよいのであれば、Pythonなどは確か2010年頃にはもう動いていたし(黒いターミナルもどきが出るやつだ)、V8は動くのだからJSエンジンを使った機構を作るのは(相対的には)簡単だ。

プラットフォームAPIをサポートすると決めたら、バインディングを用意してやる必要がある。手作業でバインドするやり方と、ツールで自動化するやり方だ。後者はとても難しいのだけど、どこかの時点で必ず必要になる。いずれサードパーティのライブラリをサポートする必要が生じるからだ。頻繁に更新されるAndroidサポートライブラリを手作業でメンテする労力を考えてみてほしい。自動化して生成されたパッケージをメンテするだけでも大仕事だ。

そこまでやるのはしんどいので、バインディングを自動化して提供しない、という生き方もアリだ。React NativeやTitanium Mobileはそうやってきた。同じJS/TSに根差すフレームワークでも、NativeScriptはバインディングを提供する途を選んだ。Kotlin/Nativeもそうだ(KotlinはたかだかC APIinteropしか自動化しないので、難易度は相対的には低い。といってもそれも簡単ではないけど)。

バインディング自動化機構: やっていき

バインディング ライブラリは、オリジナルのライブラリがもつ階層的な依存関係を反映した階層的な依存関係をもつことになる。そうしないことも可能ではあるけど、依存関係はたいがい問題が生じないようにオリジナル側で慎重に設計されていることが多い。バインディングでこれをそのまま反映しないと、ユーザーがオリジナルと同様の依存関係に基づいてアプリケーションを構築できなくなるケースが出てきてしまう。必然的に、プラットフォームAPIバインディングも、サードパーティ ライブラリのバインディングも、同じ俎上に載せることになるだろう。

最初から全てを用意しない場合、プラットフォームAPIを呼び出す口は大概どのフレームワークにもあるので、ネイティブAPIを呼び出したいという需要にどれだけ答えられるかは、「使いたいものが最初から(あるいは既に)あるか」「どれだけ簡単に作れるか」にかかっている。最初から無くても、コミュニティが十分に大きければ、コミュニティの誰かがメンテしてくれるかもしれない。そのためには、ライブラリのエコシステムが機能していることが重要だ。gem、pip、npm、nuget、maven、cocoapods…

バインディングの自動化は、注文する側は「自動的に全部バインディングできるようにしてほしい」と気軽に言うだけだけど、そんな夢みたいなものが出てくることは有り得ない。言語間の相違を意識して、なるべくそれらのギャップを吸収できるようにしてやる必要がある。言語間の違いは、およそ開発者が思っている以上に大きい。better JavaC#からJavaを呼び出すのすら大変なのだ。ジェネリクス情報とか消えて無くなってるし。逆向きなんて無理ゲーにもほどがある。

無理ゲーなので、何をサポートして何をサポートしないか、サポートしない場合にどんな回避策やデメリットがあるか、といった事項を細かく気づいて対応できることが望ましい。設計重要。この点e4kはいささか危うい。設計議論も無ければ意思決定も無いように見える。逆にKotlin/Nativeのcinteropを見てほしい。素晴らしい。問題になりそうなコーナーケースはだいたいここに集まっている。

Xamarin.Androidは吸い出したAPI定義に変更を加えてからバインディングを生成するアプローチを採った。Xamarin.iOSは逆で、完成形のコードのスタブを作って、それらにAttributeを付けることで、コード生成時のヒントをそこから提供できるようにした。Kotlin/Nativeではコードを追加したり、バインドするメンバーをツール引数で調整できるようにしたり(ツール引数は設定ファイルからも指定できる)、さらにサポートできないメソッドについても、対応コードを生成した上で「これはサポートできない」というエラーを投げるようにしている。「バインディングツールが期待通りに動かない」という問題は、「期待されたコードが生成されない」と「間違ったコードが生成される」に大別される。サポートされないコードの生成を無視するよりは、生成されたコードに埋め込んでおくほうが妥当だ。

e4kにとっての「入力」は.NETアセンブリだ。アセンブリの内容を自由にカスタマイズするものとしては、mono linkerがある。メンバーの追加は無理だが、削除はできる。e4kはlinkerを内部で呼び出すことはしていないので、e4kに食わせる前にアセンブリをリンクするのが現状では妥当な解ということになる。ツールが分離独立していたほうが良いのかどうかは、正直まだ判断できない。

ビルドツールとIDEによるサポート: 仕上げ

ツールチェインの機能が充足してきたら、そろそろIDEで省力化したい。省力化というのは具体的には

  • 一般的なパラメータ集合のテンプレート化、簡易指定オプションの追加、設定ダイアログなどの追加
  • IDEからのビルド指示(ツールの実行)

くらいだろうか。こういうのをIDEでサポートする場合は、間違いなくアドインで実現することになる。もしIDEの必須機能になることがあったとしても、内部的には必ずアドイン機構を使用して実装する。monodevelopC#エディタなんかがそれだ。C#エディタの無いmonodevelopなんて考えられないけど、IDEそのものはC#エディタが無くても動くし、アドインを無効にすればC#編集サポート機能が無くてもよい。

ただ、IDEサポートは本当に必要だと考えられる場合にのみやったほうがよい。ビルドツールの拡張が先だ。.NETなら(残念ながら)MSBuildAndroidならGradleの拡張によって、ビルドツールをプロジェクトファイルで記述したとおりに呼び出して実行できるようにする。この時、ツールチェイン側も頻繁にコマンドライン オプションの変更があると、追従するのが面倒になる。だからある程度落ち着いてから着手したほうがよい。

IDEAPIを用いた拡張の作り込みは、実のところあまり望ましいとは思えない。GUIで作業したほうが効率的なのであれば、単独で動作するツールを構築したほうがよい。IDE側にも、それなりにGUIを組み込んでホストする仕組みが用意されているので、常に単独で動かさなければならないのか、という心配はあまりしなくてもよい。

機能によっては「IDEでやらざるを得ない」場合もあるが、それは主としてIDEの操作と密着した要件がある場合だ(たとえば、編集中のコードエディタのテキストバッファにアクセスするとか。この辺もlanguage-server-protocolや.NETのomnisharpなどを使うと必須でもなくなってくるが)。バインディングツールの支援機能に、そのようなものが求められることはあまりない。あるとしたらIDEしかプロジェクトの依存関係を提供してくれないような場合だ(e4kはアセンブリの参照解決を自前でやっつけているのでそのような問題はない)。

なぜIDEAPIを使用しないほうが良いかというと、APIの安定性がアテにならないからである。さらに、IDEも含むプラットフォームの開発者としては、一般の開発者にはおよそIDEAPIに安定性を求めないでほしいという気持ちがある。IDEAPIの安定性を過剰に求めると、IDEの進化が止まり、またAPIの互換性を維持するために内部で無理のあるスパゲッティ実装がなされ、実装が不安定になる。変化を嫌うなら一生古いものを使い続けていたほうがよい。

セッションの主な対象者(最後に)

こんな感じで、最後はまとめにくい論考になってしまったので、当日どこに落としどころをもっていくか決め兼ねているのだけど、フレームワークを作る側…あるいはそれにちかいところ…でいろいろ考えて発表する人はDroidKaigiでもほとんどいないと思うので、そういう話に興味をもってくれそうな人にはぜひ参加していただきたいと思っている。もちろんセッション後にも会場をフラフラしている予定なので、e4kに限らず議論したいことがあれば声をかけていただければと思う。

1/27: .NET Fringe Japan 2018(新年会)をやります

今週末、1/27なのですが、2016年以来の.NET Fringe Japanの勉強会を行います。

dotnetfringe-japan.connpass.com

前回みたいなガチガチの深いセッションばかりにはならないので*1「新年会」というゆるふわな名前を鈴木さん @yukitos が設定されたのですが、ただの飲み会かな?という感じにも見えてしまうので、ハッキリ書いておきますが「勉強会」ですw *2

わたしは、今回は2週間後にDroidKaigiもあるので*3、残り少ない人生の時間をセッション詰め込みで費やすわけにはいかないと思い「今回はしゃべらない」と明言してきたのですが、今日の時点で30分セッションが3本の状態だったので*4、さすがに時間がちょっと余りすぎるから15分くらいのショートセッションくらいはやって時間を稼いだ場を繋いだほうがいいかと思い、イベント管理グループの皆さんと相談して、軽くやることにしました。

「.NETプログラムからアセンブリ名が消えるまで」という仮題で、.NET Core 2.0時代のクラスライブラリの設計に関する議論を出すつもりです。あんまり考えがまとまっていないので皆さんと議論できればと思います。入念に事前準備する余裕は作れないので(すみません)、デモなどは最初から考慮せずにしゃべる予定です。既に15分でしゃべれない量になっている気がするのですが気づかなかったことにします…

勉強会自体はまだけっこう席の余裕があるので、.NET方面に関心があってお時間のある方は是非おいでくださいませ。

*1:って書いてしばらく経ってから気づいたけど、長丁場で消耗しないだけで濃さは多分そんなに変わらないな…?

*2:新年会、って付けないと今年の後半にガチ勉強会やるかもしれないから付けているという話もありますね。

*3:こっちはこっちで告知書かないと…

*4:ちなみに正確には4本なのですが、当時1行抜けていたのでした…