3

I'm building C++11 with GCC 4.8 on CentOS 6 using "hax", then deploying on arbitrary CentOS 6 targets (on which anything C++-related out of the box will have been built as C++03 with GCC 4.3) (ref).

To make this work, I'm going to ship all of my third-party libs as well as the g++ runtimes, and rpath my executables so the newer libs are assuredly found in the proper place. For the runtimes, by my count I need to ship libstdc++ and libgcc_s. But I need to know where they are on my build system so that I can package them up.

Is there some neat way I can query for their location from within my packaging script?

(If the best approach is too awkward I'll just link them statically, but I'd like to avoid that if I can as my project includes several executables. Also if I were to statically link everything I believe I'd run the risk of GPL-ing my whole project, e.g. by statically linking the MySQL C API via my C++ MySQL wrapper lib. Could do a mixture of both, I suppose, though some sources warn against this…)

For bonus points, do I need to add anything to this list, out of libssl, libcrypto, libm, libpthread, libc, librt, libz and ld-linux-x86-64?

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • I think g++ can dump its search path with some command line flag, which you can grep out of the output, and then try the directories to find the libraries. – Sebastian Redl Aug 17 '16 at 16:19

2 Answers2

6

If I understand correctly, you have already built your binaries and just want to get a list of runtime libraries to package them along with binaries? You can try using ldd for this, like:

> ldd /usr/bin/ls
    linux-vdso.so.1 (0x00007ffe76dd2000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fc97131f000)
    libcap.so.2 => /lib64/libcap.so.2 (0x00007fc97111a000)
    libacl.so.1 => /lib64/libacl.so.1 (0x00007fc970f10000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fc970b68000)
    libpcre.so.1 => /usr/lib64/libpcre.so.1 (0x00007fc970902000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fc9706fd000)
    /lib64/ld-linux-x86-64.so.2 (0x000055c4ba4ed000)
    libattr.so.1 => /lib64/libattr.so.1 (0x00007fc9704f8000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fc9702db000)

This way you will see all libraries needed except, of course, the ones that are used via dlopen().

Roman Khimov
  • 4,807
  • 1
  • 27
  • 35
  • You just don't usually need to package the dynamic loader itself, `ld-linux*.so.*`, although, if the target system has very old glibc, you may have to. – Ruslan Aug 17 '16 at 16:27
  • 1
    @Ruslan: true, although it really depends on what you're trying to do, maybe some chrooted environment. – Roman Khimov Aug 17 '16 at 16:28
  • I used the approach in my answer for libstdc++, then `-print-file-name` for other shared libraries I want to package. – Lightness Races in Orbit Aug 17 '16 at 19:24
  • (the advantage being that I can do so in make variables before I've even built anything) – Lightness Races in Orbit Aug 17 '16 at 20:29
  • @LightnessRacesinOrbit: Well, YMMV, but for determining libraries used in run time I'd rather use something that uses ld.so instead of GCC which is about compile time. Granted, there should be no practical difference, but who knows. – Roman Khimov Aug 17 '16 at 20:32
  • @RomanKhimov: Dunno, seems to me that it's _even better_ to explicitly name the libraries that are actually being found during the build, so if there _were_ a practical difference (I agree, there shouldn't be) I'd definitely be getting what I want. And then I'd be nuking the practical difference by redistributing literally the libraries I linked against and ensuring that these were the objects used at runtime (cos I'm `rpath`ing). – Lightness Races in Orbit Aug 17 '16 at 20:41
  • @LightnessRacesinOrbit: maybe it's just very unusual for me to see GCC being used this way, because the usual package build process has separate stages for compilation, installation and packaging that involves automatic dependency finding, the latter never uses GCC and only operates on final resulting binaries. Also, the right answer might be dependant on the way you test your application, if you always test your full final (libraries included) package, then you may really not care much and use something that is easier to implement for some reason. – Roman Khimov Aug 17 '16 at 21:07
  • 1
    Your approach has the benefit of working even when `$(GCC_INSTALL_DIR)/libstdc++.so` is a linker script, I've discovered... – Lightness Races in Orbit Aug 19 '16 at 13:47
1

In my Makefile:

GCC_INSTALL_DIR := $(shell $(CXX) -print-search-dirs | grep install | cut -d' ' -f2)

…then my main build target will perform:

ln -sf $(GCC_INSTALL_DIR)/libstdc++.so $(BIN_DIR)/deps/

…and I can dump everything in $(BIN_DIR)/deps into the right place on install.

I think.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055