Unmangling apxs and mod_deflate

I had a boat load of fun today debugging apxs and apr-config. The issue I was debugging came about when I decided to use mod_deflate to compress text, xml and style sheets on my web server. Since mod_deflate wasn’t built when I had originally configured Apache, I thought I would fire up apxs to build the Apache module:

$ LDFLAGS=”-lz” apxs -c mod_deflate.c
/var/tmp/apache/build/libtool –silent –mode=compile gcc -prefer-pic -DAP_HAVE_DESIGNATED_INITIALIZER -DSOLARIS2=10 -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT -g -O2 -I/var/tmp/apache/include -I/var/tmp/apache/include -I/var/tmp/apache/include -c -o mod_deflate.lo mod_deflate.c && touch mod_deflate.slo
/var/tmp/apache/build/libtool –silent –mode=link gcc -o mod_deflate.la -rpath /var/tmp/apache/modules -module -avoid-version mod_deflate.lo

W00t! The module built, so I installed it and tried to fire up Apache:

$ cp .libs/mod_deflate.so /var/tmp/apache/modules/

$ apachectl start
Syntax error on line 268 of /var/tmp/apache/conf/httpd.conf:
Cannot load /var/tmp/apache/modules/mod_deflate.so into server: ld.so.1: httpd: fatal: relocation error: file /var/tmp/apache/modules/mod_deflate.so: symbol crc32: referenced symbol not found

Ack! For some reason mod_deflate.so wasn’t able to find the symbol crc32, which I knew from past experience was part of libz.so. To see what was going on, I pulled out the trusy old ldd utility:

$ ldd /var/tmp/apache/modules/mod_deflate.so
libc.so.1 => /lib/libc.so.1
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libm.so.2 => /lib/libm.so.2
/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1

Hmmm — since libz.so was absent from the output, I quickly realized that apxs was ignoring the LDFLAGS variable. To get a better idea of how apxs figures out which libraries to add, I fired up vi and poked around the apxs Perl script. After two minutes of searching, I came across the following Perl code that controls the link process:

if ($opt_p == 1) {

   my $apr_libs=`$apr_bindir/apr-config --ldflags --link-libtool --libs`;
   chomp($apr_libs);
   my $apu_libs=`$apu_bindir/apu-config --ldflags --link-libtool --libs`;
   chomp($apu_libs);

   $opt .= " ".$apu_libs." ".$apr_libs;
 } else {
    my $apr_ldflags=`$apr_bindir/apr-config --ldflags`;
    chomp($apr_ldflags);
    $opt .= "-rpath $CFG_LIBEXECDIR -module -avoid-version $apr_ldflags";
}

push(@cmds, "$libtool $ltflags --mode=link $CFG_CC -o $dso_file $opt $lo");

Since the libraries are derived from the output of ‘apr-config –ldflags,” I thought I would run it manually to see what was going on:

$ apr-config –ldflags

$ LDFLAGS=”-lz” apr-config –ldflags

$

So given the fact that apr-config doesn’t print “-lz” or pay attention to the LDFLAGS variable (it uses the value of $flags and $LDFLAGS to derive this information, and both are set in the apr-config script), I was forced to add “-lz” to the global LDFLAGS section in the apr-config script:

$ grep ^LDFLAGS apr-config
LDFLAGS=”-lz”

Once this hack was made to apr-config, libtool used the library:

$ make clean && /var/tmp/apache/bin/apxs -c mod_deflate.c
rm -f *.o *.lo *.slo *.obj *.a *.la mod_include.la
rm -rf .libs
/var/tmp/apache/build/libtool –silent –mode=compile gcc -prefer-pic -DAP_HAVE_DESIGNATED_INITIALIZER -DSOLARIS2=10 -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT -g -O2 -I/var/tmp/apache/include -I/var/tmp/apache/include -I/var/tmp/apache/include -c -o mod_deflate.lo mod_deflate.c && touch mod_deflate.slo
/var/tmp/apache/build/libtool –silent –mode=link gcc -o mod_deflate.la -rpath /var/tmp/apache/modules -module -avoid-version -lz mod_deflate.lo

And ldd showed the correct output:

$ ldd /var/tmp/apache/modules/mod_deflate.so
libz.so.1 => /usr/lib/libz.so.1
libc.so.1 => /lib/libc.so.1
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libm.so.2 => /lib/libm.so.2
/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1

While this fix is not ideal, it allowed me to build mod_deflate without incurring the overhead from a complete build. The better solution would have been to re-build Apache with “–enable-deflate=shared,” but that takes a while on my slow box. :)

12 Comments

HM  on February 2nd, 2006

Phew! Thanks a bunch. If it wasnt for this article I would have had to search or recompile Apache. It works and that’s all that matters!

Charlie  on June 20th, 2007

I get the same burp on crc32 when building entire Apache –with–deflate. Any idea how to hack a fix for that?

-bash-3.00$ ./apachectl -t -f /usr/local/apache2/conf/httpd.conf
Syntax error on line 1117 of /usr/local/apache2/conf/httpd.conf:
Cannot load /usr/local/apache2/modules/mod_deflate.so into server: ld.so.1: httpd: fatal: relocation error: file /usr/local/apache2/modules/mod_deflate.so: symbol crc32: referenced symbol not found

mod_deflate frustation  on June 20th, 2007

Argh

Tried to use apxs as described in the blog, but getting this when trying to LoadModule mod_deflate:

-bash-3.00$ ./apachectl -t -f /usr/local/apache2/conf/test.conf
Syntax error on line 1119 of /usr/local/apache2/conf/test.conf:
Can’t locate API module structure `mod_deflate’ in file /usr/local/apache2/modules/mod_deflate.so: ld.so.1: httpd: fatal: mod_deflate: can’t find symbol

any idea?

mod_deflate frustation  on June 20th, 2007

Everything looks kosher here?

-bash-3.00$ ./apachectl -t -f /usr/local/apache2/conf/httpd.conf
Syntax error on line 1117 of /usr/local/apache2/conf/httpd.conf:
Can’t locate API module structure `mod_deflate’ in file /usr/local/apache2/modules/mod_deflate.so: ld.so.1: httpd: fatal: mod_deflate: can’t find symbol
-bash-3.00$ ldd ../modules/mod_deflate.so
libz.so.1 => /usr/lib/libz.so.1
libc.so.1 => /lib/libc.so.1
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libm.so.2 => /lib/libm.so.2
/platform/SUNW,Sun-Fire-V210/lib/libc_psr.so.1

kapil  on August 4th, 2007

hi

i am stuck at step 2.

where is .libs directory ? I can’t find it.

I am a newbie.

regards
kapil

Aditya  on November 9th, 2007

you have to go to “/httpd-2.x.y/modules/filters” and then run “bin/apxs -c mod_deflate.c” .. after this you can find the mod_deflate.so in .libs folder

maciekk  on March 20th, 2008

thanks a lot!!!

Me  on June 6th, 2008

Hey, you just saved another guy a lot of pain.

Ashit Kumar  on September 17th, 2008

I have install apache2 on solaris 9 but when I am installing perl modules (mod_perl-2.0.4) on this machine it is giving error….

Please provide the location of the Apache directory: /usr/local/apache2
Configuring Apache/2.0.50 mod_perl/2.0.4 Perl/v5.8.5
[ error] can’t find ‘apr-config’, please pass MP_APR_CONFIG=/full/path/to/apr-config to ‘perl Makefile.PL’
root@uatbed #

can any body help me on this issue…

Cheers
Ashit Kumar Das

anomdebus  on April 23rd, 2010

Thanks for the tip. I was able to do it via the command line (vs editing files) with:

apxs -c -Wl,”-lz” mod_deflate.c

gv  on December 22nd, 2011

Great article

danny  on September 26th, 2012

why so troublesome?

just do this will solve the issue.

apxs -c -lz -i -a mod_deflate.c

Leave a Comment