bcc32 putty.c

patch -Np1 < puttykj.patch
patch -Np1 < puttyjp.patch
patch -Np1 < putty-imefix.patch # 行番号が変わってたので手動で。

make -f makefile.bor
# iso2022.c でなんだかエラー。不正な初期化とかなんとか。
<調査中>
「WCHAR a = { buf2, 0 };」が悪さをしていました。こんな初期化を認めていないのがBorlandだそうな。仕方が無いので、「WCHAR a = { 0, 0 }; a[0] = buf2;」とワンクッション入れます*1。これを3箇所(マクロ内とその後のCASE文に2箇所)訂正してもう一度困憊る。

わーにんぐが大量に出るが、使われないコード!って怒られるくらい。気になるならコメントアウトしてやんなー。と、追っていくと、「strncasecmp」って関数が見つからないそうな。なにそれ?…いや、無いって言われても。さてどうしましょうかね。strcmp改造して作るかな?

結局作ってしまった。まいっか。
その後、l10n.cでも似たコトが。今度はn無しの「strcasecmp」が無いって。えー。// こぴぺー
でもそれはエラーじゃなくて、鰐さんだった。エラーの原因は同一変数名の多重定義。C++じゃないんだから〜と思いつつ変数名をぺちぺち変えてあげる。けど、ダメダメちゃん。何も良い方法が思いつかなかったので「q = p_v->DUMMYUNIONNAME.item.pszText;」とかに変えてみる。unionを使ってたらしいので、仕方なし。しかし、何故?

やっとコンパイルは出来た、けど動作確認なんてしてもない。とりあえず改変記録をメモめもめも。

#ifdef __BORLANDC__
int strncasecmp(const char *s1, const char *s2, size_t n)
{
register size_t i;
register int a=0,b=0;
for(i=0;i b ) return +1;
else if( a < b ) return -1;
else return 0;
}
#endif

#ifdef __BORLANDC__
int strcasecmp(const char *s1, const char *s2)
{
register int a=0,b=0;
register int i=0;

while(1) {
a = s1[i];
b = s2[i];
if( a == 0 || b == 0 ) break;
if( 'a' <= a && a <= 'z' ) a = a + 'A' - 'a';
if( 'a' <= b && b <= 'z' ) b = b + 'A' - 'a';
if( a != b ) break;
i++;
}
if( a > b ) return +1;
else if( a < b ) return -1;
else return 0;
}
#endif

と、static LRESULT CALLBACK wndproc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 関数にて、

q = p->item.pszText;
if (getl10nstr (q, "", a, 256))
p->item.pszText = a;
r = CallWindowProc (proc, hwnd, msg, wparam, lparam);
p->item.pszText = q;

を次に変更

#if (_WIN32_IE >= 0x0400) && (defined __BORLANDC__)
q = p_v->DUMMYUNIONNAME.item.pszText;
if (getl10nstr (q, "", a, 256))
p_v->DUMMYUNIONNAME.item.pszText = a;
r = CallWindowProc (proc, hwnd, msg, wparam, lparam);
p_v->DUMMYUNIONNAME.item.pszText = q;
#else
q = p_v->item.pszText;
if (getl10nstr (q, "", a, 256))
p_v->item.pszText = a;
r = CallWindowProc (proc, hwnd, msg, wparam, lparam);
p_v->item.pszText = q;
#endif

以上。

見事に動作しました、拍手。 // そんな簡単なコトに拍手しなくても、ねぇ。

  • 折角だから*2CYGWIN版でも作ってみる

「MonitorFromWindow」って関数のリンカエラーが発生していたのが気になってたのでめも。
スマートじゃないけど、「MONITOR_DEFAULTTONEAREST」を#undefした方が早いと思うし、影響がどう出るかは知らない。

*1:実はもーちょっと違うけど

*2:赤い扉は選びません

まとめ Puttyを自力コンパイルする方法 with bcc32(Borland C++ Compiler)

  1. 本家(http://www.chiark.greenend.org.uk/%7Esgtatham/putty/)と、JPパッチ(http://hp.vector.co.jp/authors/VA024651/)を取得。
  2. 適当なディレクトリを作ってソースを解凍
  3. パッチを当てる。# patch -Np1 < putty---.patch x3
  4. まず、メイクしてから考える。# make -f makefile.bor
  5. i2022.c と l10n.c あたりでエラーが発生しているはず。
    1. i2022.c内のマクロBで、「WCHAR a = { buf2, 0 };」が有るので、分解して「WCHAR a = { 0, 0 }; a[0] = buf2;」見たいにする。
    2. strncasecmp 関数が無いので、自分で考えて作るか、探してくる。たぶん自分で書いたほうが製作時間は短い*1
    3. l10n.c内で、特定条件下ではポインタの指す場所でエラーが起きる。まずは変数名の多重定義を直して、「q = p_v->DUMMYUNIONNAME.item.pszText;」の用にDUMMYUNIONNAMEを挟まないと通らない*2
    4. strcasecmp*3 関数が無いので、自分で考えて作るか、探してくる。たぶん自分で書いたほうが製作時間は短い*4

以上で、BorlandC++5.5でコンパイルできるはずです。出来なければエラーを取り除いてください。わたしの環境でエラーが出なければデバッグできませんし。

*1:が、実行速度は遅いかもしれない

*2:commctr.h参照

*3:strncasecmp ではない。

*4:が、実行速度は遅いかもしれない

クロスコンパイル環境を整えてみる?

cygwingmpコンパイルをすると、forkが溢れるらしく、まともにコンパイルできずに困憊る。だからLinux機を使ってWin用のバイナリを作って、持ってこようとやってみる。

対象:vine26-x86
インストールするもの:mingwと、binutil&gcc(mingw用?)
やりかた。
http://bitwalk.hp.infoseek.co.jp/index.htmlMinGWインストールそのまんまやってたりする。エラーらしきものが出てこないので、特別書くこともなく…。

  1. OHP(http://sourceforge.net/project/showfiles.php?group_id=2435&release_id=158844)から、MinGW Runtime(バイナリ&ソース)、GCCbinutilsのソースをもらう*1
  2. 適当に展開
    1. バイナリは /usr/local/i386-mingw32 で展開。
    2. ソースはわかりやすい場所に展開して、次のようにSymLinkを作る。
    • ~/work/binutils
    • ~/work/gcc
    • ~/work/runtime
    • ~/work/w32api
  3. binutilsコンパイル
    1. configure --prefix=/usr/local --target=i386-mingw32 -v
    2. make
    3. su -c "make install"
    4. export PATH=$PATH:/usr/local/bin # パスが通ってる場合は省略OK*2
  4. gccコンパイル
    1. configure --prefix=/usr/local --target=i386-mingw32 -v
    2. make
    3. su -c "make install"
  5. mingw-runtime のコンパイル
    1. AS=i386-mingw32-as CC=i386-mingw32-gcc AR=i386-mingw32-ar RANLIB=i386-mingw32-ranlib LD=i386-mingw32-ld DLLTOOL=i386-mingw32-dlltool DLLTOOL=i386-mingw32-dlltool WINDRES=i386-mingw32-windres configure --prefix=/usr/local/i386-mingw32 --target=i386-mingw32 -v
    2. make
    3. su -c "make install"
  6. w32api のコンパイル
    1. AS=i386-mingw32-as CC=i386-mingw32-gcc AR=i386-mingw32-ar RANLIB=i386-mingw32-ranlib LD=i386-mingw32-ld DLLTOOL=i386-mingw32-dlltool DLLTOOL=i386-mingw32-dlltool WINDRES=i386-mingw32-windres configure --prefix=/usr/local/i386-mingw32 --target=i386-mingw32 -v
    2. make
    3. su -c "make install"

詳細は上記のHPで見てってね。そのまんま写すことになっちゃうから、書かないの*3。とりあえずは、インストールが出来たので、GMPをインストールするべし。

…一体、何を考えていたんだろう…。何も考えずに、流れるまま行動するって、時間の浪費以外何物でもない。んー、馬鹿なことを…。

*1:ついでにWin32APIももらったけど使わないような気がしてならない

*2:通ってると思ってやったら失敗。通ってなかった

*3:書いちゃったけど