Adam Pierce
Adam Pierce

Reputation: 34345

How do you link to a specific version of a shared library in GCC

I'm compiling some code which uses libcurl on a Debian Linux system. My dev machine is running Debian 5 but I want the binary to be usable on older Debian 4 systems too.

I find that if I specify -lcurl it will link to libcurl.so.4 but Debian 4 systems only have libcurl.so.3

Is there some way I can tell GCC to link to either libcurl.so.3 (which exists in both Debian 4 and 5) or just libcurl.so so it will use whatever version is available ?

Upvotes: 55

Views: 61974

Answers (4)

bdonlan
bdonlan

Reputation: 231133

You can pass the specific version shared library file using the syntax -l:libfoo.so.1 that specifies the filename instead of the syntax -lfoo that specifies the library name following the convention libfoo.so on the linker command line, and it ought to do what you want as can be seen at the linker documentation section for the option --library=namespec.

If namespec is of the form :filename, ld will search the library path for a file called filename

In order to provide more details on how to link to a specific version through an example, consider a system that contains two versions of the same library, namely libfoo.so.1.0 and libfoo.so.2.0 installed in one of the library directories, in this case /lib.

$ ls -l /lib/libfoo*

lrwxrwxrwx root root /lib/libfoo.so     -> /lib/libfoo.so.2
lrwxrwxrwx root root /lib/libfoo.so.1   -> /lib/libfoo.so.1.1
-rwxr-xr-x root root /lib/libfoo.so.1.0
-rwxr-xr-x root root /lib/libfoo.so.1.1
lrwxrwxrwx root root /lib/libfoo.so.2   -> /lib/libfoo.so.2.2
-rwxr-xr-x root root /lib/libfoo.so.2.0
-rwxr-xr-x root root /lib/libfoo.so.2.1
-rwxr-xr-x root root /lib/libfoo.so.2.2

# ldconfig -p | grep libfoo
libfoo.so.2 (libc6,x86-64) => /lib/libfoo.so.2
libfoo.so.1 (libc6,x86-64) => /lib/libfoo.so.1
libfoo.so (libc6,x86-64)   => /lib/libfoo.so

A program compiled with the option -lfoo will make the linker look for a file that relies on the naming convention and thus resolve to /lib/libfoo.so (for a shared library object) or /lib/libfoo.a (for a static library object).

A special file name convention is used for libraries: A library known as foo is expected to exist as the file libfoo.so or libfoo.a.

In contrast to that, a program compiled with the option -l:libfoo.so.1 will be linked against /lib/libfoo.so.1, that is a itself currently a symbolic link to libfoo.so.1.1 as can be seen from the listing above, a minor update from 1.0.

And finally, a program compiled with the option -l:libfoo.so.2 will be linked against /lib/libfoo.so.2, that is itself currently a symbolic link to libfoo.so.2.2 as can be seen from the listing above, a minor update from 2.0 and 2.1.

Should you install a newer version of such library, as long as it is a minor update, there should be no need to recompile programs linked to it, since compatible versions should have the same soname and the symbolic links should be updated accordingly.

The actual library foo version X.Y exists as the file libfoo.so.x.y. Inside the library file, a soname is recorded with the value libfoo.so.x to signal the compatibility.

$ ls -l /lib/libfoo.so.2*

lrwxrwxrwx root root /lib/libfoo.so.2   -> /lib/libfoo.so.2.3
[...]
-rwxr-xr-x root root /lib/libfoo.so.2.3

Upvotes: 33

engineer.udays
engineer.udays

Reputation: 1071

Instead of using -lcurl use -l:libcurl.so.3 And of course also use -L _installed_path_

Upvotes: 97

galk
galk

Reputation: 61

I think the correct way to do that will be to use the --filter and --auxiliary flags of the linker.

They are not very documented, but should allow you to load symbols from different versions of the same library according to the machine you are installed on.

Upvotes: 1

Dana the Sane
Dana the Sane

Reputation: 15198

How about creating a symlink local to your project that links to .3, then you can just use -L at compile time. I'm not sure if you'd get a name conflict though, but you could always call it libcurl-old.so just in case.

Upvotes: 1

Related Questions