Dieses Jahr habe ich vor, einen ernsthaften Blick auf den Nginx-Quellcode zu werfen. Der Zweck besteht darin, die Netzwerkprogrammierung zu erlernen. Die erste Version des Quellcodes, die ich verwendet habe, ist nginx-0.1.0-RELEASE, die Codeadresse : http://hg.nginx.org/nginx/rev/551102312e19
Klicken Sie zum Herunterladen einfach links im Browser auf zip oder gz. Nach der Dekomprimierung gibt es 4 Ordner im Quellcodeverzeichnis:
Kopieren Sie die Konfigurationsdatei im Auto-Verzeichnis in das Quellverzeichnis und führen Sie .configure
aus
Das Makefile kann generiert werden und die Ausgabe des configure-Befehls sieht auf meinem Ubuntu wie folgt aus:
Konfigurationszusammenfassung
PCRE-Bibliothek wurde nicht gefunden
MD5-Bibliothek wird nicht verwendet
Die OpenSSL-Bibliothek wird nicht verwendet
Verwendung der System-Zlib-Bibliothek./configure: Fehler: Das HTTP-Rewrite-Modul erfordert die PCRE-Bibliothek
Sie können das Modul entweder deaktivieren, indem Sie –without-http_rewrite_module
verwenden Option, oder installieren Sie die PCRE-Bibliothek im System, oder erstellen Sie die PCRE-Bibliothek
Statisch aus der Quelle mit Nginx unter Verwendung der Option –with-pcre=.`
Die PCRE-Bibliothek wurde nicht gefunden, daher konnte das HTTP-Rewrite-Modul nicht korrekt installiert werden.
Befehl ausführen: sudo apt-get install libpcre3 libpcre3-dev
Führen Sie dann make clean, configure; display results aus:
Konfigurationszusammenfassung
Verwendung der System-PCRE-Bibliothek
MD5-Bibliothek wird nicht verwendet
Die OpenSSL-Bibliothek wird nicht verwendet
Verwendung der System-Zlib-BibliothekNginx-Pfadpräfix: /usr/local/nginx
Nginx-Binärdatei: /usr/local/nginx/sbin/nginx
Nginx-Konfigurationsdatei: /usr/local/nginx/conf/nginx.conf
Nginx-PID-Datei: /usr/local/nginx/logs/nginx.pid
Nginx-Fehlerprotokolldatei: /usr/local/nginx/logs/error.log
Nginx-HTTP-Zugriffsprotokolldatei: /usr/local/nginx/logs/access.log
MD5 und OpenSSL werden nicht verwendet, wir werden später darüber sprechen. Dann wird ein Fehler angezeigt. Öffnen Sie die objs/Makefie-Datei und sehen Sie sich die aktuellen Kompilierungsoptionen an: CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused -Werror -g
Darunter
-Werror Behandelt Warnungen als Fehler. Brechen Sie die Kompilierung ab, wenn eine Warnung auftritt.
-Wpointer-arith Warnt, wenn arithmetische Operationen an Funktionszeigern oder Zeigern vom Typ void * ausgeführt werden. Auch sehr nützlich. -Wall schaltet dies nicht ein.
-pipe Verwenden Sie Pipes anstelle temporärer Dateien.
-Wno-unused Warnung vor nicht verwendeten Variablen
Entfernen Sie alle folgenden Optionen und erstellen Sie sie erneut. Es wird auch ein Fehler angezeigt: Das Anzeigemakro ngx_blocking_n ist nicht in der Datei ngx_event_accept.c deklariert. Überprüfen Sie objs/Makefile und stellen Sie fest, dass dieser Kompilierungsfehler vom Befehl 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
herrührt
Überprüfen Sie abschließend die Datei src/os/unix/ngx_socket.h. Die Definition lautet wie folgt:
<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>
enthält nicht die vorletzte Codezeile, die von mir neu hinzugefügt wurde Der Test Ich habe festgestellt, dass sich der obige if-Zweig in Ubuntu befindet. Das Folgende ist der else-Codeblock, aber das Makro ngx_blocking_n ist in else nicht definiert, also fügen Sie es einfach hinzu.
Machen Sie weiter.
Es wurde festgestellt, dass IOV_MAX in ngx_writev_chain.c nicht gefunden werden kann. Verwenden Sie den Befehl grep IOV_MAX -r src/os/unix/*
Ich habe festgestellt, dass dieses Makro nur im FreeBSD-System definiert ist und direkt zu core/ngx_config.h hinzugefügt wird.
Machen Sie weiter.
Es wurde festgestellt, dass die Elemente msg_accrights und msg_accrightslen nur in zwei niedrigeren Versionen des Betriebssystems vorhanden sind. Überprüfen Sie jedoch den Code in der Datei src /os/unix/ngx_channel.c wie folgt:
<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>
Das Versionsproblem wurde hier berücksichtigt und zur Unterscheidung wurde ein Makro definiert. Es muss sein, dass dieses Makro nicht definiert ist Bedingung erreicht den else-Zweig, daher wird ein Fehler gemeldet. Definieren Sie das Makro direkt in der Datei:
<code><span>#define HAVE_MSGHDR_MSG_CONTROL 1</span></code>
Weitermachen.
Diesmal wurden alle Zieldateien generiert, aber beim Verknüpfen ist ein Fehler aufgetreten. Der Fehlerinhalt ist wie folgt:
objs/src/core/ngx_times .o: in Funktion ' ngx_time_update':
/home/nginx-0.1.1/src/core/ngx_times.c:179: undefinierter Verweis auf „ngx_timezone“
objs/src/event/ngx_event_accept.o: In Funktion „ngx_event_accept“:
/home/nginx-0.1.1/src/event/ngx_event_accept.c:165: undefinierter Verweis auf „ngx_blocking“
objs/src/event/ngx_event_connect.o: In Funktion „ngx_event_connect_peer“:
/home/nginx-0.1.1/src/event/ngx_event_connect.c:301: undefinierter Verweis auf „ngx_blocking“
objs/src/event/modules/ngx_rtsig_module.o: In Funktion „ngx_rtsig_done“:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:173: undefinierter Verweis auf „ngx_poll_module_ctx“
objs/src/event/modules/ngx_rtsig_module.o: In Funktion „ngx_rtsig_init“:
/home/nginx-0.1.1/src/event/modules/ngx_rtsig_module.c:134: undefinierter Verweis auf „ngx_poll_module_ctx“
Collect2: Fehler: ld hat 1 Exit-Status zurückgegeben
一次全部解决
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教程有兴趣的朋友有所帮助。