2014/01/21


ninja いままで「SCons とか gyp とか、なんで C++ のシステムに python 入れなあかんねん」とか「せっかく python 入れたのに windows でビルドするには cygwin 版が必要とかいい加減にしろ」とか色んな事があったのですが、ninja を使う事で悩みが解消するかもしれません。
Ninja, a small build system with a focus on speed

Ninja is a small build system with a focus on speed. It differs from other build systems in two majo...

http://martine.github.io/ninja/

如何にも外国人ウケしそうなプロジェクト名です。
ninja は chromium ブラウザの開発者が現行のビルドシステムに嫌気をさして作り始めたビルドシステムです。これまでちょっとしたファイルの変更であってもビルド開始までに10秒掛かっていたのが1秒以下になるとの事です。ninja のウリは高速であり、ゴールも高速。configure の様な依存から解決するのではなく、現行のファイル構成からソースレベルの依存情報を解決します。
主に以下の様な目標をかかげています。
  • 高速なインクリメンタルビルド
  • コードのビルド方法を記述する為のポリシーをなるべく小さく
  • 正しく依存を解決
ちなみに ninja は Windows でも簡単にビルド出来ます。mingw を使う場合は python bootstrap.py --platform=mingw とすればok。
ninja は build.ninja というファイルを読み込みます。記述方法は Makefile に似ています。
build.ninja には rule という形でコマンドを定義し、あとは依存関係のみを記述します。例えば Windows で foo.c から foo.o を作り、foo.exe を生成する build.ninja を書くとすれば以下の様になります。
cflags = -Wall

rule ld
  command = gcc $ldlags $in -o $out
rule cc
  command = gcc $cflags -c $in -o $out

build foo.o: cc foo.c
build foo.exe: ld foo.o
depfile にも対応しており、gcc -M と連携して簡単に依存関係が記述出来ます。 rule cc
  depfile = $out.d
  command = gcc -MMD -MF $out.d [other gcc flags here]
色んな所で速度比較が行われている様ですが、ninja の特徴はコマンドを実行してからビルドが開始するまでのオーバーヘッドの短縮にある様です。いずれ chromium のビルドに使われ始めるかもしれませんね。

使われ方は通常の Makefile の様に使うのも良いですが、メタビルドシステムと連携して使うと便利で、例えば gyp のジェネレータとして使う方法もある様です。
NinjaBuild - chromium - Using the Ninja build system - An open-source project to help move the web forward. - Google Project Hosting

Help me to solve this error [44/11153] CC obj\third_party\lzma_sdk\lzma_sdk.7zAlloc.obj FAILED: ninj...

https://code.google.com/p/chromium/wiki/NinjaBuild
Posted at by



2013/12/25


Golang ってネットワークを扱うのが凄く楽で色んな物が作りたくなるんだけど、いつも pubsub っぽいのが欲しくなって毎回作ってる気がしたので汎用的に扱えるインタフェースを作った。
mattn/go-pubsub - GitHub
https://github.com/mattn/go-pubsub
使い方は簡単で、まず subscribe 側はある型を引数に持つコールバックで Sub を呼び出す。 ps := pubsub.New()
ps.Sub(func(i int) {
    fmt.Println("int subscriber: ", i)
})
そして publish 側はある型を指定して Pub を呼び出す。 ps.Pub(1)
Pub された値と同じ型の引数を持つ subscriber のみがメッセージを受け取れるという仕組み。構造体も渡せるので複雑なメッセージ内容もOK。
ちなみに unsubscribe は Sub に渡したコールバック関数を Leave に渡すか、コールバック内で ps.Sub(func(f *foo) {
    fmt.Println("foo subscriber: ", f.bar)
    ps.Leave(nil)
})
この様に nil を与えると呼出中のコールバックが unsubscribe されます。 簡単に chat を作ってみました。 package main

import (
    "bufio"
    "github.com/mattn/go-pubsub"
    "log"
    "net"
    "strings"
)

func main() {
    ps := pubsub.New()

    l, err := net.Listen("tcp"":5555")
    if err != nil {
        log.Fatal(err)
    }
    log.Println("Listing", l.Addr().String())
    log.Println("Clients can connect to this server like follow:")
    log.Println("  $ telnet server:5555")
    for {
        c, err := l.Accept()
        if err != nil {
            log.Fatal(err)
        }
        go func(c net.Conn) {
            buf := bufio.NewReader(c)
            ps.Sub(func(t string) {
                log.Println(t)
                c.Write([]byte(t + "\n"))
            })
            log.Println("Subscribed", c.RemoteAddr().String())
            for {
                b, _, err := buf.ReadLine()
                if err != nil {
                    log.Println("Closed", c.RemoteAddr().String())
                    break
                }
                ps.Pub(strings.TrimSpace(string(b)))
            }
            ps.Leave(nil)
        }(c)
    }
}
やばい。簡単すぎる。
Posted at by



2013/12/06


この記事はVim Advent Calendar 2013 : ATND 7日目の記事になります。

2013年もあと少しです。今年も Vim に関する色んな話題が登場しました。
そして数多くの Vim plugin が今年も登場しました。
  • ステータスバーをスタイリッシュにするプラグイン
  • Markdownをプレビューするプラグイン
  • 正規表現をプレビューするプラグイン
  • ブラウザと通信するプラグイン
  • 補完プラグイン
  • 貴様!?まさか!
  • そのまさかだ!フハハハハハハ...
どれも凄い物ばかりでした。そして Vim 界においては日本人の活動が特に素晴らしかったと思っています。 k_takata さんの大活躍で多くのパッチが vim-jp より提出され取り込まれました。
何名かの方には Vim 7.4 のリリース後も動作検証に協力頂きましたし、Vim advent calendar 2012 は結局1年を通して記事をポストし続けてしまいましたし、vimrc読書会も毎週続けられ、Vim に関するイベントも多く開催されました。
個人的には9月に KoRoN さん、h_east さん、ytaniike さんとお好み焼きを食べに行った事も良い思い出になりました。ありがとうございました。

来年も Vim にとって良い年である事を切に願います。
さて、今年作られた Vim plugin、どれも良い物でしたが僕がいつも思う事はこんな事です。

Vim プラグインとは言え、作るからには人々の暮らしを豊かにしなければならないッ!
僕は Windows を良く使います。僕の Vim script 力で Windows ユーザを豊かにしたい、くじけそうになっている人を Vim で救いたい。モテたいと願っている青年達を Vim でモテモテにしたい。そう願って今年も新しいプラグインを作りました。
mattn/startmenu-vim - GitHub
https://github.com/mattn/startmenu-vim
StartMenu

CtrlPUnite で Windows のスタートメニューが扱えます。
これでいちいちマウスに手を伸ばしてスタートメニューをクリックし、ポチポチとツリーを展開したり検索語を入力していく必要もありません。

あえて日本語ロケールの名称で一覧していませんので、IME を使わず英名でマッチします(ショートカット名が日本語の場合は頑張って下さい)。これで Vim から Excel 等を簡単に起動出来る様になりました。
会社で Vim から Excel 起動したら、きっと同僚の眼差しも「センパイッ!すごい!」となるでしょう。
もっと豊かに、もっと豊かに...

そうだ...そうなんだ。僕のプラグインで便利になったのはプログラムの起動方法でしかないッ!Windows ユーザはそのランチャーから起動した Excel で設計書を閲覧するんだ!彼らの生活を豊かにする為には、Vim で Excel を開けなければならないんだァッ!!これはもう、Vim で Excel を見れる様にするしかない!!1
そう思って、もう一つプラグインを作りました。
mattn/excelview-vim - GitHub
https://github.com/mattn/excelview-vim
てっとりばやく言うと、Vim で Excel を閲覧出来ます。 :ExcelView Book1.xls で表示出来ます。シート番号を指定して :ExcelView Book1.xls 2 という開き方も出来ます(この辺は、今後もしかしたら変更するかもしれません)。
excelview1
こんな Excel ファイルであれば
excelview2
こう表示されます。
xlsx 形式(Excel 2007形式)のファイルしか読めないです。今後、もしかしたら CSV には対応するかもしれません。実行には webapi-vim が必要です。
ちなみに Pure Vim script の XML パーサでこんな事やってます。
let doc = webapi#xml#parse(xml)
let rows = doc.childNode("sheetData").childNodes("row")
let cells = map(range(1256)'map(range(1,256), "''''")')
let aa = char2nr('A')
for row in rows
  for col in row.childNodes("c")
    let r = col.attr["r"]
    let nv = col.childNode("v")
    let v = empty(nv) ? "" : nv.value()
    if has_key(col.attr, "t") && col.attr["t"== "s"
      let v = ss[v]
    endif
    let x = char2nr(r[0]) - aa
    let y = matchstr(r, '\d\+')
    let cells[y][x+1= v
  endfor
endfor
今の所、制限事項として 256x256 のデータしか表示出来ません。それ以上のデータを読み込むとエラーが発生します(改良の予定です)。

これでとても豊かになりました。ssh でサーバにログインしている開発者が Excel で仕様書を送りつけられても椅子を投げる事も無くなると信じています。

良い年末をお過ごし下さい。
Posted at by