What are some reasons not to statically link to the VC CRT? - c++

I'm finding that with dynamic linking, even with SxS, Windows Update will come along and stomp on a version of the VC8 CRT (for example it has a security flaw) and then my app will fail to run with older versions.
What are some of the important reasons to stay with the dynamic linking with VC CRT, other than increasing the size of your binaries?

Staying up to date on security fixes is a good reason. Otherwise, you're responsible for rebuilding your application with a fixed CRT and deploying it to your customers.
Using a shared CRT should result in lower memory footprint for the system, since most of the DLL's pages can be shared between processes.

I prefer static linking. Security is not a really big issue since hackers target applications that many users have installed on their system. So unless your application has over 1 million users, I wouldn't worry about it being exploited by hackers.
I don't like dynamic linking. It just feels too fragile to me.
EDIT: And if you want to make sure that your users have an up-to-date version of your application then also write an updater application that is automatically installed along with your main app. On Windows this could be implemented as a Service.

See http://people.redhat.com/drepper/no_static_linking.html
It's about linux, but some of the ideas apply.

If done right there should be absolutely no problem with dynamic linking and the application should not fail to run. The only hard part is to switch to building your installer from whatever method you use now to the way supported by Microsoft (redistributable merge modules - MSM, MSI, dynamic linking). See this link for extremely precious advice right from the source. Some interesting quotes from the blog:
In order to redistribute the Visual C++ libraries, all you need to do is include the appropriate .MSM file and its accompanying policy .MSM to distribute the library you need.
Again, just to emphasize – do not use VCRedist*.exe unless you are using Click Once to deploy your application.
However, I can think of no scenarios in which this (my note: static linking) is actually the right thing to do when shipping your product to customers.
I do agree that you might need to do non-trivial work to implement this (maybe you're not using MSI right now etc.) but I think that if resources allow you should try to switch to the recommended methods described above.
And if you don't do it the way described above your application will indeed stop working at some point. And developers blame Microsoft while they were really not following the supported way described above. Maybe Microsoft is to blame because it doesn't link to the blog above more often on MSDN to spread the word but that's about it.

You're lucky out there in Windows. And Linux literally consists of libraries, and you have such issues with all of them. :-)
As far as I understand, library vendors always retain backward compatibility, especially if it's Microsoft. So, the possible solution is to build your application on an old machine, keeping in mind that Microsoft develops CRT library in the way that your app will run on all further versions.

When your program is using something from the CRT that is one of the 'security leaks' that you mention. If you link statically your users won't know that they are subject to a security flaw, and are maybe in danger of a virus. On the other hand if your program doesn't work because it is dynamically linked they will be forced to update to the new safe version.

Related

Options for distributing a C++ Linux application that uses wxWidgets

I'm working on a C++ Linux application that uses wxWidgets, and needs to be distributed as a compiled binary application. The project lead has specified that we are to include all dependencies for the application so that the end user does not need to install anything to run the application, provided they have standard system components installed already (libc, etc). I think this requirement is something that the end user asked for. I know that this is not what you might consider to be a "normal" distribution process for Linux applications.
For simple libraries that don't have many dependencies themselves, this is not an issue. But for wxWidgets I'm running into issues with webkitgtk which is required for the WebView class (which is used in the application). webkitgtk has a number of dependencies itself, which may have their own dependencies, and so on. Basically, it looks like I'd be opening a real can of worms by trying to include everything in the application, and the more senior developer on the project seems to agree.
So I'm wondering, what are my options for distributing such an application? I've tried searching for information about this, and the prevailing opinion seems to be to have the end user install wxWidgets. These are the options that I've come across:
Compile all dependencies as shared libraries as the project lead wants. The downside to this is that there are many libraries to worry about and this will lead to significant bloat.
Require that the end user install wxWidgets (on top of GTK and webkitgtk). The downside here is that the user would have to install multiple dependencies, and if they aren't on a distribution with appropriate versions of the above in their package manager, this could be a real hassle for them. It also means we couldn't provide something that was specifically asked for.
Require that the end user have GTK and webkitgtk installed, but not wxWidgets. Same downsides as above, but with fewer dependencies. An additional downside is that there may be version compatibility issues if different versions of the dependencies are installed than were used to build the packaged wxWidgets library.
Am I correct in my assessment of the pros and cons of these various options? Are there any options that I'm missing?
Thanks!
David,
The best possible solution is probably to ask user to install X11, GTK+{2,3} and WebKit-GTK.
wxWidgets can be statically linked with the application.
You can ask you user to have a WebKit-GTK to be at least version X.Y.Z and that should satisfy the requirements. Integrating WebKit-GTK with all its dependencies, especially since there is a dependency on GTK+ itself will be very hard. So if you go this route you will be screwed.
As linux user i vote for manual dependencies installation via package manager. It's not that hard and could even be done automatically if you provide package (Not just binary). Carrying runtime may cause problems (E.g. Steam on Debian). Another option is to provide two flavors: all inclusive and dependency requiring.

What is best practice for deploying an application as static or as dynamic build?

I am planning to release and deploy an application, written in C++ and wxWidgets. The wxWidgets-library is available as dll and as well as static library. Therefore, i have the option to deploy the application as dynamic built application or as static build.
Currently, i prefer the static-build option, because:
the executable is not too big ( < 20 MegaByte).
there are no dependencies to consider.
there is no installation required.
Question
Did i miss something very important?
You should use dynamic linking when there is a good reason to use it and static linking otherwise. Some good reasons to use dynamic linking are:
You're distributing binaries for a system which already has or, may have, wxWidgets libraries such as a number of Linux distributions, OS X (with Homebrew) etc. In this case it is strongly preferable to reuse the existing system libraries rather than using your own ones.
You have several modules using wxWidgets: space saving from using dynamic linking may be quite significant here.
You use wxWidgets from a DLL under MSW: in this case wxWidgets itself should also be linked as a DLL, otherwise you risk having problems if more than one instance of wxWidgets is loaded into the process address space.
You plan on updating the installation of your application via network: in this case it may be nice to be able to update just a single DLL instead of a whole monolithic application.
If neither of these reasons apply, e.g. you just want to distribute a single program under MSW, static linking is simpler and so preferable.
A related note: if you do end up distributing wxWidgets DLLs, consider using a unique suffix for them instead of "custom" used by default, this will reduce the chances of confusion between your DLLs and some other version of wx.
My suggestion would be to go for static linkage. My two cents on advantage:
You aren't dependent on WX toolset being installed on client site, neither you need to give it bundled with your installer, not as standalone installer as a prerequisite.
You don't expect or ask the customer to do WX installation (or even XCOPY deployment). Customer won't bother!
20MBs is quite small in TBs of world and good MBs of Internet speed.
You don't get unexpected behavior bugs from customer, if they happen to use higher/lower version of library.
You can be confident that application will work the same way you tested in your environment (mostly)
You can continue using X version of WX, even if buggy/flashy X+1 version comes out. You don't want to let customer have "newer and refined" version of library, which breaks your app!
Whilst in your case the executable isn't very big, it can get extremely large if you link everything statically. It also uses more memory, as the larger executable has to be loaded into memory.
If you were to use a dynamic library, the operating system can "share" the read only memory from each between processes, lowering your memory requirements.
Updating your application can also be easier with a dynamic library, as rather than having to update the entire executable you can just swap out the dynamic library (assuming its interface is the same) and voila! The same applies if the user wants to update their dynamic library (for example, via a package manager).

How should/could/must I handle the dll that my C++ projects depend on?

I'm lost here and I have no clue how to proceed. This is not a question about how to make my program work, this is a question about how to stop wasting my time.
My programming environment is Visual Studio 2013 on windows, in C++.
I use 3 libraries extensively, namely: boost (using dynamic linking), OpenCV, and Qt.
During the development, I have configured VS to look at those 3 libraries by default for include and .lib. I have also added the 3 folders containing all the dlls to my PATH environment variable.
It works, but it is sometime painful, let me explain you when.
First hassle: Anytime I have a LNK error telling me I miss a function, it is usually on OpenCV since it has only one include file referencing all the functions. I have to look at OpenCV's source code to see what module this function belongs to and to know what I must link my program to.
Second Hassle: When comes the time to deploy my application, I have to ship it with all the relevant dlls. To know which one I need, I open dependency walker and try to forget nothing, I have then to test it on a different computer because 102% of the time I have missed a couple, and then I have to configure my Installer generator to include all those one by one.
Third Hassle: To ease a little bit the process of configuring a new development machine, I have recently switched to NuGet. It is great, I add boost with a couple of clicks to any project. But now my boost DLLs are everywhere, I have one folder per boost library, and since there are dozens of those I can't even add them all at once to my PATH now, so I have to move them manually to the appropriate folder, and that is really not what I want to do with my not-so-precious-but-who-are-you-to-judge time
I have looked around and couldn't find any good practice regarding this issue, maybe because they are too obvious, or too specific to a particular setup.
How do you do? How would you do if you were me?
We put all our external dependencies in version control along with the code. This ensures that all code can build "out of the box" on any of our development machines and also ensures that for any given version of the code, we know exactly which dependencies is has.
The best way to check for missing dependencies is how have a good automated test suite, if you've got comprehensive converge then if your tests pass you must have deployed the required libraries.
In terms of linking to the appropriate libraries, unfortunately, that just sounds like an issue with the structure of OpenCV (I'm not familiar with OpenCV). I tend to use dumpbin under Windows and nm under Linux to easily grep for symbols when I get link errors with an unfamiliar library.

How to deploy a portable C++ application?

I have written a portable C++ application using Qt libraries. This means that I cannot use the MT flag for compiling without risking memory issues.
This leaves me with two options:
1) Deploy the portable application with an installer.
2) Package the C++ dependencies within the same folder or use private assemblies.
Both 1 and 2 defeat the idea of portable software, so I was thinking of a third option:
3) Use IExpress to drop the C++ dependencies before launching the application. On exit, delete the C++ dependencies.
Unfortunately, option 3 has received some flak from some stackoverflow members. They even dislike option 2 which leaves me with only option 1. I can see option 1 as doable if I use a portable installer.
Is there such thing as a portable installer? Essentially, I want the installer to check to see if the needed dependencies are installed before running my application (just like a regular installer would) and if they are, then just continue running my application. Otherwise, give a message box to the user that they could download it providing a link to the URL. I am aware I can write my own installer that can do this in C++ but I was wondering if there are any installers that already offer this specific functionality.
http://qt-project.org/doc/qt-4.8/deployment.html
The dlls for Qt in windows are so small, that deploying them with the application isn't an issue in my opinion.
There aren't any programs out there that I know of that place the Qt dlls on windows in some place that another program later would find (like c:/Windows/system32).
I think the only place where you could expect reuse of the libraries is in Linux or a mobile device that has a lot of Qt apps. But even then you have make sure that the versions of the libraries are high enough to support all the functionality that you are using.
Hope that helps.

General approach to missing DLL's

I guess everyone has run into missing dll's issues from time to time. What I am trying to get is the 'recommended' method to find and install the dll's. Finding out which dll's are missing is easy enough using depends.exe.
Don't use depends.exe anymore, it hasn't kept up with developments in the Windows core and deployment strategies like the side-by-side cache. Trying to fix the warnings it gives will actually mess up your machine pretty badly. Only use it for hints if a program actually fails to start.
99% of the missing dll errors that I tend to come across are missing C++ runtime libraries (eg =MSVC*.dll=) or the .Net framework, where the developer has built with dynamic linking to the C++ runtimes but hasn't created an installer with the required merge modules, or they have built a debug version which links against the debug runtime libraries which you are not permitted to redistribute.
In the vast majority of these cases, simply installing the correct Visual Studio 2005/2008 C++ runtimes (eg see here) or .Net framework will fix the problem.
That depends greatly on which DLLs are missing and why they are missing, I don't know that there is a one-size-fits-all answer.
My advice would be to use depends to find which DLLs are missing, try to find out where those DLLs were supposed to be installed (and what application was supposed to install them), and then try to reinstall that application or find out what happened to screw up the dlls.
Another thing to check is for 32bit/64bit mismatches, that can make it seem like DLLs are missing sometimes, especially on 64bit platforms.
Or if you are using .NET, you can have trouble with assembly versions and the GAC sometimes.
You can also check the PATH environment variable, I would advise against blindly adding to your PATH to get it to find DLLs you want, that can cause all sorts of other weird problems.
Sometimes you have to hack around with the PATH or copy files to get things to work, but it is usually better if you can figure out what went wrong in the first place and fix it.
Get the DLL from its publisher's website, if possible, and then follow the publisher instructions to install. Don't forget to respect licensing rules!