This page was exported from phaq [ http://phaq.phunsites.net ]
Export date: Fri Apr 19 11:03:14 2024 / +0000 GMT
When I was setting up a development box today I encountered a strange error while compiling the Mail::ClamAV perl module.

[output stripped]
Starting Build Compile Stage
Starting "perl Makefile.PL" Stage
Note (probably harmless): No library found for -lclamav
Writing Makefile for Mail::ClamAV
Finished "perl Makefile.PL" Stage
Starting "make" Stage
/usr/local/bin/perl /usr/local/lib/perl5/5.8.8/ExtUtils/xsubpp -typemap /usr/local/lib/perl5/5.8.8/ExtUtils/typemap ClamAV.xs > ClamAV.xsc && mv ClamAV.xsc ClamAV.c
cc -c -I/usr/ports/mail/p5-Mail-ClamAV/work/Mail-ClamAV-0.17 -DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement -g -DVERSION="0.17" -DXS_VERSION="0.17" -DPIC -fPIC "-I/usr/local/lib/perl5/5.8.8/mach/CORE" ClamAV.c
ClamAV.xs:11:20: clamav.h: No such file or directory
ClamAV.xs:19: error: field `limits' has incomplete type
ClamAV.xs:20: error: field `st' has incomplete type
ClamAV.xs: In function `clamav_perl_new':
ClamAV.xs:48: error: invalid application of `sizeof' to incomplete type `cl_stat'
[output stripped]

At first I thought of a bug in the module package itself, but after further inspection I noticed these two lines:

>> Note (probably harmless): No library found for -lclamav
>> ClamAV.xs:11:20: clamav.h: No such file or directory

So at a first glance it would look like libclamav and it's header file were not installed properly (hence not found), but since it did so only minutes ago there must have been another reason for this error to come up.

Looking at the cc command line I noticed the absence of the usual include statement pointing to /usr/local/include.

To fix this issue we need to know how module compilation actually works in Perl.

Some may be familiar with autoconfig (configure.sh) used with most source tarballs out there. Perl uses a similar approach to bring together it's build dependencies called MakeMaker (ExtUtils::MakeMaker). Perl module packages usually come along with a MakeMaker prototype file (Makefile.PL) which serves the purpose to build a regurlar Makefile.

MakeMaker relies on Perl's bootstrap build settings to stick things together, so if anything is missing there errors at compile time may arise.

So we need to check out the Perl configuration files Config.pm and Config_heavy.pl. These are usually found at /usr/local/lib/perl5/x.y.z/mach (x.y.z denotes the Perl version, e.g. 5.8.8. If this does not apply to you, check your 'perl -V' output and look at your @INC directories, also [s]locate/find may be of use too).

Let's look at Config.pm first, locating this line:

libpth='/usr/lib',

Change it to to include "/usr/local/lib" (or any lib directory that may apply to your environment) and save the file.

libpth='/usr/lib /usr/local/lib',

This will cause MakeMaker to not claim any longer about "No library found for -lclamav".

Doing the same for the header files does involve a bit of additional work. Let's check out Config_heavy.pl.
This file contains a lot of settings written out by autoconf during Perl's initial bootstrap compilation, some of which are used to compile inline code in Perl.

Let's look at the ccflags/cppflags first:

ccflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe'
cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe'

Adding the include directory (/usr/local/include or whatever may apply to you) will cause the header files to be found at compile time:

ccflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -I/usr/local/include'
cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -I/usr/local/include'

Since compiling usually also involves linking these additional settings must be changed to:

lddlflags='-shared '
ldflags=' -Wl,-E'
libpth='/usr/lib'
libspath=' /usr/lib'

Change the lines to include the library directory (/usr/local/lib in my case) to ensure ld finding all dependencies:

lddlflags='-shared -L/usr/local/lib'
ldflags=' -Wl,-E -L/usr/local/lib'
libpth='/usr/lib /usr/local/lib'
libspath=' /usr/lib /usr/local/lib'

After applying all these changes I could finally compile and install Mail::ClamAV with success.

After all only one question remains: Why was my Perl config so totally screwed up? But this is another story...
Powered by [ Universal Post Manager ] plugin. HTML saving format developed by gVectors Team www.gVectors.com