Search code examples
ubuntulinkerg++linker-errorssuse

Explaining a difference between g++ on SUSE SLED 11 SP2 versus Ubuntu 14.04


I'm bringing an Ubuntu 14.04 OS up to a build standard. The goal is for it to replace an existing SUSE SLED 11 SP2 builder. But I've hit an error I find difficult to explain.

The build command which produces the error is

g++
-o
out/linux-rel/bin/PrtReporter
-fstack-protector
-m32
-Wl,-rpath,/local/out/linux-rel/bin
-l:libz.so.1.2.8
out/linux-rel/obj-static/prt/CrashReporter.o
out/linux-rel/obj-static/prt/LibArchiveWrapper.o
out/linux-rel/obj-static/utilities/RTSConfigUtilities.o
-Lout/linux-rel/bin
-Lout/linux-rel/bin
out/linux-rel/bin/libcurl.so
out/linux-rel/bin/libcurl.a
out/linux-rel/bin/libarchive.a
-lpthread
-lrt
-lxml2

On Ubuntu this results in a link error. g++ cannot find the symbols from libz.

To fix this I can simply place -l:libz.so.1.2.8 after out/linux-rel/bin/libarchive.a. This 'looks' correct as it allows libarchive.a to find the libz symbols. i.e. Which I believe should be listed after the library that depends upon them.

But I don't know why this is necessary on Ubuntu. The same command works fine on SLED.

Any ideas?


Solution

  • g++ cannot find the symbols from libz.

    You have libz in the wrong place on the link line, and Ubuntu configured their gcc to pass --as-needed to the linker by default.

    You can run readelf -d PrtReporter | grep libz and verify that libz.so is missing (i.e. the loader will not even try to load it).

    To fix, add -Wl,--no-as-needed or (better) move libz to correct place on the link line.