libpng16.so.16: undefined reference to `inflateReset2@ZLIB_1.2.3.4'

5.5k views Asked by At

I am building a fork of caffe (3D-caffe), on my university cluster which has a different builds of different versions of different software in /software/software/<package>/<version-compiler>/

When cmake executes this compilation step:

g++ -fPIC -Wall -Wno-sign-compare -Wno-uninitialized -O3 -DNDEBUG \
CMakeFiles/caffe.bin.dir/caffe.cpp.o  -o caffe -rdynamic ../lib/libcaffe.so \
../lib/libproto.a /software/software/Boost/1.61.0-foss-2016a/lib/libboost_system.so \
/software/software/Boost/1.61.0-foss-2016a/lib/libboost_thread.so \
-lpthread -lglog /software/software/gflags/2.1.2-foss-2016a/lib/libgflags.so \
-lprotobuf -lpthread -lglog \
/software/software/gflags/2.1.2-foss-2016a/lib/libgflags.so \
-lprotobuf -lhdf5_hl -lhdf5 -lrt -lsz -lz -ldl -lm -lpthread -llmdb -lleveldb -lsnappy \
-lcudart -lcurand -lcublas -lcudnn \
/software/software/OpenCV/3.1.0-foss-2016a/lib/libopencv_highgui.so.3.1.0 \
/software/software/OpenCV/3.1.0-foss-2016a/lib/libopencv_imgcodecs.so.3.1.0 \
/software/software/OpenCV/3.1.0-foss-2016a/lib/libopencv_imgproc.so.3.1.0 \
/software/software/OpenCV/3.1.0-foss-2016a/lib/libopencv_core.so.3.1.0 \
-lopenblas -Wl,-rpath,/home/p253591/3D-Caffe/build/lib:/software/software/Boost/1.61.0-foss-2016a/lib:/software/software/gflags/2.1.2-foss-2016a/lib

TL;DR: The essentials form is (note the -lz for linking to libz):

g++ ... .../caffe.cpp.o  -o caffe .../libcaffe.so .../libproto.a .../libboost_system.so ...more .so's and -lxyz's... -lz

It errors:

/software/software/libpng/1.6.23-foss-2016a/lib/libpng16.so.16: undefined reference to `inflateReset2@ZLIB_1.2.3.4'
collect2: error: ld returned 1 exit status

And this seems to be correct, because when I specify the -print-file-name=libz.so.1 option to g++, it prints /lib/../lib64/libz.so.1, which is slightly too old regarding version.

I have a newer version in /software/software/zlib/1.2.8-foss-2016a/lib/, but when I:

  • prepend this path to LD_LIBARY_PATH,
  • append it to the -rpath option, or
  • add it using the -L option,

g++ keeps using /lib/../lib64/libz.so.1 as it reports using -print-file-name

What does work, is removing the -lz option and adding /software/software/zlib/1.2.8-foss-2016a/lib/libz.so.1 explicitly as a file to include during compilation/linking. But that seems like a hack.

How can I tell g++ to use /software/software/zlib/1.2.8-foss-2016a/lib/libz.so.1 instead of /lib/../lib64/libz.so.1 when fulfilling the -lz option? Preferably indirectly via cmake (when building caffe).

Thank you in advance!

EDIT

ldd states the right .so is used:

# ldd /software/software/libpng/1.6.23-foss-2016a/lib/libpng16.so.16
        linux-vdso.so.1 =>  (0x00007fff55599000)
        libz.so.1 => /software/software/zlib/1.2.8/lib/libz.so.1 (0x00007f7875b29000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f7875888000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f787566b000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f78752d7000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003328800000)

Moreover, the symbol should be there in this libz.so.1:

# nm /software/software/zlib/1.2.8/lib/libz.so.1
...
0000000000008270 T inflateReset2
...
0000000000000000 A ZLIB_1.2.3.4
....
#

I'm assuming the @-notation in de undefined symbol-error somehow needs the A-type symbol to be there as a version check (but I could not find any documentation on this in ld.so man pages)

1

There are 1 answers

1
yugr On BEST ANSWER

My guess is that you add -L after -lz which won't work as -L only affects -l which follow it. Also note that -rpath and LD_LIBRARY_PATH are influencing runtime library search (and also ldd output) so they won't have much influence on compilation.