読者です 読者をやめる 読者になる 読者になる

Calmery.me

みっかぼうずにならないようがんばる

WebAssemblyを試してみた

JavaScript Node.js WebAssembly Rust Memo

メモ.

追記

main 関数があっても動かせた.
楓 software: wasm に clang を使った場合に C 内で関数呼び出しする場合に出るエラー

(index):25 Uncaught (in promise) LinkError: WebAssembly.Instance(): Import #0 module="env" function="printf" error: function import requires a callable
    at fetch.then.then.then.module (http://localhost/:25:24)
    at <anonymous>
$ s2wasm main.s -o main.wast --allocate-stack 1024
const loadWebAssembly = ( filename, imports ) => {
    return fetch( filename )
        .then( response => response.arrayBuffer() )
        .then( buffer => WebAssembly.compile( buffer ) )
        .then( module => {
            imports = imports || {}
            imports.env = imports.env || {}

            imports.env.printf = arg => console.log( arg )

            if( !imports.env.memory )
                imports.env.memory = new WebAssembly.Memory( {
                    initial: 256
                } )

            if( !imports.env.table )
                imports.env.table = new WebAssembly.Table( {
                    initial: 18,
                    element: 'anyfunc'
                } )

            return new WebAssembly.Instance( module, imports )
        } )
}

loadWebAssembly( 'main.wasm' ).then( instance => {
    const exports = instance.exports
    exports.main()
} )

Google Chrome Canary や Node.js で WebAssembly を読み込むための関数を作った(よくわかっていないのでものによっては動かないかも)
WebAssembly/loadWebAssembly.js at master · calmery/WebAssembly · GitHub

環境構築

Mac OS X 10.11.6
Google Chrome Canary 59.0.3030.0 canary (64-bit)
Firefox Nightly 54.0a1 (2017-03-05) (64 bit)
Node.js v8.0.0-pre

おまじない.

$ pyenv global 2.7.12

The LLVM Compiler Infrastructure Project

$ cd
$ mkdir workspace
$ cd workspace
$ git clone http://llvm.org/git/llvm.git
$ cd llvm/tools
$ git clone http://llvm.org/git/clang.git
$ cd ../projects
$ git clone http://llvm.org/git/compiler-rt
$ cd ~/workspace
$ mkdir llvm_build
$ cd llvm_build
$ cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/usr/local -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly ../llvm
$ make -j 8
$ sudo make install

GitHub - WebAssembly/binaryen: Compiler infrastructure and toolchain library for WebAssembly, in C++

$ cd ~/workspace
$ git clone https://github.com/WebAssembly/binaryen.git
$ cd binaryen
$ cmake . && make
$ sudo make install

GitHub - WebAssembly/wabt: The WebAssembly Binary Toolkit

$ cd /usr/local/src
$ sudo git clone --recursive https://github.com/WebAssembly/wabt
$ cd wabt
$ sudo make gcc-debug-no-tests
$ cd
$ echo "export PATH=$PATH:/usr/local/src/wabt/out/gcc/Debug/no-tests/" >> .bash_profile

Node.js は v8.0.0-pre でないと Google Chrome Canary や Firefox Nightly で動く WebAssembly が動かない.そのため v8/nodenodejs/node を使う.Nightly builds の v8.0.0-nightly20170307efaab8fccf も試したが動かなかった.
GitHub - nodejs/node: Node.js JavaScript runtime

$ git clone https://github.com/nodejs/node.git
$ cd node
$ git checkout -b canary origin/canary
$ ./configure
$ make -j4
 if [ ! -r node -o ! -L node ]; then ln -fs out/Release/node node; fi
$ ./out/Release/node -v
 v8.0.0-pre
$ ./out/Release/node --expose-wasm
> WebAssembly
{}

GitHub - v8/node: Node.js JavaScript runtime

$ git clone https://github.com/v8/node.git
$ cd node
$ git checkout -b vee-eight-lkgr origin/vee-eight-lkgr
$ ./configure
$ make -j4
 if [ ! -r node -o ! -L node ]; then ln -fs out/Release/node node; fi
$ ./out/Release/node -v
 v8.0.0-pre
$ ./out/Release/node --expose-wasm
> WebAssembly
{}

WebAssembly に変換する

C や C++ で書かれたコードを WebAssembly に変換する.

extern "C" {
    int fib( int n ){
        switch( n ){
            case 0: 
            	return 0;
            case 1: 
            	return 1;
            default: 
            	return fib( n - 2 ) + fib( n - 1 );
        }
    }
}

C や C++ のコードをまず LLVM bitecode に変換し,次にアセンブリに変換する.その後 S 式に変換しバイナリに変換する.

$ clang++ -v
clang version 5.0.0 (http://llvm.org/git/clang.git fc2d9054c86c9b8acbc98b06f1b9d8aa0e5d40f9) (http://llvm.org/git/llvm.git 58580c59aefa59fb793a72dd5abeb6a60340a317)
$ clang++ main.cpp -emit-llvm --target=wasm32 -Oz -c -o main.bc
$ llc -version
LLVM (http://llvm.org/):
  LLVM version 5.0.0svn
...
$ llc main.bc -march=wasm32 -filetype=asm -o main.s
$ s2wasm main.s > main.wast
$ sexpr-wasm main.wast -o main.wasm

動かしてみる

GitHub - 1984weed/webassembly-sample を参考にした.

const loadWebAssembly = ( filename, imports ) => {
    return fetch(filename)
        .then( response => response.arrayBuffer() )
        .then( buffer => WebAssembly.compile( buffer ) )
        .then( module => {
            imports = imports || {}
            imports.env = imports.env || {}
            imports.env.memoryBase = imports.env.memoryBase || 0
            imports.env.tableBase = imports.env.tableBase || 0
            
            if( !imports.env.memory )
                imports.env.memory = new WebAssembly.Memory( {
                    initial: 256
                } )

            if( !imports.env.table )
                imports.env.table = new WebAssembly.Table( {
                    initial: 0,
                    element: 'anyfunc'
                } )

            return new WebAssembly.Instance( module, imports )
        } )
}

loadWebAssembly( 'main.wasm' ).then( instance => {
    const exports = instance.exports
    console.log( exports ) // => Object {memory: W…y.Memory, fib: function}
} )

Node.js はオプションで --expose-wasm をつける必要がある.

// Node.js v8.0.0-pre
// node --expose-wasm
const fs = require( 'fs' )
const buffer = fs.readFileSync( './main.wasm' )

const arrayBuffer = new Uint8Array( buffer ).buffer

WebAssembly.compile( arrayBuffer ).then( module => {
    let imports = {}
    imports.env = {}
    imports.env.memoryBase = 0
    imports.env.tableBase = 0

    if( !imports.env.memory )
        imports.env.memory = new WebAssembly.Memory( {
            initial: 256
        } )

    if( !imports.env.table )
        imports.env.table = new WebAssembly.Table( {
            initial: 0,
            element: 'anyfunc'
        } )

    const instance = new WebAssembly.Instance( module, imports )
    console.log( instance.exports )
} )
// Node.js v7.7.1
Promise {
  <rejected> Error: WebAssembly.compile(): Wasm decoding failedResult = expected version 0c 00 00 00, found 01 00 00 00 @+4

ちなみに C++ では名前に修飾がついてしまうので extern "C" で囲う必要がある.

console.log( instance.exports ) // => Object {memory: W…y.Memory, _Z3fibi: function}
> WebAssembly.Instance( module ).exports
{ _Z3fibi: [Function: 0], memory: Memory {} }

サンプルなどを見ていると WebAssembly ではなく Wasm を使っているものがある.だが Google Chrome Canary や Firefox Nightly では Wasm がない.

// Replace
Wasm.instantiateModule() // => ReferenceError: WASM is not defined
WebAssembly.Instance()

Node.js v7.2.1

Getting Started With WebAssembly in Node.js | www.thecodebarbarian.com
この方法は v.7.7.1 では動かなかった.sexpr-wasm demo も s2wasm で作られた wast がそのままでは使えない.書き換えれば使えはしたが v7.7.1 で動かなかった.

Emscripten で変換する

Developer’s Guide - WebAssembly を参考にして導入する.
Main — Emscripten 1.37.3 documentation
latest ではなく incoming を使う.

$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install sdk-incoming-64bit binaryen-master-64bit
$ ./emsdk activate sdk-incoming-64bit binaryen-master-64bit
$ source ./emsdk_env.sh
$ emcc
INFO:root:(Emscripten: Running sanity checks)
WARNING:root:no input files
$ mkdir hello
$ cd hello
$ echo '#include <stdio.h>' > hello.c
$ echo 'int main(int argc, char ** argv) {' >> hello.c
$ echo 'printf("Hello, world!\n");' >> hello.c
$ echo '}' >> hello.c
$ emcc hello.c -s WASM=1 -o hello.html
$ ls
hello.c		hello.html	hello.js	hello.wasm
$ node -v
 v8.0.0-pre
$ node --expose-wasm hello.js
trying binaryen method: native-wasm
asynchronously preparing wasm
binaryen method succeeded.
run() called, but dependencies remain, so not running
Hello, world!

ここで生成された hello.wasm は動かしてみるのように読み込むことはできなかった.

> WebAssembly.compile( arrayBuffer ).then( ...
Promise { <pending> }
(node:92075) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): LinkError: WebAssembly.Instance(): Import #0 module="env" function="DYNAMICTOP_PTR" error: global import must be a number
(node:92075) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

どうやら main 関数があると動かないみたい.出力されたファイルをそのまま実行すると動きはする.Google Chrome Canary や Firefox Nightly も出力された hello.html では動くのだが動かしてみるのように読み込むと動かない.以下のようにオプションを指定すると動いた.だがこちらも main 関数があると動かない.この辺りはもうちょっと調べたい.

$ emcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -s 'BINARYEN_METHOD="native-wasm"' -o hello.wasm
$ ls
main.cpp main.wasm
$ node --expose-wasm
> const fs = require( 'fs' )
> const buffer = fs.readFileSync( 'hello.wasm' )
> const arrayBuffer = new Uint8Array( buffer ).buffer
...

動かしてみる のコードを使用して動かした結果はこうなった.

emcc hello.c -s WASM=1 -o hello.html

main 関数があってもなくても読み込めない.

emcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -s 'BINARYEN_METHOD="native-wasm"' -o hello.wasm

main 関数がなければ Google Chrome Canary,Firefox Nightly,Node.js v8.0.0-pre で動かせた.
最適化の -Os を抜くと読み込めなかったりとよくわからない.

Rust から変換する

Compiling Rust to WebAssembly Guide – Hacker Noon
結局は Emscripten と同じみたい.

fn main(){
    println!( "Hello World" );
}
$ rustc --target=wasm32-unknown-emscripten hello.rs -o hello.html
$ node -v
 v8.0.0-pre
$ node --expose-wasm hello.js
trying binaryen method: native-wasm
asynchronously preparing wasm
binaryen method succeeded.
run() called, but dependencies remain, so not running
Hello World

まとめ

Emscripten を使えば良さそうだけどよくわからなかった.調べる.

稲荷山登山チャレンジ(成功)

旅行

友達と京都旅行,伏見稲荷大社に行ってきた.以前来たときは時間がなくて本殿で引き返したのだけど今回は登ることができた.満足.夕方と翌日のお昼,合わせて二回登ったのだけど雰囲気が違っていて面白い.夜は本当に何か出そう.夕方から夜にかけては人も少ないし(暗くて危ないけど)いいかも.

きれいだった😆 #theta360 - Spherical Image - RICOH THETA
京都駅から稲荷駅までは JR の奈良行きに乗って二駅.近い.快速は停まらないみたい.初めは日も暮れかけていたので寄り道せずに登った.翌日は記録をとってみた.多少抜けはあるけどこんな感じ.これで歩いた距離は 7 キロらしい.

思い出というか,一度目は飲み物を買い忘れていて途中の自販機で買った.当然といえば当然なのだけど高い.飲み物は登る前に買った方がよさそう(当たり前)

翌日は参拝できるところは全て行こうと五円玉を三十枚ほど持っていったのだけど足りなかった.倍はいる.この日は休日で五円玉を作るのに京都駅近くのゆうちょでひたすら五円玉を引き出した.今思うともはや不審者だった.

手荷物は稲荷駅から本殿に向う途中,右手の参集殿にあるロッカーに預けた.駅のロッカーは全く空いてなかったけど,こっちはかなり空いていた.意外と知られてないのかも.

案内には山頂まで一時間と書いてあるけど,休まず歩いて 30 分くらい.思ったより近い.二回目はお参りしつつ,寄り道しつつだったので時間がかかった.登り始めたのが 11 時半,山頂に着いたのが 13 時半,本殿に戻ってきたのが 15 時で三時間半くらい.途中でご飯を食べたりお参りしたりで歩いたのは二時間くらいだと思う.

ところどころ寄り道するのが楽しい.力松社近くからいける清瀧はすごい.行ってよかった.ジブリに出てきそう.ただ帰りが登りできつい.
f:id:calmery:20170225034614j:plain
f:id:calmery:20170225012858j:plain
四ツ辻からは道が二つに分かれていた.どちらに行っても山頂に行くことはできる.だけどここは登ってきた方から見て右側の道に進んだ方が良さそう.まっすぐ行くと緩やかで楽かと思いきや最後にトドメを刺しにくる.鬼畜.ここを登るのは相当きつそう.

Post from RICOH THETA. - Spherical Image - RICOH THETA
楽しかった.また秋くらいに行きたい.春は花粉症で夏は暑い,冬は寒いし.秋くらいがちょうどいい.まあ人が多そうだけど.

伏見稲荷大社とは全く関係がないのだけど嵐山の トップページ|京都嵐山 鯛茶漬け専門店-鯛匠HANANA- で食べることができる鯛茶漬けがおいしい.本当においしい.お店が開く 30 分前に行ったからか待たずに食べることができた.あんまり遅いと待つことになるので早めに.というか予約しておけばいい.
f:id:calmery:20170225021237j:plain
友達と.わーい!すごーい!おいしー!

Post from RICOH THETA. - Spherical Image - RICOH THETA

npm installで起こるnode-gypのエラーの対処方法

NodeJS Memo

忘れそうなのでメモ.npm install すると node-gyp のエラーが出た.

$ npm install opencv

> opencv@6.0.0 install /Users/calmery/projects/opencv/node_modules/opencv
> node-pre-gyp install --fallback-to-build

node-pre-gyp ERR! Tried to download(403): https://node-opencv.s3.amazonaws.com/opencv/v6.0.0/Release/node-v51-darwin-x64.tar.gz 
node-pre-gyp ERR! Pre-built binaries not found for opencv@6.0.0 and node@7.1.0 (node-v51 ABI) (falling back to source compile with node-gyp) 
gyp ERR! configure error 
gyp ERR! stack Error: Command failed: /Users/calmery/.pyenv/shims/python2 -c import platform; print(platform.python_version());
gyp ERR! stack pyenv: python2: command not found
gyp ERR! stack 
gyp ERR! stack The `python2' command exists in these Python versions:
gyp ERR! stack   2.7.12
gyp ERR! stack 
gyp ERR! stack 
gyp ERR! stack     at ChildProcess.exithandler (child_process.js:211:12)
gyp ERR! stack     at emitTwo (events.js:106:13)
gyp ERR! stack     at ChildProcess.emit (events.js:191:7)
gyp ERR! stack     at maybeClose (internal/child_process.js:885:16)
gyp ERR! stack     at Socket.<anonymous> (internal/child_process.js:334:11)
gyp ERR! stack     at emitOne (events.js:96:13)
gyp ERR! stack     at Socket.emit (events.js:188:7)
gyp ERR! stack     at Pipe._handle.close [as _onclose] (net.js:501:12)
gyp ERR! System Darwin 15.6.0
gyp ERR! command "/usr/local/bin/node" "/Users/calmery/projects/opencv/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/Users/calmery/projects/opencv/node_modules/opencv/build/opencv/v6.0.0/Release/node-v51-darwin-x64/opencv.node" "--module_name=opencv" "--module_path=/Users/calmery/projects/opencv/node_modules/opencv/build/opencv/v6.0.0/Release/node-v51-darwin-x64"
gyp ERR! cwd /Users/calmery/projects/opencv/node_modules/opencv
gyp ERR! node -v v7.1.0
gyp ERR! node-gyp -v v3.5.0
gyp ERR! not ok 
node-pre-gyp ERR! build error 
node-pre-gyp ERR! stack Error: Failed to execute '/usr/local/bin/node /Users/calmery/projects/opencv/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/Users/calmery/projects/opencv/node_modules/opencv/build/opencv/v6.0.0/Release/node-v51-darwin-x64/opencv.node --module_name=opencv --module_path=/Users/calmery/projects/opencv/node_modules/opencv/build/opencv/v6.0.0/Release/node-v51-darwin-x64' (1)
node-pre-gyp ERR! stack     at ChildProcess.<anonymous> (/Users/calmery/projects/opencv/node_modules/opencv/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack     at emitTwo (events.js:106:13)
node-pre-gyp ERR! stack     at ChildProcess.emit (events.js:191:7)
node-pre-gyp ERR! stack     at maybeClose (internal/child_process.js:885:16)
node-pre-gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
node-pre-gyp ERR! System Darwin 15.6.0
node-pre-gyp ERR! command "/usr/local/bin/node" "/Users/calmery/projects/opencv/node_modules/opencv/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! cwd /Users/calmery/projects/opencv/node_modules/opencv
node-pre-gyp ERR! node -v v7.1.0
node-pre-gyp ERR! node-pre-gyp -v v0.6.32
node-pre-gyp ERR! not ok 
Failed to execute '/usr/local/bin/node /Users/calmery/projects/opencv/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/Users/calmery/projects/opencv/node_modules/opencv/build/opencv/v6.0.0/Release/node-v51-darwin-x64/opencv.node --module_name=opencv --module_path=/Users/calmery/projects/opencv/node_modules/opencv/build/opencv/v6.0.0/Release/node-v51-darwin-x64' (1)
npm WARN enoent ENOENT: no such file or directory, open '/Users/calmery/projects/opencv/package.json'
npm WARN a No description
npm WARN a No repository field.
npm WARN a No README data
npm WARN a No license field.
npm WARN In opencv@6.0.0 replacing bundled version of node-pre-gyp with node-pre-gyp@0.6.32
npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "opencv"
npm ERR! node v7.1.0
npm ERR! npm  v3.10.9
npm ERR! code ELIFECYCLE

npm ERR! opencv@6.0.0 install: `node-pre-gyp install --fallback-to-build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the opencv@6.0.0 install script 'node-pre-gyp install --fallback-to-build'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the opencv package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-pre-gyp install --fallback-to-build
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs opencv
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls opencv
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/calmery/projects/opencv/npm-debug.log

Windowsでnpm installしてnode-gypでつまずいた時対処方法 - Qiita によると

pythonも必要らしい。
そしてpython3.x系は未対応ということなので2.7系をインストールする。

ということみたい.

$ pyenv local 2.7.12
$ npm install opencv

> opencv@6.0.0 install /Users/calmery/projects/opencv/node_modules/opencv
> node-pre-gyp install --fallback-to-build

node-pre-gyp ERR! Tried to download(403): https://node-opencv.s3.amazonaws.com/opencv/v6.0.0/Release/node-v51-darwin-x64.tar.gz 
node-pre-gyp ERR! Pre-built binaries not found for opencv@6.0.0 and node@7.1.0 (node-v51 ABI) (falling back to source compile with node-gyp) 
  CXX(target) Release/obj.target/opencv/src/init.o
  CXX(target) Release/obj.target/opencv/src/Matrix.o
../src/Matrix.cc:335:59: warning: 'NewInstance' is deprecated
      [-Wdeprecated-declarations]
  v8::Local<v8::Object> actualBuffer = bufferConstructor->NewInstance(3...
                                                          ^
/Users/calmery/.node-gyp/7.1.0/include/node/v8.h:3288:31: note: 'NewInstance'
      has been explicitly marked deprecated here
                Local<Object> NewInstance(int argc, Local<Value> argv[]) const);
                              ^
...
                                                                   ^
/Users/calmery/.node-gyp/7.1.0/include/node/v8.h:3292:52: note: 'NewInstance'
      has been explicitly marked deprecated here
  V8_DEPRECATED("Use maybe version", Local<Object> NewInstance() const);
                                                   ^
2 warnings generated.
  SOLINK_MODULE(target) Release/opencv.node
  COPY /Users/calmery/projects/opencv/node_modules/opencv/build/opencv/v6.0.0/Release/node-v51-darwin-x64/opencv.node
  TOUCH Release/obj.target/action_after_build.stamp
  CXX(target) Release/obj.target/test_nativemat/test/nativemat.o
  SOLINK_MODULE(target) Release/test_nativemat.node
/Users/calmery/projects/a
└─┬ opencv@6.0.0 
  ├── buffers@0.1.1 
  ├─┬ istanbul@0.4.5 
  │ ├── async@1.5.2 
  │ ├─┬ escodegen@1.8.1 
  │ │ ├── estraverse@1.9.3 
  │ │ ├── esutils@2.0.2 
  │ │ ├─┬ optionator@0.8.2 
  │ │ │ ├── deep-is@0.1.3 
  │ │ │ ├── fast-levenshtein@2.0.6 
  │ │ │ ├── levn@0.3.0 
  │ │ │ ├── prelude-ls@1.1.2 
  │ │ │ └── type-check@0.3.2 
  │ │ └─┬ source-map@0.2.0 
  │ │   └── amdefine@1.0.1 
  │ ├── esprima@2.7.3 
  │ ├── glob@5.0.15 
  │ ├─┬ handlebars@4.0.6 
  │ │ ├─┬ optimist@0.6.1 
  │ │ │ └── wordwrap@0.0.3 
  │ │ ├── source-map@0.4.4 
  │ │ └─┬ uglify-js@2.7.5 
  │ │   ├── async@0.2.10 
  │ │   ├── source-map@0.5.6 
  │ │   ├── uglify-to-browserify@1.0.2 
  │ │   └─┬ yargs@3.10.0 
  │ │     ├── camelcase@1.2.1 
  │ │     ├─┬ cliui@2.1.0 
  │ │     │ ├─┬ center-align@0.1.3 
  │ │     │ │ ├─┬ align-text@0.1.4 
  │ │     │ │ │ ├─┬ kind-of@3.1.0 
  │ │     │ │ │ │ └── is-buffer@1.1.4 
  │ │     │ │ │ ├── longest@1.0.1 
  │ │     │ │ │ └── repeat-string@1.6.1 
  │ │     │ │ └── lazy-cache@1.0.4 
  │ │     │ ├── right-align@0.1.3 
  │ │     │ └── wordwrap@0.0.2 
  │ │     ├── decamelize@1.2.0 
  │ │     └── window-size@0.1.0 
  │ ├─┬ js-yaml@3.7.0 
  │ │ └─┬ argparse@1.0.9 
  │ │   └── sprintf-js@1.0.3 
  │ ├── resolve@1.1.7 
  │ ├─┬ supports-color@3.1.2 
  │ │ └── has-flag@1.0.0 
  │ └── wordwrap@1.0.0 
  ├── nan@2.5.0 
  └─┬ node-pre-gyp@0.6.32 
    ├─┬ rc@1.1.6 
    │ ├── deep-extend@0.4.1 
    │ ├── ini@1.3.4 
    │ ├── minimist@1.2.0 
    │ └── strip-json-comments@1.0.4 
    └─┬ tar-pack@3.3.0 
      ├─┬ debug@2.2.0 
      │ └── ms@0.7.1 
      ├── fstream-ignore@1.0.5 
      ├── once@1.3.3 
      ├── readable-stream@2.1.5 
      └── uid-number@0.0.6 

npm WARN enoent ENOENT: no such file or directory, open '/Users/calmery/projects/opencv/package.json'
npm WARN a No description
npm WARN a No repository field.
npm WARN a No README data
npm WARN a No license field.
npm WARN In opencv@6.0.0 replacing bundled version of node-pre-gyp with node-pre-gyp@0.6.32

出来た.

$ node
> require( 'opencv' )
{ version: '2.4',
  readImage: [Function: readImage],
  Point: [Function: Point],
  Matrix: 
   { [Function: Matrix]
     Zeros: [Function: Zeros],
     Ones: [Function: Ones],
     Eye: [Function: Eye],
     getRotationMatrix2D: [Function: getRotationMatrix2D] },
  CascadeClassifier: [Function: CascadeClassifier],
  VideoCapture: [Function: VideoCapture],
  Contours: [Function: Contours],
  TrackedObject: [Function: TrackedObject],
  NamedWindow: [Function: NamedWindow],
  ...
  FACE_CASCADE: '/Users/calmery/projects/opencv/node_modules/opencv/data/haarcascade_frontalface_alt.xml',
  EYE_CASCADE: '/Users/calmery/projects/opencv/node_modules/opencv/data/haarcascade_eye.xml',
  EYEGLASSES_CASCADE: '/Users/calmery/projects/opencv/node_modules/opencv/data/haarcascade_eye_tree_eyeglasses.xml',
  FULLBODY_CASCADE: '/Users/calmery/projects/opencv/node_modules/opencv/data/haarcascade_fullbody.xml',
  CAR_SIDE_CASCADE: '/Users/calmery/projects/opencv/node_modules/opencv/data/hogcascade_cars_sideview.xml' }