Native Client // C++へ帰る日。ネイティブの空を遠いウェブの地からも仰ぎ見よう!
一般論としてよく、女子はキラキラしたものが好きだと言われる。たぶん同様に私の場合はマシンネイティブな対象が好きなんだと思う。HTMLとかJavaScriptとか、心の故郷から遠すぎる旅路が長くなると帰りたくなる、C++へ。例えまだ帰り付く街が03だったとしても、clang++3.1がまだ開発中だったとしても。しかし、Native Clientを使えばこのネイティブから遠く離れたHTMLという文書を中心として構築される世界にワームホールを開いて故郷の空を仰ぎ見る事ができる。私は最近になって漸く実際にChromiumでBastionやRime Bertaを動作させてみた。そこに見た空はWebGLが見せる架空では無く、紛れもないネイティブな空であった。
前置きはこのくらいにして、実際に Arch Linux で Native Client を始める手立てについてメモを残す事にする。
差し当たりの資料は下記の文書。先ずはその中の初め、SDKの導入から。
環境は以下の通り。
LH-MAIN /tmp/nacl_sdk% uname -a Linux LH-MAIN 3.3.2-1-ARCH #1 SMP PREEMPT Sat Apr 14 09:48:37 CEST 2012 x86_64 AMD Phenom(tm) II X4 940 Processor AuthenticAMD GNU/Linux
手順 1 Python2 を使えるか?
LH-MAIN /tmp% python2 --version Python 2.7.2
問題ない。
手順 2 SDK を入手せよ & 手順 3 アーカイブを展開せよ
先ずはSDKを導入しなければ作り始める事は出来ない。
手順には.zipへの直リンが示されている。
LH-MAIN /tmp% wget http://commondatastorage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/nacl_sdk.zip LH-MAIN /tmp% unzip nacl_sdk.zip LH-MAIN /tmp% cd nacl_sdk LH-MAIN /tmp/nacl_sdk%
何が入っているのやら unzip して見ると、SDKのインストーラーがbashスクリプトと不自由なWindowsの.batで収まっていた。
最終的にはsdk_update.pyが呼ばれる仕掛けになっている。
LH-MAIN /tmp/nacl_sdk% ls ** -rwxr-x--- 1 usagi users 601 3月 22 08:29 naclsdk -rwxr-x--- 1 usagi users 575 3月 22 08:29 naclsdk.bat sdk_cache: 合計 4.0K drwxr-xr-x 2 usagi users 60 4月 18 14:24 . drwxr-xr-x 4 usagi users 120 4月 18 14:24 .. -rw------- 1 usagi users 1.2K 3月 22 08:29 naclsdk_manifest2.json sdk_tools: 合計 56K drwxr-xr-x 2 usagi users 100 4月 18 14:24 . drwxr-xr-x 4 usagi users 120 4月 18 14:24 .. -rw-r----- 1 usagi users 1.5K 3月 22 08:29 LICENSE -rwxr-x--- 1 usagi users 12K 3月 22 08:29 cygtar.py -rwxr-x--- 1 usagi users 38K 3月 22 08:29 sdk_update.py
ちなみに、Arch Linuxを使っているのならAURにPKGBUILDのエントリーを見付けられる。
しかしPKGBUILDを覗き見ると入手するSDKに特定のバージョンが振られていて、パッケージの更新も1年以上前。念の為、これは使わないで措く事にしよう。
なお、ドキュメントにあったURLの.zipの中身もpython2をpythonと呼びだすように書いてある。たぶん私の環境ではここでpython3が実行されてコケるのだろうな…。もう慣れたが、何時もながらこの問題には、なぜ互換性の無い処理系を同じコマンドエイリアスで動作する様にしているやら理解に苦しむ。
手順 4 `./naclsdk list` せよ
LH-MAIN /tmp/nacl_sdk% ./naclsdk list File "/tmp/nacl_sdk/sdk_tools/sdk_update.py", line 430 print 'Scanning archive to generate sha1 and size info:'
お約束のPython2依存ネタな気がするので、さっそく
LH-MAIN /tmp/nacl_sdk% mkdir bin && ln -s /usr/bin/python2 bin/python && PATH=`pwd`/bin:$PATH
(↑binというディレクトリを仮設して、python2へのシンボリックリンクpythonを作り、シェル変数のPATHに仮設コマンドを入れたbinを最優先する様に放り込んでいます。)
それから、再び:
LH-MAIN /tmp/nacl_sdk% ./naclsdk list Available bundles: sdk_tools description: Native Client SDK Tools, revision 1.16 stability: stable recommended: yes version: 1 revision: 16 pepper_16 description: Chrome 16 bundle, revision 1398 stability: post_stable recommended: no version: 16 revision: 1398 pepper_17 description: Chrome 17 bundle, revision 112997 stability: stable recommended: no version: 17 revision: 112997 pepper_18 repath: pepper_18 description: Chrome 18 bundle, revision 124251 stability: beta recommended: yes version: 18 revision: 124253 pepper_19 repath: pepper_19 description: Chrome 19 bundle, revision 127407 stability: dev recommended: no version: 19 revision: 128837 Currently installed bundles: sdk_tools description: Native Client SDK Tools, revision 1.16 stability: stable recommended: yes version: 1 revision: 16
よし、先へ進もう・w・b
`./nacl_sdk update` し、 シェルに変数 NACL_SDK_ROOT をセットせよ
LH-MAIN /tmp/nacl_sdk% ./naclsdk update sdk_tools is already up-to-date. Downloading https://commondatastorage.googleapis.com/nativeclient-mirror/nacl/nacl_sdk/18.0.1025.46/naclsdk_linux.bz2 |================================================| .................................................. Updating bundle pepper_18 to version 18, revision 124253 |------------------------------------------------| ..................................................
無事にSDKを更新できたらしい。
続いてドキュメントの最後にある NACL_SDK_ROOT 変数の設定を自動化する。
と、その前に私は作業を/tmpで行なっていたので、先にnacl_sdkを`~/opt/`へ移動してして措く事にする。
LH-MAIN /tmp/nacl_sdk% .. LH-MAIN /tmp% mv nacl_sdk ~/opt
変数 NACL_SDK_ROOT は差し当たり.zshrcにでも追加しておくとしよう。
NACL_SDK_ROOT=~/opt/nacl_sdk/pepper_18
チュートリアル 3 examples でお楽しみ
LH-MAIN /tmp% cd ~/opt/nacl_sdk/pepper_18/examples
執筆時点では`pepper_18`を使っているけれど、もちろんバージョンはどんどんインクリメントされる。
LH-MAIN /home/usagi/opt/nacl_sdk/pepper_18/examples% python httpd.py 12345 INFO:root:Starting local server on port 12345 INFO:root:To shut down send http://localhost:12345?quit=1
Chromiumでこのサーバーにアクセスする。
サンプルお楽しみタイムの始まり…の前にビルド。
LH-MAIN /home/usagi/opt/nacl_sdk/pepper_18/examples% make make -C dlopen File "/home/usagi/opt/nacl_sdk/pepper_18/tools/getos.py", line 29 print 'Unknown platform.' ^ SyntaxError: invalid syntax make[1]: ディレクトリ `/home/usagi/opt/nacl_sdk/pepper_18/examples/dlopen' に入ります /home/usagi/opt/nacl_sdk/pepper_18/toolchain/_x86_glibc/bin/i686-nacl-g++ -o dlopen_x86_32.o -c dlopen.cc -m32 -g -O0 -pthread -std=gnu++98 -Wno-long-long -Wall make[1]: /home/usagi/opt/nacl_sdk/pepper_18/toolchain/_x86_glibc/bin/i686-nacl-g++: コマンドが見つかりませんでした make[1]: *** [dlopen_x86_32.o] エラー 127 make[1]: ディレクトリ `/home/usagi/opt/nacl_sdk/pepper_18/examples/dlopen' から出ます make: *** [dlopen_TARGET] エラー 2
ふむ、どうも`i686-nacl-g++`の呼び出しパスが怪しく見える。`_x86_glibc`の部分はアンダースコアの前に何か入れるのに失敗しているのでは無かろうか?
"exmaples/Makefile"を確認し、どうもそこには具体的に失敗したコマンドに関する記述は見られない様なので、そこから呼び出される"examples/dlopen/Makefile"を確認してみた。すると、:
OSNAME:=$(shell python $(NACL_SDK_ROOT)/tools/getos.py) TC_PATH:=$(abspath $(NACL_SDK_ROOT)/toolchain/$(OSNAME)_x86_glibc) CXX:=$(TC_PATH)/bin/i686-nacl-g++ || とかなんとかやっている。このOSNAMEの取得`getos.py`がしくじっているに違いない。 >|sh| LH-MAIN /home/usagi/opt/nacl_sdk/pepper_18/examples% python ../tools/getos.py File "../tools/getos.py", line 29 print 'Unknown platform.' ^ SyntaxError: invalid syntax LH-MAIN /home/usagi/opt/nacl_sdk/pepper_18/examples% python --version Python 3.2.2
ぁぁ、また君か・・・パイソン君…。何故互換性の無いコマンドを上書きしたのだ…この馬鹿パイソンが…。
LH-MAIN /home/usagi/opt/nacl_sdk/pepper_18/examples% python --version Python 2.7.2 LH-MAIN /home/usagi/opt/nacl_sdk/pepper_18/examples% python ../tools/getos.py linux
ふむ、どうやらそういう事らしい。ここでふとpython3/python2が同じコマンド名である事に由来するあほらしい問題に単にコマンドを実行できれば良いだけの状況でちまちまと触れるのが馬鹿らしいので、
とか作った。・・・この試みはCERRは汚くなるが、まあ上手く行くだろうと思った…。しかし`make`の途中で止まった。ふう、ダルい。
パイソン君、君はなぜ互換性の無いpython3をpython2と同じpythonというコマンドで提供し使う様にユーザーを導いたのかね。それが無ければよく使ってもいない君を嫌いだとまでは言わなかったろうに。
— 伊藤 兎 (実際にんじん)さん (@USAGI_WRP) 4月 18, 2012
さてもう私はpython3なんてこの世に無い事にする事にした。
% su - # rm /usr/bin/python # ln -s /usr/bin/python2 python
もう知らん。私はpythonを自分で書く予定は無いし、書くとしても必ずや`python3 hogehoge`と呼び出される事を前提としたスクリプトとその呼び出し用のシバンを作って提供するだろう。これは本当に馬鹿馬鹿しい問題だ=w=;
さてまあ、pythonコマンドが必ずpython2を実行する様にしてしまえば`make`は綺麗に通って、NaClにより開かれた、楽しいC++によるネイティブの空をChromiumで無事に見られる様になります。
いやっほー・w・b
<追記>