Nginx 添加第三方模块,出现 is not binary compatible in 错误的问题解决

(156) 2024-03-26 17:01:01

Nginx 添加第三方模块,出现 is not binary compatible in 错误的问题解决

在启动
nginx 时,可能碰到过这种情况:

[centos@localhost ~]$ sudo /usr/sbin/nginx
[sudo] centos 的密码:
nginx: [emerg] module "/usr/lib64/nginx/modules/ngx_http_image_filter_module.so" is not binary compatible in /usr/share/nginx/modules/mod-http-image-filter.conf:1

这种情况一般是第三方模块编译中包含的签名和使用的 nignx 不一致导致的。

解决如下

首先,通过 nginx -V 查看编译使用选项(即当前配置的 configure 参数):

[centos@localhost ~]$ nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx1.16.1 --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --user=nginx --group=nginx --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --with-select_module --with-poll_module --with-threads --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-mail=dynamic --with-mail_ssl_module --with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_geoip_module=dynamic --with-stream_ssl_preread_module --with-compat --with-debug

之后,重新编译 nginx 源码生成的 .so 模块并复制到旧目标路径(即覆盖掉原有的)。操作时需要在 configure 命令上追加一个动态编译的选项 --add-dynamic-module= 或者直接调用 ./configure --with-compat --add-dynamic-module= 第三方模块动态编译命令。此处路径需要找到你要编译的动态模块,即 .c 文件,后面使用 cp 指令在迁移到目标文件即可。

[centos@localhost nginx-1.16.1]$ find . -name "*http_image_filter_module*"
./src/http/modules/ngx_http_image_filter_module.c

同时还要在该 modules 文件夹下新增 config 文件,该文件来自官网,需要根据实际情况进行调整。

[centos@localhost nginx-1.16.1]$ :<<!
 这里为了文件的更加规则有序,不直接在 'modules' 里新加 'config' 文件,而是新建立 'ngx_http_image_filter_module' 文件,并将 '.c' 原文件复制到该目录中
!
[centos@localhost nginx-1.16.1]$ mkdir src/http/modules/ngx_http_image_filter_module
[centos@localhost nginx-1.16.1]$ cp src/http/modules/ngx_http_image_filter_module.c src/http/modules/ngx_http_image_filter_module/ngx_http_image_filter_module.c 
[centos@localhost nginx-1.16.1]$ vim src/http/modules/ngx_http_image_filter_module/config
ngx_addon_name=ngx_http_image_filter_module

if test -n "$ngx_module_link"; then
    ngx_module_type=HTTP
    ngx_module_name=ngx_http_image_filter_module
    ngx_module_srcs="$ngx_addon_dir/ngx_http_image_filter_module.c"

    . auto/module
else
    HTTP_MODULES="$HTTP_MODULES ngx_http_image_filter_module"
    NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_image_filter_module.c"
fi

[centos@localhost nginx-1.16.1]$ :<<!
 在后续 make 编译阶段,发现错误
!
Assembler messages:
致命错误:can't create objs/src/http/modules/ngx_http_image_filter_module/ngx_http_image_filter_module.o: 没有那个文件或目录
make[1]: *** [objs/src/http/modules/ngx_http_image_filter_module/ngx_http_image_filter_module.o] 错误 2
make[1]: 离开目录“/home/centos/nginx-1.16.1”
make: *** [build] 错误 2
[centos@localhost nginx-1.16.1]$ :<<!
 这里应该使该文件与nginx目录平级
!
[centos@localhost nginx-1.16.1]$ cd ..
[centos@localhost ~]$ cp -r nginx-1.16.1/src/http/modules/ngx_http_image_filter_module ngx_http_image_filter_module/

此处 config 文件来源,参考官方说明:Converting Static Modules to Dynamic Modules

完整流程如下:
在你编译 nginx 源码的文件里再次执行 ./configure 指令,如果你使用直接追加的命令, 注意 ,原有的配置参数一定也要加入。

$ ./configure --prefix=/usr/local/nginx1.16.1 \
            --sbin-path=/usr/sbin/nginx \
            --conf-path=/etc/nginx/nginx.conf \
            --user=nginx \
            --group=nginx \
            --pid-path=/var/run/nginx.pid \
            --lock-path=/var/run/nginx.lock \
            --error-log-path=/var/log/nginx/error.log \
            --http-log-path=/var/log/nginx/access.log \
            --with-select_module \
            --with-poll_module \
            --with-threads \
            --with-file-aio \
            --with-http_ssl_module \
            --with-http_v2_module \
            --with-http_realip_module \
            --with-http_addition_module \
            --with-http_xslt_module=dynamic \
            --with-http_image_filter_module=dynamic \
            --with-http_geoip_module=dynamic \
            --with-http_sub_module \
            --with-http_dav_module \
            --with-http_flv_module \
            --with-http_mp4_module \
            --with-http_gunzip_module \
            --with-http_gzip_static_module \
            --with-http_auth_request_module \
            --with-http_random_index_module \
            --with-http_secure_link_module \
            --with-http_degradation_module \
            --with-http_slice_module \
            --with-http_stub_status_module \
            --with-mail=dynamic \
            --with-mail_ssl_module \
            --with-stream \
            --with-stream_ssl_module \
            --with-stream_realip_module \
            --with-stream_geoip_module=dynamic \
            --with-stream_ssl_preread_module \
            --with-compat \
            --with-pcre=../pcre-8.42 \
            --with-pcre-jit \
            --with-zlib=../zlib-1.2.11 \
            --with-openssl=../openssl-1.1.1a \
            --with-openssl-opt=no-nextprotoneg \
            --with-debug \
 			--add-dynamic-module=../ngx_http_image_filter_module #追加的动态编译

或者采用动态编译的命令,显然这种命令比较方便,省去了了解原有 configure 配置参数的步骤:

$ ./configure --with-compat --add-dynamic-module=../ngx_http_image_filter_module

执行 make 编译命令,编译成功之后,不要继续执行 make install

$ make 

最后将你重新编译生成的文件复制(覆盖)掉原文件即可,先将原路径下 .so 文件备份,防止意外:

[centos@localhost nginx-1.16.1]$ sudo mv /usr/lib64/nginx/modules/ngx_http_image_filter_module.so /usr/lib64/nginx/modules/ngx_http_image_filter_module.so-bak
[centos@localhost nginx-1.16.1]$ sudo cp objs/ngx_http_image_filter_module.so /usr/lib64/nginx/modules/

这样便完成了动态编译。配置如果没开,记得加载打开即可。

第三方模块动态编译官方网站参考:Compiling Third-Party Dynamic Modules for NGINX and NGINX Plus

THE END

发表回复