121

My current preferred C++ environment is the free and largely excellent Microsoft Visual Studio 2005 Express edition. From time to time I have sent release .exe files to other people with pleasing results. However recently I made the disturbing discovery that the pleasing results were based on more luck that I would like. Attempting to run one of these programs on an old (2001 vintage, not scrupulously updated) XP box gave me nothing but a nasty "System cannot run x.exe" (or similar) message.

Some googling revealed that with this toolset, even specifying static linking results in a simple hello-world.exe actually relying on extra .dll files (msvcm80.dll etc.). An incredibly elaborate version scheming system (manifest files anyone?) then will not let the .exe run without exactly the right .dll versions. I don't want or need this stuff, I just want an old fashioned self contained .exe that does nothing but lowest common denominator Win32 operations and runs on any old win32 OS.

Does anyone know if its possible to do what I want to do with my existing toolset ?

Thank you.

Bill Forster
  • 5,835
  • 3
  • 24
  • 26

4 Answers4

135

For the C-runtime go to the project settings, choose C/C++ then 'Code Generation'. Change the 'runtime library' setting to 'multithreaded' instead of 'multithreaded dll'.

If you are using any other libraries you may need to tell the linker to ignore the dynamically linked CRT explicitly.

Rob Walker
  • 43,959
  • 15
  • 93
  • 134
  • "If you are using any other libraries you may need to tell the linker to ignore the dynamically linked CRT explicitly." Recently I ran into this issue. I was building a wxWidgets app, I found I needed to rebuild the wxWidgets libs with the same code generation modification – Bill Forster Nov 12 '08 at 02:55
  • 6
    Man 300 characters isn't many. In case the comment above is unclear, the problem is that both your .cpp files and any library .cpp files need to have 'multithreaded' instead of 'multithreaded dll' else you might get link errors. – Bill Forster Nov 12 '08 at 02:57
  • This introduces numerous issues regarding heap management that you probably want nothing to do with. – Edward Strange Feb 14 '11 at 23:35
  • For the CRT libraries, the VS provides the /MD & /MT options. But, what about linking other libraries statically in general - say, libX.lib (which could be my own library or third party library)? – Kiran M N Feb 28 '13 at 14:07
  • 5
    I get `error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'`. Is there someplace else to change the type of the build? I'm building wxWigets application, much like @BillForster. So will I have to *rebuild* wxWidgets? How do I do that? – Tomáš Zato - Reinstate Monica May 06 '14 at 14:11
  • @Rob Walker "If you are using any other libraries you may need to tell the linker to ignore the dynamically linked CRT explicitly." How do we do this – Gaspa79 Aug 28 '20 at 09:45
  • 1
    @EdwardStrange what kind of issues? – jrh Sep 15 '20 at 13:07
22

My experience in Visual Studio 2010 is that there are two changes needed so as to not need DLL's. From the project property page (right click on the project name in the Solution Explorer window):

  1. Under Configuration Properties --> General, change the "Use of MFC" field to "Use MFC in a Static Library".

  2. Under Configuration Properties --> C/C++ --> Code Generation, change the "Runtime Library" field to "Multi-Threaded (/MT)"

Not sure why both were needed. I used this to remove a dependency on glut32.dll.

Added later: When making these changes to the configurations, you should make them to "All Configurations" --- you can select this at the top of the Properties window. If you make the change to just the Debug configuration, it won't apply to the Release configuration, and vice-versa.

Sam Buss
  • 361
  • 2
  • 9
  • 1
    This appears to work in Visual Studio 2013 with one small addition: I had to change Configuration Properties -> General -> Character Set to "Use Unicode Character Set". – gnovice Sep 12 '18 at 20:30
4

I've had this same dependency problem and I also know that you can include the VS 8.0 DLLs (release only! not debug!---and your program has to be release, too) in a folder of the appropriate name, in the parent folder with your .exe:

How to: Deploy using XCopy (MSDN)

Also note that things are guaranteed to go awry if you need to have C++ and C code in the same statically linked .exe because you will get linker conflicts that can only be resolved by ignoring the correct libXXX.lib and then linking dynamically (DLLs).

Lastly, with a different toolset (VC++ 6.0) things "just work", since Windows 2000 and above have the correct DLLs installed.

Ayxan Haqverdili
  • 17,764
  • 5
  • 27
  • 57
Jared Updike
  • 6,806
  • 7
  • 42
  • 67
1

In regards Jared's response, having Windows 2000 or better will not necessarily fix the issue at hand. Rob's response does work, however it is possible that this fix introduces security issues, as Windows updates will not be able to patch applications built as such.

In another post, Nick Guerrera suggests packaging the Visual C++ Runtime Redistributable with your applications, which installs quickly, and is independent of Visual Studio.

bunkerdive
  • 1,801
  • 1
  • 23
  • 26
  • 4
    While packaging the redistributable seems to be the preferred solution, you need admin privs to run the redistributable installer. That's not a viable option if you have any non-admin users. – Kevin Condon Apr 04 '13 at 16:49