ホームページ > バックエンド開発 > PHPチュートリアル > nginx ソースコード (1) コンパイル

nginx ソースコード (1) コンパイル

WBOY
リリース: 2016-08-08 09:28:09
オリジナル
1280 人が閲覧しました

今年は、nginx のソース コードを真剣に検討する予定です。その目的は、ネットワーク プログラミングを学ぶことです。私が使用したソース コードの最初のバージョンは nginx-0.1.0-RELEASE、コード アドレスは
http://hg.nginx.org/nginx/rev/551102312e19
です。 ブラウザの左側にある zip または gz をクリックしてダウンロードします。解凍後、ソース コード ディレクトリに 4 つのフォルダーが存在します:

  • auto
  • conf
  • docs
  • src

auto ディレクトリ内のconfigure ファイルをソース コード ディレクトリにコピーし、
.configure
を実行します。 Makefile を生成できます。私の ubuntu では、configure コマンドの出力は次のようになります。

構成の概要
+ PCRE ライブラリが見つかりません
+ md5ライブラリは使用されません
+ OpenSSL ライブラリは使用されません
+ システム zlib ライブラリの使用

./configure: エラー: HTTP 書き換えモジュールには PCRE ライブラリが必要です。 –without-http_rewrite_module を使用してモジュールを無効にすることもできます
オプションを使用するか、PCRE ライブラリをシステムにインストールするか、PCRE ライブラリをビルドします
–with-pcre= オプションを使用して、nginx でソースから静的に実行します。`

PCRE ライブラリが見つからなかったため、HTTP 書き換えモジュールを正しくインストールできませんでした。

実行コマンド:

sudo apt-get install libpcre3 libpcre3-dev 次に、make clean を実行し、結果を表示します:

設定の概要

+ システム PCRE ライブラリを使用する
+ md5ライブラリは使用されません
+ OpenSSL ライブラリは使用されません
+ システム zlib ライブラリを使用

nginx パス プレフィックス: /usr/local/nginx

nginx バイナリ ファイル: /usr/local/nginx/sbin/nginx
nginx 設定ファイル: /usr/local/nginx/conf/nginx.conf
nginx pid ファイル: /usr/local/nginx/logs/nginx.pid
nginx エラー ログ ファイル: /usr/local/nginx/logs/error.log
nginx http アクセス ログ ファイル: /usr/local/nginx/logs/access.log

md5 と openssl は使用されません。これについては後ほど説明します。次に make を実行すると、エラーが表示されます。objs/Makefie ファイルを開いて、現在のコンパイル オプションを表示します:


CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused -Werror -g その中には
-Werror 警告をエラーとして扱います。警告が発生した場合はコンパイルを中止します。
-Wpointer-arith 関数ポインターまたは void * 型のポインターに対して算術演算を実行するときに警告します。また、非常に便利です。 -壁ではオンになりません。
-pipe 一時ファイルの代わりにパイプを使用します。
-Wno-unused 未使用の変数について警告します
以下のオプションをすべて削除して、再度作成してください。また、表示マクロ ngx_blocking_n がファイル ngx_event_accept.c で宣言されていないというエラーも発生します。objs/Makefile を確認すると、このコンパイル エラーが次のコマンドから発生していることがわかります:

gcc -c -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs src/event/ngx_event_accept.c -o ngx_event_accept.o 最後に、ファイル src/os/unix/ngx_socket.h を確認します。定義は次のとおりです。

<code><span>#if (HAVE_FIONBIO)</span><span>int</span> ngx_nonblocking(ngx_socket_t s);
<span>int</span> ngx_blocking(ngx_socket_t s);

<span>#define ngx_nonblocking_n   "ioctl(FIONBIO)"</span><span>#define ngx_blocking_n      "ioctl(!FIONBIO)"</span><span>#else</span><span>#define ngx_nonblocking(s)  fcntl(s, F_SETFL, O_NONBLOCK)</span><span>#define ngx_nonblocking_n   "fcntl(O_NONBLOCK)"</span><span>#define ngx_blocking_n      "ioctl(!FIONBIO)"</span><span>#endif</span></code>
ログイン後にコピー
には、私が新たに追加したコードの最後から 2 行目が含まれていません。テストにより、上記の if 分岐が検出されました。はubuntuブロック下のelseコードですが、elseにはマクロngx_blocking_nが定義されていないので追加するだけです。

作り続けます。

IOV_MAX が ngx_writev_chain.c に見つからないことが判明しました。コマンド

grep IOV_MAX -r src/os/unix/* を使用してください このマクロは freebsd システムでのみ定義されており、core/ngx_config.h に直接追加されることがわかりました。

作り続けます。

struct msghdr にはメンバー msg_accrights と msg_accrightslen が存在しないことが判明しました。これらは、オペレーティング システムの 2 つの下位バージョンでのみ使用できる変数名です。ただし、ファイル src 内のコードを確認してください。 /os/unix/ngx_channel.c は次のようになります。

<code><span>#if (HAVE_MSGHDR_MSG_CONTROL)</span>
    msg.msg_control = (caddr_t) &cmsg;
    msg.msg_controllen = <span>sizeof</span>(cmsg);
<span>#else</span>
    msg.msg_accrights = (caddr_t) &fd;
    msg.msg_accrightslen = <span>sizeof</span>(<span>int</span>);
<span>#endif</span></code>
ログイン後にコピー
ここではバージョンの問題が考慮されており、それを区別するためのマクロが定義されています。このマクロが定義されておらず、条件が else 分岐に到達しているはずです。ファイル内でマクロを直接定義します:

<code><span>#define HAVE_MSGHDR_MSG_CONTROL 1</span></code>
ログイン後にコピー
作成を続行します。

今回は対象のファイルは全て生成されましたが、一部のシンボルが見つからないためにエラーが発生しました。

objs/src/core/ngx_times.o: 関数内。 「ngx_time_update」:

/home/nginx-0.1.1/src/core/ngx_times.c:179: 「ngx_timezone」への未定義の参照
objs/src/event/ngx_event_accept.o: 関数「ngx_event_accept」内:
/home/nginx-0.1.1/src/event/ngx_event_accept.c:165: 「ngx_blocking」への未定義の参照
objs/src/event/ngx_event_connect.o: 関数「ngx_event_connect_peer」内:
/home/nginx-0.1.1/src/event/ngx_event_connect.c:301: 「ngx_blocking」への未定義の参照
objs/src/event/modules/ngx_rtsig_module.o: 関数「ngx_rtsig_done」内:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:173: 「ngx_poll_module_ctx」への未定義の参照
objs/src/event/modules/ngx_rtsig_module.o: 関数「ngx_rtsig_init」内:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:134: 「ngx_poll_module_ctx」への未定義の参照
collect2: エラー: ld は 1 つの終了ステータスを返しました

一次全部解决
1 在src/core/ngx_times.c文件里代码又走到了else分支里,然后在 src/os/unix/ngx_time.h中只有solaris才定义了ngx_timezone这个函数:

<code><span>#<span>define</span> ngx_timezone(isdst) (- (isdst ? altzone : timezone) / 60)</span></code>
ログイン後にコピー

放开宏定义会发现找不到altzone, 暂时不管这个,把它直接改成0:

<code><span>#<span>define</span> ngx_timezone(isdst) (- (isdst ? 0 : timezone) / 60)</span></code>
ログイン後にコピー

2 src/event/ngx_event_accept.c中未定义引用ngx_blocking,原因刚才已经找到了,在src/os/unix/ngx_socket.h中走了else分支,把if里的函数声明直接拷贝一份到else中,因为这是个函数,还有定义部分,在src/os/unix/ngx_socket.c中把这个函数从if宏定义中移出来。 注意,不要修改ngx_nonblocking函数。
3 src/event/modules/ngx_rtsig_module.c中未定义引用ngx_poll_module_ctx,查代码发现这是一个全局变量:

<code><span>extern</span> ngx_event_module_t  ngx_poll_module_ctx;</code>
ログイン後にコピー

被定义在poll模块内,但编译的时候在objs/Makefile中没有编译这个模块,把它一起编译了,改3个地方,和epoll的编译一样,有epoll的地方直接复制epoll相关的内容,把里面的epoll改成poll就可以了。

最后make成功!
生成了nginx二进制文件。直接./nginx运行,报错:

[emerg] 11732#0: open() /usr/local/nginx/conf/nginx.conf failed (2: No such file or directory)

to be continued…

以上就介绍了nginx 源码(1)编译,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート