I have a C++ applicatoin which uses dynamically linked libary. I have placed application and library on target and application is running. Now i have changed some thing in library and made the library and replaced old library on target with new library.
My questions is
Does application takes new libarary with out recompliing and relinking?
Thanks!
Yes, but only if your new library is ABI compatible with the older one.
You can find many info about it on the web. I'd suggest you to read this FAQ about binary compatibility.
Yes, so long as the interface hasn't changed. That's one advantage of dynamically-linked libraries.
Yes. The library is loaded at run-time by the dynamic linker. As long as the ABI is preserved (same compiler and version), your code will use the new code seamlessly without need for recompilation.
If you are just talking about binary compatibility and whether it is necessary to recompile and relink the application, then you should read the link provided in peoro's answer.
However, I am slightly confused by the "application is running" part of your question. If you mean that it is in fact running at the very moment when you replace the library, then it won't use the new version unless it's restarted first or another instance of the application is started (but then the old instance would still use the old version). Not every OS will allow you to just replace a library that is in use by an application, but there are workarounds. In Windows, you can't overwrite or delete the old library, but you can move or rename it before putting the new version there. Linux will allow you to delete the old version, and if you copy the new version using the install command, it will do it automatically for you. But the old version won't be deleted physically from the file system until the application finishes, it will just be invisible.
Related
Let's describe the following scenario:
I intend to create an application for the Linux platform
The application will contain a core shared/dynamic library and the executable. The library will act like an engine, providing common and essential classes and functions.
Now, I know that both the library and executable may change over time and I want to make sure that each executable knows what library is for it and in case the library version is different it will show a message about the library being two old (this could be a constant, abiding by the ABI rules, that will always contain the version and will be checked against the executable's version at the beginning of the entry point).
I have read the ABI specifications and rules and I don't like them (too strict). I don't want to have a single library on the user's system, which I update and try to keep compatible with older executables. I prefer, because I don't know how the interface will change and I want to reserve myself the freedom of doing any change later, to have each executable with its own library version on the user's machine. For example:
Today the user has downloaded the executable "MyApp1" and the version 1.0.0 of the library "MyCoreLib".
One week later I created a new application based on a new version of the library. The user downloads the version 1.1.0 of the library "MyCoreLib" and a new executable called "MyApp2". So, we have 2 different executables and two different versions of the same library (the same name).
"MyApp1" should still be linked to the version 1.0.0 of "MyCoreLib" while "MyApp2" should be linked to the new version 1.1.0.
One week later I create a new application based on the older version 1.0.0 of the library. As the library already exists on the user's computer then we will use that.
Now we have two executables using the first version of the library and one executable using the newer version, and so on.
In Linux, we have the version numbers at the end of the .so libraries. Does this give us the possibility to have multiple versions of the same library and each executable linked to its own library version?
This should be a entry point:
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
Yes. Read up on SONAMEs and RPATH.
Read Drepper's paper: How To Write Shared Libraries
The version 1.0 of your library should generally change only for incompatible API changes.
I'm writing an application that uses both Intel's TBB library, and an API from a company called Maplink, which also uses TBB. The problem is that both my application and the Maplink API want to load TBB.dll from the directory containing my application's binary. The version of TBB.dll that Maplink provided with their API differs from the one my application requires, and they can't both co-exist in the application's executable directory. Do I have any option here other than statically linking TBB into my application so that it doesn't try to load the wrong version of TBB.dll that the Maplink API is using?
In the real world, it is a bad idea to mix different versions of the same DLL. You should really try and get your platform aligned. It is not called package hell for nothing.
That being said, it is very much up to the TBB.dll if it allows for multiple versions at once. You might be able to statically link your code against your version of TBB, but in doing so you will need to make sure the statically linked-in symbols are not dynamically visible (a compiler collection dependant linker option). The code that you have that depends on TBB must probably also be linked in a separate linker step from the one that includes linking to maplink. And the application will need to be linked without relinking against TBB.dll.
At least that is how it could work for so files in Linux.
As mentioned in the comments, you may put the newer version of tbb.dll into your application directory, and it should work properly for both the application and the 3rd party library it uses. For example, the recent version - TBB 4.2 - is binary compatible with old versions back to TBB 2.0.
I have a program which depends on MSVCR90.dll, library which I'm shipping with it alongside the main executable among other things:
ProgramFolder\Main.exe
ProgramFolder\MSVCR90.dll
I wanted to know if when a new update to it is available (fixing a security issue for example) the one I supply would take precedence over the updated file in System32 or SxS.
Is there a way to programatically know which version of the C runtime is being used?
You can check the executables import header to find which version of C runtime it has got references to. Removing it from system32 directory wont help, instead it will create a crash.
I've been having a lot of conceptual issues with Microsoft's CRT. For any project you have to compile all required libraries to link against the same version of the CRT.
The first problem is when your project statically links against the CRT (/MT). Then all the dependant libraries must also link their own CRT statically. So each library has its own version of - for example - malloc(). If you compiled one of the libraries last year on system A, that CRT version may be different than the one you're currently using on another system B with service pack 3+. So if you're freeing objects allocated by the library you may run into problems.
So it seems dynamically linked CRT is the way to go (/MD). With dlls all the libraries would get the current implementation of the CRT on the system. Except that with Microsoft's Side by Side mechanism that's not what happens. Instead you get the CRT version that's stamped on the library you compiled and that version of the DLL is supplied to that library. So exactly the same problem I described before can occur. You compile a library on system A a year ago against one CRT. A year later there's a new version with upgrade. Your main program gets the DLL with one version of the CRT, the library gets the DLL with another version of CRT, same problem can occur.
So what do you do? I realize cross library memory allocation is frowned upon. But you can ignore the malloc example and come up with another one. Do you have every developer recompile every dependant library on their machine to make sure everything does use the same CRT? Then for the release you recompile every library again?
How does this work on Linux? That's my main interest. Is there a CRT supplied with GCC or the Linux system itself comes with CRT libraries? I've never seen the CRT linked explicitly in Makefils.
On Linux, what CRT do dynamic libraries link against? The most current one on the machine, or is it more "side by side" mechanism.
On the Linux side I think there are two basic parts of the standard library that are at issue: We have the C-runtime part, which should pretty much be ABI compatible forever. Effectively whichever version links at final link time should be fine, and you can redistribute any needed shared library with your binary if it's an older version needed for compatibility. Usually the libraries just sit side-by-side on *NIX systems.
Secondly, you have the C++ libraries. These are pretty much guaranteed to not be ABI compatible in any way, so you must rebuild every single component of a final binary against the same version of the C++ library. There's just no way around it unfortunately because otherwise you could wind up with a variety of mismatches. This is why many open source libraries don't even bother with premade library binaries: Everyone needs to build their own copy to make sure that it will properly link into their final application code.
I'm writing a cross-platform application which is not GNU GPL compatible. The major problem I'm currently facing is that the application is linked dynamically with glibc and libstdc++, and almost every new major update to the libraries are not backwards compatible. Hence, random crashes are seen in my application.
As a workaround, I distribute binaries of my application compiled on several different systems (with different C/C++ runtime versions). But I want to do without this. So my question is, keeping licensing and everything in mind, can I link against glibc and libstdc++ statically? Also, will this cause issues with rtld?
You don't need to.
Copy the original libraries you linked against to a directory (../lib in this example) in your application folder.
Like:
my_app_install_path
.bin
lib
documentation
Rename you app for something like app.bin. Substitute your app for a little shell script that sets the enviroment variable LD_LIBRARY_PATH to the library path (and concatenate the previous LD_LIBRARY_PATH contents, if any). Now ld should be able to find the dynamic libraries you linked against and you don't need to compile them statically to your executable.
Remember to comply with the LGPL adding the given attribution to the libraries and pointing in the documentation where the source can be downloaded.
glibc is under the LGPL. Under section 6. of LGPL 2.1, you can distribute your program linked to the library provided you comply with one of five options. The first is to provide the source code of the library, along with the object code (source is optional, not required) of your own program, so it can be relinked with the library. You can alternatively provide a written offer of the same. Your own code does not have to be under the LGPL, and you don't have to release source.
libstdc++ is under the GPL, but with a major exception. You can basically just distribute under the license of your choice without providing source for either your own code or libstdc++. The only condition is that you compile normally, without e.g. proprietary modifications or plugins to GCC.
IANAL, and you should consider consulting one if you need real legal advice.
Specifying the option -static-libgcc to the linker would cause it to link against a static version of the C library, if available on the system. Otherwise it is ignored.
I must question what the heck you are doing with the poor library functions?
I have some cross platform software as well. It runs fine on Linux systems of all sorts. Build with the oldest version of software that you want to support. The glibc and libstdc++ libraries are really very backward compatible.
I have built on CentOS 4 and run it on RHEL 6 beta. No problems.
I can build on stable Debian and run it on testing.
Now, I do sometimes have trouble with some libraries if I try to build on, say old Debian and try to run it on CentOS 5.4. That is usually due to distribution configuration choices that are different, like choosing threading or non-threading.