Compiling code in Visual Studio that does not require .net C ++ installation

I am trying to compile a C ++ application that works without the .net framework or the Visual Studio runtime that needs to be installed. I did some research and found this article from MSDN, which shows how to compile native code in C ++. However, when I followed this example, after running the generated executable on a computer without Visual Studio runtime, I get the error MSVCP100D.dll missing on your computer. I know that you can fix a similar error with GCC by typing -static-libgcc -static-libstdc++ to generate static binary code. Can this be done with Visual Studio 2010? The reason I want to do this is because I like working with the Visual Studio IDE, but I would like my code to be portable for other OSs like UNIX. Thanks!

Note. I thought it might be useful to post the code that I am compiling for testing.

 #include <iostream> int main() { std::cout << "Hello world"; } 
+4
source share
3 answers

MSVCP100D.dll is a debug version of MSVCP100.dll . These are dynamic link libraries that implement C runtime libraries. This is necessary to implement the standard C ++ libraries in Visual C ++ 2010.

The compiler communicates with MSVCP100D.dll in debug mode. Your development machine should have MSVCP100D.dll when you install the compilers that ship with Visual Studio 2010. If this is not the case, something went wrong with the installation.

The compiler communicates with MSVCP100.dll in release mode. If you plan to deploy your application, you need to compile it in release mode and distribute the release versions of the binary. Do not distribute debug versions of the binary.

If even after that you still get errors, you may need to set the runtime of Visual C ++ 2010.

Installers are available for download:


If you prefer not to reference the dynamic library, you can statically link the C runtime libraries to your application by specifying the /MT compiler as described here .

Please note that static binding will increase the size of the application binary, and if the C runtime libraries are updated (for example, security / performance improvements), the application will not use them unless you recompile the application.

I highly recommend that you install the redistributable package anyway, as many other applications that you can use may require libraries.

+6
source

If you feel hacked and want to get the best of both worlds (i.e. a small executable and C runtime) only in release mode:

  • Download and install the Windows Driver Kit .

  • In your Properties project, select Release and:

    • Add the following to C / C ++ → General → Include Directories:

      • C:\WinDDK\7600.16385.1\inc\crt
      • C:\WinDDK\7600.16385.1\inc\api
      • C:\WinDDK\7600.16385.1\inc\atl71
      • C:\WinDDK\7600.16385.1\inc\mfc42
    • Install C / C ++ -> Code Generation -> Runtime Library before Multi-threaded DLL (/MD) .

    • Add the following links to Linker -> General -> Additional Library Directories (select the appropriate architecture / version):

      • C:\WinDDK\7600.16385.1\lib\Crt\i386
      • C:\WinDDK\7600.16385.1\lib\wxp\i386 (use wnet instead of wxp for the 64-bit version)
      • C:\WinDDK\7600.16385.1\lib\ATL\i386
      • C:\WinDDK\7600.16385.1\lib\Mfc\i386
    • Add BufferOverflowU.lib and msvcrt_winxp.obj to Linker → Input → Additional Dependencies.

    • You may need to disable buffer overflow checking ( /GS- )

  • Rebuild.

  • ...

  • Profit *

* Duck and cover when people shout at you for using WDK to create apps .: Sub>


Note:

If you use C ++ exception handling, you will have problems.

You will get an unresolved reference to __CxxFrameHandler3 because msvcrt only exports __CxxFrameHandler , which uses a different version of frame handlers than VS 2008.

Turns out Microsoft already has a hack for this in the WDK ( msvcrt_winxp.obj ), but it's a bit bloated, so I just ("just") made an abridged version instead (it took days ).

In short, you can fix this by including this build file in your project (make sure you define _WIN64 for 64-bit - the custom build step made for you below):

 ; Custom build step (use for x64 only): ; ml64.exe /Fo"$(IntDir)\$(InputName).obj" /D_WIN64 /c /nologo /W3 /Zi /Ta "$(InputPath)" ; Custom build output: $(IntDir)\$(InputName).obj ; ; Relevant links: ; http://kobyk.wordpress.com/2007/07/20/dynamically-linking-with-msvcrtdll-using-visual-c-2005/ ; http://www.openrce.org/articles/full_view/21 ; http://blogs.msdn.com/b/freik/archive/2006/01/04/509372.aspx ifndef _WIN64 .386 .model flat, c endif option dotname extern __CxxFrameHandler: PROC ifdef _WIN64 extern __imp___CxxFrameHandler: PROC extern __imp_VirtualProtect: PROC extern __imp_Sleep: PROC extern __imp_GetVersion: PROC endif .data ifdef _WIN64 ;ProtectFlag EQU ?ProtectFlag@ ?1??__CxxFrameHandler3@ @ 9@9 ProtectFlag dd ? endif ifdef _WIN64 endif .code ifdef _WIN64 includelib kernel32.lib endif includelib msvcrt.lib public __CxxFrameHandler3 ifdef _WIN64 __CxxFrameHandler3 proc frame else __CxxFrameHandler3 proc endif ifndef _WIN64 push ebp mov ebp,esp sub esp,28h push ebx push esi push edi cld mov dword ptr [ebp-4],eax mov esi,dword ptr [ebp-4] push 9 pop ecx lea edi,[ebp-28h] rep movs dword ptr es:[edi],dword ptr [esi] mov eax,dword ptr [ebp-28h] and eax,0F9930520h or eax,019930520h mov dword ptr [ebp-28h],eax lea eax,[ebp-28h] mov dword ptr [ebp-4],eax push dword ptr [ebp+14h] push dword ptr [ebp+10h] push dword ptr [ebp+0Ch] push dword ptr [ebp+8] mov eax,dword ptr [ebp-4] call __CxxFrameHandler add esp,10h pop edi pop esi pop ebx mov esp,ebp pop ebp ret else mov rax,rsp mov qword ptr [rax+8],rbx .savereg rbx, 50h mov qword ptr [rax+10h],rbp .savereg rbp, 58h mov qword ptr [rax+18h],rsi .savereg rsi, 60h push rdi .pushreg rdi push r12 .pushreg r12 push r13 .pushreg r13 sub rsp,30h .allocstack 30h .endprolog mov dword ptr [rax+20h],40h mov rax,qword ptr [r9+38h] mov rdi,r9 mov ebx,dword ptr [rax] mov rsi,r8 mov rbp,rdx add rbx,qword ptr [r9+8] mov r12,rcx mov eax,dword ptr [rbx] and eax,1FFFFFFFh cmp eax,19930520h je L140001261 mov r13d,1 mov eax,r13d lock xadd dword ptr [ProtectFlag],eax add eax,r13d cmp eax,r13d je L140001217 L1400011F0: lock add dword ptr [ProtectFlag],0FFFFFFFFh mov ecx,0Ah call qword ptr [__imp_Sleep] mov r11d,r13d lock xadd dword ptr [ProtectFlag],r11d add r11d,r13d cmp r11d,r13d jne L1400011F0 L140001217: mov r8d,dword ptr [rsp+68h] mov r13d,4 lea r9,[rsp+20h] mov rdx,r13 mov rcx,rbx call qword ptr [__imp_VirtualProtect] test eax,eax je L140001259 and dword ptr [rbx],0F9930520h or dword ptr [rbx],19930520h mov r8d,dword ptr [rsp+20h] lea r9,[rsp+68h] mov rdx,r13 mov rcx,rbx call qword ptr [__imp_VirtualProtect] L140001259: lock add dword ptr [ProtectFlag],0FFFFFFFFh L140001261: mov r9,rdi mov r8,rsi mov rdx,rbp mov rcx,r12 call qword ptr [__imp___CxxFrameHandler] mov rbx,qword ptr [rsp+50h] mov rbp,qword ptr [rsp+58h] mov rsi,qword ptr [rsp+60h] add rsp,30h pop r13 pop r12 pop rdi ret endif __CxxFrameHandler3 endp end 

(Note: You cannot implement this in C or C ++, since the calling convention is different from the one used by C / C ++ - this seems to be an undocumented format, assuming that the registers are defined in a certain way.)

If you get unresolved references to _chkstk or _alloca or something else, just find the version of alloca16.asm in your CRT (should be in Visual Studio CRT) and use this.

+3
source

This option may help:

http://msdn.microsoft.com/en-us/library/abx4dbyh.aspx

I think you need a multi-threaded static link: / MTd

+2
source

Source: https://habr.com/ru/post/1382995/


All Articles