2

How to correctly locate libstdc++.so.* used to compile an autotools project, in order to bundle it with the distribution?

After our team switched to C++11, we need to bundle the new libstdc++.so.6 with every distribution of our software, but how to correctly find the library?

  • Cygwin: /lib/gcc/x86_64-pc-cygwin/5.2.0
  • Linux: /usr/lib64
  • Custom install: /usr/local/gcc-5.2.0/lib64

I already tried:

install-exec-local:
    cp $(shell dirname $(shell which ${CXX}))/../lib64/libstdc++.so.6 ${prefix}/lib

(instead of make dist, we make install into a configured prefix and then bundle the prefix)

And this works, but not for Cygwin, and I'm not sure it will work on other platforms, thus my question.

Edit

See this question for a rationale of bundling libstdc++.so with the software. It works very well. We also use dlopen to load .sos that depend on libstdc++.so so it's harder to link statically than it sounds.

The only issue is locating the libstdc++.so.6 at make dist time (or our equivalent thereof), so that I can cp it to our distribution's ${prefix}/lib directory, before tar-gzipping it and delivering it to the customer. Ideally, I'm looking for something like g++ --print-path-to-libstdc++.so.

The target system, where the software is run, has an older libstdc++.so, that's the whole reason for bundling our own.

Community
  • 1
  • 1
Irfy
  • 9,323
  • 1
  • 45
  • 67

3 Answers3

5

g++ -print-file-name=libstdc++.so

2

Why don't you just link with the -static-libstdc++ option (and -static-libgcc too if you need it)? Then you don't have to worry about bundling, library search paths, etc.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
0

Such a simple thing, but so hard to do.

On Cygwin/MSys, it looks like g++ -print-file-name= only echoes the same file name you provide to it, without adding path.

Instead of focusing on CXX, I tried ldd BINFILE. And that does work on both Linux and Cygwin/MSys, providing full path. But on the latter - only if the binary is 64-bit; for 32-bit, it only shows paths to wow64*.dll.

The only solution which worked for all binaries on both Linux and Windows was:

objdump -p BINFILE | sed -n 's/\s*\(DLL Name:\|NEEDED\)\s*\(.*\)$/\2/p'

But - this gives only file names, without paths. Plus, complex sed query does not provide the best maintainability.

So I think the best solution is to hard-code file names for each OS, and use CXX location as the base for path - like the OP proposed.

Here is a Makefile.am snippet for copying all libraries, but only on Windows (within configure.ac, AM_CONDITIONAL([TARGET_WINDOWS],... needs to be set).

if TARGET_WINDOWS
install-exec-hook:
    mkdir -p "$(DESTDIR)${prefix}/lib"
    $(eval lib_SHARED_INSTALL := $(shell objdump -p BINFILE$(EXEEXT) | sed -n 's/\s*\(DLL Name:\|NEEDED\)\s*\(.*\)$$/\2/p' | xargs -I {} find $(shell dirname $(shell which ${CXX})) -name '{}'))
    cp $(lib_SHARED_INSTALL) $(DESTDIR)${prefix}/lib
endif
mefistotelis
  • 170
  • 1
  • 5