7

I have an autotools C project.

How do I compile a binary which works with both libcrypto.so.0.9.8 and libcryto.so.1.0.0? (i.e. Ubuntu 9.10 and 12.04)

Depending on the age of the OS on which I do the build, the binary requires one version or the other.

Is there a way of making it not care, or are the differences between the libcryto versions insurmountable?

fadedbee
  • 37,386
  • 39
  • 142
  • 236
  • 1
    As far as I know, from my own experience, if you don't use 1.0 features (such as time stamp) it will work fine. All you have to do is put a dependency on libssl-dev. But since the soname changed, meaning a change in the interface, you have to test it... – Felipe Apr 23 '13 at 21:18
  • @Felipe - no, the major version number change is the core of the problem, the executable requires either 0.9.8 or 1.0.0, depending on the OS version on which it was built. i.e. wherever the libcrypt.so symlink pointed at build-time. – fadedbee Apr 24 '13 at 16:28
  • Ah, I think I understood. You compile your program somewhere (in either 0.9.8 or 1.0.0) and, then, you have to run it somewhere else (again in either 0.9.8 or 1.0.0). Your build environment is different from your runtime environment and they both can vary, correct? – Felipe Apr 24 '13 at 17:42
  • Well, library versioning is designed not to allow doing what you want to do (I think). What you can do is make a script that `ldd` your binary to find out which version it requires and, after that, create a symlink from the required not found library to the one present in the OS. For example, create a symlink from `libcrypto.0.9.8` to `libcrypto.1.0.0`. This is by no means recommended, but I've done already in test environments, and worked.. – Felipe Apr 24 '13 at 18:09
  • @Felipe Yes, I am running the binary in different OSs from where it was built. I'm writing commercial software for Linux. I don't want to have to build on every variant of Linux, but I can't produce a static executable because of GPL. – fadedbee Apr 25 '13 at 07:44
  • The version of the OS is totally irrelevant. The only thing that matters is the version of the library. – William Pursell Apr 25 '13 at 11:56
  • 1
    Note that the previous comment means that you don't have to build for every variant of Linux; you merely need to build once using 0.9.8 and once using 1.0.0. – William Pursell Apr 25 '13 at 11:59

3 Answers3

3

In my opinion, you want to use some function of libcrypto.so.0.9.8 and some from libcryto.so.1.0.0. If most of the functions are required from 1.0.0 or is preferred choice then link with libcrypto.so.1.0.0.

And you may need some function from libcrypto.so.0.9.8 or you may have other good reasons to use libcrypto.so.0.9.8.

In my view, if you link from both the library, you will get linker error (duplicate symbols as both of the library contains same symbols).

If you need to use 0.9.8, then load it dynamically using dlopen and get the function callback which you want use with dlsym.

This can be accomplished as follows:

void * handle;
/*reqd_callback is the callback of required function.*/
reqd_callback cb;

handle = dlopen ("libcrypto.so.0.9.8", RTLD_LAZY);
cb     = (reqd_callback)dlsym(handle, "reqd_function");
//Call the cb
cb (parameters);

//Close the library.
dlclose(handle);

I think this may solve your purpose. If the preference is inverse, invert the library in linking and in loading through program.

doptimusprime
  • 8,303
  • 5
  • 41
  • 82
  • Thanks, I'd already implemented this before your answer, but you get the bounty :-) I first try libcrypto.so, then libcrypto.so.1.0.0, then libcrypto.so.0.9.8, and finally libcrypto.so.0.9.8e (RHEL 5). I only need a few hash functions present in all versions I've encountered. This gives me better than 5 years compatibility (when built on Etch) across RHEL/CentOS/Debian/Ubuntu/Fedora. I have sanity checking code for the dynamically linked functions, just in case they change in future version of libcrypto. P.S. http://www.virtsync.com – fadedbee Apr 29 '13 at 14:00
2

Can you make a soft link that will "point" to either libcrypto.so.0.9.8 or libcryto.so.1.0.0. Give it a generic name and then use that, then whatever version of the library the link "points" to, will be picked up? On app install, you set your soft link to point to the library version available. Your software might be tested up to 1.0.0 if the lib is backward compatible enough, i.e. you don't rely on somthing in 1.0.0 that's not in 0.9.8, your ok.

Jimbo
  • 4,322
  • 2
  • 20
  • 43
2

You can rebuild ssl-0.9.8 (not 1.x because it contains some things that won't work on the older version) and change the line in the makefile where it does the final shared library linkage and embeds the SONAME

recompile it with the SONAME changed from libssl.so.0.9.8 to libssl.so.0

it will look something like: -Wl,-soname,libssl.so.0.9.8 change it to: -Wl,-soname,libssl.so.0

now when you compile against this library the binaries built against it will look for libssl.so.0 (which is included as a symlink in both versions)

technosaurus
  • 7,101
  • 1
  • 28
  • 49
  • RHEL 5.X does not have a libcrypto.so symlink. It only has libcrypto.so.6 and libcrypto.so.0.9.8e iirc. – fadedbee Apr 29 '13 at 08:32
  • I really liked the earlier version of this answer. If it weren't for RHEL 5 lacking the libcrypto.so symlink, I would have accepted it. – fadedbee Apr 29 '13 at 14:04
  • I didn't mention libcrypto because the original question asked about ssl. Still, if you do this and directly link to `-lssl` but _not_ `-lcrypto` (let it dynamically find them at runtime) then objdump -x will only show a NEEDED soname for ssl and since crypto is a dependency, it will get loaded dynamically based on the NEEDED in whichever installed libssl that has a symlink for libssl.so.0 – technosaurus Apr 29 '13 at 17:20