03_08_01

お、八月。
先月はMozilla強化月間だったけど、あんまり何もしなかったな…
Mozillaもバージョン1.4越えたあたりからページによってはIEよりも速いような気がする。 まあ、Mozillaなんか使ったことねーよ。っていう人はぜひ一度お試しあれ。

何故Mozillaを使うべきかっていう僕の考えは先月分に書いてあります。


XUL、ネタはあるけど、「誰か既にやってるん違うかな。」っていうのが恐くて どうも取り掛かれない。まあ、実装方法がわからないっていうのもあるけど。
なんかドキュメントの量に対してXPCOMの量が圧倒的に多すぎるような気がする。
投げやりなAPIごとのドキュメントだけじゃなくて、もっと、 「〜するには〜したらいい」系ドキュメントがあればいいのに。って思った。

3億1600万までいった。ちょっと更新。ただ、2-1即死だった。
最近四描いてないな…というか、どうも思い付かない。どうしよう… 一回描かなくなると全然思い付かなくなる…

03_08_02

HTML正しくなったはず。IEでどう表示されるか確認してないけど。
ただ、CSS使うとw3mで見たときにセンタリングとか無くなって見にくいんだよな…


C++でごにょごにょ
#include <stdio.h>

template < class ValueT, ValueT min, ValueT max, template<class R> class RangeChecker >
class RangeValue
{
        ValueT value_;
public:
        RangeValue( const ValueT &val )
                :value_(val)
                {
                        RangeChecker<ValueT>(min,max).check( val );
                }

        ValueT getValue() const { return value_; }
};

template <class T>
class Checker
{
        T min_, max_;

public:
        Checker( const T &min, const T &max )
                :min_(min), max_(max)
                {}

        void check( const T &val ) const 
                {
                        if ( val<min_ || val>max_ ) 
                                throw val;

                }
        
};

template <class T>
class NoChecker
{

public:
        NoChecker( const T &min, const T &max )
                {}

        void check( const T &val ) const 
                {
                }
};

typedef RangeValue<int,0,3,Checker> RangeInt_0_3;
typedef RangeValue<int,9,10,Checker> RangeInt_9_10;

RangeInt_9_10 foo( const RangeInt_0_3 &i )
{
        printf("foo: %d\n",i.getValue());
        return 11;
}

int main()
{
        try {
                foo( 3 );
//              foo( 4 );
        } catch (int i) {
                printf("%d\n", i);
        }

        return 0;
}
実際使うかどうかわからんけど、こういうの考えるのは楽しい。

あと、
typedef template<int min, int max> RangeValue<int,min,max,Checker> RangeInt;

void foo(RangeInt<0,3> num){}
とかってやりたいけど、コンパイルエラーになる。
なんとかできないかな…

iostream使うとコンパイル時間がやたら長くなるので気軽に使えない。

03_08_06

本人も忘れかけてたmvmがどうなったんだろう。って 書かれてた から、久しぶりに引っ張り出していじってみた。

色々修正したいところがあったので、しばらくmvmについて書こうと思う。
卒研の資料にもなるだろうし。

とりあえず、以前から直そうと思っていたメソッドの検索部分を修正。
仮想関数テーブル実装するの面倒だなと思って取って付けたけど、 結局仮想関数テーブル実装したから削除する予定だった部分。
なんで残してたかっていうと、 別に消す必要無かったのと、ローダ(loader.c)を結構書きかえないといけないっていうのがあったから。
でも、ネイティブクラス書く時に色々面倒だったのでやっぱり削除。

とりあえず、あとちょっとバグ残ってるけど大体終わった。


あと例外の部分と、卒研がガーベジコレクタ良くするとかだったからその部分いじる予定。

03_08_07

ウかんむりとワかんむり。
ワかんむりのほうが偉い。
ワかんむりは漢字で書くと「ワ冠」。
名前に含まれる「冠」という文字に自身を包含させることにより、 再帰名前を実現することになる。
それに対し、ウかんむりのほうで思い付く漢字と言えば、「穴」とか「空」 とかその程度。
間違いなくワかんむりのほうが圧倒的に偉いのである。

ウかんむりの敗因は何なのか。
それはやはりウかんむりが無駄に点を持っているということだろう。
あの点がもはや取手にしか見えず、 そのことが冠らしさを表す冠度を下げてしまい、 もはや冠ではなく「蓋」として見るほうが現実的になってしまっているのだ。


自分自身をむやみに着飾ることは自分自身の価値を下げることになってしまう。


たかが漢字一文字だが、そういう、現代人が見失ってしまいそうな大切な何かを教えてくれるのである。

03_08_09


あー、やっぱこういうの描いてるのは楽しいな…


最近手のごまかし方がわかってきた。
よく見ると変だけど、ぱっと見大丈夫。多分。

ケツイがこのところひたすら死にパターン作ってるような感じで 同じとこで死にまくってたけど、なんとか久しぶりに5ボス行けた。
安定して一周クリアできるようにしないとな…

03_08_10

どうも0オリジンが体に染み付かない。
いや、理解できないのではない。forループとかは何の苦痛もなく書ける。
でも、例えば一時変数をふたつ作ったときに、
int t1, t2;
とかって書いてしまう。真のコード書きならば、無意識のうちに
int t0, t1;
と書くべきだろう。いや、別にどうでもええけど。
1000よりも1024のほうがちょうどな感じは体に染み付いてんだけど。

日本語変だな…


エスプガルーダ
かなり面白そうなんだけど。どうせ僕の周りでは誰もやらないんだろな…


mvm弄るとか言っといて何もやってないな


今からやるか…

03_08_14

長いこと休んだつもりだけど、3日しか休んでないんだな…
しばらくバイト行かないでいいみたいなのでもうちょっと更新できるか。

ケツイ、おとといは4回やって一回一周。今日は二回やって一回一周。大分安定してきたか。
stage2までノーミスでいけるようになったのが大きい。1.12億。


mvmに例外実装しようと思ったけど、やっぱりGCCというかC++の例外について調べることにした。
僕の考えだと、例外を実装するためにどうやっても実行時にスタックなりリストなりを 作ってそこに自分が通ってきたtryブロックの情報を残していかないといけないような気がするのだ。
しかし、

extern "C" void check() throw(); // わかりやすいように

void bar()
{
        throw "test";
}

void foo()
{
        check();
        try {
                bar();
        } catch ( const char *mes ) {
                check();
        }
}
このソースコードをコンパイルすると、
_Z3barv:
.LFB3:
        # basic block 0
.L2:
        pushl        %ebp
.LCFI0:
        movl        %esp, %ebp
.LCFI1:
        subl        $24, %esp
.LCFI2:
        movl        $4, (%esp)
        call        __cxa_allocate_exception
        movl        $.LC0, (%eax)
        movl        $0, 8(%esp)
        movl        $_ZTIPKc, 4(%esp)
        movl        %eax, (%esp)
        call        __cxa_throw
.LFE3:
        .size        _Z3barv, .-_Z3barv
.globl _Unwind_Resume
        .align 2
        .p2align 4,,15
.globl _Z3foov
        .type        _Z3foov, @function
;****************************************
_Z3foov:
.LFB5:
        # basic block 0
        pushl        %ebp
.LCFI3:
        movl        %esp, %ebp
.LCFI4:
        subl        $24, %esp
.LCFI5:
        call        check
.LEHB0:
        call        _Z3barv
.LEHE0:
.L4:
        # basic block 1
        movl        %ebp, %esp
        popl        %ebp
        ret
;****************************************
        .p2align 4,,7
.L10:
        # basic block 2
        decl        %edx
        je        .L6
        # basic block 3
        movl        %eax, (%esp)
.LEHB1:
        call        _Unwind_Resume
.LEHE1:
.L6:
        # basic block 4
.L7:
        movl        %eax, (%esp)
        call        __cxa_begin_catch
        call        check
        call        __cxa_end_catch
        jmp        .L4
こんな感じになるのだ。
****で囲った部分がfoo関数の実体(のはず)である。
おわかり頂けるだろうか。例外が起こった場合、catchブロック内、すなわち.L7へジャンプ しないといけないはずである。しかし、foo内で.L7のアドレスをどこかへ保存するなどと いうようなことは行っていないのである。
もし、本当にこれで問題無く動くのならばその方法を調べてみる価値はあるのではないだろうか。
例外が起こらない限り動的メモリ確保が必要無いとすれば、それって結構効率良いんじゃないだろうか。

で、6月は、これがどうやって実装されているかをlibstdc++のソースから調べようとしたのだが、挫折してしまっているので、 今回は例外テーブルから調べてみることにした。

下がその例外テーブルである。(一部抜粋)
	.section	.gcc_except_table,"a",@progbits
	.align 4
.LLSDA5:
	.byte	0xff	# @LPStart format (omit)
	.byte	0x0	# @TType format (absolute)
	.uleb128 .LLSDATT5-.LLSDATTD5	# @TType base offset
.LLSDATTD5:
	.byte	0x1	# call-site format (uleb128)
	.uleb128 .LLSDACSE5-.LLSDACSB5	# Call-site table length
.LLSDACSB5:
	.uleb128 .LEHB0-.LFB5	# region 0 start
	.uleb128 .LEHE0-.LEHB0	# length
	.uleb128 .L10-.LFB5	# landing pad
	.uleb128 0x1	# action
	.uleb128 .LEHB1-.LFB5	# region 1 start





わかんねーよ…

一応わかったこと。
  • GCCがバイナリデータ弄る時はdwarf2ていうのを使ってる。
  • で、それは dwarf2xxx.c ていうソース見たら若干説明載ってる。
  • 例外に関するコードはC++専用のではなく、どの言語からも使えるみたい。
  • gcc に -dA って付けたら生成されるアセンブラに色々コメントが付く。

03_08_16

今日もケツイ二回やって一回いけた。残二あったし。
そろそろ二週狙うか。でもボム無しっていわれるときついな…
あと、またしても大往生3億1600万。ここらへんが限界なのか…
それとやっぱり2-1即死。何故だ。



ぼーっとC++の例外どうなってんかなーって考えてたら、 Javaで例外扱う方法思い付いた。
っていうか何も問題無かった。難しいことも無かった。

まず、Java仮想マシンっていうのは仕様上現在のスコープがどのメソッドなのか っていうのを常に覚えておかないといけない。で、その都合上、仕様としては規定されてないけど、 多分自分の通ってきたメソッドのをオペランドスタックに積んであるはずなのである。
ていうか、mvmはそうなってる。
で、例外テーブルの情報はメソッド自身にくっついてるんだから、それを利用すれば何も問題無く 動くじゃん。って思って、今日実装した。動いた。
C++の例外は謎なままだが。

で、あとはインターフェースとswitch-case実装すれば、まあアルファバージョンにしてもええんではないかと思う。
それで適当にテストコード書いてGC遅いっていうデータをとって、卒研か。
ここでGC遅くなかったら卒研始まらないんだよな……そうなったら…どうしようか。



眠い時に描いたから明日後悔する。多分。

03_08_17

今日マウス新しくした。580円。
マウスよりもキーボード換えたいんだけど、キーボード全然壊れない。コーヒーこぼすか。


えーと、どうも昨日の書き方では全然伝わらなかったようで。
例外の実装について。


JavaからコンパイルされたアセンブリはC/C++からコンパイルされたアセンブリ と違って、自分でスタックフレームを作らないというのがあって、 その処理を仮想マシンの実装に任せてある。 定型処理であるフレーム構築をいちいちバイトコードで書くのは無駄だからとかそんな理由だと思うけど。
例えば、
class Nanika {
	int add( int i0, int i1 ) {
		int l0 = i0+i1;
		return l0;
	}

	void foo() {
		add( 1, 2 );
	}
}
ていうコードは実際の機械だと(最適化されないとして)
add:
	pushl   %ebp
	movl    %esp, %ebp       # フレームポインタ設定
	subl    $4, %esp         # 変数一つ分スタックを確保
	movl    -12(%ebp), %eax  # 第二引数(i0)
	addl	-8(%ebp), %eax   # 第三引数(i1)を足す
	movl	%eax, (%ebp)     # %ebp[0]が第一ローカル変数(l0)
	movl	(%ebp), %eax     # 戻り値
	addl	$4, %esp
	popl    %ebp             # ebp の値を戻す
	ret

foo:
	pushl   this
	pushl   $1
	pushl   $2
	call	add
	ret
大体こんな感じ。動作確認してないので間違ってるかもしれんが。ちなみに第一引数はthisっていうことにしといてください。
で、対してJava仮想マシンコードだと
add:
	iload_1                  # 第二ローカル変数をpush
	iload_2	                 # 第三ローカル変数をpush
	iadd                     # 二回pop → 加算 → 結果をpush
	istore_3                 # popしてその値を第四ローカル変数に格納
	iload_3                  # 第四ローカル変数の値をpush
        ireturn                  # スタックの先頭を戻り値としてリターン

foo:
	iload_0                  # this を push
	iconst_1                 # 1 を push
	iconst_2                 # 2 を push
	invokevirtual            # add 呼び出し
	return
こんな感じか。多分。

で、Java vmアセンブリなんか読めねーよっていう人も、とりあえず、上の本物アセンブリでは %esp, %ebpをいじってフレーム作ってるのに対して、下のJava vmアセンブリではメソッドの先頭、及び末尾で フレームポインタいじったりとかスタックポインタいじったりとかしてないことに注意していただきたい。

こうなってるおかげで、Java 仮想マシンでは、Java VMにおけるメソッド呼び出し、リターン命令である invoke, return, を実行する時にそのメソッドが使うフレームの大きさ(フレームポインタをどれだけ動かすか)を調べないといけなくなってしまう。
それで、仕方無いので、そのフレームの情報を持ったメソッドの情報をどこかに保存しておく(スタックに積んでおく)ことにして、 結果、例外テーブルはメソッドが持っているという仕様上、おまけとして例外テーブルの情報も一緒に保存 されているということになってしまうのである。
だから、アセンブリ上では実際の機械コードもJava VMバイトコードも同じことをしているように見えても、 Java VMバイトコードのほうはちゃっかり例外情報を保存するというようなことも行っているわけ。 (VMの実装によっては変わるだろうけど、ここではmvmの場合ね)

で、ここまで考えて昨日

「Javaの例外実装できたけど、あいかわらずC++の例外の実装はわからん」

って書いたんだけど、さすがに説明が足らなかったか…

03_08_18

3億1600万。またしても。
でも、今日はゲーセンじゃなくて家だったので進歩と言えるかと。
あと、stage4の列車地帯繋がった。あとは大砲か。無理。


線が汚いとか背景が無いとか構図が無いとか色が変とか 昔から思ってて何とかしたいんだけど、「練習しなあかんとなるとやっぱ面倒だな。 別に絵の道で食っていくことなんてありえないし。」 とかって思って結局何も上達しないままだ。
やっぱ、このへんが上手い人とそうでない人の境界なんだろう。

っていう話は昔書いたような書かなかったような。

03_08_19

あー、なんか眠い。
久し振りにエスプレイドやったら散々だった。


最近、autoconf automakeとかが便利だと思うようになってきたので自分の理解を深めるためにも その辺について書くか。

題して、
「なんとなくで覚える Auto tools」
まあ、autoconfとかの資料って長いのが多いので、短く、なんとなく理解できるようなのがあればいいなと思ったので。


まず、autoconfについて説明していくことにする。
というのもAuto tools達(autoconf とか automake, autoheader とかのこと)はautoconf無しでは仕事ができないからだ。

M4プリプロセッサについて理解してたほうがいいけど、別に知らなくてもだいたいは問題無いと思う。
でも、シェルスクリプトを理解していないのはかなり問題あると思う。


まず、適当にディレクトリを作って、そのディレクトリの中で
$ touch configure.in
$ autoconf
まあ、とりあえず動いて、configureファイルが作られてます。多分。
configure ファイルは空っぽなんだけど、これは cofigure.in が空っぽだったから。
まあ、 autoconf コマンドは configure.in をもとにして configure を生成するっていうことだけ覚えておくと吉。

Auto tools の約束として、何かのファイルを自動生成する場合、"何かのファイルの名前.in"っていう名前のファイルをもとに するっていうのがあるの。例えば、Makefileを生成する場合、"Makefile.in"っていうふうに。
(一応付け足しておくと、confiugre.in と、 config.h.in はその名前の規則は同じだが、他とは生成されかたが違う。)

で、空ファイルっていうのもつまらんので、configure.in に一行入れてみる。
AC_INIT
これで autoconf コマンドを実行してみる、すると、そこそこ長い configure が生成される。
で、この configure を実行。何も起こらない。configure.in に何も書いてないので当然なのだが。
とりあえず、これで動く configure が作れたのだ。嘘だと思う人は configure --help とかしてみると いい。感動の瞬間である。大きいことはしてないけど。とりあえず何か嬉しい。これまで謎だったconfigure はこの程度のことで作れるのである。「別に嬉しくない。」っていう人は多分僕とは相性が悪い。

さて、次は何をしようか。AC_INITが先頭にあるのはまあ定石である。何も考えないでいい。 それと同じような感じで、最後にAC_OUTPUTって書いとくことにしよう。何も考えなくていい。
configure.inファイルは AC_INIT で始まって、AC_OUTPUT で終わる。そういうものなんだ。多分。
AC_INIT
AC_OUTPUT
さて、そろそろ何かやろう。
まず、適当に foo.in ていうファイルでも書こう。本当に適当に。
@FOO@
これだけでいいか。
で、configure.inをこれまた適当に
AC_INIT

FOO=眠い
AC_SUBST(FOO)

AC_OUTPUT( foo )
としておこう。で、 autoconf; ./configure
AC_OUTPUTは何をするか。 引数で与えられた名前のファイルを作るのである。
AC_OUTPUT( Makefile )ってやれば Makefile ができあがるし、
AC_OUTPUT( src/nanika.c )ってやれば src ディレクトリの中に nanika.c っていうファイルができあがる。
もちろん勝手に生成されるわけではなくて、さきほど述べたとおり、 Makefile を作るためには Makefile.in がいるし、 nanika.c を作るためには nanika.c.in が必要になる。

今回の例では、foo.in は既にあるので、foo っていうファイルは無事生成されることになる。はず。

で、configureを実行したあと、fooを開いてみると、中には「眠い」と書いてあるはずである。
ご理解頂けるだろうか。configure.in シェルスクリプト内で定義されたある変数は AC_SUBST を用いることによって、 Auto Tools の変数(@xxx@てやつね) として用いることができるようになるのである。

autoconf, configureの基本はまさにこれなのである。xxx.in というファイル内の @xxx@ という変数が configure スクリプトによって何らかの文字列に置換され、その結果が xxx というファイルに吐き出される。 それだけのことなのである。

で、続きは次回。四回ぐらいは書けたらいいなと思う。

参考
autoconf and automake入門
前も紹介したと思う、INOUE's Home Pageの中の autotools に関する話の部分。ここに書いてある分を理解すれば実用で困ることは無いかと。
あと必要な場合はどっかのソースのconfigure.inからコピペすれば。

03_08_21

ガラ婦人と戦ってたら、なんかギャラリーが
「小林幸子、小林幸子」
って解説してた。
「ギャラリー邪魔」って始めて思った。


昨日は寝てしまった。11時くらいに。
で、今日起きたのが11時くらい。

どっちにしても11時まで寝るんだから、夜更かししたほうがお得なんだよな…


なんとなくで覚える Auto tools(2)
   〜Auto tools達っていう表現は間違いじゃないのか〜

では、Makefile.inを書くことにする。
(実際にMakefile.inを書く時にはautomake使うけど、他に例を思い付かなかったので)

まずは、Cコンパイラをどうするかを決めないといけない。
Makefile.inに
CC=@CC@
とでも書いておいて、configure.inに、
if test -z $CC    dnl CCが特に決まってなければ
then
	CC= gcc
fi
AC_SUBST(CC)
とでも書いておくか…
しかし、本当にデフォルトコンパイラはgccでいいのか?gccじゃない場合はオプションとか同じでいいのか?
とかの問題が出てくる。
まあ、本気でスクリプト書いて対応するというのも良いが、何か無駄な気がしてならない。
でどうすればいいか。

なんと、
AC_PROG_CC
とだけ書いておくだけでいいのである。
面倒なことは大体やってくれる。
これによく似たものにAC_PROG_CXX(c++コンパイラ), AC_PROG_CPP(Cプリプロセッサ)とか、色々ある。
どれもオプションとかも調べてくれる便利なものだ。


話は変わってconfig.hについての話。
configureはconfig.hの自動生成を行ってくれる。
どのヘッダファイルが足らないか、どのシステムコールが実装されてないか、等の 面倒なチェックを数行書いておくだけで行ってくれる。

しかし、これが便利な機能かといえば、全然そんなことないのである。
例えば、ライブラリが見つからなかった場合どうするか、そこから先はconfigureは面倒見てくれない。
ライブラリの場合はまだましだ。「ライブラリをインストールしてください」とかのエラーメッセージを 出せばいい。
しかし、システムコールが無い場合どうするか。代わりになるシステムコールを使うか、 そのシステムコールを使う機能を使用不可にしてコンパイルできるようにするか。
これを考える為には各Unixのバージョンとか種類とかを把握して、どのシステムではどのシステムコール が足らなくて、代わりにどのシステムコールを使わないといけないか等の膨大な知識が必要になってくる。
特にLinux使ってる人はほとんどのシステムコールが実装されてしまっている為、 こういった知識はゼロから覚えなおさないといけないだろう。(実際僕はこの辺のこと全然知らない)

で、まあ、実際autoconf使ったからって何かが便利になったりするわけではない。っていう話。
いや、"何が足らないか"を探すだけならば便利なんだけど。


とりあえず、使いかただけ。
まず、どこかに
AC_CONFIG_HEADERS(config.h)
と書いておく。引数は使うファイルの名前。何でもいいけど、伝統的に"config.h"で。
んで
AC_CHECK_HEADERS(unistd.h sys/types.h)
AC_CHECK_FUNCS(dup2 ipc)
とかってどこかに書いておく。すると、それぞれヘッダとかシステムコールとかが存在するかをチェックしてくれるわけ。

ちなみに、この情報はconfig.h.inをもとに生成されるのでconfig.h.inを用意しないといけない。
が、autoheaderというツールを使うと自分でconfigure.inを調べて、必要なconfig.h.inを 自動生成してくれるのである。便利。
$ autoheader
$ autoconf
これだけ。
それから、Xの拡張のようなものを調べたいときは、
dnl * AC_PATH_XTRA
dnl 
dnl    Xlib のヘッダとかライブラリのある場所を調べて、
dnl   それぞれ X_CFLAGS X_LIBS に結果を入れといてくれる
dnl

AC_PATH_XTRA

LIBS="$LIBS $X_LIBS -lX11 -lXext"
AC_CHECK_FUNC( XShmQueryVersion )
とかのようにして、ライブラリがリンクされるようにしておかないといけない。
そうでないと、リンクに失敗して、その関数は存在しないことにされてしまう。


autoconfについてはこんなもんか。
あとは自分で書いたプログラムなんかに適当にconfigure.inを書いてみて、 わからない部分が出てきたら誰かが書いたconfigure.inを参考にしたりすれば特に問題無いかと。

次回はautomakeで


参考
autoconfのinfo
日本語

リファレンスなんで適当に読んでも全然理解できないはず。
他人のconfigure.in読んでてわからないマクロが出てきた時に使うのがいいかと。
Emacs使いな人はM-x info m autoconfから直接どうぞ。

03_08_22

#include <stdio.h>
#include <asm/msr.h>

#include <unistd.h>
#include <fcntl.h>

#define LEN (1024*1024)
#define FNAME (argv[1])

int main( int argc, char **argv )
{
	volatile unsigned int before, after;
	int i;
	char a;

	FILE *f = fopen( FNAME, "r");
	int fd;

	fd = open( FNAME, O_RDONLY );

	rdtscll(before);
	for ( i=0; i<LEN; i++ ) {
		read( fd, &a, 1 );
	}
	rdtscll(after);

	printf("read: %u\n", after-before);
	
	rdtscll(before);
	for ( i=0; i<LEN; i++ ) {
		getc( f );
	}
	rdtscll(after);

	printf("getc: %u\n", after-before);

	fclose( f );
	return 0;
	
}
で、結果がこれ。
read: 529828303
getc: 748101128
stdioってキャッシュしてるからgetc速いと思ってたのに…。
一文字ごとにシステムコールって遅いと思ってたのに…。
今のOSのファイルシステムはそれだけ偉いっていうことか。

WindowsのFileReadはどうなんだろうか。試せばいいんだけど、面倒だし。
実際どうでもいいし。



なんか書くのつらくなってきた第三回
とりあえず四回って書いたから四回分は書こう…他にネタも無いし。

Autoconfが結局のところ大変な苦労を要するっていうのは昨日書いたが、 Automakeは全然そんなことなくて、適当にMakefile.am(AutomakeにMakefile.in吐かせるためのファイル) 書いておけば 非常に便利なMakefile.inを自動生成してくれるという便利なものだ。
いわゆる、「make install」というやつはAutomake使えば何も考えなくても勝手に使えるとか非常に便利だ。
Makefile.am 書くのもややこしいことをしないのであれば非常に楽だ。
bin_PROGRAMS= sample
sample_SOURCES = sample.c
最低限必要なのはこの二行だけである。
簡単に説明しておくと、bin_PROGRAMSっていうのが作るファイルの名前を、 sample_SOURCESっていうのが sample を作るのに必要なソースを定義する為の変数。
bin_PROGRAMS= foo bar

foo_SOURCES= foo1.c foo2.c
bar_SOURCES= bar1.c bar2.c bar3.c
こんな感じ。詳しくはリファレンス見てください。

さて、これで完了。と、したいが、いくつかしなければならないことがある。
まず、configure.inに
dnl * AM_INIT_AUTOMAKE
dnl
dnl    AUTOMAKE初期化の為のマクロ
dnl    引数は
dnl         (パッケージの名前,バージョン)
dnl    で

AM_INIT_AUTOMAKE(sample,0.0.1)

dnl * AM_CONFIG_HEADER
dnl
dnl    AC_CONFIG_HEADERではなくて、こっちを使わないといけない
dnl    やってることはAC_CONFIG_HEADERと同じだけど、
dnl    依存関係の為のタイムスタンプ残してるみたい

AM_CONFIG_HEADER(config.h)

AC_OUTPUT(Makefile)  dnl Makefile.in から Makefile を生成
と追加、修正して、シェルから
$ aclocal
$ automake -a
を実行。

aclocalはAutomake用のマクロをAutoconfから使えるようにするもの、
automake -a はAutomakeが必要とするツールをカレントディレクトリに追加するものだ。

さて、これで完了。あとは automake を実行するだけ。のはずだが、 automakeには 'NEWS', 'REDME', 'COPYING', 'ChangeLog', 'INSTALL', 'AUTHORS'等の 説明書が無い場合には利用できないというよくわからない制限があって(--foreignオプションで無効にできる)、 今の状況ではAutomakeが利用できない。(ちなみに、COPYINGだけは automake -a で自動で GPL をくっつけてくれるので 必要無いけど…GPL嫌いな人は注意。)
でも、これらは空ファイルでも別に構わないので、 $ touch NEWS とかで適当に。
で、
$ automake
$ autoconf
でエラーが出なければ完了。
ここで生成されるMakefileは相当賢いので、configure.inが変更されればautoconfやりなおしてくれるし、 Makefile.am変更されればautomakeからやりなおしてくれる。

さらに、自分でMakefile書いたときに面倒なサブディレクトリなんかもお手軽。
なんだけど、また次回。


乳酸について一応調べてみたらこんなのが。
乳酸はただの疲労物質ではなかったのか。へぇー。

03_08_24


なんていうか、「ピコーン」って書きたかったので。

夏休みも少しか…。大学生は9月一杯まであるんだよな。 別にどうせ学校行っても行ってなくても何も変わらないと思うけど。


AutoMake 最終回
→面倒なのでリファレンスとか見て調べてください。




生活リズム悪い。
午後10時過ぎたくらいに目が覚めてくる。

03_08_25


意味無し。こういうのは描いてる人だけが楽しい。
あんまりこういうのばっかり出してると、

「昔のほうが面白かった」

とか言われそうだが(誰に?)、 二年前のとか 去年のとか見たら、 昔からこの程度っていうのがわかるかと。別に退化してるわけではないです。
進化してないというのもどうかと思うが。

でも、まあやっぱり自分で面白いと思ったやつの次からっていうのは 「自分で面白いと思う境界線」みたいなのが高くなってるので、 どうもやりにくいというか、何か思い付いても
「僕だったらもっと面白いのが描けるはずだ」
みたいな変な自信が付いてしまって、で、結局何も思い付かないで自己嫌悪になって、
「あぁ…駄目だ…」
みたいな感じ。

で、何が言いたいかっていうと、別に言いたいことなんかなくて、ただの愚痴。

で、あんま関係無いけど、昔の見てたら、これ が面白かった。自分で言うのはどうかと思うが。

もう昔のだから説明しても許されるだろう。
これ、「受話器ずっと持ったままだから電話繋がるわけないやん。」っていうネタなんだが、 どのくらいの人が理解してくれただろうか。一人いれば十分だと思ったのだが、ひょっとしたら 殆どの人が理解してくれてるのかもしれない。

もし、大半の人が理解できていたであれば、今後こういうネタを思い付いたときに
「こういうのは大丈夫なんだろうか」
って悩まなくて済むのだが。どうなんだろう。

03_08_26

さて、毎日「J」をHTMLソースレベルまで熟読しているファンの方々(そんな人いません) はお気付きだろうが、昨日なんとなく思い立ってUser-Agent取ってみることにした。

「先月Mozilla推しまくったからきっとみんなMozilla使ってるだろーなー」
「むしろ、ここんとこMSBlastとかSobigとかMDACとかDirectXとか色々あったからむしろWindowsやめてんじゃねーかなー」

なんて思いながら、結果見てみると、まあ、なんていうか、予想通りというか、僕以外Mozilla使ってなかった。


IEのほうがMozillaより優れている点
最初からある
色々インストールしないでも動くしね。便利だよね。
あんまりバージョン上がらない
「IEしょっちゅうバージョン上がりすぎ」とかいうけど、mozillaに比べたら少ないしね。いいよね。
起動が速い
エクスプローラとコンポーネント色々共有してるしね。常に半分起動してるようなもんだしね。いいよね。
メモリ消費が少ない
上と同じ理由でね。mozillaは32MBな環境とかじゃ動かすの嫌だしね。
HTMLあいまい解釈が賢い
HTML大体合ってたら表示されるしね。
(でも最近mozillaでは見れないところってあんま聞かないような…)

そうだ、Mozilla FireBirdにしよ。メーラーとか使わないしな…

と、思ったらglibc-2.3要求された。どうしようか。今のままでいいか。



ああ、最近こいつ出番多いな…

03_08_27

眠い。

sylpheedのメニューのところに 「高度な操作」ってあるんだけど、その内容は「一文字進む」とか「一文字戻る」とか、そういうの ばっかりなので、どういった経緯でこうなったんだろうか。とか思った。



火星ネタで描こうと思ったけど何も思い付かなかったので。
色々駄目だなぁ…。

03_08_29

寝よう。
ていうか、今日は四を七つくらい思い付いて三つ描いてみたけど、 どれもあまりにひどいので、まじへこみ。閉鎖だ。閉鎖。

大往生調子悪いけど、ブラックレーベルだと調子良い。
二週だと2-4で4億ちょっと。一周だと3.9億で緋蜂2/3ぐらいまで。先は長い。