Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with library dependencies on linux

I am using libcurl in my project and it depends on openssl and bunch of other .so in runtime.
This dependency is kind of pain in the ass, since different distributives/versions may contain different openssl versions.

For example I am experiencing problems running on Ubuntu 11.10 if I compiled my app on Ubuntu 9.10.

I am seeing two options how to solve this but none of them aren't good enough for my case:

  1. package my app and let package manager solve this sort of stuff

  2. link all deps statically

My app is really tiny and package/maintain it would be overkill. Plus, one of the requirements is that it should be download-and-run'able. So, (1) is not an opton for me.

Static link (2) would be not-bad solution but it seems that there is no static binary distributions of libopenssl, libcrypto and other transitive dependencies that come with libcurl.

Theoretically I could try to build all that zoo of libs behind libcurl manually, but it seems that this will make maintenance much more complicated.

So, here is the question - am I missing something? Is there a less painful way to do what I want in linux world (Ubuntu to be specific) with less pain? Any suggestions are welcomed.

like image 918
Eugene Loy Avatar asked Oct 08 '22 22:10

Eugene Loy


2 Answers

I am using libcurl in my project and it depends on openssl and bunch of other .so in runtime. This dependency is kind of pain in the ass, since different distributives/versions may contain different openssl versions.

For example i am experiencing problems running on Ubuntu 11.10 if i compilled my app on Ubuntu 9.10.

First up, what is the problem with this? You shouldn't have problems if you're moving up from an older version of Ubuntu to a newer one. If I'm not mistaken, you only need to specify which minimum version of a library you need and the package manager should be able to install a suitable version. Newer versions of libraries should not break existing apps unless you're using deprecated features.

My app is really tiny and package/maintain it would be overkill. Plus, one of the requirements is that it should be download-and-run'able. So, (1) is not an opton for me.

For Linux (especially Ubuntu, Fedora and other top distros), packaging is really the way to distribute your application. Download-install-run is a Windows thing and it's not the way people on Linux install software (well, people new to Linux might...)

You should also try for distro acceptance which will reduce your burden over time. The first step towards this, atleast on Ubuntu, is to create your own PPA (https://help.launchpad.net/Packaging/PPA).

Static link (2) would be not-bad solution but it seems that there is no static binary distributions of libopenssl, libcrypto and other transitive dependencies that come with libcurl.

This is usually a very very bad thing to do. Static linking or just bundling the library with your app puts the burden of updating it on you and there are implications if you don't update those. So, I don't recommend this approach. See here for more details: http://www.dwheeler.com/blog/2012/04/03/#insecure-libraries

Here is Fedora's policy: http://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries

So, here is the question - am I missing something? Is there a less painful way to do what I want in linux world (Ubuntu to be specific) with less pain? Any suggestions are welcomed.

There really are two things to do here:

  1. Packaging: Ideally, this'll be deb for Ubuntu/Debian and rpm for Fedora/Suse. The other popular alternative is to use autotools (autoconf/automake) so that the user can build your application with the required pre-reqs. The last option is to provide just a Makefile and a README and expect your users to do the right thing.
  2. Distribution: Ideally, this is with the distro repositories. Ubuntu PPA is a good starting point. Alternative is to host the binaries/packages on your own site.

Most popular applications provide both a .deb/.rpm for the popular Linux distros as well as .tar.gz with autotools for building on distros that have a different packaging system.

In the end, let me ask you this: is your focus on making it less painful for you to provide your application, or making it less painful for your users to obtain your application?

like image 149
Naveen Avatar answered Oct 12 '22 10:10

Naveen


There is a third option:

Create an archive of some sort that fits your needs and include the .so/.dll files you need, depending on platform. A ZIP archive should work for both Linux and Windows.

Then use LD_LIBRARY_PATH in a wrapper script for your Linux installation (which lets you place your .so files in some special place, typically in a libs directory). Windows, as far as I know, uses CWD as the first place to look for .dll files that are needed by a binary so all you need to do is place them in the same directory as the binary and you're good to go.

Using this method, you get to keep your "distribution" small and there is no need for static linking or any other special handling.

Just make sure that you analyze the actual dependency chain for your .so/.dll files as to not get surprised when some unintended library gets loaded in the target environment.

like image 38
HonkyTonk Avatar answered Oct 12 '22 11:10

HonkyTonk