2

I'm compiling a Static (added static after reading comments) C++ library PoDoFo and some of its dependencies are optional, such as libJPEG, libTiff and libPNG. Though, a lot of the libraries have an option to depend on one another as well. For instance you can enable JPEG support in libTiff by compiling libTIFF with libJPEG.

In a perfect world I would hope that libTIFF would enable the libJPEG functions by realizing it has access to libJPEG because I included it in my compilation of PoDoFo. Sadly I think enabling/disabling functions is decided when I first compile libTIFF.

So then that means my PoDoFo library will contain libJPEG multiple times, probably even identical copies if I use the same library.

Will GCC compiler realize this and eliminate/relink the libraries to just one copy of libJPEG?

  • 1
    I believe the answer is **yes**. – Eljay Jul 16 '20 at 01:23
  • 3
    Are these libraries being linked in statically or dynamically? – Human-Compiler Jul 16 '20 at 01:24
  • 2
    It's not normally the compiler that would do this. It is related to how the program is linked. – Peter Jul 16 '20 at 01:33
  • I can't imagine that you have switches to the compiler that are enabling/disabling whole libraries, unless you are talking about manually adding `-DHAVE_LIBFOO=1` or similar, in which case I would recommend upgrading the project's build system. In general, the answer to your question is probably "yes, the compiler will do what you want", but you will need to give accurate details on the build system being used to expect a more specific answer. – William Pursell Jul 16 '20 at 11:53

2 Answers2

2

Basically yes, it'll only include one copy.

The compile switches you are changing don't actually include one library into another, they just enable functionality that requires those libraries, e.g. libTIFF might include functions to convert between jpeg and tiff formats if you enable libJPEG support, but allows you to compile the rest of the library without that functionality if you don't want that.

When you link a final application with PoDoFo, you will also have to link all of the optional dependencies you enabled. This can be automatic for dynamic libraries but the dependencies will all be required at runtime.

In almost all cases there is only one copy of each library linked with the final application - the one exception is if you mix static and dynamic libraries, but that's a whole new can of worms.

Joseph Ireland
  • 2,465
  • 13
  • 21
  • Thank you! Though what made me think I was not just enabling/disabling functions was the fact that, to enable the JPEG functions in libTIFF, you had to provide the source directory for the libJPEG library within the nmake.opt, which made me think it was actually adding libJPEG to the static compilation of libTIFF. – Dmitri Korin Jul 16 '20 at 22:31
  • It wants to know that so it can find header files – Joseph Ireland Jul 16 '20 at 22:49
  • 1
    FYI for static libraries it's actually impossible to accidentally include two copies of a symbol in an executable due to how linking works. The linker will search each library and object file for all symbols required in the application and it's only possible to include each one once. There are weak symbols - i.e. functions declared "inline", it'll pick the first definition it finds, or strong symbols, where having duplicates is an error and you'll see "multiple definitions of XYZ", either way everything can only have one definition. – Joseph Ireland Jul 16 '20 at 23:00
0

Assuming all library are dynamically linked, runtime linker would only load a single copy of each dependent library (so a single copy of libJPEG will be loaded).

In a perfect world I would hope that libTIFF would enable the libJPEG functions by realizing it has access to libJPEG because I included it in my compilation of PoDoFo, but sadly I think enabling/disabling functions is decided when I first compiled libTIFF.

The feature that you describe is called delayed loading and is supported in Windows but not on Linux (at least not by default, see Implib.so tool).

yugr
  • 19,769
  • 3
  • 51
  • 96