Dealing with library dependencies on linux

删除回忆录丶 提交于 2019-12-21 14:51:08

问题


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.


回答1:


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?




回答2:


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.




回答3:


Did you consider using qt? You simply would not have those problems there, and they have powerful and rmeasy support of ssl and http




回答4:


So you ask "Is there a less painful way." I like the other answers, particularly Naveen's answer. So you have two solutions

  1. Use the .so files (shared libraries) in the operating system and recommend to your users that they use "at least version x." That'll pretty much take care of everything.

  2. Bundle either non-shared (static) libraries -- the .a files -- with your application or bundle shared libraries -- the .so files -- with your application.

The static .a files are pretty simple to build from the source using the ./configure scripts. The .so files you can easily get, but you'll require quite a trick to bundle them with your application. The .so files can be patched; they have paths inside saying from where dependencies should be loaded. So bundling .so files isn't impossible and might even be a handy way of avoiding the manual steps of building .a files for a series of dependencies -- if you find and use the scripts for relocating the .so files.

You write:

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.

Yes, it will, because you'll want security patches as they come out, right? So the best method is #1 -- to let the user install the latest versions he can get his hands upon and take the responsibility to make his system secure.

Solution #2 is handy when you hit a situation where you are doing custom work for a customer who cannot use solution #1. Here you provide periodic releases of your software on a schedule, including the latest dependencies with all their fixes. Small software usually gets to a point where it just stops needing changes. This solution is not a good solution for a small piece of software because you're software isn't changing but you're still making periodic releases simply because the dependencies have updates. So don't use this solution unless your customer actually requires it. It is more expensive in the long run.

Hope this helps!



来源:https://stackoverflow.com/questions/10426868/dealing-with-library-dependencies-on-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!