Search code examples
c++windowsvisual-c++software-distributionmsvcrt

Statically link all dependences so that the end user will never be asked to install vc_redist.exe


I'm building a Windows executable with VS 2019. When I run it on my machine, it works, but I'm not 100% sure it will work for end users who don't have vc_redist.x64.exe version 2019. (Especially users on Win7 - it's in a niche where users still use this version).

How to statically link everything so that the end user will never be asked to download and install Visual C++ Redistributable "vc_redist"?

I'm using msbuild.exe, and no IDE. Which setting to add in the .vcxproj file or in the .cpp file to enable full static linking, to prevent the need for vcredist?

My .cpp code asks for these libraries:

#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "winmm.lib")

Sample .vcxproj:

<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>    
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props" />
  <PropertyGroup>
    <ConfigurationType>Application</ConfigurationType>
    <PlatformToolset>v142</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ItemGroup>
    <ClCompile Include="main.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="main.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Targets" />
</Project>

Note: it is linked with the topic How to deploy a Win32 API application as an executable, but here it's about doing it specifically directly from the .vcxproj file and without the IDE.


Solution

  • Add a specific ClCompile property for the compilation configuration:

    <Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        ...
        <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
            <ClCompile>
              <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
            </ClCompile>
        </ItemDefinitionGroup>
    </Project>
    

    Possible values are here: runtimeLibraryOption Enum (remove the "rt" prefix)

    rtMultiThreaded 0 : Multi-threaded (/MT)

    rtMultiThreadedDebug 1 : Multi-threaded Debug (/MTd)

    rtMultiThreadedDebugDLL 3 : Multi-threaded Debug DLL (/MDd)

    rtMultiThreadedDLL 2 : Multi-threaded DLL (/MD)

    More info about MT / MD can be found here: /MD, /MT, /LD (Use Run-Time Library)