Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is not binary compatible #82

Closed
measwel opened this issue Oct 31, 2019 · 21 comments
Closed

is not binary compatible #82

measwel opened this issue Oct 31, 2019 · 21 comments

Comments

@measwel
Copy link

measwel commented Oct 31, 2019

I have build the module with the same nginx version (1.14.0) and the same build flags like this:
./configure --add-dynamic-module=/home/marek/ngx_http_geoip2_module $(nginx -V)

nginx -t shows:
nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_geoip2_module.so" is not binary compatible in /etc/nginx/nginx.conf:5

what could be wrong?

@porjo
Copy link

porjo commented Nov 4, 2019

I'm seeing this also using Nginx 1.16 source, then attempting to use the resulting module with Centos/Rhel nginx-1.16 package. Sorry, I don't have any suggested workarounds.

@leev
Copy link
Owner

leev commented Nov 6, 2019

You need to build nginx and the module with the same build flags. So compiling nginx, then taking its flags and adding --add-dynamic-module to now build the module, unless you also take the nginx binary produced by that build, they will have been built differently.

@measwel
Copy link
Author

measwel commented Nov 6, 2019

Thank you leev. Are you saying the module build failed because nginx itself was not compiled before it?

@leev
Copy link
Owner

leev commented Nov 6, 2019

No. To my knowledge, nginx and the modules need to be compiled with the same flags. Eg, if you did:
./configure -flag1 to build nginx.
Then you do ./configure --add-dynamic-module=/home/marek/ngx_http_geoip2_module $(nginx -V) to build the module.

You have built nginx with -flag1 and the module with -flag1 --add-dynamic-module..., which is different. They need to be built with the same flags.

@measwel
Copy link
Author

measwel commented Nov 6, 2019

$(nginx -V) outputs all the flags of the currently system installed nginx. I never built nginx from source to use it ( only as part of building the module). I use the system installed nginx.

@leev
Copy link
Owner

leev commented Nov 6, 2019

Yes, I don't believe that is possible. You aren't compiling them with the same flags. Your nginx binary has no knowledge of the module. Please consult the nginx documentation for dynamic modules.

@leev leev closed this as completed Nov 6, 2019
@measwel
Copy link
Author

measwel commented Nov 6, 2019

Leev. You have completely lost me I'm afraid. I have no idea anymore how the module should be compiled.

@measwel
Copy link
Author

measwel commented Nov 6, 2019

The steps I have taken are:

  1. Checked my system installed version: nginx version: nginx/1.14.0 (Ubuntu)
  2. Downloaded sources for that version.
  3. ./configure --add-dynamic-module=/home/marek/ngx_http_geoip2_module $(nginx -V)
  4. make && make install
  5. copied the module to the modules directory
  6. loaded it in /etc/nginx/nginx.conf : load_module modules/ngx_http_geoip2_module.so;

I don't know where I went wrong. Maybe I should specify the flags explicitly.

@measwel
Copy link
Author

measwel commented Nov 6, 2019

Specifying the flags explicitly at the build step ( instead of using $(nginx -V) ) solved the problem. The module loads now. Thank you.

@measwel
Copy link
Author

measwel commented Nov 6, 2019

Thank you for developing this module. Very useful.

@majaray
Copy link

majaray commented Nov 10, 2019

Specifying the flags explicitly at the build step ( instead of using $(nginx -V) ) solved the problem. The module loads now. Thank you.

Hi @measwel I having the same issue on the same ubuntu version u have.
May I know what's the flags that u specify explicitly now?

@measwel
Copy link
Author

measwel commented Nov 10, 2019

Hi. I just used the command nginx -V and copied all flags output by it:

--with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-DUghaW/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Then I configured the build:
./configure --add-dynamic-module=/home/marek/ngx_http_geoip2_module {plus the flags shown above}

Some of these are not necessary, as they define the build of other modules, but I just kept them all.

@joaompinto
Copy link

The following method allows automation:

nginx -V 2>&1 | egrep  "^configure" | cut -d: -f2 > /tmp/nginx_build_options.txt
sh -c "./configure $(cat /tmp/nginx_build_options.txt) --add-dynamic-module=..."

@centminmod
Copy link

centminmod commented Jan 31, 2020

AFAIK, if you want to drop in dynamic built nginx modules, nginx needs to be compiled with --with-compat flag too https://www.nginx.com/blog/nginx-dynamic-modules-how-they-work/#compatibility. That's how I build Nginx and dynamic modules. HTH

First, compatibility between builds.

This is actually related to signature checking. It’s a pain to compile dynamic modules if you do it outside of NGINX itself. You have to use the same configure options, or signature checking prevents you from loading the module.

We are currently working to make this easier. With a special option to configure, perhaps something like --with-compat, NGINX will just compile in all the structure fields it knows about, so that modules will be compatible even with different configure options. You will be able to load them even if you compile NGINX and the module with a different set of configure options.

@joaompinto that method may not work depending how Nginx is compiled.

For instance all i'd get would be

nginx -V 2>&1 | egrep  "^configure" | cut -d: -f2
 --with-ld-opt='-Wl,-E -L/usr/local/zlib-cf/lib -L/usr/local/lib -ljemalloc -lpcre -Wl,-z,relro -Wl,-rpath,/usr/local/zlib-cf/lib

as opposed to my full Nginx configure on CentOS 7.7 64bit

nginx -V
nginx version: nginx/1.17.8 (230120-223604-centos7-50774ee)
built by gcc 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC) 
built with OpenSSL 1.1.1d  10 Sep 2019
TLS SNI support enabled

configure arguments: --with-ld-opt='-Wl,-E -L/usr/local/zlib-cf/lib -L/usr/local/lib -ljemalloc -lpcre -Wl,-z,relro -Wl,-rpath,/usr/local/zlib-cf/lib:/usr/local/lib -flto=8 -fuse-ld=gold' --with-cc-opt='-I/usr/local/zlib-cf/include -I/usr/local/include -m64 -march=native -DTCP_FASTOPEN=23 -falign-functions=32 -g -O3 -Wno-error=strict-aliasing -fstack-protector-strong -flto=8 -fuse-ld=gold --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wimplicit-fallthrough=0 -fcode-hoisting -Wp,-D_FORTIFY_SOURCE=2 -Wno-deprecated-declarations -gsplit-dwarf' --sbin-path=/usr/local/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --build=230120-223604-centos7-50774ee --with-compat --with-http_stub_status_module --with-http_secure_link_module --with-http_flv_module --with-http_mp4_module --add-module=../nginx-rtmp-module --with-libatomic --with-http_gzip_static_module --add-dynamic-module=../ngx_brotli --add-dynamic-module=../ngx_http_geoip2_module --with-http_sub_module --with-http_addition_module --with-http_image_filter_module=dynamic --with-http_geoip_module --with-stream_geoip_module --with-stream_realip_module --with-stream_ssl_preread_module --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-http_realip_module --add-dynamic-module=../ngx-fancyindex-0.4.2 --add-module=../ngx_cache_purge-2.5 --add-dynamic-module=../ngx_devel_kit-0.3.0 --add-dynamic-module=../set-misc-nginx-module-0.32 --add-dynamic-module=../echo-nginx-module-0.61 --add-module=../redis2-nginx-module-0.15 --add-module=../ngx_http_redis-0.3.7 --add-dynamic-module=../lua-nginx-module-0.10.15 --add-module=../memc-nginx-module-0.18 --add-module=../srcache-nginx-module-0.31 --add-dynamic-module=../headers-more-nginx-module-0.33 --with-pcre-jit --with-zlib=../zlib-cloudflare-1.3.0 --with-http_ssl_module --with-http_v2_module --with-http_v2_hpack_enc --with-openssl=../openssl-1.1.1d --with-openssl-opt='enable-ec_nistp_64_gcc_128 enable-tls1_3 -fuse-ld=gold'

@joaompinto
Copy link

On my specific case I had the requirement to use a RedHat provided nginx image which was built without --compat, and yes that egrep | cut needs some love :)

@Stef-33560
Copy link

Stef-33560 commented Nov 10, 2020

Hi !

With nginx-1.14.2 on debian 10 buster (nginx already installed with apt), I've done the following steps:

git clone https://github.com/leev/ngx_http_geoip2_module.git
version=$(nginx -v 2>&1|cut -d"/" -f 2)
wget http://nginx.org/download/nginx-$version.tar.gz && tar zxfv nginx-$version.tar.gz && cd nginx-$version
apt install libmaxminddb0 libmaxminddb-dev mmdb-bin geoipupdate 
apt install libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev
./configure  --add-dynamic-module=../ngx_http_geoip2_module $(nginx -V) --with-compat
make modules
echo "load_module modules/ngx_http_geoip2_module.so;" > /etc/nginx/modules-available/mod-http-geoip2.conf
ln -s /etc/nginx/modules-available/mod-http-geoip2.conf /etc/nginx/modules-enabled/60-mod-http-geoip2.conf
cp objs/ngx_http_geoip2_module.so /usr/share/nginx/modules/ngx_http_geoip2_module.so

nginx -t gives :

nginx: [emerg] module "/usr/share/nginx/modules/ngx_http_geoip2_module.so" is not binary compatible in /etc/nginx/modules-enabled/60-mod-http-geoip2.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed

What the hell I'm doing wrong ?

Thanks a lot :)

@trey-jones
Copy link

AFAIK, if you want to drop in dynamic built nginx modules, nginx needs to be compiled with --with-compat flag too

This doesn't seem to be so, at least on my Debian 10 nginx install (1.14.2), nginx -V does not include --with-compat but I was able to successfully build and use this module without replacing the nginx binary.

I also discovered that you needn't include any of the --add-dynamic-modules from the binary you are using in order to build another dynamic module. I got the options like so, though if there's anything after --add-dynamic-module then it will probably fail:

NGINX_CONFIGURE_OPTIONS=$(nginx -V 2>&1 | grep configure | sed -e 's/^configure arguments: //' -e 's/ --add-dynamic-module.*$//')

@adrian-green
Copy link

adrian-green commented Jan 21, 2022

This process of configuring by discovering existing flags should be added into the readme. Once it's understood - and easily findable in the main doc, most people will immediately be able to fix their specific variation of the issue.

Many people only compile modules such as this on an ad-hoc basis - having the knowhow to match compile flags exactly does not sit at the top of mind.

Admittedly the readme does say to compile direct from source, but it would be super helpful (I think) to add in a small aside in the docs to assist those who might need to contend with alternative build scenarios.

I had the same issue - but as soon as I found the flags (nginx -V) and could add them to the --add-dynamic-module during configure, all worked fine. Please consider updating the readme, it may save a few headaches for those who are do this infrequently.

Btw - I had the exact same issue a year ago - but had already forgotten (no notes!) - the readme would help enormously for people like me. :-)

@kilvn
Copy link

kilvn commented Jun 25, 2023

nginx -V 2>&1 | egrep  "^configure" | cut -d: -f2

like this:

./configure $(nginx -V 2>&1 | egrep  "^configure" | cut -d: -f2) --add-dynamic-module=../ngx_brotli

if error: ./configure: error: invalid option "-fomit-frame-pointer"

./configure \
$(nginx -V 2>&1 | tail -1 | sed -e 's/configure arguments://' -e "s/ --with-cc-opt='-Os -fomit-frame-pointer -g'//" -e 's| --add-dynamic-module=[^ ]*||g') \
--add-dynamic-module=../ngx_brotli

@lincyim
Copy link

lincyim commented Jan 5, 2024

Specifying the flags explicitly at the build step ( instead of using $(nginx -V) ) solved the problem. The module loads now. Thank you.

Thanks for saving me tons of time!!

@blind-oracle
Copy link

Just FYI e.g. missing a PCRE library during geoip2 module build would also cause this error, even if you use correct flags from nginx -V

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests