c++cmakecompilationpoppler

Compile a library in a way that it's shippable


I've a question regarding compilation of a dependency (namely poppler). Poppler is a dependency of my app which is an electron app.

It's working fine on windows (because npm package node-poppler ships the poppler windows build). But on a mac / linux I have to install poppler dependencies by myself (e.g. via homebrew) and then also everything works well.

Now I want to ship the app including poppler and therefore I've started to compile poppler by myself. This is working particularly and all dependencies that it needs I've added via homebrew and finally the build is running and it compiles successfully after long try and error.

But my problem now is, hat if I remove all homebrew dependencies after I've compiled poppler it stops working because there are "links ? (dont know the exact term)" to these dependencies.

e.g.

 cmd: './extlib/darwin/poppler/poppler-gitlab/cmake-build-release/utils/pdfinfo -v',
  stdout: '',
  stderr: 'dyld[93398]: Library not loaded: /usr/local/opt/fontconfig/lib/libfontconfig.1.dylib\n' +
    '  Referenced from: <0062B574-27F1-35D4-BEF8-81E2F2B5EEDB> /Users/bernhard´/Coding/Sides/backend/extlib/darwin/poppler/poppler-gitlab/cmake-build-release/libpoppler.126.0.0.dylib\n' +
    "  Reason: tried: '/usr/local/opt/fontconfig/lib/libfontconfig.1.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/usr/local/opt/fontconfig/lib/libfontconfig.1.dylib' (no such file), '/usr/local/opt/fontconfig/lib/libfontconfig.1.dylib' (no such file), '/usr/local/lib/libfontconfig.1.dylib' (no such file), '/usr/lib/libfontconfig.1.dylib' (no such file, not in dyld cache)\n"

After a lot of reading I've found out that it might be possible to compile it static (even unsure if I'm using the right term here).

I'd like to know what I neet to do, that I can ship the app and what's required, to build poppler in a way that is has no dependencies anymore or has it's dependencies in a place that I have control over and can ship it with my app.

Actually I'm building using following CMAKE options:

-G Ninja -DCMAKE_BUILD_TYPE=Release -DC_MAKE_PROGRAM=/Applications/CLion.app/Contents/bin/ninja/mac/ninja  -DCMAKE_FIND_FRAMEWORK=LAST -DCMAKE_VERBOSE_MAKEFILE=ON -DPOPPLER_QT5=OFF -DPOPPLER_ENABLE_CMS=none -DPOPPLER_ENABLE_SPLASH=OFF -DPOPPLER_ENABLE_UTILS=OFF -DPOPPLER_ENABLE_GLIB=OFF -DPOPPLER_ENABLE_CPP=OFF -DPOPPLER_ENABLE_XPDF_HEADERS=OFF -DPOPPLER_ENABLE_ZLIB=OFF -DPOPPLER_ENABLE_LIBCURL=OFF -DPOPPLER_ENABLE_LIBSYSTEMD=OFF -DPOPPLER_ENABLE_OPENJPEG=OFF -DPOPPLER_ENABLE_TIFF=OFF

Thanks for any help and sorry for maybe misusing terms as I'm mostly a frontend dev.


Solution

  • You have to compile your program with an RPATH option for your shipped libraries. The reason why you can't run it without those deleted dependencies is simple. (Regarding RPATH check out the ld man pages.)

    1. Your application seems to be linking against the same version of the dependency as the one in your homebrew directory. Thus this shared object is compatible with your executable.

    2. Your linker is only configured to look for the shared objects within certain directories. Thus when you delete the directory, your linker doesn't know where to find these shared objects anymore (because they do not exist).

    On linux distributions you could run your application for example with: LD_LIBRARY_PATH=./path_to_your/library/ && ./your_executable. And it would suddenly work.

    RPATH solves this by telling the linker where to look for the linked dependencies.

    I would like to give you a general warning here. This is not the way to go when it comes to shipping your executable (and especially libraries) on different distros. It's better to make a package, using the available -dev packages for the given distribution. - Because otherwise you are slowly introducing dependency hell for the developers who wish to use it!

    To answer your question regarding static linking: You will increase the size of your executable, so keep that in your mind if you wish to take this path instead