Vcpkg: Support static linking with /MT /MTd

Created on 20 Sep 2016  路  7Comments  路  Source: microsoft/vcpkg

Maybe it is already possible, but the docs so far appear to imply code gets compiled into DLLs.

Please also support compiling all code into a .lib with /MT /MTd runtime libraries for those of use who prefer their executables to be self-contained (or document how it is done).

vcpkg-feature discussion

Most helpful comment

If we're discussing static linking, it might be worthwhile asking how to handle LTCG (primarily for the purposes of PGO), as not all libraries can be compiled as static libraries. (there are probably a few out there that don't play nice with LTCG, but those should be significantly rarer)

Are there any plans to also support individual libraries as statically-linked but built against the dynamic runtime?

All 7 comments

DLLs are the hardest, so we've focused on them first, but static linking is definitely a needed feature!

Our current plan (open for discussion) is to have /MT be configured in the triplets files. So, you would add a single line to triplets\<triplet>.cmake like set(VCPKG_VS_CRT_LINKAGE STATIC). This would likely need to be combined with a separate set of triplets (like x86-winstatic).

In Visual Studio, this triplet would automatically get picked whenever /MT is selected.

If we're discussing static linking, it might be worthwhile asking how to handle LTCG (primarily for the purposes of PGO), as not all libraries can be compiled as static libraries. (there are probably a few out there that don't play nice with LTCG, but those should be significantly rarer)

Are there any plans to also support individual libraries as statically-linked but built against the dynamic runtime?

I have created a new branch: staticlibs.

In this branch we introduce an initial approach to supporting static libs.
Static libs are treated as a separate triplet. For example, in addition to x86-windows there is now x86-windows-static.

The triplet definitions in triplets\ specify some variables that can be used by the portfiles to configure the build appropriately. Currently, we have modified zlib only to take them into account and build either dlls or static libs.

To install zlib dlls or static libs you need the following commands, respectively:

vcpkg install zlib:x86-windows
vcpkg install zlib:x86-windows-static

We welcome feedback on the approach we have taken. In particular, one of the points that was raised is the name of the triplets. Some alternatives are:

x86-win (for dlls, instead of x86-windows)
x86-winstatic
x86-win-static

Is this issue resolved via #97 and therefore can be closed or is there still something missing needing to be addressed @aardappel

@adam4813 : thanks, this is very helpful.

One issue that worries me is that now each package needs to explicitly support static linking in its portfile, and if portfile authors are generally omitting this, it will be some pain for those using static linking getting that fixed.

Since most open source libraries have no particular requirements on what their code gets compiled into, a default solution that automagically is able to link statically would have been even better.

But this is already entirely workable, so feel free to close the issue.

To fill in a few more details about the support we've added with #97: these settings are controlled by the variables VCPKG_CRT_LINKAGE and VCPKG_LIBRARY_LINKAGE inside the triplet file [1]. These will then be used by vcpkg_configure_cmake to automatically set the appropriate compiler options and BUILD_SHARED_LIBS, so cmake-based ports will generally get support for free :) (@aardappel).

Are there any plans to also support individual libraries as statically-linked but built against the dynamic runtime?

@Orvid Yes, this is supported! We don't currently ship with a triplet that has the appropriate settings, but you can create your own triplet or modify the existing ones.

Finally, due to unfortunate interactions with the core of C++'s MSBuild, it is exceedingly difficult to reliably switch triplets based on the project's CRT linkage so we have removed that particular feature. <arch>-windows will always be selected when targetting Windows desktop and if you'd like to use an alternative triplet you will need to override the automatic detection.

  • MSBuild uses the property VcpkgTriplet which can be overridden with /p:VcpkgTriplet=<triplet> on the command line
  • CMake uses the macro VCPKG_TARGET_TRIPLET which can be overridden with -DVCPKG_TARGET_TRIPLET=<triplet> on the configure line
  • Other buildsystems are already encoding the triplet in their include dir and link dir, so just change those :)

[1] https://github.com/Microsoft/vcpkg/blob/master/triplets/x86-windows.cmake#L2

Thanks, that's even better :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oahzuw picture oahzuw  路  3Comments

PhilLab picture PhilLab  路  3Comments

husseinalihazime picture husseinalihazime  路  3Comments

grandprixgp picture grandprixgp  路  3Comments

invy picture invy  路  3Comments