1. 程式人生 > >使用c++/c++11開發nginx模組時的兩種編譯方法

使用c++/c++11開發nginx模組時的兩種編譯方法

使用c++開發nginx模組時的兩種編譯方法
Nginx本身只支援使用C語言開發模組,如果我們需要使用C++,那麼必須修改原始碼裡的編譯指令碼
首先,我們不能使用g++編譯Nginx自身的C程式碼,因為C++的語法比C嚴格很多,而Nginx程式碼用到了很多C語言的“邊角”特性,直接使用g++編譯會報大量錯誤
正確的做法是使用gcc來編譯nginx原始碼,而使用g++來編譯我們自己的C++程式碼,兩者可使用副檔名區分(*.c和*.cpp),最後使用g++連結所有的目標檔案,如果使用其他第三方庫
(如boost),可以在configure時用--with-ld-opt引數,
在執行configure時,會呼叫auto/make這個指令碼來生成Makeile, 此Makefile決定了原始碼的編譯連結方式  

方法一:修改auto/make指令碼

1、連結器LINK改用g++
2、增加C++編譯器和編譯選項,啟用C++11標準
3、生成編譯命令時用副檔名區分C原始碼和C++原始碼

具體做法(此處nginx版本為1.10.1):

#LINK =  $LINK    					#26行,註釋掉原連結器
CXX = g++							#新增C++編譯器
CXXFLAGS = -std=c++0x -Wall			#新增C++編譯選項,啟用C++11,此處可以新增更多引數
LINK = g++							#新增C++連結器

修改# the addons sources(406行)下的程式碼

if test -n "$NGX_ADDON_SRCS"; then
 
    ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch ddons sources\$(ALL_INCS)"
#定義c++編譯命令
	ngx_cxx="\$(CXX) $ngx_compile_opt \$(CXXFLAGS) $ngx_use_pch ddons sources\$(ALL_INCS)"
	
	for ngx_src in $NGX_ADDON_SRCS
    do
		...
	ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
	#獲取原始碼檔案字尾,決定使用gcc還是g++
	ext=`echo ${ngx_src} | cut -d . -f 2`
	ngx_gcc=$ngx_cc
	if [ $ext = "cpp" ]; then	
		ngx_gcc=$ngc_cxx
	fi
	
	cat << END                                            >> $NGX_MAKEFILE
 
 $ngx_obj:       \$(ADDON_DEPS)$ngx_cont$ngx_src
        #$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
		$ngx_gcc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
 
 END
      done
此處使用cut來獲取副檔名,如果使用bash,可以更方便地獲取副檔名:
ext = ·echo ${ngx_src:(-4)}·     #bash支援直接獲取末尾字串

方法二:直接修改Makefile檔案

對nginx原始碼執行configure後,在obj目錄下生成Makefile檔案

CC =    cc
CFLAGS =  -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -DNGX_HTTP_HEADERS -g
後面新增
CXX =    g++
CXXFLAGS =  -pipe  -O -W -Wall -std=c++11 -Wpointer-arith -Wno-unused-parameter -Werror 
修改
#LINK =  $(CC)
LINK =  $(CXX)
對於每個.cpp檔案,手動修改編譯方式

修改

objs/addon/snpixel/pixel_module.o:      $(ADDON_DEPS) \
         /home/lijinqi/project/code/snpixel/snpixel/pixel_module.cpp
         #$(CC) -c $(CFLAGS)  $(ALL_INCS) \
		 $(CXX) -c $(CXXFLAGS)  $(ALL_INCS) 
                 -o objs/addon/snpixel/pixel_module.o \
                 /home/lijinqi/project/code/snpixel/snpixel/pixel_module.cpp
另外,在引用nginx原始碼時,需要加上extern“C”

如:

extern "C" {
    #include <ngx_core.h>
    #include <ngx_http.h>
    #include <nginx.h>
}