2012-03-30

善のため、プロプライエタリなドライバーを根絶せよ

[Phoronix] Qualcomm Calls To "Kill All Proprietary Drivers For Good"
[Phoronix] Qualcomm Calls To "Kill All Proprietary Drivers For Good"
Let's Kill All Proprietary Drivers For Good

来週開かれる6th annual Linux Foundation Collaboration Summitで、Qualcommのプレゼンする内容は、「善のため、プロプライエタリなドライバを根絶せよ」というものだ。あの悪名高いQualcommが、ここまで姿勢を変えたというのは、なかなか感慨深いものがある。

なぜ一部のドライバーはクローズドソースなのか。これには、色々と複雑な事情がある。特に、ソフトウェア特許の問題がある。連中は、既存のソフトウェア特許への抵触を恐れるあまりに、ソースコードを開示しない。これは、実際にソフトウェア特許に抵触していることを連中が知っているかどうかとは別問題である。何故ならば、ソフトウェア特許に抵触しているかどうかを確かめるなど不可能であるし、そもそも、すでに大量のクズみたいな特許が認められている。だから、その手の特許ゴロに訴えられにくくするために、ドライバーのソースコードを公開しないのだ。

言うまでもなく、ソフトウェア特許は有害である。ソフトウェア特許の害悪の影響は、自由なソフトウェアやオープンソースの世界にとどまらない。なんの新規性もない単なる純粋な数式や手順が、ソフトウェアによって記述されただけで、特許になりうるのだ。クローズドソースによる難読化は問題の解決方法ではない。ソフトウェア特許は邪悪なのだ。

ところで、私もこの被害を受けているのだ。さきほど、サスペンドからの復帰に失敗した。なぜかXの応答がない。しかたなく、Ctrl+Alt+ファンクションキーでターミナルに切り替え、dmesgを実行してみたら、最後の二行に、nVidiaのプロプライエタリなドライバーがクラッシュしたとはっきり記録されていた。糞が。Xを再起動させる方法がわからなかったので、仕方なくリブートした。

調べたところ、UbuntuではXを再起動させるショートカットキーが、有名なCtrl+Alt+BackSpaceではない。Ctrl+PrintScreen+Kだそうである。変更した理由は、Ctrl+Alt+BackSpaceはうっかり押してしまう場合があって問題だから、あまり知られていない組み合わせに変更した、とのことである。

また、コマンドでXを再起動させるのも少し勝手が違う。Ubuntuのデフォルトではlightdmを使っているので、以下のコマンドになる。

sudo restart lightdm

ちなみに、GNOMEを使っている場合はgdm、KDEを使っている場合はkdmである。

再起動ではなく、止める場合はstop、開始させる場合はstartとなる。

本日の猫動画

映画と猫を組み合わせてみる。

最後に流れているのは、映画オズの魔法使いの歌、Over the Rainbowである。Nyan Catつながりなのだろう。どこかで聞いた気がするのだが、どこだっただろうか。

GNU/Linuxでfontconfigにより日本語フォントを優先させる方法

GNU/Linuxでは、fontconfigによりフォントの優先順位を設定している。この設定によって、フォントに存在しないグリフでも補完して表示できる。この機能は、モダンなOSなら大抵備えている機能である。しかし、もし、日本語と文字を共有している他言語のフォント、例えば簡体字や繁体字のフォントの優先順位が、日本語フォントより高い場合、そのフォントが日本語フォントより優先されてしまう。

どうも、この問題に対して、場当たり的に対処している人間が多いようだ。たとえば、該当の日本語以外のフォントを削除するという選択だ。PulseAudioの件と同じ場当たり的な対応である。なぜ問題の本質を探ろうとしないのか。そもそも、多言語環境を本当に実現したければ、重複数複数のフォントがあっても問題ないようにすべきである。問題を本当に解決するためには、フォントの優先順位の変更が必要だ。

日本人ならば、日本語フォントを優先したいだろう。そこで、GNU/Linux環境が日本語フォントを優先する設定になっていない場合、以下の手順で日本語を優先的に使用できる。

まず、できるだけシステム全体には影響を及ぼしたくないので、ユーザーごとの設定を行う。まず、設定ファイルをユーザーのホームディレクトリにコピーする

cp /etc/fonts/conf.avail/69-language-selector-ja-jp.conf ~/.fonts.conf

次にsedかawkを・・・といきたいところだが、この先の内容は環境によって異なると思われるので、残念ながらここに汎用的で自動的な方法を書くことはできない。まあ、そもそもfontconfigのディレクトリも環境により異なるかもしれないし、69-language-selector-ja-jp.confというファイル名だって、一致しているとも思えないが、それはさておき、とりあえず使い慣れたテキストエディタで開く

vim ~/.fonts.conf

ここから先は、環境によって異なるので、なんとも言えないのだが、Ubuntu 11.10の場合で説明する。以下の三行が何箇所かにあるので、すべて削除する。

<test name="lang" compare="contains">
    <string>ja</string>
</test>

このコードが、ロケールが日本語の場合のみ日本語フォントを適用するようにしている問題の本質だ。これを消せば、常に日本語フォントが適用される。この~/.fonts.confは、/etc/fonts/conf.avail/50-user.confから参照されている設定ファイルで、69-language-selector-ja-jp.confより優先される。

更にこの際に、日本語フォントの設定をお好みに合わせて変えておこう。ユーザーごとのホームディレクトリで行うので、どんな編集をしても安全である。もし失敗した場合は、~/.fonts.confを消して、最初からやり直せばよい。/etcにあるファイルは、今後のアップデートで書き換えられるかもしれないファイルである。書き換えるのはやめておこう。

じつは、これも問題の根本的解決ではない。根本的解決には、やはりシステム側でフォントの設定ツールを提供すべきではないのか。私は日本人なので日本語フォントが優先されることを好むが、中国人や台湾人は、簡体字や繁体字フォントを優先させたいはずだ。

と思ってみてみたら、zh-cnとかzh-hkとかzh-twには、上の三行のような条件指定がない。やはり不具合かもしれぬ。

追記:Ubuntu 12.10からは、.fonts.confの置き場所としてホームディレクトリ直下はdeprecatedになり、~/.config/fontconfig/下に置くべきだそうだ。

~/.fonts.conf は deprecated らしい - どせいけいさんき。

プリンスオブペルシャのソースコードが発掘された

Prince of Persia creator finds lost source code 23 years later – Video Games Reviews, Cheats | Geek.com

最初のプリンス・オブ・ペルシャは、Apple II向けに開発された。そのオリジナルのソースコードは、久しく失われていた。

この度、作者がソースコードを発掘したそうだ。

ソースコードの保存は非常に厄介な問題である。多くの文化的に重要なソースコードが、すでに失われてしまっている。自由なソフトウェアの意義はここにある。本来、ソースコードは公開するのが自然なのだ。ソースコードを公開しないのは反社会的であり、人道上の罪である。

参考:本の虫: なぜ歴史には海賊が必要なのか
本の虫: 最初のWebサーバーを保存せよ

GNU/Linuxのパフォーマンスはすばらしい

GNU/Linuxのパフォーマンスは素晴らしい。不自由なWindowsをブッちぎりで超越している。

もちろん、これは技術的に公平な比較ではない。まず、HDDが違う。不自由なWindowsで使っていたのは、かれこれ5年間も使っているSumsungの500GBのHDD、HD501LJであり、いまGNU/Linuxに使っているのは、新品のSeagateの3TBのHDD、ST3000DM001である。ただし、不自由なWindowsはBIOS上でのGPTを使ったHDDからのブートをサポートしていないので、このHDDからはブートすらできない。それから、アーキテクチャも違う。以前使っていたWindowsは32bit版だが、今のGNU/Linuxは64bitである。もっとも、これは当時のアカデミック版不自由Windowsが、なぜか32bit版しか提供されていなかったためである。それでも確か、1500円ぐらいした。一方、私の今使っている自由なGNU/Linuxを土台としたUbuntuは無料で、しかも64bitである。つまり、不自由なWindowsはインストールする時点で同じ土俵に立つことができないのである。だから、現実的には公平な比較である。そもそも、不自由なWindowsでは実現不可能な環境なのだ。

HDDの違いから、技術的に公平な比較は難しいが、GNU/Linuxで動かすプログラムのパフォーマンスは素晴らしい。不自由なWindowsの同じプログラムより高速に動作する。たとえば、FirefoxやChromiumの動作が非常に軽快だ。また非常の驚いたことに、SubversionやGitのパフォーマンスが素晴らしい。不自由なWindowsを使っていた頃には、私はプログラマーを自称しながら、バージョン管理システムに馴染めないでいた。理由は、パフォーマンスが非常に悪かったからである。しかし、GNU/Linux環境でのSubversionやGitのパフォーマンスを体験すると、これなら使ってもいいと、ようやく思うことができた。また、ターミナルが優れていて、CLIの使用が苦にならないのも利点である。

おどろいたことに、Chromiumが軽快に動作するのみならず、WebGLを利用したGoogle Mapsのパフォーマンスも、GNU/Linuxの方がはるかに上だ。もちろん、これにはnVidiaの不自由なバイナリブロブも関わっているが、グラフィックドライバーに関しては、Windowsも同じなので、公平である。

さて、このように快適なLinuxカーネルについて、少し学びたい。もちろん、Linuxカーネルのソースコードは真に自由なライセンスで公開されているので、いつでも読むことができる。しかし、いきなりLinuxカーネルのソースコードを読むのは敷居が高い。まず準備のために、Linuxカーネルの概要を解説した簡単な本が読みたい。不自由なWindows NTカーネルの詳細を噛み砕いて簡単に解説したWindows Internalsのような本のLinux版が欲しい。

色々と調べてみたところ、O'Reillyから出版されている、 Daniel P. BovetとMarco Cesatiの共著、Understanding The Linux Kernel が良さそうだ。日本語の翻訳では、詳解 Linuxカーネル 第3版がある。しかし、私は日本語訳というものを一切信用していないので、読むとしたら原著に限る。金が入ったら購入しようと思う。

Web上にも、いくつか興味深い書き物がある。たとえば、The Linux KernelとかLinux Kernel Newbiesなどは参考になりそうだ。

PulseAudioの問題

PulseAudioについては、悪い話しか聞かない。まだ私が不自由なOSであるWindowsを使っていた頃から、PulseAudioは酷評されていた記憶がある。

これが不思議だ。そもそも、PulseAudioというのは、低レベルAPIをラップする高レベルAPIである。PulseAudioによって、すべてのプログラムが、あたかもサウンドデバイスを独占的に使用できているかのような環境をエミュレートしている。その実装の質はともかく、思想は至って普通だ。モダンなOSなら、当然ハードウェアなどは通常のプログラムから意識させないようにするべきである。いまや、OSはサウンドデバイスの制限のあるミキシングに頼らないのだ。CPUは十分に速くなった。ソフトウェアでのミキシングは、現代のCPUならパフォーマンス上、なんの問題もない。いまや、完全なソフトウェアによるリアルタイムのミキシングやリサンプリングは当たり前である。

ところが、PulseAudioについて検索すると、まず出てくるのが、「お前を消す方法」である。これは一体どういうことか。大抵のディストリでPulseAudioはデフォルトで入っているのだ。入っているからには理由があるはずだ。理由とは、ハードウェアを仮想化するためである。

さて、この問題に、私もぶち当たった。なぜか、一部のプログラムでの音の再生に、周期的なノイズが乗るのである。私は当初、Linuxのサウンドドライバーを疑った。しかし、一部のプログラムだけに発生するので、ドライバーではあるまい。では、プログラム側の問題なのだろうか。このプログラムは非常にダメな実装をしているのだろうか。しかし、どうも実装の質による問題でもなさそうだ。

問題の根本的な理由は、この一部のプログラムが、ALSAを直接使っているためである。PulseAudioはALSAを仮想化するものだから、その仮想化に従わないプログラムがあると問題になる。

なるほど、一部の短気な人間が、PulseAudioをアンインストールすることによって問題の解決を図るのも納得だ。PulseAudioを消せば、すわなち、PulseAudioのサーバーを実行しなければ、とりあえず問題は解決する。PulseAudioの高レベルな仮想化の恩恵は受けられないが、ALSAを直接使っているプログラムは、正しく動作する。そして、ほとんどのGNU/Linuxで動く音声を再生するプログラムは、実行環境にPulseAudioがない場合を想定して、ALSAを直接使う動的なフォールバックを提供している。だから、PulseAudioがなくても、とりあえずは動く。

明らかに、これは間違っている。この手のことは個々のプログラムで行うべきことではない。システム側で一律に行うべきことだ。PulseAudioの実装の質はどうあれ、その理念は当然だ。

では解決方法はあるのか。真の解決には、すべてのプログラムが最終的にはPulseAudioを使うことである。PulseAudioを直接使うにせよ、OpenALとかlibabなどの更に高レベルなライブラリに頼るにせよ、最終的にPulseAudioを使うことが重要だ。しかし、ことGNU/Linuxの世界で、そのようなAPIの統一を図るのは不可能だ。ALSAを直接使うプログラムは依然として存在する。ソースコードが公開されていれば、自力で直すこともできようが、労力的に現実的ではない。

そこで、普通にALSAを使った場合は、PulseAudioが提供している仮想的なデバイスに入出力するようにするのだ。仮想的なデバイス経由で使われたPulseAudioは入出力を一手に引受、ALSAを使って、本当の物理的なハードウェアに出力する。

そのためには、.asoundrcか、あるいはシステムワイドな/etc/asound.confを設定する必要がある。詳しくは、以下を参照されたし。

freedesktop.org - Software/PulseAudio/Documentation/User/PerfectSetup

問題は、なぜUbuntuはデフォルトでこの設定をしていないのかということだ。不思議だ。まあもっとも、調べて設定するのはそれほど難しくないので、特に困らないが。

GNU/Linuxの問題は、ここにある。本来、このようなオーディオスタックは、単一の実装が低レベルから高レベルまで提供すべきなのだ。そうであれば、たとえ低レベルなAPIを使ったとしても、高レベルなAPIと強調できる。GNU/LinuxではALSAとPulseAudioが分離しているために、協調的な動作が難しい。選択の自由があることは素晴らしいことだが、運用を少しややこしくする。

2012-03-29

AdobeがFlashゲームのみかじめ料を要求しはじめた

Adobe Flash Player Premium Features for Gaming | Adobe Developer Connection
Got a Profitable Flash-Based Video Game? Adobe Wants a Cut | Webmonkey | Wired.com

Adobeの不自由なソフトウェアであるFlash Playerのプレミアムな機能を使っていて、$50000以上の売上のあるFlashで作られたゲームは、売上の9%をAdobeに差し出すこと。

この利用料を回避する方法は、プレミアムな機能を使わないか、売上を下げるか、今年の8月までにFlashゲームの公開を取り下げることである。

もちろん、我々が皆同意するように、不自由なソフトウェアであるFlashを使わないという選択肢が最も優れている。だから早く不自由なFlashの利用をやめるべきである。

何という馬鹿げた利用料金だろう。コンパイラーやライブラリに金を取るのはまだわかる。しかし、利用するときに売上に応じてみかじめ料を払わなければならないというのは馬鹿げている。しかも後出しだ。

ますます、自由なソフトウェアの存在価値を認識した。読者は一刻も早く、自由な開発環境に移行するべきである。プログラミングは根本的に自由が自然なのだ。不自由な開発環境などというのは反社会的かつ半倫理的である。

このブログのライセンスをCreative CommonsからGFDLに変更

このブログのライセンスを、今日より、CC-3.0-BY-SAからGFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Textsに変更することにした。

これは以前からGFDLとCCを比較して考えていたことである。

変更の理由は、Creative Commonsという名称のややこしさである。Creative Commonsは一枚岩ではなく、派生物を認めるかどうか、派生物は認めるがShare-Alikeかどうか、Non Commercialかどうかなど、それぞれ細部が異なるライセンスの集合である。お互いに互換性はない。だから、単にCreative Commonsといった際、非常に紛らわしいのだ。

また、Non Commercialという概念の定義も曖昧である。何を持って商用とするのかという定義が、国や法律どころか、人ごとに異なる。たとえば、このブログは閲覧に際し一切金銭を要求しないが、広告を設置している。これは商用だろうか。たとえば、私がNCなライセンスで提供されているコンテンツをネット上で公開するために、レンタルサーバーを借りて、そこにデータをホストさせたとする。しかし、このサーバーはコンテンツの利用に対し利益を得ている。これはどうなのか。

このため、Creative Commonsは真に自由なコンテンツを提供するためにはふさわしくない。

GFDLはどうか。GFDLは、商用非商用などといった区別を設けていない。これは当然のことだ。また、必ずcopyleftである。ただし、GFDLも天衣無縫というわけではない。Invariant Sectionsの問題がある。これは派生できない。翻訳はできるが、必ず原文を併記しなければならない。そのため、Invariant Sectionsなどを適用しないことにした。すくなくとも、Share-Alikeかどうかすら選択制になっているライセンスよりましだ。

また、GFDLの英語は非常に読みづらい。DRMに関する定義や、通過、非通過といった言葉の定義も曖昧である。SFDLのドラフトでは、英語は平易になっている。しかし、SFDLではInvariatn Sectionsこそ廃止したものの、様々な制限を受けるClauseを設けている。これはあまりよろしくない。また、通過、非通過の定義も、やはりあまりよろしくない。通過、非通過というもの規定することには同意するが、その定義がどうもよろしくないのだ。

また、今日のこの投稿から、このブログに対するコメントも、GFDLでライセンスされることにした。今日以前のコメントは、そのような規定を設けていなかったために、この限りではない。

ちなみに、明日以前のコンテンツは、すでにライセンスされたのだから、依然として、CC 3.0-BY-SAでも提供されている。ただし、GFDLを使うほうが望ましい。

2012-03-28

不自由なソフトウェアの時代は終わった

もはや、不自由なソフトウェアの時代は終わった。単純に終わったのだ。もうこれ以上、不自由なソフトウェアの未来はない。金銭的な価値はともかく、ソフトウェアの質は自由な方が圧倒的に高い。だからWindowsとかiOSとかAndoridが手元にあるならば、窓から投げ捨てるべきである。

こう言ったからとて、私は何も、フリーソフトウェア原理主義に改宗したのではない。今や、自由なソフトウェアの方が質が高くなっているからという至極単純な理由から言っているのである。私は質を優先する。不自由なソフトウェアの方が優れているのならば、いくら金を払っても構わないし、ソースコードが公開されていなくても構わない。しかし、事実として、今や、不自由でクローズドソースなソフトウェアは劣っている。自由か、最低でもオープンソースなソフトウェアの方が優れている。わざわざ不自由でクローズドソースなソフトウェアを使う必要はない。ましてや、劣ったソフトウェアに金を出すなんて論外だ。

10年前、私が初めて自分の稼いだ金を使って、コンピューターを所有しようしたとき、私はWindowsを選んだ、当時のGNU/Linuxの日本語サポートはおろそかだったからだ。5年前、今使っているコンピューターを買ったとき、私はまたもやWindowsを選んだ。当時学生だったので、アカデミック版が安かったからだ。

4日前まで、私はWindowsからGNU/Linuxへの移行に言い知れぬ恐怖を感じていた。なにしろ、10年間も使い慣れた環境である。勝手はわかっている。Windowsについては、ある程度理解しているつもりだ。Windows Internalsも、4thだが、読んでいる。MSDNの読み方も心得ている。今や、どんなWin32 APIだろうがらくらくと使えるようになった。この今までの経験が、すべて無になってしまうのだ。

もちろん、C言語やC++といった言語の文法知識は、GNU/Linuxでも通用するだろう。しかし、POSIXやLinux特有のAPIについては、Cの標準ライブラリの範囲しか知らないし、ましてやドキュメントの読み方もわからない。

Windowsでは、非常に有名なMicrosoft製の便利なIDEがある。しかしUNIXの世界では、エディタとビルドシステムはあまり密接に関係していないことが多い。もちろん、IDEもないことはないが、事実上、業界標準となっているIDEはないので、やはり広範な環境には対応できない。

そもそも、プログラミングどころか、UIも大幅に異なる。CLIの操作性も異なるし、GUIも勝手が違う。OSを変更するというのは、非常に怖いのだ。プログラマーこそ、最も変化に素早く対応しなければならない人種である。悲しいかな、我らもまた人間に過ぎず、旧態依然の環境に閉じこもっている。

ともかく、このままではならぬと、意を決して物理的に違うHDDにUbuntuをインストールし、Windowsの入ったHDDを取り外した。そして4日たった今、なぜあれだけWindowsにこだわっていたのか、すっかり忘れてしまった。このGNU/Linuxは、Windowsをブッちぎりで超越したのだ!! Ubuntuは利便性やパフォーマンスなど、すべての点においてWidnowsに優っている。

ターミナルや、GNU/LinuxのX環境でのターミナルエミュレーターは、Windowsよりはるかに優れている。一部の昔気質なユーザーが、いまだにCLIから移行しないのも納得だ。今はUbuntuデフォルトのUnityを使っているが、これも色々言われている割に、悪くはない。私はほとんどのソフトウェアを全画面で使うので、ごちゃごちゃとした高機能なランチャーやらメニューやらボタンやらは必要ないのだ。それより、compizの実解像度より広い画面を高速に移動できる方がいい

最も感動したのは、Debianのaptだ。これを使えば、コンパイル済みのソフトウェアのインストールはもちろん、ソースコードからのコンパイルも楽勝だ。あるソフトウェアをビルドするのに必要なツールやライブラリなどの依存関係を、すべて自動で解決してくれる。これにより、私の全くあずかり知らぬ言語とライブラリを使って書かれたソフトウェアのソースコードでも、簡単にビルドできる。

さらに、十分に有名なソフトウェアには、メンテナーが必要な調整を行ってくれていて、妥当なデフォルトの設定がされている。そのため、インストールしてすぐに使うことができる。調整や設定が気に入らない場合、自力での変更を妨げるような障害物は一切ない。

これでいて、ほぼすべてバイナリパッケージをインストールすることを前提にしたUbuntuなのだ。なぜこんなに他人の書いたソフトウェアのコンパイルが楽なのか。本当にこんなに楽をしていいのか。自前ビルド原理主義者のためのGentooやArchのようなディストロは、一体どうなっているのか。

環境を変えたために、学ぶことは膨大だ。しかし、実はそんなに学ぶ必要はないのだ。GNU/Linuxを使っていると、いかにWindowsが不自由であったかを思い知らされる。Windowsを使っていたときの「学ぶ」とは、本来、ユーザーのする必要がなかった「作業」でしかないのだ。有名ディストリには、そういう手間暇かかる面倒な作業をしてくれるメンテナーがいるおかげで、大多数のユーザーは、作業をせずにすむ。ありがたい。

ドキュメントだが、manとinfoはそれなりに使える。yelpから読むこともできるが、どうも今のyelpにはバグがあり、検索できないようだ。

ただし、今の私の環境には、ふたつの不自由なソフトウェアがある。nVidiaのプロプライエタリなバイナリブロブのドライバーと、AdobeのFlash Playerだ。

nVidiaのドライバーは、これは仕方がない。nouveauを使うと、ブートすらできないのだから、どうしようもない。nVidiaの公式ドライバーは、少なくとも、Winodows版と遜色ない出来であることは確かだ。しかし、Kernel Mode Settingに対応していないので、このままでは未来がない。Waylandのこともある。もしnVidiaが現状を維持するのであれば、次のGPUはAMDにする。すくなくとも、未来のないnVidiaよりはましだ。

Flash Playerは、実はほとんど必要ないのだ。事実、デフォルトのブラウザーであるChromiumでは無効にしている。ただし、たまにどうしてもFlashが必要な場合があるので、その時だけ、Flashを使うように設定したFirefoxを立ち上げている。なんにせよ、Flashにはもう未来がない。数年後には、アンインストールしても問題がなくなっているだろう。

もはや、不自由なソフトウェアは逝ってしまった。もはや先はない。止まった。天寿を全うして造物主のところに帰った。故ソフトウェアだ。停止した。逝去した。安らかに眠っている。既存のユーザーがいなければ立ち行かない。天界の妙なる鳴り物の音の列に加わった。かつてのソフトウェアだ。

clangにinheriting constructorが実装されない理由

Clangにopaque-enum-declarationがコミットされた。これで、残す機能はあと2つ、AttributeとInheriting constructorsだ。おそらく、最後に残るのはInheriting constructorsになるだろう。なぜか。誰も興味がないからだ。

freenodeでDouglas Gregorとチャットしていてこれを聞いたのだが、Inheriting constructorsが未だに存在しない理由は、興味を持つ者がほとんどいないからだそうである。それに、Inheriting constructorsの文面には、未だに曖昧な部分もあるとか。

実は、Inheriting constructorsとほぼ同等機能を、Variadic Templatesによってエミュレートできるのだ。これは、Douglas Gregorもペーパーで書いている。

US-65: Removing Inheriting Constructors

template<typename Mixin>
class add_color : public Mixin {
  Color color;

public:
  template<typename ...Args>
  add_color(Args &&...args)
    : Mixin(std::forward<Args>(args)...), color(Red) { }
};

この例では、テンプレートパラメーターであるMixinがどのようなコンストラクターを持つのかは、インスタンス化されるまでわからない。そのため、このMixinを基本クラスに据えようと思ったら、Inheriting constructorsが必要である。あるいは、エミュレーションだ。

std::forwardを使っているのは重要である。詳しくは、Perfect Forwardingなどのキーワードで調べること。

さて、このVariadic Teamplatesは正しく動くが、2つ問題がある。まずひとつは、Variadic Templatesなので、どんな実引数に対してもインスタンス化されてしまうことだ。エラーメッセージは、クラスadd_colorがオーバーロード解決可能なコンストラクターを持っていないというわかりやすいものではなく、テンプレートパラメーターMixinのコンストラクターがオーバーロード解決できないというものになってしまう。正しくコンパイルエラーにはなるものの、少しわかりにくい。

もうひとつの問題は、explicitやconstexprが引き継がれないことだ。たとえ基本クラスのexplicitコンストラクターであっても、派生クラスのコンストラクターはexplicitではないので、explicitの挙動はしない。さらに、constexprでもなくなってしまう。

しかし、この2つの問題は、些細なものである。Variadic Templatesによるエミュレーションは、十分実用的だ。

2012-03-27

precompiled header in clang

clangのprecompiled headerの使い方は、gccとは少し違う。まず、拡張子がちがう。.gchではなく.pchである。

まず、共通のヘッダーファイルを用意して、あまり変更されることのないヘッダーをincludeする。次に、以下のようにしてコンパイル済みヘッダーを生成する

clang++ -x c++-header header.h -o header.h.pch

ソースファイルをコンパイルするときは、-includeでヘッダーを指定する

clang++ -include header.h source.cpp

clangは、gccとは違い、同じ名前で拡張子.gchを付加したファイルを自動で探すことはない。自分で指定しなければならない。

Clang Compiler User's Manual

ffmpegとlibavの背景事情

ffmpegをインストールしようとしたら、なにやらちょうど一年前あたり、大規模なforkが起こったらしい。いまや、ffmpegとlibavに分裂している。forkは自由なソフトウェアではいたって普通の出来事だ。大抵の場合、開発者の間での意見の不一致により起こる自然な現象だ。自由なソフトウェアであれば、fork自体はそれほど悪いことではない。どちらも自由であるので、双方の開発者がIRCやMLで広角泡を飛ばしながら喧嘩しつつ、何事もなかったかのように相手のコードをこちらのコードベースにマージできる。なぜならば、どちらも自由なソフトウェアという共通点を持っているからだ。

しかし、ffmpegは、だいぶ巨大なソフトウェアだ。おそらく、現時点でこれ以上にでかい動画と音声のソフトウェアは、mplayerしかあるまい。mplayerはffmpegを包括しつつ、さらに変態的なことをしている。これについては後ほど述べるとして、まずはffmpegだ。どうやら、一年前に起こった出来事にも関わらず、ffmpegとlibavのforkの背景事情を説明する日本語の文献がないようなので、ここで解説する。

ffmpegは、世界一の規模を誇る動画と音声のエンコーダー、デコーダー集である。ffmpegはこの世に存在した、ありとあらゆる動画のエンコーダーとデコーダーを自由なソフトウェアとして提供する目的で開発されている。中には、大昔のゲーム専用機でしか使われていない、ドキュメントもない動画圧縮形式を、解析して実装することまでしている。ffmpegは、YouTubeを始めとしたあらゆる動画投稿サイトで使われている。なぜならば、このような動画投稿サイトにアップロードされる、それはそれは多数の圧縮形式を一手に引き受けて、正しくデコードし、さらに別の使いやすい圧縮形式にエンコードしてくれるのは、ffmpegをおいてほかにないからだ。ffmpegは、今日の動画サイトの舞台裏を支えているのだ。

そのffmpegがforkするというのだから、穏やかではない。いくら自由なソフトウェアとはいえ、物理的にコードベースが分離して、開発も分断されてしまうと、他方のコードでの変更点をこちらにマージするのは、一手間かかる。バージョン管理ソフトの自動的なマージ機能は、近年大幅に進化しているが、万能ではない。どうしても、人手による作業は避けられない。それでもなお、forkは起こる。

libavが発表されたとき、いち早くlibavに追随すると発表したのは、DebianとUbuntuである。実は、ここに問題の発端がある。問題は年々積もり積もっていたのだが、DebianとUbuntuも一枚噛んでいる。

Debianとその派生のUbuntuは、膨大なコンパイル済みのバイナリパッケージを提供している。パッケージはメンテナーによって、正しくコンパイルされ、適切に設定され、自動的にインストールされるよう調整される。このおかげで、ユーザーはCLIやGUIから、望みのパッケージを簡単にインストールできる。たとえば、ffmpegなら、以下のコマンド一行ですむ。

sudo apt-get install ffmpeg

あるいは、ソフトウェアセンターでffmpegと検索してインストールをクリックすれば良い。

無論、これは今さら言うまでもない。問題は、DebianとUbuntuにおけるffmpegのメンテナーが、バイナリパッケージをメンテする際のffmpegの問題をffmpegのトップの開発者、Michael Niedermayer(Lair Of The Multimedia Guru)にかけあった際、Michaelの対応がおろそかだったのだ。

さて、まずはlibav側の主張だ。

Ubuntu renaming FFmpeg to libav

問題とは、ffmpegがころころAPIやABIを変更することである。これでは長期的なサポートが難しい。だから、常にtrunkというわけではなく、stable版も提供してはくれないかという提案が出された。ところが、Michael Niedermayerはこの提案に否定的だった。さらに、Michaelはバイナリパッケージ自体にも、あまり興味を示さなかった。まるで、「ユーザーは常に最新版を自前でコンパイルして使うべきである」、といわんばかりの姿勢だった。

さらに、Michaelの指導下にあるffmpegは、機能の追加に対して保守的だった。たとえば、マルチスレッドによるデコード、ffmpeg-mtは、いまだにマージされない。しかも、「俺は絶対にffmpeg-mtなんかマージしねーよ」とまで明言した。

ここで、一部の開発者がより集まって相談した結果、forkするべきであるという結論に達した。Michael Niedermayerはこのforkに対して、口汚く罵り、身体上に危害を加えることを示唆するような悪質な冗談を繰り返したという。

FFmpeg
Libav

その後、お互いに相手のコミットを自分のコードベースにマージしたり、libavは名前をAPIをリファクタリングしたり名前を変更し始めたりと、やや不毛な作業も行われていたようだ。これが影響されたのだろう、Michael Niedermayer率いるffmpegはこの事件のあとすぐに、ffmpeg-mtをマージしたりしている。libavの方がバイナリパッケージのメンテナーの声をよく聞き入れる。DebianとUbuntuのlibavへの追随はこのためだ。

と、ここまではlibav側の主張である。Michael Niedermayerの主張は、また少し異なる。

Ubuntu renaming FFmpeg to libav

まず、Michael Niedermayerは、何も自前ビルドの原理主義者ではない。ただ、バイナリパッケージというものが大抵、一年以上も前のバージョンから更新されなかったりすることに不服だという。すでに多くのバグフィクスや改良、新機能の追加が行われているというのに、バイナリパッケージはいまだに大昔のままである。さらに、ffmpegをめぐるソフトウェア特許の問題もある。ソフトウェア特許に対処するためには、ソースコードの形で提供して、ユーザーにコンパイルさせた方がいい。

「ffmpeg-mtなんてマージしねーよ」というのは、単にIRC上でのチャットであり、その文脈上の冗談である。悪口というのも、たんなる冗談を本来の文脈から切り離して不当に評価したものである。

fork後にffmpeg-mtをマージしたのは、別に普通の作業であって、forkとは関係がない。

ABIの変化を気にかけないというのも不当である。というのも、MichaelはABI変化の問題を調査して、GNU ld.soにバグがあることをつきとめている。リンカーのバグ探しがなんで悪いのか。

ましてや、そのforkの方法たる、サーバーの管理者と協力して、MichaelのMLやソースレポジトリへのアクセスを禁止した。このような締め出しは開発者に与えられる正しい処遇ではない。

Lair Of The Multimedia Guru » ld.so GNU linker/loader

さて、プログラム的にみると、このforkの問題は少し厄介だ。まず、プログラム自体は、別の名前に変更されることになった。ただし、ライブラリの名前は変更されない。だから、このままでは、名前が衝突してしまう。両者とも比較的最近に、同じコードベースを共有していたのだから、ライブラリの互換性はあるが、混在はできない。ライブラリの名前を変えない以上、どちらかを選ばないといけない。GCCとEGCSのように、いつか和解して一つに戻る日がくるのだろうか。

DebianとUbuntuはlibav側に追随したし、Gentooも同じ影響を受ける。その他の有名なディストリはどうするのだろう。ffmpeg/libavは非常に有名なライブラリなので、ほぼすべての有名ディストリはパッケージに含んでいる。対応しないわけには行かないのだ。

ちなみに、冒頭の、mplayerはffmpegより巨大であるという話であるが、これはmplayerはffmpegを完全に包括するのみならず、Windowsのバイナリブロブを読み込むための機構を備えている。これは、Wineから拝借してきたコードである。数年前、コードを覗いてみたとき笑ってしまった。mplayerはLoadLibraryを自前実装しているのだ。

ちなみに、mplayerもforkされている。mplayer2という。より綺麗なコードベース(mplayerはffmpegのソースコードをコードベースに包括する。頻繁に更新されるffmpegは、外部に置きたい)、バグフィクスや改良などを含むという。mplayer2では、mencoderは提供されていない。

ちなみに、UbuntuのパッケージにあるChromiumは、ffmpegを使ったプラグインでvideoとaudioの対応形式を大幅に増やせる。このプラグインもlibavに変更されるのだろうか。

Google Summer of Code 2012では、ffmpegとlibavの両方が登録されており、両方とも似たような提案だらけだ。

FFmpeg Summer of Code 2012 - MultimediaWiki
Libav Summer Of Code 2012 - MultimediaWiki

clangを再コンパイルするときの注意点

clangのbinディレクトリにパスが通ったままだと、configureはデフォルトでclangを使おうとするので注意。もちろん、今のclangはセルフホスティング可能なレベルに達しているが、やはりtrunkから引っ張ってきたソースで、次のclangをコンパイルするのは不安だ。

さて、clangはmakeを多用している。ひとたびconfigureしたならば、clangをビルドする際のほとんどの作業は、makeで済ませることができる。

clangをSVNから引っ張ってきてビルドするには、最低でも三箇所から別々にチェックアウトしなければならない。もちろん、そんなことは手動でしたくないので、make updateを使う。これにより、自動的にすべての場所からチェックアウトしてくれる。

また、もしmakefileに変更があれば、再びconfigureする必要がある。もちろん、makefileのアップデートがあったかどうかを目diffするのは面倒なので、make preconditionsを使う。これにより、makefileの更新を確かめて、更新があればconfigureする処理を自動でしてくれる。

それにしても、UNIX環境ではmakeは変態的に活用されがちだ。たしかに、ほとんどのUNIX環境では、make、とくにGNU makeがまず存在する。だから使う気持ちもわからないことはないのだが、やり過ぎではないかと思うこともある。

不自由な環境に金が流れる事実

グリーは一体どこから道を間違え始めたのかという知られざる歴史まとめ - GIGAZINE

これはなかなか面白い。利益を追求する方向に進んでいったら、今の形になったというわけか。

それにしても、なぜ利益を追求しようとすると、ああいう不自由な形になってしまうのだろう。なぜ独占的で排他的な囲い込みに走ってしまうのか。Appleしかり、Microsoftしかり、Sonyしかり。事実として、利益が出ているのだから、認めるしかないが、それにしてもなぜこうなるのか。なぜ自由と利益は両立できぬのか。

ともかく、不自由なOSの使用をやめた身からすると、不思議でならない。今の私は、グラフィックドライバー以外は自由もしくはオープンソースなソフトウェアを使っているが、不自由なソフトウェアを使っていた時よりも、よほど快適だ。もっと早く移行するべきだったと後悔している。

ただし、私は今の自由なソフトウェアの環境を手に入れるために、一銭たりとも金を支払っていない。だから自由と利益は両立しないのかもしれない。ところで、ソフトウェアの質は、自由な方が圧倒的によい。ソフトウェアの本質から考えて、自由なソフトウェアの方が質が良くなるのは当然のことだ。しかし、事実として、金は不自由なソフトウェアの方に流れる。不思議だ。不自由なソフトウェアが優れているのなら、金を払う価値はあるだろう。しかし、自由なソフトウェアの方が優れていて、しかも安価で手に入るならば、なぜ不自由なソフトウェアに金を払うのか。

Unix - Wikipedia, the free encyclopedia

UNIXの歴史も興味深い。当初、UNIXはAT&TのBell Labで生まれた。AT&Tは当時、法規制によって、コンピューター産業への参入を禁止されていた。そこで、UNIXは無料でソースごと配布された。そのため、多くの大学機関でUNIXを採用した。後に、この法規制が解かれ、AT&TはUNIXで商売をやりだすようになった。その際、既存のUNIXの使用に対して、金を要求した。このため、オリジナルのUNIXの利用率は低下した。

その後、続々と自由なUNIX風OSが登場するわけだ。「自由」の定義は異なるが、少なくとも、ソースコードが公開されていて、改変できて、再配布できるという点では共通している。現在、広く使われているのは、このUNIXのようなOSである。

こちらは、不自由なソフトウェアが負けた例だ。もはや、オリジナルのUNIXは生き残っていない。パチモンに負けたわけだ。

2012-03-26

X11でクリップボードを操作しようと思ったら

Windowsでは、私はクリップボードを操作する簡単なツールを使っていた。たとえば、ブログにコードを貼り付けたりするとき、

template < typename T >
void f( T & ) ;

というコードは、実は、以下のようにエスケープしている。

template &lt; typename T &gt;
void f( T &amp; ) ;

もちろん、これも更にエスケープしているわけだ。CDATAセクションでも使わない限り、XML上で、&, <, >を直接書くことはできない。もっともBloggerはなんちゃってXHTMLを使っているので、実はちょっと変なHTMLにすぎないのだが。

このような変換を手sedで行うのはプログラマーたる者のすることではない。しかし問題は、私はいろんなソフトウェアを使っているということだ。vimやemacsのような一つの環境に閉じこもるならば、そのツール内で完結するコードを書けばいいが、実際には、テキストエディターは複数使うし、ブラウザーも複数使う。できるだけ広範囲で動かすには、クリップボードが最適だ。X11の練習がてら、さっそくC++で書いてみようと思った。

問題は、X11におけるクリップボードが使いづらいということだ。X11におけるクリップボードは、イベント駆動な仕組みになっている。クリップボードにデータを供給するには、その旨を通知した上で、さらに他のプログラムからの実際のデータの要求を待たねばならない。つまり、クリップボードに通知したあと、要求があるまで、ソフトウェアは起動したまま待たねばならない。私が今欲しいツールにはGUIなどいらないというのに、イベントループを回して要求を待たねばならない。もちろん、ウインドウを作ったりする必要はないが、たかだかクリップボード程度にえらく大げさなコードになる。

最近は、クリップボードサーバーがあり、プログラムの間の橋渡しをしてくれるので、一度要求を処理して終了してもクリップボードは維持されるようになった。しかし、結局コード上では通知して要求待ちしなければならないことに変わりはない。

なぜこう設計せねばならなかったのか。クリップボードのアイディアは、何もGUIを必須とするわけでもあるまい。GUIがなかった時代だって、プログラムごとにミニバッファなどと称して、クリップボードと本質的には大差ない機能をプログラムごとに実装していた。だから、クリップボードというのはそれほど新しい発送でもないはずだ。なぜ、/dev/clipboardみたいな仕組みがないのか。

Win32 APIのクリップボードも、あまりいい設計とは言えない。なにしろ、今となって古びたGlobalAllocを使わなければならないのだから。とはいえ、単純なクリップボードの読み書きごときにイベントループを回す必要はない。

というわけで、X11を直接使うのはやめることにした。聞説、Waylandなるものが将来、X11を完全に置き換えるらしい。とりあえず、今はGTK+でもいじって遊んでいよう。しかし、GTK+も概要を理解するだけで少し時間がかかるので、やはり面倒だ。

というわけで、未だに一行のコードも書いていないわけだ。ただし救いはある。私はいまGNU/Linuxを使っている。そのため、私は一行のコードも書くことなく目的を達成できるのだ。

顧客が本当に必要だったもの

#!/bin/sh
xclip -selection clipboard -o | sed "s/&/\&amp;/g;s/</\&lt;/g;s/>/\&gt;/g" | xclip -selection clipboard

clangのビルド

さて、Ubuntuの基本的な使い方に慣れたので、さっそく環境の構築に入る。まず、GNU/Linuxに移行した最初の目的である、clangを使うことにする。Ubuntuのレポジトリにはclangはあるが、残念ながら古すぎる。面白いことをするには、SVNから最新版を引っ張ってこなければならない。

clangをコンパイルするのは非常に簡単だ。とくに珍しいツールも必要ない。比較的新しいgccとGNU makeがあればいい。テストするには、もうすこしツールが必要だ。基本的にはClang - Getting Startedに従えばよい。ただし、SVNから取得すると、デフォルトのビルドがとんでもないことになるので、このままでは使いづらい。もちろん、普通に使うことは想定してないのだから、当然といえば当然だが、clangをハックするのでもなければ、やはり使いづらい。

まず、デフォルトでは、すべてのアーキテクチャ向けのクロスコンパイルができるようになっている。また、デフォルトではデバッグビルドかつassertが有効である。そのため、clangの単一のバイナリだけで、サイズが460MBぐらいになる。なかなか壮大だ。

configureしたあとでも設定を上書きできるのだが、どうせならconfigure時に指定してしまおう。

configure --enable-optimized --enable-assertions=no --enable-targets=host-only

これで、とりあえず試してみるだけのビルドができる。

ちなみに、SSVNではllvmとclangとcompiler-rtが分離されているので、アップデートするときは、ひとつひとつsvn checkoutするより、make updateを使ったほうが便利だ。

しかしまあ、なんとLinuxでは他人の書いたソフトウェアのビルドがたやすいことよ。これがWindowsなら、まずビルドツールからしててんでバラバラなので、非常に苦労する。

そんなわけで、clangを試してみたが、まあ、特にこれと言って面白いこともなく、普通に動作する。gccも頑張っているので、clangだけがサポートしている機能といえば、非staticメンバー関数のref-qualifierしかない。

#include <iostream>
#include <utility>

struct X
{
    void f() & { std::cout << "lvalue" << std::endl ;}
    void f() && { std::cout << "rvalue" << std::endl ; }

} ;

int main()
{
    X x ;
    x.f() ;
    std::move(x).f() ;
}

Getting Started with LLVM System
LLVM Makefile Guide

2012-03-25

なぜエロサイトの動画プレイヤーはYouTubeより高機能なのか

Redditで、以下の質問が注目を集めていた。

Why do porn sites have video players that are so much better than Youtube? : AskReddit

エロサイトの動画プレイヤーは、YouTubeのよりはるかにいい。すべての男と、おそらく大多数の女は、この事実を認めるであろう。YouTubeは動画中のコマを見ることができる機能を追加した。しかし、そんなのはエロサイトならとっくの昔に実装されていたことだ。エロサイトでは、動画のプレビューがある。単なる一枚の画像ではなく、アニメーションGIFのような形のプレビューだ。しかも、エロサイトはフルスクリーンへの切り替えにもたつくことはない。なんでエロサイトはGoogleよりよっぽどいいUIを提供しているんだ?

面白い質問だ。

評価の高かった書き込みの意見はどうか。曰く、エロサイトはYouTubeよりも競争が激しい。したがって、最新の技術を取り込まなければユーザーが得られない。一方、YouTubeはあまりにも巨大すぎて、大きな変更が難しい。UIをほんの少し変えただけで、多数のユーザーが文句を言う。

ただ、これは何も、エロサイトに限った話でもないと思う。実際、YouTubeは動画投稿サイトとして、現在のところ最大手であろう。他にも無料の動画投稿サイトは山ほどあるし、YouTubeとの差別化を図るため、様々な機能を追加している。しかし、やはりYouTubeには勝てない。そもそも、どうも多くのサイトは、YouTubeに勝つことを目的としていないように思われる。汎用的な動画サイトとなるよりも、独自性を売りに出すサイトの方が多い。

Ubuntuは便利だ

長年Windowsを使ってきたせいで、なかなかWindowsからは離れづらかった。そのため、Ubuntuのインストールも、あれやこれやと理由をつけて、なるべく引き延ばしていた。ともかく、これ以上机上で学んでも仕方がないので、意を決してインストールすることにした。

さて、今日一日、慣れるためにUbuntuを使っていたが、一切問題を感じなかった。ChromiumはWindowsと全く同じ操作性だし、IRCクライアントも、とりあえずXChatを選んでみたが、全く申し分ない。

最も感心したのが、ターミナルだ。なるほど、たしかにこれは使いやすい。未だにCLIでほとんどすべてを済ます猛者がいて、 dwmやxmonadやawesomeのような漢らしいウインドウマネージャが流行るのもわかる気がする。

現在悩んでいるのは、エディタだ。 geditはたしかに無難だ。必要な機能は全て揃っている。しかし、どうも面白みがない。nanoは素晴らしいエディタだ。ほんのちょっとテキストファイルを書き換えたい時には、nanoはとても便利なエディタだ。しかし、やはり機能が足りない。機能が少ないからこそ、nanoは優れているのだから、これは仕方がないことであるが、不足は不足だ。とすると、vimとemacsのどちらかを選ばざるを得ない。さて、どうするか。個人的には、vimの方がエディタとしては使いやすいのではないかと思う。emacsは、emacs自体を完成された一つの環境だと考える人間だけが価値を見出すのであろう。

もっとも手こずったのは、GeForce GTX 560Tiである。このデバイスは、Linux環境では一長一短だ。まず、長所としては、nVidiaのプロプライエタリなドライバーを使えば、満足の行くパフォーマンスが得られるということだ。ともかく、Windowsとほとんど遜色ないドライバーが提供されているのは利点だ。

問題も、このドライバーだ。このドライバーは、Kernel mode settingに対応していない。そのため、ブートやサスペンドからの復帰や、Ctrl+Alt+ファンクションキーでのターミナル切り替えなどで、画面が汚くちらつく。それに、時間もかかる。サスペンドからの復帰に数十秒かかり、しかもその間画面に描画がないので、本当に正しく動いているのかどうか不安になる。サスペンドからの復帰に数十秒もかかるのは到底納得できない。

ともかく、今となっては、なぜ昨日まであんなにWindowsにこだわっていたのか、さっぱり忘れてしまった。もっと早く移行しておけばよかった。 もはや、Windowsを使うべき理由は何もない。

2012-03-24

Ubuntuに移行した

そういうわけで、Ubuntuに移行した。Windowsを入れたHDDは、念のために残しておくが、おそらくもうWindowsに戻ることはないだろう。Ubuntuは十分に快適だ。

何が便利かと言って、膨大なオープンソースのソフトウェアが、公式レポジトリで提供されていることだ。有名どころのソフトウェアなら、まず確実に存在する。これにより、ソフトウェアの管理に煩わされることがない。しかも、コマンド一発でインストールできる。

そして、ソフトウェアのコンパイルも非常に簡単だ。

とりあえず、デフォルトではTakaoPGothicしか入っていなかったので、Takaoフォントを一式入れた。また、inconsolataもいれた。gitとsubversionやg++のインストールも一瞬で終わり、すぐに使える状態になった。これは便利だ。

ブラウザーには、Chromiumを使うことにした。Googleのアカウントと同期する設定にしておいたので、これまでのブックマークや拡張などがすべて自動で復元された。すばらしい。

さて、今日一日、色々と試してみたが、UbuntuはWindowsと遜色なく使えるのみならず、Windowsよりよほど使いやすいことがわかった。もっと早く移行しておけばよかった。

さて、とりあえず、今はUbuntuで満足している。ただ、Arch Linuxも気になるが、まあしばらくはUbuntuでいいだろう。とりあえず有名なものを使っておけば、それほど悪くなることはないだろう。

Victory!

So, I installed and am writing this from Linux. Well, GNU/Linux according to the famous fundamentalist. I choose Ubuntu a try because I don't want to worry about editing everything by hand or compiling everything from source. So far, so good. It works well.

The only problem I faced at the installing was kernel mode setting. The open source driver for nVidia graphic card, known as nouveau, didn't work well for my GPU, GeForce GTX560Ti. So, I had to manually gave kernel parameter of nomodeset. Aside that, the Installing was easy enough. Although I had to try twice.

If I checked to install proprietary software, the Installer automatically recognize my GPU and installed the appropriate nVidia's binary blob. But I think the description of this check box is misreading. It said, if I check this, I can get proprietary mp3 decoder. well, I don't need mp3 decoder. Even if I need it, I can install it later. So naturally, I skipped it the first time and got no binary driver, failed to boot(because of nouveau).

After the reboot, it had 364 security updates. which I installed. and another reboot.

さて、ここまで書いてmozcをインストールしたので、これ以降は日本語で書く。とりあえず、Ubuntuはどうしてなかなか悪くない。

2012-03-22

C++11のstd::swapはC++03のstd::swapとは互換性がない

C++11のstd::swapは、だいぶ大きく変更された。C++03までのswapは、<algorithm>にあり、CopyConstructibleかつAssignable(C++11のCopyAssignableに相当)を要求した。ところが、C++11では、<utility>に移されたあげく、MoveConstructibleかつMoveAssignableを要求するようになった。まるっきり別物になってしまっているのだ。果たして問題を起こさないものだろうか。おぼつかないものだ。

実装例は以下のようになる。

// C++03のswap
template < typename T >
void swap( T & a, T & b )
{
    T temp = a ;
    a = b ;
    b = temp ;
}

// C++11のswap
template < typename T >
void swap( T & a, T & b )
{
    T temp = std::move(a) ;
    a = std::move(b) ;
    b = std::move(temp) ;
}

ところで、Andrew Koenigは、swapはコピーやムーブ以上に基本的な操作だと書いている。

Object Swapping Part 1: Its Surprising Importance | Dr Dobb's
Object Swapping, Part 2: Algorithms Can Often Swap Instead of Copy | Dr Dobb's

C++11のswapはムーブになっているので、わざわざメンバー関数としてのswapを実装する必要はない。ムーブコンストラクターさえ実装しておけば、それがそのままstd::swapで使える。さて、koenigの理論を実践してみる。

class X
{
private :
    std::size_t size ;
    char * ptr ;

public :
    X( std::size_t size )
        : size(size), ptr( new char[size] )
    { }
    ~X()
    {
        delete[] ptr ;
    }

    X( X const & t )
        : size( t.size ), ptr( new char[t.size] )
    {
        std::copy( t.ptr, t.ptr + size, this->ptr ) ;
    }

    X ( X && t ) 
        : size( t.size ), ptr( t.ptr )
    {
        t.size = 0 ;
        t.ptr = nullptr ;
    }

    X & operator = ( X const & t )
    {
        if ( this == &t )
            return *this ;

        X temp = t ;
        std::swap( *this, temp ) ;
        return *this ;
    }

    X & operator = ( X && t )
    {
        if ( this == &t )
            return *this ; 

        std::swap( *this, t ) ;
        return *this ;
    }
} ;

なるほど、コピー/ムーブコンストラクター以外はすべてswapで実現可能なのだな。

BloggerのccTLDリダイレクトは相当ひどい

このブログでは、主に日本語を使っている。そのため、読者の大半は日本に属するIPからのアクセスである。したがって、最近のBloggerの変更により、自動的にcpplover.blogspot.jpにリダイレクトされる。既存のcpplover.blogspot.comはちゃんとリダイレクトされるので、すでに存在するリンクはそのまま動く。しかし、URLが異なるというのは、非常に問題だ。とくに、このソーシャル全盛の時代においては。

オンラインブックマークというサービスがある。これは、ブックマークをオンライン上で公開できるサービスである。多くのユーザーがブックマークするURLは、高価値の可能性が高い。Web検索の黎明期、多くの被リンクを得ているURLの価値が高いと判断されたのと同様だ。他にも、Twitterで多く言及されているURLは、価値が高い可能性がある。他にも、FacebookのLikeボタンやGoogle自らやっている+1ボタンのようなものも同様だ。これらのサービスは、URLに対して評価のカウントを与える。

ところが、既存のURLは、すべてblogspot.comを使っている。これがblogspot.jpに変更されたことにより、今までのカウントがすべてご破算になってしまうのだ。正確に言うと、既存のカウントがなくなるわけではない。しかし、これ以上既存のカウントは上がらない。新しいコンテンツは、.comではなく.jpでドメインでカウントされる。何にせよ、従来のカウントは、もうこれ以上上がらないのだ。つまり、このブログでは、従来の.comと今の.jpにカウントが分散してしまっている。

英語で書かれているブログはもっと悲惨だ。英語が母国語の国は多数ある。アメリカとイギリスとオーストラリアだけ考えたとしても、diggやredditに登録する時、Likeボタンや+1ボタンを押す時、それぞれ.com、.uk、.auに分散してしまう。

結局、Googleはソーシャルのことなど何もわかっていないのだ。既存のカウントが、評価が、どれだけ大事なのか全然わかっていない。

この問題は、独自ドメインを取得して使うことにより、回避できる。しかし、今まで独自ドメインを使って来なかったのに、今更やるのは、やはり同じ事だとも言える。既存の評価をすべて置き去りにしてしまうのだ。

ところで、Bloggerにはソーシャル系へ投稿するためのリンクを生成する機能がある。試してみたが、結局無効にしてしまった。なぜかというと、Google +1ボタンが、カウントを取得するためにJavascriptでカウント数を問い合わせる。これがページのロード時間を増やす。あほじゃなかろうか。

以前のテンプレートでやっていたように、自前のJavascriptコードを書くという手もあるが、やはり読者もロード時間の短い方を好むと思うので、やらないことにした。第一、ソーシャル好きな読者は、今みているURLをすぐにtweetなりlikeなりできるようにするブックマークレットなり拡張機能なりを導入しているだろうから、サイトごとにコロコロ変わる独自のtweetボタンなど余計なお世話だろう。それよりロード時間の方が重要だ。

汚いものは隠して解決?

Linuxについて調べていると、どうも引っかかることがある。それは、Linuxがどうも、汚いものは隠して解決するという文化を持っていることだ。

たとえばXだ。聞きかじったところによると、X11は相当に汚いらしい。使いづらいし、今となっては不必要な古びた機能が多数存在する。これは、ほとんどの文章にそう書いてあるし、また実際に人にたずねても、誰一人としてX11の醜悪を否定したりしない。XFree86からフォークしたX.Orgなどは、Xを直接使うなと公式に宣言している。GTK+とかQtなどの、汚いものを隠した上のレイヤーを使えと推奨している。

X.Org Wiki - Documentation

では、何故未だにX11が使い続けられているのか。もし、ある標準のAPIの設計が悪いとしたら、より優れた標準のAPIを設計すべきではないのか。なぜ悪い標準のAPIをラップした非標準のAPIを多数生み出すのか。これが理解できない。

IMEもそうだ。聞きかじった知識によると、XIMは非常に汚いそうである。しかし、なぜか明白で根本的な解決方法である、XIMの後継APIの再設計は行われない。XIMをラップした上でさらに機能を付け加えた、iBusとかSCIMとかuimが、雨後の筍のようにぽこぽこ登場している。

X11は非常に複雑なシステムだから、一から設計して実装するリソースがない、などという理由は信じない。GTK+やQtでは、結局ほとんどの機能は自前で実装している。開発リソースは十分にあるはずだ。互換性の問題とも思われない。今やほとんどのソフトウェアは、Xを直接使わずに、その上のレイヤーのライブラリを使っているのだから、バックエンドを変更するのは、比較的軽い変更と、ソフトウェアの再コンパイルで済むはずである。ソースコードを公開するという文化のあるLinuxでは、そのような破壊的な変更も、他のプラットフォームに比べて、比較的敷居が低いはずである。(もちろん、楽ではないだろうが)

なぜこうなってしまうのだろうか。どうもLinuxの歴史をみていると、ひとつの優れた標準のライブラリを開発するより、多数の互換性のないライブラリが独自に立ち上がっていることが多い。しかも、最終的に一つの優れたライブラリに統一されるのではなく、複数の主要なライブラリが生き残っている。

と、こう身の程知らずに偉そうなことを書くと、「じゃあお前が書けよ」と言われるかもしれない。しかし、仮に書いたところで、もう一つ規格が増えるだけだ。

状況:競合する規格が14個ある。
甲:なんやて14個? アホくさ。ワシらで誰でも使えるめっちゃえー規格作って、他の奴らなんか蹴散らしてやろうやないか
乙:そうや、そうや
状況:競合する規格が15個ある。

xkcd: Standards

といいつつも、Waylandには少し期待している。

LinuxカーネルがVMUFATをサポートするかも

[Phoronix] Linux Kernel May Gain VMUFAT File-System Support

LinuxカーネルにVMUFATの実装が取り入れられるかもしれない。とはいっても、誰も喜ばないだろうとおもうし、そもそもVMUFATが何であるかを知る読者もいないであろう。そもそも、この名前からして、正式なものではなく、仮に付けられた名前なのだ。

VMUFATとは、セガのドリームキャストで使われていたファイルシステムである。いったい今、ドリームキャストの実機でLinuxを動かす需要がどれだけあるのか。

ちなみに、動画ブログのBreaking Eggs And Making Omelettesで有名なこの人は、Dreamcastの実機で色々と遊んでいるようだ。

Dreamcast | Breaking Eggs And Making Omelettes

2012-03-20

なぜDOSのパスはバックスラッシュなのか

Why is the DOS path character "\"? - Larry Osterman's WebLog - Site Home - MSDN Blogs

基本的にDOSのパスはUNIX由来なのだが、スラッシュはすでにスイッチとして使われていたので、仕方なくバックスラッシュにしたらしい。

GCC 5はモジュール化できるか

[Phoronix] Talk Of GCC 5.0 To Be Modular, More Like LLVM
David Malcolm - GCC 5? (was Re: GCC 4.7.0RC: Mangled names in cc1)

聞説、今のGCCのコードは、やや悲惨な部類に入るらしい。十分な実績があり正しく動くのは確かだが、コードはほとんどCで書かれており、名前空間もなく、グローバルな状態が多く、スレッドもない。これはつまり、GCCは他のソフトウェアに組み込むのが難しい。

一方、LLVMは、設計段階からモジュール化を念頭に置いており、GCCよりはるかに後発なのにもかかわらず、他のソフトウェアに組み込む用途で広く使われている。たとえば、 MesaのGallium3Dとか、OpenCLとか、Monoとかで、JITコンパイルを実現するために、すでに使われている。他にもLLVMを利用して、CやC++をJavascriptに変換するようなプロジェクトも生まれている。

GCCは歴史や実績こそ十分だが、このような組込用途には、現在のコードベースでは圧倒的に向いていない。そこで、GCCをLLVMのようにモジュール化して使いやすくしようという議論がある。

問題は、長年の歴史あるGCCのコードをモジュール化するための変更は相当にでかい。したがって、現実的な方法でモジュール化を進めると、GCCは短期的に、機能が少なくなり、最適化も悪くなり、あらゆる点で現行のGCCより劣ることになる。もしすべての現行機能をそのまま保とうとしたら、作業が莫大すぎて現実的に行えない。多くのGCCのコントリビューターは、すでにGCCを自社で使っている会社に雇われて働いている。そのような会社が、GCCの機能を、短期的に劣化させる作業に金を出したいと思うだろうか。

もうひとつの問題は、ライセンスだ。GCCはGPLv3で提供されているが、LLVMはより柔軟でpermissiveなライセンスで提供されている。たとえモジュール化をやり遂げて、組込用途でLLVMに対抗できるようになったとしても、GPLでは使えない企業も出てくるだろう。現時点で、GCCがいまさらライセンスを変更できるはずもない。一体どうするのか。

なんにせよ、今のLLVMの開発速度は驚異的だ。GCCは今の地位を保てるだろうか。明らかに今のGCCのケツには、やがて発火する煙がくすぶっているように思われる。

C++Now!行きたいなう

Keynotes! |

豪華過ぎる。clangのlibc++作者のHoward HinnantとEDGでC++ Templates作者のDavid Vandevoordeだなんて。

Howard Hinnantはrvalue referenceについて話すらしい。David Vandevoordeはなんと、現在策定中のモジュールについて話すとか。

ちなみに、モジュールについて知りたければ、N3347を読むといい。特に、某人はC++Now!に参加するそうだから、まだ読んでいないとしたら、是非とも読むべきである。

2012-03-19

Linuxの作法

どうもLinuxにおけるプログラムからのディレクトリの使い方の作法が難しい。

あるプログラムが、動作に設定ファイルとデータファイルを必要とする。これには、Linuxの作法では、それぞれbinとetcとshareを使うようだ。問題は、主要なものだけ挙げても、/binと/usr/binと/usr/local/binがあり、、etcとshareに関してもそれぞれ同じものがあるということだ。もちろん、これらのディレクトリの違いは解説されている。しかし、一体どうやって、どこに置いても正しく動作するプログラムを書けばいいのだろうか。

/usr/binに置かれたプログラムは、やはり/usr/etcを使うべきなのだろうし、/usr/local/binに置かれたプログラムは、/usr/local/etcを使うべきなのだろう。それ以外のディレクトリ下に置かれたプログラムも、やはりそこから見て相対的なetcやshareなディレクトリを使うべきなのだろうか。問題は、そのように振る舞うプログラムをどうやって書けばいいのだろうかということだ。実行可能ファイルが置かれている場所からの相対パスでも使うのだろうか。また、ある名前のディレクトリがどのような目的で使われているかというのは、ディストリごとに微妙に異なる。どうやってポータブルなプログラムを書けばいいのだろうか。すべてのディストロに対応するなどということは、到底小規模なソフトウェアでできそうなことではない。

調べてみると、その手の作業は、autotoolsなどのビルドのためのビルドツールの役割であるらしい。つまり、ソフトウェアはソースコードの型で提供する文化なのだから、コンパイル時にそのような変更をする簡単な方法を提供してやればいい。コンパイルや設定方法などのドキュメントを用意すれば、あとは使用者が自力で設定、コンパイルして使う。ソフトウェアに十分なユーザーがいれば、誰かしら、自分のディストロ用のパッケージなどを作成してくれるだろうから、自力で設定してコンパイルする知識のないユーザーでも、ビルド済みのそのディストロで動くソフトウェアを手に入れられる。

結局、GPLがどうとか、フリーなソフトウェアがどうとかという大義名分とは関係なく、UNIX環境でまともに動くソフトウェアを提供するならば、ソースコードを公開することは至って自然なことのように思える。

まあ少なくとも、プログラマーにとっては便利な環境であるとは言える。ただし、すべてのディストリで動くポータブルでジェネリックなバイナリなどというものを提供することはできない。これは、プログラマーではないユーザーにとっては難しい状況だ。

これを考えるに、LinuxがWindowsやMacを駆逐するということは無理だろう。やはり一般に普及するには、誰か強力な独裁者がひとつの環境を提供する必要がある。androidやUbuntuも、独断的な部分があるからこそ、ある程度の成功をおさめているのだろう。

それにしても、autotoolsを使うのに覚えることが多そうだ。とりあえず必要になるまで学ぶのは保留しておこう。

Linuxのディレクトリ構造について

Windowsにおける、ユーザーが見るディレクトリ構造は、ドライブレターを用いてる。これは、物理的なHDDなどの記憶装置による分割はもちろん、その上に構築されるパーティションによる論理的な分割もある。

一方、Linuxのディレクトリ構造は論理的なもので、ユーザー側からは、通常の利用においては、あまり物理的な記憶装置を意識しないようになっている。

もちろん、最近は両OSとも、古典的なファイルシステムや物理的な記憶装置、パーティション管理を捨てて、ソフトウェア側で複数の記憶装置を、あたかもひとつの巨大な記憶装置のように使う手法を提供している。Windowsでも、今やシンボリックリンクはサポートされている。とはいえ、依然としてWindowsではシンボリックリンクが一般的ではなく、本来そういったハードウェア上の詳細を知らなくてもいいはずの末端ユーザーでも、ドライブレターを意識しなければならない。もちろん、これはWindowsではシンボリックリンクが一般的ではなかったので、急にGUIのエクスプローラーにシンボリックリンク作成の機能を付け加えても、混乱が大きいことにもよろう。それに、Windowsの顧客層を考えれば、ドライブレターという従来の仕組みを急に捨て去ることは難しい。

Linuxの問題は、ディレクトリ構造がディストリごとに微妙に異なるということだ。一応、Filesystem Hierarchy Standardという規格はある。しかし、この規格は本当に基本的で大雑把な構造を規定しているだけだ。それに、標準的なディレクトリパスを取得する標準の方法がない。Windowsでいう、SHGetKnownFolderPath関数のようなAPIがないのだ。Linuxでディストロ間のバイナリ互換性を保証するのが難しい理由の一つに、ディレクトリ構造の差異によるものがあると聞く。

追記:FHSによれば、ユーザーのホームディレクトリを取得するには、getpwentを使うことが推奨されている。

それに、FHSはすべてのディストリで守られているわけではない。たとえば、DebianはFHSに完全には従っていない。とくに、DebianはFHSのmultiarchの場当たり的でx86とx86-64限定の対応に不満を持っていて、もっと汎用的な方法を独自に考案し、今移行中である。Ubuntu 12.04では移行するらしい。もっとも、/lib32や/lib64へはシンボリックリンクを貼るので、ある程度の互換性は保たれるようだが。

Debian Policy Manual - The Operating System
Multiarch - Debian Wiki

ともかく、慣習的に、Linuxではパスは大抵ハードコードされている。移植性を考えたソフトウェアは、使用時やビルド時にパスを指定する機能を提供している。これは、ユーザーは最低限のプログラミングの知識を有していることが期待され、ソフトウエアはソースコードの形で提供するというUNIX文化ならばうまく動く。また、主要なディストリには、公式なパッケージの仕組みがあり、需要のある有名なソフトウェアやライブラリには、専門のメンテナーがいて、そのディストリ用にあらかじめ調整してくれているので、大多数のユーザーは、そのような詳細にかかずらう必要がない。Debianが大胆なmultiarch対応を実行に移せるのも、このような文化の違いにもよろう。

もちろん、Windowsより優れている点もある。公式パッケージの仕組みもそうだし、ヘッダーファイルやライブラリファイルの標準のパスがあるので、ソースコードをコンパイルする際に都合がいいということだ。こと、他人の書いた大規模なソースコードをコンパイルする場合に関しては、Windowsよりよっぽど楽だ。あるソースコードをコンパイルするために、今まで使ったことがないコンパイラーやインタプリターやビルドシステムやライブラリの手動インストールに悪戦苦闘する必要はない。もちろん、これはソフトウェアをソースコードの形で提供する文化から生まれた必然性であろう。プログラマーは無駄な単純作業を忌み嫌うからだ。

いま理解に苦戦しているのは、Linuxでソフトウェアを作る際、どういう風にディレクトリを使えばいいのかということだ。どうも、binには実行可能ファイルだけをいれ、設定ファイルやドキュメントやその他のリソースは、それぞれ別の対応するディレクトリに入れるのが一般的らしい。しかし、binは単に/binだけではなく、複数あり、それぞれ役割が違う。それぞれの役割はFHSで規定されていて、ほとんどのディストリはこれを守っているようなので、とりあえず今はFHSを頭に入れておけば十分だろう。

ともかく、別のプラットフォームに移行するのは苦労する。このような、初心者でも当然知っているべき基本的なことから学ばなければならないのだから。もはやWindowsはプログラマーの使うデスクトップOSとして未来がない以上、しかたのないことだ。

なぜいまだにシステムプログラミングはCなのか

Programming Language Challenges in Systems Codes

システムコードにおけるプログラミング言語の挑戦、あるいは、なぜいまだにシステムプログラミングはCなのか。

著者がJonathan Shapiroであることが興味深い。Jonathan ShapiroはD&Eに頻出する名前である。Bjarne Stroustrupの記述からして、初期のC++の設計に多大な影響を与えた人物である。それに、最初にC++を使って本格的で大規模なプロジェクトを始めたのも、Jonathan Shapiroだ。しかし、今日、Jonathan Shapiroの名前はC++界では、あまり有名ではない。私はMLとかHaskellなどの言語には疎いので、この方面の話は知らなかった。

なぜシステム・プログラミングは、いまだに1970年代に開発された大昔の高級アセンブリ言語で書かれているのか。自動的に検証可能でガベコレもあってsound typeな、つまりプログラマーが直接にコードを書かずとも、条件を指定するだけで、自動的にチェックを生成してくれるような、そういう言語にとってかわらないのかという問題を考えている。

クライアントサイドでは、新しいプログラミング言語が頻繁に生まれ、一定の成功をおさめている。しかし、ことシステムプログラミングに関しては、プログラマーが直接管理できる言語が、依然として必要なのだそうだ。pre conditionやpost conditionの条件を記述すれば、自動的に検証してくれるような言語を作ろうとしたところで、そもそもシステムプログラミングでは、そのような方法で条件を記述することすら難しいのだそうである。加えてハードウェアの特性が、GCなどの高級な機能ではパフォーマンスが得られない。

インタラクティブなトラフィックにおいては、FoxNetは、当時のUNIX実装に比べて、0.00007倍のパフォーマンスを達成した。これはtypoではない。最も容易に実装できる例ですら、FoxNetはCによるネットワーク実装に比べて、11倍ものCPUロードを必要としたのである。

その後の改良で結果が向上したものの、今のUNIXの実装も当時よりさらに高速になっている。

何故こういう結果になるかというと、ハードウェアの都合上、データは正しくアライメントされていなければならなかったり、またCでは詳細なデータ構造とそのメモリ管理を手動で行うことができるからである。

2006年の結論として、結局CやC++には勝てないということである。2012年の現代でも結論は同じだろう。