オープンソースなのにわりかし再発明しがち勢として @jmuk どうですか。
というふうに(内部的に)話題をふられてしまった。再利用ねえ。あんまり考えてないよね。
Chromiumはモノリシックなコードベースだけど、もちろんいろんな他のライブラリを再利用している。だいたい third_party というところに、そういうのは押し込められている。再利用のためには、ソースコードをもってきて、自分たち用にビルドするという立場。システムに入っているライブラリ(DLL)を再利用する、みたいなことはやらない。バージョンの互換性とかABIの互換性とかがしんどすぎるから。まぁこれは普通か。
ChromiumはGNという独自のビルドシステムでビルドするが(ここがすでに独自なのかよ、というツッコミがあるかもしれませんがスルーしてください)、独自なのでこれをあらかじめサポートしている外部ライブラリというものは、事実上存在しない。なので外部ライブラリを利用するときは誰かがChromium用にGNを書かないといけない。誰かというか、だいたいはそのライブラリを使いたくてthird_partyに足したい人が自分で書くことになる。めんどうくさい。外部ライブラリはgit submodule的なものでリビジョンが指定されていて、uprevするときはGNファイルも微調整する必要がある。細かいビルドフラグの話などもあり、たまに妙な問題を引き起こしたりする(が、昔使われていたGYPよりはだいぶマシになった)。というように細々とした苦労があり、そこは別に乗り越えられていない。たんにたくさんの人がChromiumプロジェクトに雇用されているので、そのうちの誰かに頑張ってもらっているというだけ。
フレームワークという点でいうと、そういえば Chrome / ChromeOS は既存のGUIフレームワーク(gtk+とかWxとか)を使っていない。viewsという独自のGUIフレームワークが内部にあり、これを使ってUIは書かれている。viewsはバックエンドとして「ネイティブ」のUIとやりとりする部分があるが、ネイティブUIのことはあんまり使わず、たとえば全部描画するし入力イベントも自分でハンドルしている(あとChromeOSは「ネイティブ」レイヤが基本的には存在しないので、viewsのバックエンドのようなものを全部作っている)。viewsは、正直にいうとあんまり出来がよくなく、ChromeのUIで動くところしかきちんとできてなかったりということがよくある。が、自分としては一通りわかっていて(頻繁に変わるのでいつでも再確認しないといけないのだが)それなりに読んだり細かい修正をしてきたので愛着もある。内製なので好き勝手に変更できるのはメリットではある。そんなメリットは喧伝すべきかどうかわからないけど。
逆側の話、つまりChromiumそのものやその一部をライブラリ化したり再利用したい、みたいな話もあるけど、こちらもそうそう再利用していない。Chromiumのレンダリングエンジンであるblinkは、その前身であるWebKitと大きく異なり、ライブラリ化されていない。Chromiumについているcontent/というレイヤを介さない限りは使えない。結果として、WebKitベースのブラウザはありうるけど、blinkベースのブラウザというものはほとんどなく、Chromiumをベースにしたブラウザというものになっている。
また、Chromiumのbase/というディレクトリはなかなかいいように思うけど外部で利用できないか、というリクエストはたまにあったのだが、毎回にべもなく断っていた。Chromiumプロジェクトとしては自分たちの都合で好き勝手にいろいろ足したいし、後方互換性のこととかを考えたりしたくない、Chromiumのためのものなので他では勘弁な、という話になっている。これははっきりいって感じが良くないのだが、そういうことをしたくないという気持ちはよくわかる。汎用のライブラリを作ってるわけじゃないのにそんなことを要求されても困る、という話でもある。が、abseilができてからは、こういうリクエストはほぼなくなった気がする。C++も発展が進んだので、いまどきChromiumのbaseがほしい人間なんていやしないのだった。よかったよかった(?)
なおChromeOS側のサービスなどの実装のためにChromiumのbase相当のものがほしいという話が根強くあり、baseを勝手にコピーしてライブラリ化して使っている。一見再利用っぽく聞こえるかもしれないけれど、別にそういうわけでもない。勝手にコピーしてるだけだし。たまにChromiumの最新のものに更新するたびに大変な作業になっているつらさとかを垣間見るに、再利用を避けるポリシーを徹底したことの弊害が感じられないでもない。
というわけで、仕事のほうではあんまりちゃんと再利用していない昔ながらのプロジェクトをやっているので、それがどんな感じなのかを書いてみた。
この状況は、再利用がごくふつうな他の言語と比べるとかなり乖離があるが、そうなっていることにはそれなりに理由があるときもある。たとえばbaseが一般化されたライブラリになっていないのは、そういうことを指向していないからだ。専用のGUIフレームワークは、ChromeのUIで必要になりそうなところだけがよく書けていて、それ以外の部分は意外に雑なつくりになっていたりする。そういうものを使おうとすると、けっきょくそういう雑な部分を自分で書く必要が出てきたり、ということがよくある。これは残念なライブラリという見方もできるけれど、視点を変えれば、汎用のものは目指さない指向という意味では一貫している。
が……よく考えてみると、けっきょくこれは「C/C++では再利用が大変だ」という話の言い換えでしかないような気もする。再利用が大変であるがゆえに内製もしがちだし、パッケージとして公開するのもかんたんじゃないから公開しない。 後方互換性とかもべつに考えたくないけどそのための解決策もとくになかった。
他の言語だと、再利用が難しいとかできないっていうことは、みんなあんま考えてる気がしない。が、これはなんというか、パッケージシステムとかビルドシステムによって解決されてきた問題なような気がする。だいたいnpm installすればいいでしょ、go getすればいいでしょ、nuget…cargo…みたいな。C/C++にはこのレイヤの(デファクト)スタンダードがなんにもないから解決していない。しかしいまさらそんなのは望むべくもない。残念ですね、という話なような気がしてきた。
ところで逆な例でいえば、Node.js (NPM)とかを見ると「さすがに他人のコードに依存しすぎでしょ」という揺り戻しはたまに起きてる気がするし(たとえば文字列に空白を埋めるだけのライブラリが破綻を引き起こした事件とか)、lodashに依存するな問題とか、そういうのはある。もちろんこういうのは程度問題でしかなくて、再利用を一切しないっていうことはさすがに考えていないだろうけど、再利用しすぎの問題ってのも、それはそれで顕在化はしてると思う。