2009年10月17日土曜日

PythonのC++インターフェイスboost.pythonの使用例

少し前に、PythonのC/C++へのインターフェイス作成手段としてはctypesとboost.pythonが良さそうだという話を書いた。その後ctypesの使用例をメモった。

すでにCで開発されたライブラリがある場合にはctypesを使った方が楽だと思う。しかしC++や、あるいは自分でさらから書く場合にはC++を使いたいところ。場合によっては基本的にはC++で開発し、その後より楽に使用するためにPythonからも使えるようにしたい事もある。
そういう訳で、個人的にはPythonのC/C++インターフェイス開発にはboost.pythonが一番だと思う。Python自体に標準的に付随するものではない点だけが気になるところだが、とても簡単にC++のプログラムへのインターフェイスが作成できる。

というわけで、boost.pythonの使用例をメモ。

まず、C++で適当にクラスでも作る。ここでは簡単のためにsuffixarray.hhというヘッダファイルだけ。

// suffixarray.hh
#include <iostream>
#include <algorithm>
using namespace std;

class SuffixarrayCmp : binary_function<const int,const int,bool> {
protected:
    const wchar_t* _buff;
    
public:
    SuffixarrayCmp(const wchar_t* buff) : _buff(buff) {};
    bool operator()(const int x, const int y) const
    {
 return wcscmp(_buff+x, _buff+y) < 0;
    }
};

class SuffixArray {
protected:
    wchar_t* _buff;
    int      _size;
    int*     _idx;

public:
    SuffixArray() : _buff(NULL), _size(0), _idx(NULL)
    {};
    ~SuffixArray() {
 if (_idx != NULL) delete[] _idx;
    };

    bool construct(wchar_t* buff, const int size) {
 _buff = buff;
 _size = size;
 _idx = new int[_size];
 if (_idx == NULL)
     return false;

 for (int i=0; i<size; i++) {
     _idx[i] = i;
 }
 sort(_idx, _idx+size, SuffixarrayCmp(_buff));
 return true;
    };
    
    int getSize() const {
 return _size;
    };
};
このプログラムはC++として完全に独立していて、Pythonとは関係なくコンパイルもできるし利用もできる。wchar_t型(ワイド文字)の配列、要するに日本語文字列などを想定して、そのサフィックスアレイを作るもの。日本語は今はUTF-8を使う事が多いようだけど、メモリ節約にはなってもランダムアクセスには不便なのでwchar_tの配列とした。
また、私の使っているPython(2.5.4 on Debian GNU/Linux x86_64)ではunicode文字列はUTF-16で表現しwchar_t配列に格納しているようなのでそれに合わせたという意味もある。
そうでない場合に対応するにはテンプレートにでもしておけば良いのかな。そういう意味もあってヘッダファイルのみにした。

次に、これをPythonから使えるようにする必要がある。
construct()メソッドにはwchar_t*を渡す必要があるので、Pythonのunicodeからの橋渡しをする必要もある。
そのためのファイルがsuffixarray_py.cc。
// suffixarray_py.cc。
#include "suffixarray.hh"
#include <boost/python.hpp>
using namespace boost::python;

class PySuffixArray : public SuffixArray {
public:
    bool construct(PyObject* op) { // op must be a unicode object
 _buff = (wchar_t*)(PyUnicode_AS_DATA(op));
 _size = PyUnicode_GET_SIZE(op);
 return SuffixArray::construct(_buff, _size);
    };
};

int compare(PyObject* x, PyObject* y) { // x, y must be unicode objects
    wchar_t* xp = (wchar_t*)(PyUnicode_AS_DATA(x));
    wchar_t* yp = (wchar_t*)(PyUnicode_AS_DATA(y));

    return wcscmp(xp, yp);
};

BOOST_PYTHON_MODULE(suffixarray)
{
    class_<PySuffixArray>("SuffixArray")
 .def("construct", &PySuffixArray::construct)
 .add_property("size", &PySuffixArray::getSize)
 ;

    def("compare", compare);
};
PySuffixArrayクラスはSuffixArrayクラスのconstruct()メソッドをオーバーライドしているが、その中でPythonのユニコードからwchar_t*本体とサイズを取り出し、SuffixArrayのconstruct()に渡している。
unicode文字列の橋渡しもboost.pythonがやってくれるようになるとこんな面倒も必要ないのだろうけれど...
整数や普通の文字列の橋渡しはboost.pythonが面倒をみてくれるようだ。

BOOST_PYTHON_MODULEというところがPythonから見えるモジュールの定義。
大体見れば分かると思うが、suffixarrayモジュールの中にSuffixArrayというクラスを定義し、construct()メソッドをPython側からも見えるようにしている。
ここでsizeは「プロパティ」である。
実はadd_property()には三つめの引数を渡すこともできるが、その場合には
.add_property("pyname", &cplusclass::getter, &cplusclass::setter)

として、プロパティのgetter/setterを設定できるようになっている。setterを省略するとそのプロパティ(attribute)はread onlyとなる。
最後のcompare()は、クラスではなくC++の関数を取り込むためのもの。

これをコンパイルするわけだが、boost.pythonのチュートリアルだとbjamというビルドツールを使っている。実は以前、boost.pythonを触ろうとした時にそれが嫌で一瞬でやめてしまった事がある。
要するにmakeの代わりだが、最近はJavaだとAnt、boostだとbjamと、「進化」したビルドツールがよく使われるようになってきているようだ。
しかし、面倒くさい...
サブプロジェクトを含むようなプロジェクトのビルドだとか、そういうことのために色々進化しているらしいが、めんどい...
XMLみたいの書かされるのはとてもめんどいです...
あんなもの人間様が手で書くもんじゃないよね....ツール使う?それもめんどい...

ということで時代に取り残されている気もしないでもないけれど、馴染のmakeにした。
Makefileは個人的にあれこれしているので、ここでは実際のコンパイルコマンドがどうなっているかだけ。オプションもboost.pythonのコンパイルに必要なものだけ。
$ g++ -c -o suffixarray_py.o -I/usr/include/python2.5 -fpic suffixarray_py.cc
$ g++ -shared -o suffixarray.so suffixarray_py.o -lboost_python

これでsuffixarray.soというシェアードオブジェクトができる。

これをPythonから使うのはこんな感じ。
>>> import suffixarray as S
>>> s = unicode('これはぺんですがあれはぺんしるです。', 'utf-8') ## 文字コードは環境依存
>>> sa = S.SuffixArray()
>>> sa.construct(s)
True
>>> sa.size
18
>>> sa.size = 10
Traceback (most recent call last):
File "", line 1, in 
AttributeError: can't set attribute
>>> 
もしPythonからの使い勝手が悪ければ、ラッパークラスを作ってもいい。面倒なのでboost.pythonのレベルで解決した方が良さそうだけど。

なお、Pythonのunicodeオブジェクトはimmutableだが、こうしてC++に渡してあげると自由に変更できる。

Bloggerにコード片を載せる時に利用できるもの・・・?

ちょこちょことコード片を載せてきたけれど、なんだかpreタグだとかじゃうまくいかなかったりでとても嫌。
プリティファイしてくれないまでも記号類やインデントも込みでそのまま表示してくれる程度の機能は備わっているものなのだろうと思ったんだけど、GoobleのやってるBloggerにもそういう機能はないんだな・・・。他でブログ書いたこともないので他所にもあるのかどうか知らないけれど、まあ、コード片載せるなんて一般人からみたら極一部の少数派なんだろうから、きっとないんだろう(それともあるのかな?)。
が、こんな記事を見付けた。

ハイライトもGoogle流 - "google-code-prettify"でソースコードに色付けを


というわけで、この記事を参考にやってみる。ことにした。が、なんだか記事読んでもわかんない。
自前のウェブページじゃなくてBloggerでそれやりたいんだけど・・・

で、ぐぐってみるとそのやり方を説明してくれているサイトがあった。
しかもさっきのツールを一発でBloggerに追加してくれるリンクまである。ありがたい。
が、追加してみてもなんだか効いてないような・・・
ということで、そのページには前から困ってた<と>を変換してくれるツールもあったので、それだけ利用させてもらうことにした。

2009年10月12日月曜日

EmacsのWanderlustからGmailの読み書き(.foldersの設定)

メインのノートPCを常に持ち歩いていた頃には、メールは全てノートに取り込み、Emacsの中のGnusやWanderlustで読み書きしていた。
しかし今では主にGmailを使っている。
どこからでもケータイからでもアクセスできてとても便利だし、大きな不満はないのだが、一つ嫌なことが・・・
このブログの文章を書くのも同じだが、文章をブラウザで書くのがイヤ・・・
とても書き難い。文章のチェックすらする気にならない。

なので時々はEmacsで文章を書いてから貼り付けたりすることもある。

それで、いっそのことEmacsからGmailを読み書きできるようにしておくことにした。
ググると結構そんな話があり、メイラはMewかWanderlustと言ったところのようだ。
となれば以前使っていたWanderlustだという事で、ヒットしたブログなどを参考に久し振りにWanderlustの設定をした。

.emacsや.wlの基本設定などはヒットした内外のページを参考にすれば何の問題もなかった。

しかし.foldersが良く分からなかった。
特に、皆「受信トレイ」位しか見ていないような記述ばかりで、Gmailのラベルはどうすればいいのか・・・と。
なので一応メモっておく。こんな感じ。

%Inbox "受信トレイ"
%Gmailのラベル1 "ラベル1"
%Gmail label2 "ラベル2"
カテゴリ1 {
%Gmailのラベル3 "ラベル3"
%Gmail label 4 "ラベル4"
}
%[Gmail]/スター付き "スター付き"
%[Gmail]/下書き "下書き"
%[Gmail]/すべてのメール "すべてのメール"
%[Gmail]/送信済みメール "送信済みメール"
%[Gmail]/迷惑メール "迷惑メール"
%[Gmail]/ゴミ箱 "ゴミ箱"


「%Inbox "受信トレイ"」は、Gmailの「受信トレイ」をWanderlust上でも「受信トレイ」と表示するためのもの。
「%[Gmail]/スター付き "スター付き"」は、Gmailの「スター付き」をWanderlustでも「スター付き」と表示するためのもの。
「%Gmailのラベル1 "ラベル1"」は、Gmailの「Gmailのラベル1」という名前のラベルをWanderlust上では「ラベル1」と表示するためのもの。
「%Gmail label2 "ラベル2"」は、Gmailの「Gmail label2」という名前のラベルをWanderlust上では「ラベル2」と表示するためのもの。
カテゴリ1というのは、Wanderlustでフォルダをグループ化して名前を付け、入れ子表示するためのもの。

また、「[Gmail]/xxxx」というのは、自分で作ったラベルではなく、Gmailのシステム側が用意してあるxxxxというラベルという意味だ。Inboxだけは例外。Gmailの「設定-ラベル」画面で確認できる。

うっかりGmailに無いラベル名を指定するとwlで接続に行った時にGmail側にそういう名前のラベルを作ろうとするので注意。間違って作ってしまった場合にはGmail側で削除する。

もう一つ、Gmailのラベル名に":"(コロン)を使っていると問題が発生するので注意。
aa:bbbなんて名前にすると、.foldersに「%aa:bbb」と記述する事になるが、bbb上のユーザーaaと認識するようで、aaのためのパスワードを要求されたりする。

最後に、念のためメモ。
日本語ラベルを使っているが、.foldersの記述もEmacs(23)のデフォルトエンコーディングも全てUTF-8にしてある。Emacsの事なので、それにWanderlustの開発者は日本人だった気がするので、その辺りはうまくやってくれていそうだが一応注意。


キーバインドなど細かいカスタマイズをしないとまだ快適とは言えないが、とりあえずWanderlustで読み書きできるようになった。サマリーで"$"キーでマークするとそれがGmailのスターと同期もしてくれるし、ひとまずOK。細かいことは普通にGmailでやればいいし。

古いシステムにOpenSSH5.1を入れる

sshで多段ログインする話を書いてきたので、ちょっと脇道になるがその中で必要だったこともメモ。

homepc - (mansion LAN - the internet) - gw1 - gw2 - workpc

という環境下で、gw1, gw2, workpcにそれぞれsshでログインできる状態だった。
しかしgw2のsshクライアントのバージョンが古く、そのため-Yオプションが無いためtursted なXの転送ができずにXアプリが使えない状況だった。

そのためgw2にOpenSSH 5.1をインストールした。
もちろん自分のホームディレクトリ以下にインストール。
幸いgccは使えたので助かった。

OpenSSHのコンパイルに新しめのzlibとopensslも必要だったので、それらもインストール。
いずれもソースは手元のDebianマシンで

$ apt-get source zlib

のようにしてゲット。それらをgw2に持っていき、

$ ./configure --prefix=/HOMEDIR/local
$ make
$ make install

などとした。
順番はzlib, openssl, openssh。
OpenSSHのconfigureの時には

$ ./configure --prefix=/HOMEDIR/local --with-zlib=/HOMEDIR/local

とした。OpenSSLやzlibでも何かオプションが必要だった気がするけど、忘れた・・・試してエラーが出てくれば分かるはずだからいいか・・・

最後にPATHに/HOMEDIR/local/binを追加して完了。
というか、gw2、そろそろなんとかした方が・・・

sshでリモートからemacsclient

という訳で、sshで自宅から職場の強力マシンに入れるようになったし、rsyncで同期もできるし、Xアプリも使えるようになった。自宅にいるも職場にいるもあまり意識せずにほぼ同じ感覚で作業できるようになったわけだ。

しかしもう一つ。

作業の多くをEmacsの中で行なっているので、当然Emacsは常に立ち上げっぱなし。終了して起動し直す事なんて特に理由がない限りはない。当然職場PC上でもEmacsは常時起動しっぱなしだ。
で、自宅から職場PCに入って一番最初に起動するのもEmacsなわけだが、職場でやっていた作業の続きができない。diredでディレクトリを開いていたりファイルを開いていたり、shell-modeの中で何かやっていたり、Pythonその他を動かしている事もある。場合によっては時間のかかる処理を流しっぱなしにしている事もある。
その様子を見たり続きをしたいこともあるが、それにはまさにその、職場PCで動いているEmacsに入らないといけない。sshログインして別のEmacsプロセスを起動しても無理だ。

そこで思い出したのがemacsclinet。(以前はgnuclientという名前だったような気が...)

職場PCで使っているEmacsで M-x server-start とすると、Emacs serverが起動する。
そして自宅からsshで職場PCにログインしたら

workpc$ emacsclient -d localhost:10.0 test.txt

のようにすると、手元(homepc)でEmacsのウィンドウ(フレーム)が開いてtest.txtファイルのバッファが開く。そしてそれは職場PCで動いているEmacsと同じプロセスであり、当然他のバッファも見られるしその中で作業もできる。本当に中途半端な状態で職場を出て、その続きを自宅でしたり、あるいはその逆もできる訳だ。

なお、-dで指定しているのはXのディスプレイだが、サーバーEmacsと同じディスプレイの場合には既に開いているEmacsの中でtest.txtバッファが開く。今回のように別のディスプレイを指定すると、新たなフレームが開く。

指定したファイル(test.txt)のバッファをkill-bufferすると、emacsclient自身は終了する。しかしフレームは残るのでその中で作業を続けることは普通にできる。
が、先にフレームを閉じてしまいtest.txtのバッファをkill-bufferし忘れると、なぜかemacsclient自体は終了しない。起動時にファイル名を求めるというのはそういう意味だったのか...
まあプロセスを殺せばいいんだけど、ちょっとしっくりしない。

ちなみに、localhost:10.0 というのは、sshで入った時のこちら側に割り当てられたDISPLAYだ。試している限りでは、一段sshと二段sshでは自動で環境変数DISPLAYが正しく設定されているが、三段sshでは自動では":0.0"と正しい値が設定されていない。なので自分で

workpc$ export DISPLAY=localhost:10.0

のようにしないとXのウィンドウを手元に持ってこられないので注意。
また、"10.0"の"10"の部分はログイン状況によって異なるようだ。
一段・二段sshの時の値から推測すると、10あたりから順番に大きな数を使うようになっているようだが、この辺りの正式な説明は見付けられなかった。

なにはともあれ自宅から職場PCで起動しているEmacsに横入りして作業できるようになった。
普通のターミナル上でならばscreenでも使うところなのだろうが、Emacsメインの人間にとってはemacsclientの方が100万倍便利。

ただしEmacsでサーバーを起動しておかないといけないので、うっかり忘れないように.emacsに下のコード片を加えて自動で起動するようにしておいた。

(when (equal (getenv "DISPLAY") ":0.0")
(server-start))

sshの圧縮オプション

いちおう追加メモ。

前回sshで二台越しのログインをし、Xのウィンドウも表示できるようになった。Emacsなどはほとんどリモートと意識しないで使える。
しかし、例えばgimpなどのお絵描き系の場合、やはりマウスの動きに2テンポ位遅れる感じだ。まあ仕方ないだろう。

次に試しにリモートのLinux上のVMware(の中のVista)を使ってみた。
結果から言えば、あまりガシガシ使う気にはならないが、Wordで簡単な文書を書いたりPowerPointで質素なスライドを作る位なら十分使える。オートシェイプを入れたり動かしたりするのはやはりとても苦しいが。またウィンドウズの装飾的な表示効果はなるべく切っておいた方が良さそうだ。
とりあえず万一自宅や職場のウィンドウズ環境がおかしくなった場合の最後の逃げ場にはなりそうだ。

ただしこれはsshに"-C"オプションを付けて圧縮した上で転送するようにした場合のこと。
-Cオプション無しではとてもとても遅くて耐えられなかった・・・

2009年10月10日土曜日

多段sshとrsyncでデータの同期

boost.pythonの利用例をメモっておこうと思ったけれど、最近分かったsshのポートフォワーディングの使い方を先にメモしておく。
そういう機能があるのは知っていたものの、せいぜいsecureなrlogin程度の使い方しかしていなかった。しかし最近やはり使ってみたくなった。

元々自宅と職場を行き来する中で、自宅マシンと職場マシンでのデータの共有という問題があったのだが、これまではノートPCを持ち歩き、基本的にそれを媒介とすることで目的を果たしていた。
自宅や職場でそのノートとrsyncで同期をとるという方式だ。
しかし、次第にノートを持ち歩くのが億劫になってきた。
持ち歩き用のノートはB5の小さなものだから、それはメインの作業場ではなく、自宅や職場ではより速く大きなディスプレイのマシンがメインの作業場になっている。そうなると持ち歩き用ノートはもはやデータを運ぶためのものでしかない。
かつては自宅でも職場でも出先でも同じノートをメインにしてた事があり、その頃にはメールでもデータでもノートが母艦で、時々他のディスクやマシンにバックアップを取っていた。しかし、今ではメールも基本的にはweb上に置いてあり、ケータイからも読み書きできる。もうメールやWebチェックのためにPCを持ち歩く時代ではなくなっている。
出張その他どこかへ出掛けるのでない限り、もはやノートPCはデータ同期の媒介としてしか持ち運んでいなかった。
また、その目的ならば、もはやポータブルHDDや、大容量化してきたUSBメモリで充分だ。

ポータブルHDDやUSBメモリでも、やはり一々それらに同期してから持っていき、またそれから同期するのが面倒になってきた。
そこで、自宅と職場のPCの間で直接同期(rsync)したくなった。

自宅マシンから職場マシンへの三段sshでのログイン



ここで問題になるのが、自宅PCから職場PCへのアクセスだ。
もちろん、直接入れるようにはなっていない。
その間に二台のゲートウェイが挟まっている。それらをgw1, gw2とすると

homepc -(the internet) - gw1 - gw2 - workpc

という形だ。homepcは自宅のマンションLANの中でプライベートIPを振られているので外から直接アクセスすることができない。

この状況で、幸い(というか厄介事の種になっている訳だが...)gw1, gw2にもsshでログインする権利が与えられている。
ただし、インターネット側から直接はgw1にしか入れない。gw2に入るにはgw1に入ってそこからまたsshしないといけない。また、gw1からはgw2にしかsshできない。
gw2からはworkpcにsshで入れる。

workpcからは、gw1にもgw2にもsshで直接入る事ができる。ただしその他のポートには入れない。

こういう状況では、
homepc$ ssh gw1
でまずgw1に入り、次いでそこから
gw1$ ssh gw2
でgwに入り、さらにそこから
gw2$ ssh workpc
とすることで、自宅からworkpcに入ることができる。

しかしめんどい。
要するに三段越しのsshをしたいわけだが、少し調べると、こうすることで簡単に実現できることが分かった。

homepc$ ssh -t -Y gw1 ssh -t -Y gw2 ssh -Y workpc

ただし、gw1, gw2, workpcのパスワードはその順番で聞かれる。
(このあたりは設定で入力無しやパスフレーズを使うように変更できるようだが、今のところ面倒なのでノータッチ)

"-t"オプションは擬似端末を強制割り当てするものらしい。正直よく分からないが、これがないと文句を言われてしまう。
"-Y"オプションはtrusted X11 forwardingを有効にするもので、これを付けるとworkpcで実行しているXクライアントをローカルマシンに表示することができる。
ネット越しなのでいくらか遅いが、職場マシンのXクライアントを自宅でそのまま使えるのでとても重宝する。なお、-Yオプションは古いssh(私が使っているのはOpenSSH)ではサポートされていない。(untrustedな-Xオプションはあるようだ)

自宅マシンと職場マシンのrsync(三段ポートフォワーディング)



さて、これで自宅マシンから職場マシンに、間に二台のマシンを狭んでの三段sshで入れるようになった。
しかし目的は自宅マシン(homepc)と職場マシン(workpc)の間でのrsyncによる同期だ。

これにはポートフォワーディング機能を使う。
ネット上でも色々漁ってみたが、三段越しのrsyncというのはあまり見付からず、一段越しの例を参考にしてもなかなかうまくいかなかった。
正直sshの仕組みやオプションがよくわかっていなかった。今もそうだが。

結局、残念ながらコマンド一つではまだ実現できていないが、とりあえず次のようにすることでなんとか実現できた。

まず、三段sshと同じ要領で、ポートフォワーディングを三段繋ぐ。

homepc$ ssh -t -L 10022:localhost:10001 gw1 ssh -t -L 10001:localhost:10002 gw2 ssh -t -L 10002:localhost:22 workpc

これでworkpcにsshログインし、同時にhomepcのポート10022がworkpcのポート22(ssh)に、間の二台、gw1とgw2に中継されながらフォワードされる。
つまり、この状態でhomepcのポート10022に接続すると、それはworkpcのポート22に接続することになる。

この状態でhomepcとworkpcの間でrsyncを行なうには、次のようにする。

homepc$ rsync -avuSHx -e 'ssh -p 10022' /homepc/source/ localhost:/workpc/dest/

これで、homepcの/homepc/source/ディレクトリ以下がworkpcの/workpc/dest/にコピー(同期)される。実際にはいつも--deleteオプションも付けてソースにないファイルはデスティネーションからも削除している。
また、実際に行なう前に必ず--dry-runオプションを付けて削除される予定のファイルをチェックしている。
もちろん、引数の順番を逆にすればworkpcからhomepcにコピーすることもできる。

これで何も持ち歩かなくてもデータの同期を取ることができるようになった。しかもこれまでも、きっとできるだろうと思いながらやっていなかった、自宅で職場PCのXクライアントのウインドウを表示して使うことも可能になった。

というわけで、一応三段ポートフォワーディングの説明をしておくと、上記のフォワーディングでは、まず

ssh -t -L 1022:localhost:10001 gw1

の部分で、gw1にsshでログインし、homepcのポート1022がgw1の10001にフォワードされる。
localhost:10001とは、gw1から見たlocalhostという名前(or IP addr)のマシンのポート10001という意味で、localhostとした場合にはもちろんgw1自身だ。
そして、この後に続く

ssh -t -L 10001:localhost:10002 gw2

の部分でgw2にログインし、このコマンドが実行されるgw1のポート10001がgw2から見たlocalhostのポート10002にフォワードされる。
ここまでで、homepcの10022はgw2の10002にフォワードされたことになる。
そして最後に

ssh -t -L 10002:localhost:22 workpc

だが、これはgw2で実行される。そしてgw2のポート10002をworkpcから見たlocalhost、すなわちworkpc自身のポート22(ssh)にフォワードする。
これで、homepcのポート10022へのアクセスはworkpcのポート22へのアクセスを意味する事になった。
rsyncのオプションの

-e 'ssh -p 10022'

の部分は、rsyncでsshを用いそのsshでは10022ポートを用いよという意味だ。
結局rsyncへのパラメータである

localhost:/workpc/dest/

では、localhostの10022ポートを使うことになり、これはworkpcへのssh接続ということになる。

という訳だが、以上はあれこれ試行錯誤した結果の自分なりの解釈なので、間違いがあるかもしれない。一応自分なりに一貫した解釈ができるようになったので良しとする。

職場マシンからマンションLAN内の自宅PC(プライベートIP)へのsshログイン



さてさて、ここまでで一段落、どうにか目的は達成されたが、なんとなくポートフォワーディングの使い方が分かってくるともう少し欲が出てきた。
職場から自宅PCにアクセスしたい。

自宅はマンション内LANでプライベートアドレスを割り当てられているので、簡単にはそれはできない。ゲートウェイにログインできるわけでもない。
しかし、多分やってみればなんとかなるんだろうなとは思っていた。

で、上記のようにsshで自宅からgw1やgw2にリンクを張れるなら、それを職場PCから辿っていけばなんとかなるだろうと思って試してみると、案外簡単にできてしまった。

"-L"オプションで実現しているのはローカルフォワーディングと呼ばれるらしい。
今度は、homepcからsshでgw1に入り、これまでとは逆にgw1へのアクセスをhomepcにフォワードしたい。こういう方向のものをリモートフォワーディングと呼ぶらしい。

結論から書くと自宅のマシンで

homepc$ ssh -t -g -Y -R 10022:localhost:22 gw1

としておいた上で、職場で

workpc$ ssh -t -Y gw1 ssh -Y -p 10022 localhost

とすることで、目的は達成された。
なお、workpcからはgw1へもgw2へもsshで入ることができる。
もしgw2にしか入れなければ、自宅からはgw2まで継いでおけば良い。

勝手に切断されないようにする



最後に、sshのコネクションは、何もパケットが流れないと5分程度で自動的に切断されてしまうらしい。
これを防ぐのにも色々な方法があるようだが、面倒なのでターミナルの一つで

$ tload -d 100

としてそのまま放置することにした。実際ロードを見たいことは多いし。

結局一切~/.ssh/以下の設定ファイルはいじらなかったが、設定ファイルをいじればコマンドラインを簡略化できるらしい。
しかしコマンドラインで書けるものならそうする方が好きなのでこのまま。
ただしaliasで単純な名前を付けておくので、簡単に実行することができるようにはなっている。


ということで、間に挟まったマシンにsshで入れる事が必要だが、おそらく何段挟まっていてもこの方法で同期や双方向のログインができると思う。

2009年9月24日木曜日

Python ctypes からmecabを使う例

PythonとC/C++のインターフェイスとして有望だと思ったctypesとboost.python。
まずはctypesを利用する例。
もちろん自分でC/C++で書いた関数を呼び出すのでも構わないが、既存のCライブラリをPythonから利用したいというシチュエーションも多いため、まずはそういう例。

というわけで、形態素解析ソフトとして良く使われているmecabのライブラリをPythonから使えるようにしてみる。
ただし、実はmecabのPythonインターフェイスはmecabの開発元から配布されている事に気付いたので、ほんの触りだけ。
ctypesの使い方がなんとなく分かると思う。
要するにシェアードライブラリをそのまま読み込み、その中の関数を呼び出してくれる。
PythonとC間で引数や戻り値を正しくやりとりするために、必要に応じてその型情報を設定してやる必要がある。

ちなみにtext.txtには、インストールしてあるmecab用辞書に合わせて文字コードをUTF-8にした日本語文章が入っている。
他の文字コードの場合には適宜変換が必要になる。
また、unicode文字列を渡すことはできない。(segfaultになる)


import ctypes as C

MECAB_LIB_PATH = '/usr/lib/libmecab.so.1'
libmecab = C.CDLL(MECAB_LIB_PATH)
libmecab.mecab_sparse_tostr.restype = C.c_char_p
libmecab.mecab_version.restype = C.c_char_p
libmecab.mecab_strerror.restype = C.c_char_p

class MyMecab:

def __init__(self, option=''):
self.mecab = libmecab.mecab_new2('mecab ' + option)

def __del__(self):
libmecab.mecab_destroy(self.mecab)

def parse(self, text):
return libmecab.mecab_sparse_tostr(self.mecab, text)

def version(self):
return libmecab.mecab_version()

def error_message(self):
return libmecab.mecab_strerror(self.mecab)

if __name__ == '__main__':
filename = 'test.txt'
text = file(filename).read()
mecab = MyMecab()
result = mecab.parse(text)
print result

2009年9月23日水曜日

PythonとC/C++のインターフェイス開発の手段

手元のマシンにも4GBのメモリを入れ、もっと大きなメモリのデスクトップマシンも用意したが、その一番の理由は大規模なテキストの処理や行列演算などを行ないたいからだ。
行列演算そのものは、特異値分解(SVD)などの一般的なものがほとんどになるため、そのためのライブラリが必要になる。
さらに、できればC/C++でゴリゴリやるよりもスクリプトでやりたい。

それで、やはり馴染みのPythonとその数値演算用モジュールnumpyを使おうと思っている。
SVDをはじめ大抵のことはそれでなんとかなると思う。
しかし、中には自分で細かいところから書かなければいけない事もある。
numpyの良い点は、実際の計算のほとんどはC(Fortran?)で書かれた拡張モジュール内で行なわれるので、Python<->C間でのデータの受け渡しなどのわずかなオーバーヘッドがあるだけで、とても効率良く計算できることだ。例えば行列のかけ算などは実際にはそのすべてがCモジュール内で行なわれる。
しかし行列の要素の一つ一つに個別にアクセスするようなコードをPythonで書くと、その一つ一つでオーバーヘッドが生じ、実計算と比率として無視できなくなってくる。

ということで、やはり自分がやりたい計算はC/C++で書いて、それをPythonからシームレスに呼び出せるようにしたい。
そういう目的のための基本はPythonのCライブラリを利用して正規の拡張モジュールを作成することだろうが、リファレンスカウントなどの面倒も自分でみなければいけないとか何かと面倒っちい。
また、既に存在するC/C++のリソースを取り込むのも面倒だ。
幸い正規のモジュール開発方法以外にも、Pythonには様々なC/C++インターフェイス開発方法が用意されている。

その中で最終的に選択肢として残したのは、ctypesとboost.pythonだ。

ctypesはなんと言っても2.6で正規モジュールになり、2.5.xにもバックポートされていること、またPython3.xでも正規モジュールになっており、先々を考えても安心感があることが大きい。
さらにctypesの良い点は、既存のライブラリ(shared object)があれば、Cコードを書く必要がなく、Pythonサイドだけで方が付くという点だ。
もっともその分Python内でライブラリ関数の引数の型情報の設定などが必要だが。

boost.pythonは、C++のSTLの拡張とも言えるboostライブラリに含まれている。
boostはとても活発に開発されており、標準化の進捗と共にその一部はC++の規格自体に取り込まれるらしい。
そういう活発な開発母体があるので、Python 3.xにも対応するのではないかと期待している。
また、C++用ということもあり、C++のSTLや、もちろんboostのその他のライブラリも利用できるため、何かと便利だ。
で、実際に試してみたのだが、思っていた以上に簡単に使うことができた。
二つの点を除いては、もうこれが本命と言って良いと思う。
一つは、あくまでもPythonの外部から提供されているものであり、ctypesのようにPython正統のものではないこと。
もう一つは、いずれこの点も書きたいが、並列処理との兼ね合い。

ということで、ctypesとboost.pythonがお勧め。
サンプルはいずれ。

Debian GNU/Linux amd64で困ったこと

64ビット版でもほとんど何の問題もないが、若干i386にはあるがamd64には無いパッケージああるようだ。
例えばmozartがない。
$ apt-cache search mozart
とすると、mozart-docなんてのがあるのに、本体がない。

色々ググると、どうやらmozartは64ビット環境ではコンパイルできないらしい。ポインタのサイズとintのサイズが等しいことを前提とするようなプログラミングがされてしまっているようで、そこで問題が出ているらしい。
単純に -m32オプションを付けてコンパイルしただけではだめなのかな。
そのうちソースを持ってきて試してみたいが、そんなことだけでなんとかなるならもう誰かやっていると思われる。
CTMCPを読み進むのにmozartを使いたいが、いざとなったらVMwareの上に32ビット版でも入れようか...
chrootして32ビット環境を、なんて話もあるらしいが、そういうことやったことはないのでまた一調べしてからじゃないと試せないし、他には特にどうしても32ビットで使いたいものもないので、多分VMwareに落ち着くだろう。

そうそう、さすがにCore2Duo+4GBmemだとVMware上のVistaも快適快適。
CPUパワーは正義なり・・・

Linux 32ビット版と64ビット版の違い -- データサイズ

64ビット版のLinuxに移行しても、普通に使っている範囲では32ビット版との違いを意識する事はまずない。
しかし内部ではちゃんと変化がある。

末尾に付けたtest.cというファイルは、
$ gcc test.c
でコンパイルできる。そして実行すると
int = 4
int* = 8
void* = 8
long int = 8
long long = 8
short int = 2
float = 4
double = 8
char = 1
wcahr_t = 4
となる。

これが32ビット版のLinux上では
int = 4
int* = 4
void* = 4
long int = 4
long long = 8
short int = 2
float = 4
double = 8
char = 1
wcahr_t = 4
となるはずだ。

long longが4->8バイトになっている以外に、ポインタが64ビットになっている事が分かる。64ビットアドレッシングになっているからだ。
ちなみに、amd64(64ビット版)の上でも32ビット版としてコンパイルすることはできる。
$ gcc -m32 test.c
とすれば良い。
ただしシステム全体は64ビットで、ライブラリ等ももちろん64ビット版としてコンパイルされているので、-m32でコンパイルするにはlib32で始まる32ビット用パッケージをインストールする必要がある。
$ apt-cache search lib32
などとすればそれらしいものが見付かる。


# filename: test.c
#include < stdio.h>
#include < wchar.h>

int main()
{
printf("int = %d\n", sizeof(int));
printf("int* = %d\n", sizeof(int*));
printf("void* = %d\n", sizeof(void*));
printf("long int = %d\n", sizeof(long int));
printf("long long = %d\n", sizeof(long long));
printf("short int = %d\n", sizeof(short int));
printf("float = %d\n", sizeof(float));
printf("double = %d\n", sizeof(double));
printf("char = %d\n", sizeof(char));
printf("wcahr_t = %d\n", sizeof(wchar_t));
}

Linux 32ビット版と64ビット版の違い -- アドレス空間

というわけで今やメイン環境はDebian GNU/Linux x86_64(64ビット版)になった。

そもそも何故64ビット版に移行したのかというと、このノートもメモリが4GBだが、もっと多くのメモリを搭載したデスクトップマシンを使えるようになったが、その時にアドレス空間が32ビットという足枷を外したかったからだ。
Core2Duo(Pentium4位から?)には実は拡張が施されていて、32ビットモードでもアドレス空間だけは36ビットでアドレッシングできるらしい。
4GBというと丁度32ビットアドレッシングの限界なわけで、それ以上のメモリを積んでも扱えなくなってしまうわけだが、36ビットになって4ビット増えた事でその16倍、つまり64GBまでは扱えるようになっていたらしい。今度手に入れたデスクトップもさすがにそこまでのメモリは積んでいないので、32ビット版のLinuxでも良いのかも知れない。

が、実は32ビット版には、1プロセスでは2GBまでしか利用できないという限界もあるのだそうだ。さらに、実際のカーネルによるメモリ配置と利用法により、実際には2GBすら使えないらしい。
これまで使っていたマシンで最大のものでも2GBメモリだったので、そこまでを現実問題として考える事はなかった。しかしもはやノートでも4GB、そしてそれ以上のメモリが利用できるようになった。

そして64ビット版では、アドレス空間は64ビットに綺麗に広がり、1プロセスでの上限の壁も消えているらしい。
という事で、64ビット版に移行した第一の目的は、大規模メモリを無駄なく利用できるようにするためだ。

Linux x86_64 (64ビット版)

ふう、なんと先月は一度も書かなかった。やっぱ続かないな...
というわけで久し振りだけど、無理せず少しずつメモがわりに書いていこうと思う。
なるべくググってもあまり情報が見付からなかった事を中心に。

一時はVistaをメインにしてみようかなどとも考えてVista上にEmacsを導入したりC++コンパイラを入れたりとやっていたが、結局Linuxに戻ったという話。
しかし戻った先は64ビット版だった。

実は先月自宅メインマシンとすべくThinkPad T500を購入した。
IBMからlenovoに変わってからのモデルはちょっと敬遠していたが、他に移る先も見付からず、設計はまだ日本の大和らしいという事でThinkPadに落ち着いてしまった。
ディスプレイは1680x1050、WSXGA+という規格なのだそうだが、最近主流のワイドというのだろうか、横長だ。正直、横より縦が欲しいし、液晶の上、筐体としてはまだ余裕あるよなぁと思うものの、昨今の液晶パネル生産・供給事情というものもあるのかもしれない。
それでもこれだけ横があると、Gnomeのパネルを左右どちらかに縦にして置いて、そしてEmacsを二枚並べても余裕がある。これはいい。
そして今なら当然と言えば当然だが、自宅ノートでは初めてCore2Duo搭載マシンだ。
メモリもこの際4GBにした。
一昔前と比べるととにかく安い。これで12万ちょっとだった。
まだタマが入っていた頃のLet's note、あれはいくらだっただろう・・・CPUは何だっただろう・・・メモリは・・・ディスプレイは・・・・・・本当に隔世の間がある。
ハードディスクにしても容量が足りなくて、ext2に圧縮パッチを当てて自動圧縮して稼いでいたな。

それで、結局というかやっぱりというか、Debian GNU/Linuxに戻ってきたわけだが、この機に64ビット版に移行した。
Debianのディストリビューションには様々なプラットフォーム向けがあるが、フツーのPC、つまりIntelのPentium系列の場合には一般的に i386 というものが使われている。
しかしPentium4あたりからだったか、忘れたけれど、今のCore2Duoには64ビット拡張が施されていて、「64ビット版」として動作する。
ここでわざわざカッコ付きにしたのは、64ビット版ってどういう意味?というのをテキトーに流したかったから。何が64ビットだと64ビット版だとか議論し初めると、なかなか複雑な話になるようだ。
とりあえずは、レジスタも64ビット長になり本数も増え、64ビット演算もあるらしい。
マシンインストラクションの構成と構造も32ビットモードと64ビットモードで異なるらしい。

細かい事を考えなくても、今時のフツーのPCを使っていれば、i386版ではなく amd64 版のインストーラを使うだけで、何の問題も違いもなくインストール作業は終了する。
とりあえず lenny の amd64 用イメージをダウンロードしてCD-Rに焼き、最低限だけインストール(インストールの最後の方で聞かれる環境だのサーバー環境だの、そういうのも一切チェックを外して入れない)し、すぐに /etc/apt/sources.list を編集して sid にし、apt-get update, apt-get dist-upgradeを行なった。
その後リブートし、必要なパッケージを随時インストールした。

とりあえず見た目は32ビット版と何も変わらない。 uname -a とするとカーネルのバージョンに amd64 という文字列が含まれている位だ。

2009年7月18日土曜日

b-mobile 3GをLinuxで使いたいが、だめ・・・

150時間の通信時間が付いているb-mobile 3Gのhours 150というのを入手した。
USBコネクタに差して使う通信端末で、購入代金に通信料が含まれているため別途月々の料金は発生しないというものだ。150時間使い切るか使用期限の480日が来るまで利用できる。使い切った後は通信時間だけ買い足す事もできるそうだ。

普段は家や職場のネットワークを使えば良いわけだが、出先でも自分のPCでネット接続したい事がある。今のケータイではGmailも読み書きできるのでちょっとした事なら問題ないが、場合によってはファイルをアップロードしたりダウンロードしたり、あるいはそれに手を入れたりしたい事もある。そんな時のためにやはり接続手段は用意しておきたいと思っていた。しかし、使わなくても月々の固定費が取られるPHSやE-mobile、あるいはケータイのデータ通信プランを契約するのもなんだなと思っていた。そんなときに、端末購入代金に通信費も含まれるb-mobileというのを知った。というか、確か以前聞いたことがあったが、当時はあまり興味が湧かなかったものを再発見し、こっちの方がおもしろいかなと思い試してみることにした。実はE-mobileにしようかとも迷ったが、最終的にはこちらはFOMAの電波利用ということでドコモの圏内ならどこでもつながるという事でこちらにした。

それで、そのセットアップはとっても簡単だった。
まずは携帯から電話して開通手続なるものを終える。それから15分くらいすると実際に使えるようになるそうだ。
PCのセットアップも至極簡単。セットアップCD-ROMを入れ、数回クリックするだけだった。
このあとUSBコネクタに差し、認識してランプが赤から緑に変わったら準備OK、インストールされたb-アクセスというアプリのアイコンをダブルクリックして起動し、接続ボタンを押すだけだった。接続が確立すると緑のランプが点滅状態になる。速さは測定していないが、体感として、まあ普通にウェブブラウズするのなら特に問題はなさそうだ。

と、ここまではMS-Windowsの話。
Winで繋がればアクセス確保ということで一安心なんだが、できれば普段起動しているLinuxでも接続したい。それでネット上で情報を漁り色々と試してみた。

結論から言うと今のところ接続できず。
はじめはモデムとしてすら認識してくれなかったが、ネット上の情報を参考になんとかそれはクリアしたっぽいが、残念ながらモデムのATDTコマンドで発呼しようとするところで NO CARRIER となって失敗。
今のところその状態で放置しておく。ネット上の情報では、Ubuntuなどで使えているようなので、なんとかなできるんじゃないかとは思うんだが...
参考にした情報などは項を改めて。

2009年7月2日木曜日

メーリングリストって

さて、久し振り、なんてもんじゃないな・・・
ジムと同じで、調子良く通ってる時期には続くけど、一旦面倒臭くなってサボり初めるとズルズルとサボりが続くんですね、ブログって。
ちなみにジムは最近調子良く通ってます。ちょっと贅肉が気になってきたので・・・
もともと計算機の設定系の話で後々のためのメモ程度の積りで始めたので、特にそういう事柄もないと遠ざかるのは仕方ないんだけど。
でも最近、ブログってこれからの時代大事だよなぁ、やっぱ、と思うこともあり、巷に多い一言日記風でもいいからチョコマカ書いてみようと思う。といいつつ、書きはじめると一言では済まなくなって無駄に語数が増えていく・・・

それで、メーリングリストだけど、いや、メーリングリストどころかメールそのものについても、案外世の中の人はまだまだ知らなかったり充分に使ってなかったりするみたいだと気付いた。
メーリングリストなんて、結局のところ同時に多数の相手にメールを送れるってだけなわけではあるんだけど、使い方によってはとても効用の高いメディアだと思う。

その使い方というのが問題なわけだけど、基本はメーリングリストのメンバー(これは普通何か共通の興味・関心を持つ集団のはず)が興味を持つかもしれない内容について、あるいは、共有する事で全体の利益が向上する可能性がある内容について、とにかく情報を流し共有するのが第一だと思っていた。
(もっとも「情報量」の無いゴミメールばかり流してはそれはスパムと呼ばれてしまう...)

多くのメーリングリストでは、質問とそれへの返答というのがトラフィックのかなりの部分を占めているんじゃないかと思うけど、Q&Aだって共有するのがとても大事な情報だ。
その時点では興味を持っていなかったことだって、後になって自分も同じ問題に直面し、その時の回答を探して読むなんてことも普通にある。
メーリングリストシステムがアーカイブ機能を備えているのはそんな時のためでもあるだろう。
質問者と回答者が二者間だけでやりとりするのではなく、メーリングリストの中でやりとりすることで、直接そのやりとりに参加していないメンバーにも情報を与える事になる。結果的にコミュニティ全体の利益になる。

もう一つ大事なのは、(メーリングリスト内限定とは言え)オープンな環境で意見を交わし合う事だと思う。
そもそもが同じ関心を共有するメンバー達だから、誰かと議論している時に「横から」口を出してくる人もいるだろう。
議論が行き詰まっている時に、こういう「第三者」がつい軽視していた事実や可能性なんかに気付かせてくれる事もある。場合によっては、その内容についてより詳しい人がコメントしてくれる事もあるだろう。

結局、大事なのはオープンさと共有することだと思う。

ところが、これが嫌いな人もいるらしい。
プライベートな話という訳でもないのに、自分のメール(意見)が「第三者」の目に触れるのが嫌な人もいるようだ。
そういう人は大抵は自分の「意見」に反論されたり議論する事そのものが嫌なようだ。
質問や間違いの訂正を「ケチを付けられる」ことと感じていたりするようだ。場合によっては人格への攻撃とさえ受け取っていたりするのかもしれない。

そんな感覚だと、せっかくメーリングリストがあっても、事務連絡のための、それこそ同報メールシステムとしてしか使われなくなる。
正に道具は使い様。
ちょっと勿体無い気もするけれど、結局のところマインドの問題なので、どんなに技術が進歩しても有益な機能が増えてもどうにもならないのかなぁ、と思った。

2009年4月27日月曜日

Debian GNU/Linuxのptexでjsartilceなどを使う時のフォントの問題

久し振りにThinkPad T43のLinuxをゼロから入れ直した。
一度現時点の安定板であるlennyを入れてからtestingにdist-upgradeした。
いつも引っ掛かるのは、ptexでjsartilceやjsbookなどのクラスを使うとdvipdfmxでPDFファイルを作成する時にフォントのエラーが出る事だ。
毎度ネットを漁って解決法を探しては思い出すので、メモっておく。

Debian GNU/Linux squeezeで日本語TeX環境を用意するというブログを参考にした。

jsシリーズのドキュメントクラスを使った時にdvipdfmxでフォントのエラーが出て変換できない事への対処としては次のことだけ。(上のリンク先から引用)

/etc/texmf/dvipdfm/dvipdfmx.cfgの末尾に以下を加える。
f jis-cjk.map

Xming

かなり久し振り・・・
マメに書いてる人は凄いなぁ・・・

母艦のデスクトップでVistaを使うようになって、SKKIMEやkeyswapやkeyhacのお陰で文字入力についてはとても快適に過ごしてる。
おまけにNTEmacsとddskkとptexのお陰で文章書きもかなりLinux上と同様にできるようになった。
でも、やっぱり細かいところでLinuxというかDebianの快適さにはかなわない・・・
結局Windowsの上ってウェブで遊んだりOffice使ったり商用ソフト使ったりするのにはそれなりにいいんだけど、やっぱりEmacsを起点にしてプログラム書いたりあれこれいじるのはLinuxが一番か...

ということで、Linuxに戻ってもいいんだけど、実は母艦のディスプレイは24インチで新しいのに対してLinuxを入れてあるノートPCはそれなりに年数も経て結構画面が汚い・・・(母艦にも一応Linux入ってるけど)
Linuxでは基本的には背景はxplanetなどの暗い系だし、Emacsも背景は青暗くしてある。なのであまりディスプレイが暗いとか汚いとは思わないんだけど、背景が白いアプリ、ウェブブラウザも含めて、そういうのだと白が黄ばんで見える。特にデスクトップの24インチのやつの真っ白な綺麗さと比べると際立ってしまう。
ということで、ノートのLinuxを綺麗な画面(のVista)から使えるようにするために、VistaにXサーバを入れる事にした。

だけどcygwinは入れたくないし商用のサーバ買うしかないかなぁと思ったが、調べてみると他にもフリーのものがあった。
Xmingだ。
なんでも、X.orgをMinGWのコンパイラでコンパイルしたものらしい。

さっそく、上のリンクからXming-6-9-0-31-setup.exeとXming-fonts-7-4-0-3-setup.exeの二つをダウンロードしてインストール。

詳しい使い方は調べていないが、とりあえずインストールされた中の一つ、Xlaunchを起動して実行してみた。

まずはMultiple windowsというのを選択した。One windowだとルートウインドウのようなものも表示されてしまう。


















次にプログラムを起動するように指定。


そしてプログラム名とリモートのIPアドレスとユーザ名、パスワードを指定。


あとは二回ほど「次へ」をクリックで、無事起動できた。
当然Emacsを起動したが、普通に使える。
なかなかいい。

2009年3月31日火曜日

CherryPy Essentialのサンプルコードのダウンロード

随分久し振りになってしまったが、作業メモ。
と言っても結果的にはメモるほどのことではしてない。。。

しばらくの間一応Vistaを使っているので、CherryPyもVistaで動かしたい。
CherryPy Essentialsを読みながらちょこちょこ試すのもVistaでやろうと思う。
で、本を読みながらVistaにCherryPyをインストールした。
いつものようにEmacsの中のbashで

$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ python ez_setup.py

でEasy_installをインストールし、

$ c:/Python25/Scripts/easy_install-script.py cherrypy

でCherryPyの最新版をインストールした。途中"Can't process ..."とか出てたけど、とりあえず無視。一応インストールはできたらしい。後でサンプルを実行してみて問題があれば戻ってくることにする。

で、サンプルを試そうと思ったが、当然手で打ち込むなんて真似したくないので、CherryPy EssentialsのホームページからダウンロードしようとチェックしてみるとSubversionでの取得方法しか書いてないような。。。
仕方ないのでSubversionを入れてみようと思った、が、何かWindows用バイナリをダウンロードしようとすると、飛ばされたサイトでアカウント登録を求められたりする。。。
なんか嫌だし面倒になってやめてしまった。

結局Linuxを入れてあるノートのSubversionでダウンロードし、それをコピーしてきた。。。

Vistaはなかなか快適とは書いたが、その後Linux(Debian)も最新安定板のlennyをインストールし直して個人設定も整理して改めて比較してみると、やっぱりLinuxの方が快適だなぁ・・・
長年の個人設定の積み重ねやツール群への慣れもあるけれど、やっぱりLinuxの方がいい。
それに今回のSubversionもそうだが、Debianのaptでのパッケージ管理はやっぱり楽。楽過ぎ。バイナリをダウンロードしてクリックするだけでほとんど済むウィンドウズと比べても、やっぱり楽。安心。

ただどうしてもVista上でOffice 2007を使わないといけない都合もあるし。。。
という事で、とりあえずはこのままだけど、なるべく早いうちにLinux上のVMware Workstationがちゃんと動くようにして、その中に改めてVistaとOffice 2007をインストールし直そうと思った。

2009年3月1日日曜日

Vista環境その3 (Visual C++ 2008 Express Editionをbashから使う)

前回MinGWとその中のgccをインストールをしたは良いが、とりあえずg++は先延ばしにしておいた。MinGWのインストーラがg++で失敗するからだ。しかしCで書く事はほとんどなく、欲しいのはC++だ。なんとかしてMinGWのg++を入れようかと思ったが、やはりやめておくことにした。インストーラで成功しなかったのもあり、今後もちゃんとメンテされるのかに不安が残るし。それに、Windows上にLinuxと同じような環境を、とは言っても、そこまで無理する必要はない。cygwinもそうだけど。ちょっと無理矢理でしょ。win使うなら、まあ無理がないところからnativeなツールを使うようにはしたい。
Emacsとその中のbashとそこから使う基本的なコマンドはあまりにも頻繁に使ってきたので、それなしの環境は考えられないが。
という訳で、C++はMicrosoftのものを使ってみる事にした。
実はもう一つ理由がある。どのページだったか今探しても見付からなかったが、gcc, icc(Intel謹製コンパイラ)とVisual C++のパフォーマンスの比較をしてあるページがあったが、そこでVisual C++がとても速かったからだ。確か、Linux上のgccはもちろん、icc(on Linux)よりも速かったような。

ということでまずはMinGWとMsysをアンインストール。してもディレクトリや一部ファイルが残るのでそれらは自分で削除。その代わりwin用のbashのバイナリがあったところからリンクがあった、unix tools for windowsとかいうところのバイナリをいくつか入れた。この中にはmakeもある。実はMinGWのmakeはどうもいつも使っているGNU makeとは違う動きのようだった。こちらのmakeは大丈夫のようだ。

で、Visual C++ 2008 Express Editionをダウンロードしてインストール。
これはMicrosoftが無償で提共しているもので、他にもVisual Basic、Visual C#、Visual Web Developerがある。インストール・設定後に少し試してみたところ、STLはちゃんと入っている様子。ただしboostは無い。

これでGUIを作ったりIDEから使う気はあまりない。とにかくEmacsのshell(bash)から使えるようにしたい。
コマンドラインから、しかもbashからどう使えば良いのか、なかなかその手の解説は見付からないし、winの勘はないしで結構苦労したが、とりあえず~/.bashrcに次のような設定を加えることでbashの上からC/C++のファイルがコンパイルできるようになった。

VSINSTALLDIR="/Program Files/Microsoft Visual Studio 9.0"
VCINSTALLDIR="/Program Files/Microsoft Visual Studio 9.0/VC"
FrameworkDir="/Windows/Microsoft.NET/Framework"
FrameworkVersion=v2.0.50727
Framework35Version=v3.5
WindowsSdkDir="/Program Files/Microsoft SDKs/Windows/v6.0A"
DevEnvDir="/Program Files/Microsoft Visual Studio 9.0/Common7/IDE"

## **CAUTION** paths are separated by ";" in the following two
export INCLUDE="$WindowsSdkDir/include;$VCINSTALLDIR/include"
export LIB="$WindowsSdkDir/lib;$VCINSTALLDIR/lib"

export PATH="$WindowsSdkDir/bin":"$DevEnvDir":"$VCINSTALLDIR/bin":"$VSINSTALLDIR/Common7/Tools":"$FrameworkDir/$Framework35Version":"$FrameworkDir/$FrameworkVersion":"$VCINSTALLDIR/VCPackages":$PATH

visual c++のコンパイラのコマンド名は"cl"、リンカは"linker"だそうだ。これで


$ cl test.c





$ cl test.cc


とすればコンパイルできて、test.exeが作成される。ファイル内に日本語がある場合にはsjisにしておかないといけないようだ。Emacsの設定を変更しないと。

INCLUDEとLIBはclが参照する環境変数のようだ。名前の通り、インクルードファイルのあるディレクトリとライブラリ(DLL)のあるディレクトリを指すためのもの。
これは.bashrc内の設定だが、この二つはcl.exeというウインドウズプログラムにより参照されるという点を意識する必要があった。

bashでは、環境変数の、例えばPATHなどで、a, bという二つのパスを設定するには


PATH=a:b


のようにする。":"がセパレータだ。しかしwinではセパレータに";"を使う。
なので、INCLUDEには一つの文字列だけ設定し、その中にwinの環境変数として";"で区切った複数のパスを設定してある。bashのための設定としては普通こんな事はしない。

という訳で、とりあえずbashからVisual C++ 2008 Express Editionでコンパイルできるようになった。
C++でunixやwinに偏ったプログラムを書く気はないので、その範囲で使う分には恐らくこれで問題はないと思う。それにPythonなどこれまでインストールしてきたwin用のバイナリもほとんどはvisual c++でコンパイルしてあるようなので、むしろ相性は良いだろう。

あとはclやlinkerの細かいオプションを調べて基本的なMakefileを書いてしまうだけ。

そうそう、面倒なのでとても重要なもの以外はリンク張ってませんが、キーワードで検索すればすぐ見付かると思う。

Vista環境その2 (スリープ不調も)

Vista上にLinuxで使用しているものを整える続き。

・ガジェットにGchecker追加。Gmail通知用。その他設定変更で好みに。
・Mozart(Oz)環境導入。OZEMACS環境変数にemacsのパスを追加。

今更だが、winではほとんどのインストールはダウンロードしてダブルクリックするだけでできる。時々インストールパスいじったりインストール後の設定をいじったり。unixや初期のLinuxと比べれば楽といえば楽。しかしDebianのaptと比べると面倒に感じる。統一感にも欠ける。いっそaptのような統一された管理システムがあってもいい。

・keyhac導入。説明が少なく今一つ分からないなりになんとかキーバインド設定変更。Linux上でxmodmapでやっていることはほぼ完了。しかしCapsLockとCtrlキーの交換がうまくいかない。

Ctrlのようなモディファイアキーはどうやらキーコードの発生のさせ方が、デバイスの時点なのかwinがやっているのか分からないが、違うらしい。なのでコードだけ入れ変えても発生の仕方がモディファイアの様にならないためにうまくいかないように見える。今のところkeyhacでの解決法は分からない。仕方ないのでCapsLock<->Ctrlだけはkeyswapで変更し、その他はkeyhacで設定した。できればkeyhacだけでできるようにしたい。
また、ウィンドウ操作についてもサンプルにもウィンドウの単純な移動程度の例しかない。sawfishのように他のウィンドウにぶつかるまで移動するようなことがやりたいが、できないのかもしれない。ウィンドウの縦とか横とかへの最大化なんかの操作もやりたいんだが。今後の課題。

・うまくスリープできない問題の回避方法発見。USBメモリを抜いておく。

スリープを選んでもディスプレイは消えるが本体の電源は落ちなかったり、一度は落ちたようでもその瞬間にスリープから戻ってしまう状態が続いていた。BIOSのアップデートや設定確認、そしてネットも漁ってみたが解決できなかった。その原因がやっと分かった。
スペック的にあまり必要ないと思いながらもreadyboostのためにUSBメモリを本体裏面に差しっ放しにしてあったのをつい忘れていたが、USBメモリを差したままにしておくとスリープに入ってもその瞬間にまた立ち上がってしまう。抜いておけば問題なし。キーボードからのwakeupの禁止のようにデバイスドライバーの電源管理の項目で制御できるかと思ったが、プロパティにそんな項目見当たらず。仕方ないのでreadyboostは止めて、その他のUSBメモリも抜くよう気を付けるしかない。

色々やっているうちにディスクが足りなくなってきたので、パーティションを切り直し、Vistaのパーティションを拡げた。そのためにはLinuxパーティションを削除する必要があったので、削除し割り当て直した。データは全てバックアップしてあるので、Linuxも久し振りにインストールし直す事にした。Debian lennyがつい先日正式リリースされたばかりだし。

思いの外Vistaが快適だったので、Linuxで使っているものをどの位整えられるかと思って始めてはみたけど、やっぱDebianの方が快適…
フォント回りとかOfficeを使わないといけない事とか、いくつか問題はあるけれど、やっぱりDebian GNU/Linuxの方がいいなぁ…
どうしてもwin使ってないといけない事もあるので、一応継続してVista上でも大抵の事は困らないようにしておきたい。Linuxの時と同じキーバインドでEmacsとLaTeX,Pythonあたりが使えるだけでもかなり改善したが。