Subject: | no way to test with dependent libraries |
Some libraries, on some platforms, require other libraries to perform
their function.
For example, on OpenBSD 4.7 the standard libpng package requires libz
and libm to be linked in, otherwise some symbols are unresolved:
# sample code from probes I do for Imager 0.75_02
bash-4.0$ cat pngtest.c
#include <png.h>
#include <stdio.h>
int main() {
fprintf(stderr, "PNG: library version %ld, header version %ld\n",
(long)png_access_version_number(), (long)PNG_LIBPNG_VER);
return 0;
}
bash-4.0$ pkg-config --libs libpng
-L/usr/local/lib -lpng -lz -lm
bash-4.0$ pkg-config --cflags libpng
-I/usr/local/include/libpng
bash-4.0$ cc -opngtest pngtest.c -I/usr/local/include/libpng
-L/usr/local/lib -lpng -lz -lm
bash-4.0$ ./pngtest
PNG: library version 10241, header version 10241
And yes, the extra libraries specified by pkg-config are required:
bash-4.0$ cc -opngtest pngtest.c -I/usr/local/include/libpng
-L/usr/local/lib -lpng
/usr/local/lib/libpng.so.9.0: undefined reference to `deflate'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflate'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflateInit_'
/usr/local/lib/libpng.so.9.0: undefined reference to `crc32'
/usr/local/lib/libpng.so.9.0: undefined reference to `pow'
/usr/local/lib/libpng.so.9.0: undefined reference to `deflateInit2_'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflateReset'
/usr/local/lib/libpng.so.9.0: undefined reference to `deflateReset'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflateEnd'
/usr/local/lib/libpng.so.9.0: undefined reference to `deflateEnd'
collect2: ld returned 1 exit status
Now, if I supply LIBS with "-L/usr/local/lib -lpng -lz -lm" to EU::MM it
will use all of those options at once to build the library:
# extract from building Imager with the Devel::CheckLib check disabled
LD_RUN_PATH="/usr/local/lib:/usr/lib" cc -shared -fPIC
-fstack-protector PNG.o impng.o -o
../blib/arch/auto/Imager/File/PNG/PNG.so -L/usr/local/lib -lpng -lz
-lm
unfortunately Devel::CheckLib will apply the library options one at a
time, and so failing every time:
bash-4.0$ cat checklib.pl
#!perl -w
use Devel::CheckLib;
assert_lib
(
debug => 1,
function => <<'CODE',
fprintf(stderr, "PNG: library version %ld, header version %ld\n",
(long)png_access_version_number(), (long)PNG_LIBPNG_VER);
return 0;
CODE
LIBS => "-L/usr/local/lib -lpng -lz -lm",
INC => "-I/usr/local/include/libpng",
header => [ "png.h", "stdio.h" ],
);
bash-4.0$ perl -I/home/tony/dev/imager/svn/Imager/inc checklib.pl
# /usr/bin/cc assertlib7SvTIKT4.c -I/usr/local/include/libpng -o
assertlib9L8Q6Za_
# /usr/bin/cc assertlibIa6SBYbZ.c -I/usr/local/include/libpng -o
assertlibYpJcXz1F
# /usr/bin/cc assertlib_xG5BLU_.c -o assertlibDFkVO8hE -lpng
-I/usr/local/include/libpng -L/usr/local/lib
/usr/local/lib/libpng.so.9.0: undefined reference to `deflate'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflate'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflateInit_'
/usr/local/lib/libpng.so.9.0: undefined reference to `crc32'
/usr/local/lib/libpng.so.9.0: undefined reference to `pow'
/usr/local/lib/libpng.so.9.0: undefined reference to `deflateInit2_'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflateReset'
/usr/local/lib/libpng.so.9.0: undefined reference to `deflateReset'
/usr/local/lib/libpng.so.9.0: undefined reference to `inflateEnd'
/usr/local/lib/libpng.so.9.0: undefined reference to `deflateEnd'
collect2: ld returned 1 exit status
# /usr/bin/cc assertlib_xG5BLU_.c -o assertlib1DI8N7tq -lz
-I/usr/local/include/libpng -L/usr/local/lib
/tmp//ccfQ8IgC.o(.text+0x21): In function `main':
: undefined reference to `png_access_version_number'
collect2: ld returned 1 exit status
# /usr/bin/cc assertlib_xG5BLU_.c -o assertlibstnQw0RH -lm
-I/usr/local/include/libpng -L/usr/local/lib
/tmp//ccxlAPpV.o(.text+0x21): In function `main':
: undefined reference to `png_access_version_number'
collect2: ld returned 1 exit status
Can't link/include 'png', 'z', 'm'
I'm willing to produce a patch for this, but making the behaviour match
EU::MM behaviour would break backwards compatibility, since the current
split-the-scalar-on-whitespace behaviour would need to be changed.
Also, unfortunately, I don't see a way to make the LIBS behaviour
exactly match the separate lib and libpaths parameters, since each
values in the LIBS array is independent, while D::CL applies all values
in libpath to each separate library name in libs.
I expect I'd need to build a set of libtests, each with libpaths and
libraries, which would be built in different ways depending on whether
LIBS was supplied or lib/libpath.
Tony