1

Hi all I have created a c++ app for Ubuntu 16.04 (g++ 5.4.0) using and a few poco libraries. I need to install the app in a previous Ubuntu 14.04 (g++ 4.8.4). So I decided to distribute the shared libraries with the executable. Regarding the distribution of libstdc++.so library I followed the post Linking libstdc++ statically: any gotchas? I'm using the following makefile to build the executable file:

CC := g++ 

# Folders
SRCDIR := src
BUILDDIR := build
TARGETDIR := /usr/bin

# Targets
EXECUTABLE := my_app
TARGET := $(TARGETDIR)/$(EXECUTABLE)

SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -c -Wall -std=c++14
INC := -I include
LDFLAGS := '-Wl,-rpath,$$ORIGIN/../share/my_app_data/libs' -L/usr/share/my_app_data/libs
LDLIBS := -lPocoNet -lPocoFoundation -lPocoJSON 

$(TARGET): $(OBJECTS)
    @echo " Linking..."
    sudo $(CC) $^ -o $@ $(LDFLAGS) $(LDLIBS) 

$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
    @mkdir -p $(BUILDDIR)
    $(CC) $(CFLAGS) $(INC) -c -o $@ $<

clean:
    @echo " Cleaning..."; 
    sudo $(RM) -r $(BUILDDIR) $(TARGET)


.PHONY: clean

I installed the executable file in /usr/bin and the libs folder in /usr/share/my_app_data/libs. When I give readelf -d my_app I get the following in both Ubuntu versions:

  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libPocoFoundation.so.48]
 0x0000000000000001 (NEEDED)             Shared library: [libPocoJSON.so.48]
 0x0000000000000001 (NEEDED)             Shared library: [libPocoNet.so.48]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../share/my_app_data/libs]

When I run my_app the shared libraries are not found. I update the /etc/ld/so.conf with the folder /usr/share/my_app_data/libs and then finds the poco related libraries. However it does not find the libstdc++.so.6 even though the file libstdc++.so.6.0.21 exists in libs folder and I get the following printout:

my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by my_app)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by my_app)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/share/my_app_data/libs/libPocoFoundation.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/share/my_app_data/libs/libPocoFoundation.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/share/my_app_data/libs/libPocoJSON.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/share/my_app_data/libs/libPocoJSON.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/share/my_app_data/libs/libPocoNet.so.48)
my_app: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/share/my_app_data/libs/libPocoNet.so.48)

The output of ls -l in the libs folder is :

-rwx---rwx 1 root root 2092592 Dec  13 23:06 libPocoFoundation.so.48
-rwx---rwx 1 root root  348488 Dec  13 23:06 libPocoJSON.so.48
-rwx---rwx 1 root root 1225968 Dec  13 23:06 libPocoNet.so.48
lrwxrwxrwx 1 root root      19 Dec  13 23:07 libstdc++.so.6 -> libstdc++.so.6.0.21
-rw----rwx 1 root root 1566440 Dec  13 23:06 libstdc++.so.6.0.21

The output of file libs/* is:

libs/libPocoFoundation.so.48:      ELF 64-bit LSB  shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=9b5472754fa836e7be0893d6ed306f63b2cbc4aa, stripped
libs/libPocoJSON.so.48:            ELF 64-bit LSB  shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=fb57d0459e72415f90a1fc32b7bb2f695b49c5d7, stripped
libs/libPocoNet.so.48:             ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=175c019baa1ec16d908737443294ed3cf03d3315, stripped
libs/libstdc++.so.6:               symbolic link to `libstdc++.so.6.0.21' 
libs/libstdc++.so.6.0.21:          ELF 64-bit LSB  shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=b6d9d56d8e8afa9d4b46a60eda985d45dcd51524, stripped

And the output of ldd my_app is :

linux-vdso.so.1 =>  (0x00007ffcbd394000)
    libPocoFoundation.so.48 => /usr/bin/./../share/my_app_data/libs/libPocoFoundation.so.48 (0x00007feddb89a000)
    libPocoJSON.so.48 => /usr/bin/./../share/my_app_data/libs/libPocoJSON.so.48 (0x00007feddb645000)
    libPocoNet.so.48 => /usr/bin/./../share/my_app_data/libs/libPocoNet.so.48 (0x00007feddb317000)
    libstdc++.so.6 => /usr/bin/./../share/my_app_data/libs/libstdc++.so.6 (0x00007fedd9f99000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fedd9c7f000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fedd9a68000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fedd96a3000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fedd9485000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fedd9280000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fedd9078000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fedd8180000)
    libidn.so.11 => /usr/lib/x86_64-linux-gnu/libidn.so.11 (0x00007fedd7f4d000)
    librtmp.so.0 => /usr/lib/x86_64-linux-gnu/librtmp.so.0 (0x00007fedd7d33000)
    libgssapi_krb5.so.2 => /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007fedd7aeb000)
    liblber-2.4.so.2 => /usr/lib/x86_64-linux-gnu/liblber-2.4.so.2 (0x00007fedd78dc000)
    libldap_r-2.4.so.2 => /usr/lib/x86_64-linux-gnu/libldap_r-2.4.so.2 (0x00007fedd768b000)
    libgnutls.so.26 => /usr/lib/x86_64-linux-gnu/libgnutls.so.26 (0x00007fedd73cc000)
    libgcrypt.so.11 => /lib/x86_64-linux-gnu/libgcrypt.so.11 (0x00007fedd714c000)
    libkrb5.so.3 => /usr/lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007fedd6e81000)
    libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007fedd6c51000)
    libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007fedd6a4d000)
    libkrb5support.so.0 => /usr/lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007fedd6842000)
    libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007fedd6626000)
    libsasl2.so.2 => /usr/lib/x86_64-linux-gnu/libsasl2.so.2 (0x00007fedd640b000)
    libgssapi.so.3 => /usr/lib/x86_64-linux-gnu/libgssapi.so.3 (0x00007fedd61cd000)
    libtasn1.so.6 => /usr/lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007fedd5fb8000)
    libp11-kit.so.0 => /usr/lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007fedd5d76000)
    libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007fedd5b71000)
    libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007fedd596c000)
    libheimntlm.so.0 => /usr/lib/x86_64-linux-gnu/libheimntlm.so.0 (0x00007fedd5763000)
    libkrb5.so.26 => /usr/lib/x86_64-linux-gnu/libkrb5.so.26 (0x00007fedd54da000)
    libasn1.so.8 => /usr/lib/x86_64-linux-gnu/libasn1.so.8 (0x00007fedd5239000)
    libhcrypto.so.4 => /usr/lib/x86_64-linux-gnu/libhcrypto.so.4 (0x00007fedd5006000)
    libroken.so.18 => /usr/lib/x86_64-linux-gnu/libroken.so.18 (0x00007fedd4df0000)
    libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007fedd4be8000)
    libwind.so.0 => /usr/lib/x86_64-linux-gnu/libwind.so.0 (0x00007fedd49be000)
    libheimbase.so.1 => /usr/lib/x86_64-linux-gnu/libheimbase.so.1 (0x00007fedd47b0000)
    libhx509.so.5 => /usr/lib/x86_64-linux-gnu/libhx509.so.5 (0x00007fedd4567000)

I have also found that by giving ldd in one library e.x. libPocoFoundation.so.48 I get that

libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 

So the my_app executable shows to the right path for libstdc++.so.6 while the shared libraries don't. Since these libraries do not contain rpath to use chrpath is there another way to make them show

libstdc++.so.6 => /usr/share/npt-data/libs/libstdc++.so.6 

?

dk13
  • 1,461
  • 4
  • 20
  • 47
  • "I update the /etc/ld/so.conf" So you have defeated the purpose of -rpath, and in effect upgraded libc and libstdc++ and libm and lingcc_s for all programs on that machine. That's entirely your choice. "libstdc++.so.6.0.21 exists" But does libstdc++.so.6? That's what your app looks for. You need to set up symbolic link libstdc++.so.6 -> libstdc++.so.6.0.21. – n. m. could be an AI Dec 13 '17 at 22:29
  • @n.m. I updated the /etc/ld/so.conf because I wanted to check if I did something else wrong with the libraries. Regarding the files in libs folder exist both the symlink ibstdc++.so.6 as well as the the ibstdc++.so.6.0.21 – dk13 Dec 13 '17 at 22:34
  • Show what you have, don't describe it. `ls -l yourlibdir`, `file yourlibdir/*`, `ldd yourapp` and everything else that might be needed. BTW /usr/share is for platform independent files, the right place for the libraries is /usr/lib/my_app. – n. m. could be an AI Dec 13 '17 at 22:39
  • It could be that other shared libraries your app is linked with are looking for the system libstdc++ and find it first, overriding your choice. Try ldd'ing each of the dependencies. This is not how ldd is supposed to work though, so it's rather dubious. – n. m. could be an AI Dec 13 '17 at 23:33
  • @n.m. Thanks for you replies. By checking the ldd of the libraries I found that for e.x libPocoFoundation shows libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 in host machine. Since it doesn't have rpath to use chrpath is there any other way to change the path of the library in order to show the desired one? – dk13 Dec 14 '17 at 16:02
  • Try setting LD_LIBRARY_PATH and running your program. – n. m. could be an AI Dec 14 '17 at 16:20

1 Answers1

0

Starting with Natty Narwhal, the linker shipped with Ubuntu uses as-needed by default. Which means that libraries with symbols not present in your main executable won't be linked. You can quickly override that by adding Wl,--no-as-needed.

https://wiki.ubuntu.com/NattyNarwhal/ToolchainTransition

Tux
  • 101
  • 1
  • 4