Side-by-Side Horror

February 7th, 2008

I’ve been using Microsoft Visual C++ Express 2008 for a while and I really like it. The user interface is easy to get used to and rather minimalistic. Not as minimalistic as Express 2005, but still pretty slimmed compared to various other editors while still retaining high functionality such as simple refactoring, intelligent auto-complete, and decent customizability.

In Microsoft Visual C++ Express you can easily write a C++ program and compile it but you would be mistaken to think that you can simply send the program you just compiled to anyone with Windows installed. WRONG! One does not simply deploy software their way into Mordor. Not according to Microsoft.

Apparently there is this thing called SxS, or Side-by-Side. I have no idea what this means. What I do know, however, is that it’s a pain in the ass figuring out how to make your program work on other computers. This is a scenario I ended up in:

  1. I code a simple Tetris game using SDL for graphics. Nothing strange here, it’s just one extra library to link with.
  2. I compile my C++ program.
  3. Test it on my computer. It works. Rejoice.
  4. Sent it to a friend who then tells me he cant run the program. He gets this error message: “This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.”
  5. I check that I really sent him a working version. It works on my computer so what’s wrong?
  6. I start searching google for info about the surprisingly unspecific error.
  7. I read pages such as this without understanding what to do, then I start searching on MSDN.
  8. On MSDN I find this article which tells me I need to send my friend a fucking installer for the VC++ redistributable package. Now that’s fucked up. Why the hell should I have to supply a lot of extra software just to send my friend a very simple C++ program?
  9. I discard that solution and keep searching.
  10. I find this thread, which seems to be the answer to all my questions. Apparently if I compile with /MT everything should be fine!
  11. Okay where the hell do I set that compiler flag?
  12. After ten minutes of paging through about every option page of the project properties in VC++ I find the option and change it from /MD to /MT (It’s under Configuration Properties->C/C++->Code Generation->Runtime Library if you wonder).
  13. I try to compile, but now I get about ten errors which read similar to “1>msvcrt.lib(MSVCR90.dll) : error LNK2005: _fclose already defined in LIBCMT.lib(fclose.obj)”. What the hell?
  14. It seems my program is being linked with two conflicting runtime libraries now, after I changed that single compiler flag. The linker tells me I need to use /NODEFAULTLIB:msvcrt. Okay I set that in my project properies and try to compile again.
  15. Now it turns out that the SDL library I’m using is not even compatible with the Code Generation I’m using, so I’m back to square one!
  16. Back to google and MSDN library of horrors.
  17. I find this page on MSDN. I hardly bother reading all of it but what I can gather is that if I send my friend a couple DLLs located in the VC++ folder my program should be able to run.
  18. After about 10 minutes of trying to extract the important information out of the MSDN wall of text I finally find the folder C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT.
  19. Okay copy the contents to my programs working directory, 7-zip it, send it to my friend.
  20. My friend says it works. Rejoice!
  21. I post my program on an online community.
  22. The first reply I get is “This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.”
  23. ARRGHHHHH!
  24. I install MinGW.
  25. I download the SDL libraries for MinGW.
  26. I make a .bat script to compile my program.
  27. Linking fails because I linked the libraries in the wrong order. The correct order is -lmingw32 -lSDLmain -lSDL.
  28. It compiles.
  29. It works. Rejoice.
  30. I upload it.
  31. The people on the community say it works. Rejoice!

Edit: This article has created quite a discussion on programming.reddit.com. I would like to say this regarding everyone who there claims I dont know how DLLs work: I do know very well how they work, hence I did not fail to use the SDL.dll. I’ve also written a couple DLLs in my time, practiced dynamically linking them etc. Is it my fault that my program, as compiled with VC++, would link to DLLs which I did not expect it to? Is it my fault that the error message this generates is so amazingly unspecific?

  1. cencio Says:

    :)
    nice article. but it really take less time to fix trouble than read the text.

    1. just compile with static RTL
    2. or remove manifest from exe

    SxS has good side and Dark side. yes, it creates trouble for deployment(manifest hell instead of dll ) but after it create a stable env for software

  2. Joseph E. Davis Says:

    This would be the reason that many people do not like Microsoft Visual C++ Express 2008 or friends.

  3. Jamie Says:

    man, that seems like a lot of hastle. ive done some beta testing for a friend who is a programmer, so i do understand your pain.

  4. Thomas Lee Says:

    This has always been the case with VC++ (or at least it has since version 6, when I last used it). Effectively different, incompatible versions of the runtime for different versions of VC++, PLUS different, incompatible versions of the runtime for the SAME version of VC++ (multi-threaded vs single-threaded).

    Then, as you found out, third party libraries compile against different versions of these runtimes and you get more breakage still. Yucky. :)

  5. Kevin Says:

    Windows may be dominant, but there are few technical reasons for this.

    When you have some spare time, I’d experiment with either Linux or a Mac. You will be *floored* how relatively easy it is to make cool stuff work, C++ program or not.

  6. Andrew Says:

    Distributing your program in MinGW worked because the GNU implementation of the C++ Standard Library was linked *statically*, by GCC, into your program. This is generally bad practice but, as far as I know, there is no real choice in this regard when using the GNU tool chain on Windows.

    Look at, and compare, the sizes of the resulting MinGW and MS VC++ executable files and you will see the difference.

    Compiling in MS VC++ with /MT obviously failed because your SDL library already links against the MS C++ Standard Library as a shared DLL? Who knows?

    In any case, telling people to download the latest Microsoft C++ Runtime is the ‘right thing to do’. If you were writing a Python program you would expect them to install Python. If you were writing a .NET (or Mono). program you’d expect them to install the .NET runtime. This is no different.

    Checkout this interesting post:
    http://blogs.msdn.com/oldnewthing/archive/2008/01/11/7065021.aspx

    It talks of the MFC library, but I’m sure MS policy applies to the latest C++ runtime too. Coincidentally, were any of your testers running Vista? I’m not 100% but I suspect it will come with the latest Visual C++ runtime.

  7. Reddit Says:

    HAI!

    PLZ LRN DIFFERNCE BETWN STATIC AND DYNAMIC LINKING.

    KTHX BYE.

  8. jt Says:

    Microsoft sucks. It’s a fact. For real.

  9. zeek Says:

    That is why I still use Dev Studio 98.

  10. Mark Says:

    This is why I quit working on the Microsoft platform. Most of the info available (docs or Google search results) is so mixed up between all the different dev kits and sdks and libaries and versions of Visual C++, Visual Studio, Windows 32 APIs, etc. etc. it is insanity sorting out what’s what. And now with DRM library support sprinkled everywhere throughout the system, code is super-brittle and sure to break as soon as the latest service pack is installed.

    And for anyone who says this has nothing to do with DRM, bwahahahahah, just you wait and see. If you are a developer, stay far, far away from MS platforms.

  11. Mark Says:

    Libraries, I meant to say, obviously.

  12. voG Says:

    Can anyone still wonder why their software sucks anymore? They should not boy Yahoo! , They should buy some University to tough them how to programm :)

  13. Ibod Catooga Says:

    Haha Microsoft is full of faggot fucks who suck they own mom’s dick and do not swallow but spit it out into a condom and then lick they butt.

  14. Alan Says:

    Dude, step 19 is where you went wrong. You need to copy the entire Microsoft.VC90.CRT directory alongside your application. You can’t just pull individual DLLs out of it. Also, make sure you are generating a manifest for your program (linker option: /manifest).

    When you are ready to deploy, your directory structure should look something like this:

    hello.exe
    hello.exe.manifest
    Microsoft.VC90.CRT\Microsoft.VC90.CRT.manifest
    Microsoft.VC90.CRT\msvcm90.dll
    Microsoft.VC90.CRT\msvcp90.dll
    Microsoft.VC90.CRT\msvcr90.dll

    This will let your program work on any system from Windows 2000 SP3 onward.

  15. admin Says:

    Well I did Copy all of the DLLs (and the manifest=) in the Microsoft.VC90.CRT folder to my programs working directory. I did not include the programs manifest file, but this should be embedded either way.

    The Problem is that this only worked on some systems. Why? I have no idea.

  16. Pemmie Says:

    LERN2PR0RGARM U NUB U SHULD USE PYHT0N ITS LEIK TEH REEL HAXX0R CODEZ L0L

  17. Brianary Says:

    @Andrew and @Alan:
    Clearly, the author did a significant amount of research once something went wrong. How did you know these answers?

    How can any programmer reasonably rely on any of the Microsoft development products to work the first time when crap like this appears to be the norm (based on my own experience)?

    Static linkage may be generally bad practice (though not always), it potentially takes up a few more KiB of drive space, but it is ALWAYS bad practice to produce something that doesn’t work and gives you no warning that there could be trouble in many environments.

  18. Paul Betts Says:

    “9. I discard that solution and keep searching.”

    This was your fatal flaw, as this is the correct solution. The broad explanation of what’s going on is, when you build your program, it writes in to the EXE, “I want *version 9* of MSVCRT. Don’t give me anything else, cause they wrote the program against 9″. When you run it on your friend’s machine, the Loader says “Hmmm, we’ve got version 7, but they wanted 9. Let’s give up” The *manifests* describe these “I am version XXXX of hello.exe and I want version YYYY of MSVCRT”.

    I would also avoid using static libraries, because you don’t get bugfixes when Microsoft releases them, because you statically compiled the code into your EXE, and it also makes your EXE bigger.

    I do realize that SxS can sometimes be a real pain, especially with that really opaque error message. A tool to figure out what’s going on in the Windows SDK called Fusion Log Viewer can help you figure stuff out, as well as Junfang Zhang’s MSDN blog (http://blogs.msdn.com/junfeng/).

  19. Paul Betts Says:

    Oh, as an addendum, the reason why you don’t have trouble with MinGW, is that it doesn’t use SxS. But instead, you’ll hit a much trickier to diagnose with larger programs if you go this (seemingly easier) way, where people will install your app, but they have a slightly different version of SDL or MSVCRT, then totally weird things happen that will make you crazy. Admittedly, SxS isn’t the best solution, but it at least gives you a clear error, instead of random hard-to-debug “why doesn’t this work!!!” errors.

  20. Jesse Says:

    Common problem, you were correct when using the multithreaded option instead of the multithreaded dll, but this creates linker errors, so you need to go to your linker and manually put in all the libs that you’ll need to use, these will conflict with the default libs so you’ll also need to set the NODEFAULTLIBS option to get around that (from memory it’s below where you enter the libs). SDL will also not compile under Visual Studio 2008 as a command line program and needs to be built as a windows app (I don’t think you can switch from one to the other, so you’d need to build a new project as a windows app and copy your code over to it). From memory common libs you’ll need are libcmt.lib and msvcrt.lib (for debugging use libcmtd.lib and msvcrtd.lib) there might be others but I can’t remember them all. After that’s done you shouldn’t have any Visual Studio dll dependencies.

  21. Alan Says:

    “SDL for graphics” is “just one extra library”

    “It works on my computer so what

  22. admin Says:

    “And you think Microsoft is the root of your problems ?”

    Did I say that?

    “Your problem, child, is that you are a amateur.”

    Did I say I wasnt?

  23. kometbomb Says:

    When not using SxS it at least is very simple to redistribute the needed libraries (or link statically) to ensure the program will use the same version of the libraries. I’m all for making things less optimal but easier to use so the dreaded amateurs won’t lose their motivation because of things quite unrelated to _programming_.

  24. Scarleth Says:

    I have to agree with you on this issue. But the fact is that your machine had the most recent version of a library and depended on that while you made your code. Your friend however did not have that library and thus couldn’t understand your code. However, to the best of my knowledge Visual C++ Express has a feature especially made to get past those problems, Called “Bootstrap” or something alike, where it straps the needed DLL files to the .exe file itself, and the publishing utility should have another feature to make an installer that will download all the needed DLL’s and other files from the MSDN site.

  25. Gallico Says:

    It could’ve been so easy. If only your first step would have been “Continue with step 24.” :)

  26. Chris Says:

    Thanks for the article, interesting for us non-elite especially given the subsequent discussion / tips.

    @Alan who is LOLWTFBBQ: it’s clear that you have no friends.

    Regards.

  27. Tobias Says:

    “Alan Says:
    February 7th, 2008 at 9:56 am

    Dude, step 19 is where you went wrong. You need to copy the entire Microsoft.VC90.CRT directory alongside your application. You can

  28. Tobias Says:

    “Unfortunately, the manifest file that is generated contains references not only to VC90 DLLs, but also to VC80 DLLs.”

    ok, reason is clear in hindsight: VS derived the VC80 DLL dependency from the linked SDL.

    I rebuilt SDL 1.2.13 (current stable) using VS9 (needed to download/install DirectX SDK for that). After that, the second dependency is gone, embedding the manifest works and side-by-side installation of the Microsoft.VC90.CRT folder works (at least on a fresh XP SP2 machine).

    For earlier systems it is likely that you then need to add the path to the Microsoft.VC90.CRT folder to PATH.

    The following is also working: put the _contents_ of the Microsoft.VC90.CRT folder in the same folder as your app. You’ll need the manifest! Probably, this way on older systems than XP SP2, this works without setting PATH. I don’t have an older system around, so I don’t know ..

  29. giry Says:

    Thx for the article, i find some answers here.

  30. Christian Says:

    This was very helpful. I spent many hours wrestling with this problem.

  31. Fred Says:

    And, I spent many days wrestling with this BIG problem. After this horror don’t want to use any more f*cked M$ products.

  32. HEX Says:

    I can build console project in VS2005 and VS2008 with /MTd code generating. Both 2005 and 2008 have same problems. The only diffrence between is, I don’t know how to build a win32 form application in VS2008 but I do know how to do it in VS2005. (but I can use VS2005 project v VS2008 and it works for the most of folks)

  33. radioman Says:

    ..my favorite stuff, i love it ;} http://img162.imageshack.us/my.php?image=vsversionao0.png

    after each ServicePack visual studio use old runtime, wtf ;/

    last time i solve it by clean windows reinstall and then vs install, and then sp1 install. but if you install sp1 later you have incorect versions ;{

  34. Doug Says:

    You might consider creating an install package that also installs the c runtime.

    Take a look here for more information:
    How to redistribute the Visual C++ Libraries with your application
    http://blogs.msdn.com/vcblog/archive/2007/10/12/how-to-redistribute-the-visual-c-libraries-with-your-application.aspx

    Of course I have found it to be a little flakey. In some cases it will install only the amd64 bit version on an OS that is 32bit but running on a 64 bit capable processor. I haven’t found a solution to that yet, very annoying.

  35. lilJ0hn Says:

    Wow…no one has mentioned where you really went wrong…
    c++

    see also humor http://www-users.cs.york.ac.uk/susan/joke/cpp.htm

  36. bollywood fun Says:

    Look at, and compare, the sizes of the resulting MinGW and MS VC++ executable files and you will see the difference.

  37. Gary kaizer Says:

    In order for your friend to run your application without running a setup wizard you should use the manual deployment method for the new libraries leveraged in VS2008.

    This is meant for x86 machines, but can be easily modified:

    1) Download and run http://www.microsoft.com/downloads/details.aspx?familyid=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en. Which should install the side-by-side assemblies needed. (vcredist_*.exe where * is the processor they have: x86, IA64, x64)

    2) If you are using any custom libraries include them with your exe and either put them with your exe or in the folder named after the library (so MFC90 library would go in the Myapp\MFC90\).

    3) Run you executable.

Leave a Reply