endflow.net blog

/* programming and programming */

Archive for the ‘Windows’ tag

[lang_ja]mod_bwをWindowsでビルドする #1[/lang_ja][lang_en]Build mod_bw on Windows #1[/lang_en]

without comments

[lang_ja]

/* 経緯 */

Flashでローディング表示を作るとき、ローカルサーバを使うとロードが一瞬で終わってしまいデバッグできないので、mod_bwのような帯域制限モジュールを利用することが多いと思います。

この便利なmod_bwですが、なぜか.htaccessファイルでの設定に対応しておらず、httpd.confファイルで設定する必要があります。私はデバッグ中に頻繁に制限速度を変更したくなるので、いちいちApacheを再起動するのは面倒です。.htaccessファイルに対応していない理由はREADMEによると

This mod, is able to limit bandwidth usage on every virtual host or directory. htaccess files are not supported yet, cause i’ve been having some serious segfaults when implementing it.

ということなので、無理だろうけど原因を探るべく、はじめの目標は Windowsでmod_bw 0.8をビルドすることにします。配布されているVisual Studio用のプロジェクトファイルは0.7用なので最初は0.7をビルドしてみます。ChangeLogではあんまり大きな変更はなさそうなので、たぶん0.7がビルドできたら0.8のソースに差し替えればそのままビルドできるだろう、という魂胆です。

/* Apacheのビルド */

Apacheモジュールビルドのために、まずApacheをビルドする必要があります。

Apacheのソースを落としたらデフォでVisual Studio用(たぶんVisual C++ 6.0)のdswファイルがあったのでVisual Studio 2003で開きました。変換自体は問題なくパスしたわけですが、ビルドしたらまぁお約束のエラーが出てきたわけです。

例えばmod_dirをビルドすると

fatal error RC1107: invalid usage; use RC /? for Help

ってエラーが出て、ビルドログでどんなコマンドで死んだのか見ると、

コマンド ライン “rc.exe /d “NDEBUG” /d “BIN_NAME=”mod_dir.so”" /d “LONG_NAME=”dir_module for Apache”" /l 0×409 /I “workhttpd-2.2.4buildwin32″ /I “../../include” /I “../../srclib/apr/include” /fo”Release/mod_dir.res” workhttpdbuildwin32httpd.rc” を作成しています。

というようにリソースコンパイルエラー(RC1107)が発生します。原因は見ての通りBIN_NAMEとかLONG_NAMEのディレクティブのネストされたダブルクオーテーションなので、内側のクオーテーションをシングルクオーテーションにすることで回避しました。mod_dirに限らず、libhttpdとかのエラーもこれで回避できます。

/* mod_bw のビルド */

まずソースをダウンロード。

mod_bw-0.7.tgz / mod_bw-0.7vc.zip / mod_bw-0.8.tgz

mod_bw_vsとか適当な名前のディレクトリに1つ目と2つ目のソースを解凍して、dswをVisual Studio 2003で開いて変換します。次にプロジェクトのプロパティのC/C++の全般のところのincludeパスを先ほどビルドしたApacheのディレクトリにします。リンカの入力のところはちょっと注意が必要です。設定ではlibapr.libやlibaprutil.libとなっていますが、先ほどビルドしたApacheではなぜかlibapr-1.libやlibaprutil-1.libとなっています。指定は相対パスでも絶対パスでも特に問題ないです。

この状態でビルドすると

mod_bw fatal error LNK1104: コンパイラは、ファイル ‘httpd-2.0.52oswin32BaseAddr.ref’ を開くことができません。

と表示されて、ファイルが開けないようです。しかし正しくパスを設定しても今度は

mod_bw fatal error LNK1147: オプション ‘/BASE:@httpd-2.0.52oswin32BaseAddr.ref,mod_bw.so’ で無効な番号が指定されています。

というエラーが出てきます。そもそも /BASE というオプションはDLLのベースアドレス設定のようです。解説には実行時のページングが軽減されてパフォーマンスの向上につながると書いてあります。なるほど。・・・ってことは別に無くてもいいということになるので、即刻外します。

そしてリビルドすると

mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_set が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_cas が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_dec が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_add が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_inc が関数 _bw_filter で参照されました。
mod_bw fatal error LNK1120: 外部参照 5 が未解決です。

と、今度はリンカエラーが出てきました。libapr-1.libに関数がエクスポートされていないのでしょうか?ちょっとlibapr-1.expをテキストエディタで開いてatomicで検索すると・・・ちゃんと各関数はエクスポートされているようです。ここでソース(mod_bw.c)を見てみると、最初の方に怪しげなプリプロセッサが見つかりました。

/* Compatibility for APR < 1 */

#if (APR_MAJOR_VERSION < 1)
#define apr_atomic_inc32 apr_atomic_inc
#define apr_atomic_dec32 apr_atomic_dec
#define apr_atomic_add32 apr_atomic_add
#define apr_atomic_cas32 apr_atomic_cas
#define apr_atomic_set32 apr_atomic_set
#endif

試しに全部コメントアウトします。そしてリビルド・・・成功。

このAPR_MAJOR_VERSIONっていうのはapr_version.hで定義されています。が、それにもかかわらず何故かインクルードされていないので、全てプリプロセッサで置換されてしまったようです。ということで

#include “apr_version.h”

をmod_bw.cに追加してリビルドするとうまくいきました。

今日はここまで。

[/lang_ja]
[lang_en]

/* Background */

When I debug flash content that includes progress bar for informing status of loading using a local web server (Apache), it will finish loading in no time. So I use “mod_bw” is a module of Apache. “mod_bw” limit band-width and number of connections from the same client.

This module is very useful but it DOES NOT support .htaccess files. Therefore, we have to configure in httpd.conf file. It mean you must restart Apache web server every time you change it. It is annoying operation for me because I very often change configurations of mod_bw. From README, the reason that mod_bw doesn’t support .htaccess is

This mod, is able to limit bandwidth usage on every virtual host or directory. htaccess files are not supported yet, cause i’ve been having some serious segfaults when implementing it.

So I try to research and remove this problem. At first, I try to build mod_bw 0.8 on Windows + Visual Studio because there is no binary of mod_bw 0.8 for Windows. it only distribute project files of Visual Studio for version 0.7 but there are only a little changes between 0.7 and 0.8. Therefore I think I will replace from 0.7 source to 0.8 source after I build 0.7 source. Tongue out

/* Building Apache */

First of all, you have to build Apache web server for building Apache module.

You can find dsw file (project file for Visual C++ 6.0) in the source code of Apache web server and open it with Visual Studio 2003 .NET. It will finish converting without troubles. However, errors will rise when you build any project in the solution of Apache web server. Yell

For instance, you build “mod_dir” project,

fatal error RC1107: invalid usage; use RC /? for Help

As you see, this is resource compile error (RC1107) and you find cause what command in the build log.

command line “rc.exe /d “NDEBUG” /d “BIN_NAME=”mod_dir.so”" /d “LONG_NAME=”dir_module for Apache”" /l 0×409 /I “workhttpd-2.2.4buildwin32″ /I “../../include” /I “../../srclib/apr/include” /fo”Release/mod_dir.res” workhttpdbuildwin32httpd.rc”

This error caused by a nested double quotations of directives BIN_NAME and LONG_NAME. So I replaced from double quotation to single quotation for avoiding this resource compile error. You can also avoid errors of libhttpd project using same way.

/* Building mod_bw */

At first, you download following archives:

mod_bw-0.7.tgz / mod_bw-0.7vc.zip / mod_bw-0.8.tgz

Extract mod_bw-0.7.tgz and mod_bw-0.7vc.zip into a same folder (i.e. “mod_bw_vs”), open and convert dsw file with Visual Studio 2003 .NET. In the next, Open project property, move to [C/C++] -> [General] -> [include path] and set the path of Apache build directory. But note at [Linker] -> [Input]. In default configuration, it setted libapr.lib and libaprutil.lib but libapr and libaprutil project of Apache solution will generates libapr-1.lib and libaprutil-1.lib. For your information, you can use both of absolute path and relative path.

You start building …

mod_bw fatal error LNK1104: compiler doesn’t open a file ‘httpd-2.0.52oswin32BaseAddr.ref’

The error of file open occured. However, you set correct path …

mod_bw fatal error LNK1147: Option ‘/BASE:@httpd-2.0.52oswin32BaseAddr.ref,mod_bw.so’ で無効な番号が指定されています。

The other error ocurred. Wait … a option /BASE specify base address of DLL in memory space. This option affect runtime performance. That is no problem without /BASE option and I removed this option.

OK, and build …

mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_set が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_cas が関数 _update_counters で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_dec が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_add が関数 _bw_filter で参照されました。
mod_bw error LNK2019: 未解決の外部シンボル _apr_atomic_inc が関数 _bw_filter で参照されました。
mod_bw fatal error LNK1120: 外部参照 5 が未解決です。

The next are linker errors. There is a possibility that functions (_apr_atomic_set, _apr_atomic_cas, …) wasn’t exported into libapr-1.lib. I have opened libapr-1.exp using text editor and searched with keyword “atomic”. As a result, each functions were exported correctly. So I opened source code (mod_bw.c) and found doubtful preprocessors at head of code.

/* Compatibility for APR < 1 */

#if (APR_MAJOR_VERSION < 1)
#define apr_atomic_inc32 apr_atomic_inc
#define apr_atomic_dec32 apr_atomic_dec
#define apr_atomic_add32 apr_atomic_add
#define apr_atomic_cas32 apr_atomic_cas
#define apr_atomic_set32 apr_atomic_set
#endif

Comment out these lines and rebuild project … succeed !  Laughing

A symbol APR_MAJOR_VERSION is defined in apr_version.h but I wonder why apr_version.h doesn’t include in mod_bw.c. So all of “… atomic … 32″ are replaced by preprocessor program. Therefore I appended

#include “apr_version.h”

to mod_bw.c and rebuild project … OK !

Thanks for reading. Wink

[/lang_en]

Written by kuy

August 12th, 2007 at 4:11 am

Posted in Uncategorized

Tagged with , , ,