How to Specify the Library Version to Use At Link Time

How to specify the library version to use at link time?

The linker is able to accept filenames too

gcc  app.o -l:libmy.so.1 -o app

From man ld:

-l namespec

--library=namespec

Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If
namespec is of the form :filename, ld will search the library path for a file called filename
, otherwise it will search the library
path for a file called libnamespec.a.

I noticed that older versions do not support it, so check man ld -l or --library option on your system.

You could also link to the file mentioning its full name

gcc  app.o /mylibpath/libmy.so.1 -o app

How to specify the library version to use at link time in eclipse?

I coworker helped me to solve this:

  1. Right Click on the Project => Properties => C/C++ Build => Settings
  2. Under GCC C++ Linker => Miscellaneous: Write the full name of your library, including the library path. Similar to the indications on this post for building with GCC.

GCC: Specifying a Minimum Shared Library Version

You are describing external library versioning, where the app is built against libfoo.so.0, libfoo.so.1, etc. Documentation here.

Using external library versioning requires that exactly the same version of libfoo.so.x be present at runtime.

This is generally not the right technique on Linux, which, through the magic of symbol versioning, allows a single libfoo.so.Y to provide multiple incompatible definitions of the same symbol, and thus allows a single library serve both the old and the new applications simultaneously.

In addition, if you are simply always adding new symbols, and are not modifying existing symbols in incompatible way, then there is no reason to increment the external version. Keep libfoo.so at version 0, provide a int foo_version_X_Y; global variable in it (as well as all previous versions: foo_version_1_0, foo_version_1_1, etc.), and have an application binary read the variable that it requres. If an application requires a new symbol foo_version_1_2 and is run with an old library that only provides foo_version_1_1, then the application will fail to start with an obvious error.

How do applications resolve to different versions of shared libraries at run time?

Versioning of shared objects works as follows:

When you create a shared object, you give it both a real name and an soname. These are used to install the shared object (which creates both the object and a link to it).

So you can end up with the situation:

pax> ls -al xyz*
-rw-r--r-- 1 pax paxgroup 12345 Nov 18 2009 xyz.so.1.5
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so.1 -> xyz.so.1.5
lrwxrwxrwx 1 pax paxgroup 0 Nov 18 2009 xyz.so -> xyz.so.1

with xyz.so.1.5 possessing the SONAME of xyz.so.1.

When the linker links in xyz.so, it follows the links all the way to xyz.so.1.5 and uses its SONAME of xyz.so.1 to store in the executable. Then, when you run the executable, it tries to load xyz.so.1 which will point to a specific xyz.so.1.N (not necessarily version 1.5).

So you could install xyz.so.1.6 and update the xyz.so.1 link to point to it instead and already-linked executables would use that instead.

One advantage of this multi-layer method is that you can have multiple potentially incompatible libraries of the same name (xyz.so.1.*, xyz.so.2.*) but, within each major version, you can freely upgrade them since they're supposed to be compatible.

When you link new executables:

  • Those linking with xyz.so will get the latest minor version of the latest major version.
  • Others linking with xyz.so.1 will get the latest minor version of a specific major version.
  • Still others linking with xyz.so.1.2 will get a specific minor version of a specific major version.

Now keep that last paragraph in mind as we examine your comment:

Now lets say I compile another version of the same library with the following real-name, libmy.so.2.0. The SONAME by guidelines would be libmy.so.2.0.

No, I don't believe so. The soname would be more likely to be libmy.so.2 so that you can make minor updates to the 2.x stream and get the latest behaviour.

Is there a way to set the elf NEEDED field at link time?

I think I have answered my problem though not the question I actually asked.

RPATH is searched before LD_LIBRARY_PATH.
The reason /usr/lib64/libstdc++.so.6 is being picked up rather than libstdc++.so.6.0.22 is that there is no symbolic link from /where/i/installed/libstdc++.so.6 to /where/i/installed/libstdc++.so.6.0.22

So the rule is follow the standards for your platform (where they are sensible). In this case:
Whenever you install a shared library install the expected links as well.

I think the actual question I asked is still interesting technically so I will still accept a better answer to that if anyone has one (even years later).

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

You can pass the actual .so file instead of -l on the linker command line, and it ought to do what you want.

How to specify the correct library to use when LD_LIBRARY_PATH includes path to both 32 bit and 64 bit versions

In answer to your second question, you only used -L to specify the link time path. You need to also add -rpath=<path> for each path that you specify with -L. to get it to look at run-time as well.

If you're using the gcc/g++ driver for linking, then you should use -Wl,-rpath=<path>

e.g. library libfoo.so in /opt/libs/lib64:

gcc -o test test.o -L/opt/libs/lib64 -Wl,-rpath=/opt/libs/lib64 -lfoo

In answer to your first question, if LD_LIBRARY_PATH is causing issues, then your first port of call is ldd which shows the paths to the libraries that are being linked at run-time. Start with an empty string and work up from there.

Thirdly, if the reason that LD_LIBRARY_PATH needs to be set is because there are libraries in /opt/lib, etc... then you should be adding these paths to your /etc/ld.so.conf and using ldconfig to update the search map for these libraries. This will typically save you from needing the LD_LIBRARY_PATH variable at all.

Which is the correct way to build a static library with link time code generation on Linux?

If you don't add --plugin /psth/to/lto-plugin.so* to ar parameters, you will get undefined references at link time and a warning at archive creation time. Or at least that's what I'm getting. You probably need to add it here:

set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> --plugin <LTO_PLUGIN_PATH> \
qcs <TARGET> <OBJECTS>")

(LINK_FLAGS probably don't belong here, so I omitted them).

I don't know how to set LTO_PLUGIN_PATH automatically.

The plugin enables ar to create LTO-enabled archives. All other methods either don't work at all (non-fat objects in the archive) or don't actually result in link time optimisation (fat objects in the archive — in this case only the traditional object code is used, the LTO information is ignored).



Related Topics



Leave a reply



Submit