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. :)
February 2nd, 2006 at 11:05 pm
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!
June 20th, 2007 at 10:43 am
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
June 20th, 2007 at 12:46 pm
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?
June 20th, 2007 at 1:13 pm
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
August 4th, 2007 at 4:01 am
hi
i am stuck at step 2.
where is .libs directory ? I can’t find it.
I am a newbie.
regards
kapil
November 9th, 2007 at 11:09 am
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
March 20th, 2008 at 9:17 am
thanks a lot!!!
June 6th, 2008 at 3:05 pm
Hey, you just saved another guy a lot of pain.
September 17th, 2008 at 11:32 am
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