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:
- Right Click on the Project => Properties => C/C++ Build => Settings
- 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 belibmy.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
How to Normalize a File Path in Bash
Is There Really No Asynchronous Block I/O on Linux
How to Use Debug Version of Libc
The Bash Command :(){ :|:& };: Will Spawn Processes to Kernel Death. Can You Explain the Syntax
How to Deal With a Filename That Starts With the Hyphen (-) Character
How to Loop Over the Output of a Shell Command
How to Create Docker Overlay Network Between Multi Hosts
How to Add Users to Docker Container
Imagemagick Security Policy 'Pdf' Blocking Conversion
Curl to Access a Page That Requires a Login from a Different Page
Difference Between Using 'Sh' and 'Source'
Find Multiple Files and Rename Them in Linux
How to Handle More Than 10 Parameters in Shell
Is Gettimeofday() Guaranteed to Be of Microsecond Resolution
How to Add a Default Include Path For Gcc in Linux
How to Build & Install Glfw 3 and Use It in a Linux Project